diff options
Diffstat (limited to 'llvm/test/Transforms/SimpleLoopUnswitch')
-rw-r--r-- | llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll | 16 | ||||
-rw-r--r-- | llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll | 176 |
2 files changed, 188 insertions, 4 deletions
diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll b/llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll index cbee0fef14b..03c23da6c96 100644 --- a/llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll @@ -4,17 +4,25 @@ ; itself is an LIV loop condition (not partial LIV which could occur in and/or). define i32 @test(i1 %cond1, i32 %var1) { +; CHECK-LABEL: define i32 @test( entry: br label %loop_begin +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split +; +; CHECK: entry.split: +; CHECK-NEXT: br label %loop_begin loop_begin: %var3 = phi i32 [%var1, %entry], [%var2, %do_something] %cond2 = icmp eq i32 %var3, 10 %cond.and = and i1 %cond1, %cond2 - -; %cond.and only has %cond1 as LIV so no unswitch should happen. -; CHECK: br i1 %cond.and, label %do_something, label %loop_exit - br i1 %cond.and, label %do_something, label %loop_exit + br i1 %cond.and, label %do_something, label %loop_exit +; CHECK: loop_begin: +; CHECK-NEXT: %[[VAR3:.*]] = phi i32 +; CHECK-NEXT: %[[COND2:.*]] = icmp eq i32 %[[VAR3]], 10 +; CHECK-NEXT: %[[COND_AND:.*]] = and i1 true, %[[COND2]] +; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit do_something: %var2 = add i32 %var3, 1 diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll index a97e3f81a8e..572d2b6cf83 100644 --- a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll @@ -443,3 +443,179 @@ cleanup: ; CHECK: cleanup: ; CHECK-NEXT: ret void } + +define i32 @test_partial_condition_unswitch_and(i32* %var, i1 %cond1, i1 %cond2) { +; CHECK-LABEL: @test_partial_condition_unswitch_and( +entry: + br label %loop_begin +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split +; +; CHECK: entry.split: +; CHECK-NEXT: br i1 %cond2, label %entry.split.split, label %loop_exit +; +; CHECK: entry.split.split: +; CHECK-NEXT: br label %loop_begin + +loop_begin: + br i1 %cond1, label %continue, label %loop_exit +; CHECK: loop_begin: +; CHECK-NEXT: br label %continue + +continue: + %var_val = load i32, i32* %var + %var_cond = trunc i32 %var_val to i1 + %cond_and = and i1 %var_cond, %cond2 + br i1 %cond_and, label %do_something, label %loop_exit +; CHECK: continue: +; CHECK-NEXT: %[[VAR:.*]] = load i32 +; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1 +; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true +; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit + +do_something: + call void @some_func() noreturn nounwind + br label %loop_begin +; CHECK: do_something: +; CHECK-NEXT: call +; CHECK-NEXT: br label %loop_begin + +loop_exit: + ret i32 0 +; CHECK: loop_exit: +; CHECK-NEXT: br label %loop_exit.split +; +; CHECK: loop_exit.split: +; CHECK-NEXT: ret +} + +define i32 @test_partial_condition_unswitch_or(i32* %var, i1 %cond1, i1 %cond2, i1 %cond3, i1 %cond4, i1 %cond5, i1 %cond6) { +; CHECK-LABEL: @test_partial_condition_unswitch_or( +entry: + br label %loop_begin +; CHECK-NEXT: entry: +; CHECK-NEXT: %[[INV_OR1:.*]] = or i1 %cond4, %cond2 +; CHECK-NEXT: %[[INV_OR2:.*]] = or i1 %[[INV_OR1]], %cond3 +; CHECK-NEXT: %[[INV_OR3:.*]] = or i1 %[[INV_OR2]], %cond1 +; CHECK-NEXT: br i1 %[[INV_OR3]], label %loop_exit.split, label %entry.split +; +; CHECK: entry.split: +; CHECK-NEXT: br label %loop_begin + +loop_begin: + %var_val = load i32, i32* %var + %var_cond = trunc i32 %var_val to i1 + %cond_or1 = or i1 %var_cond, %cond1 + %cond_or2 = or i1 %cond2, %cond3 + %cond_or3 = or i1 %cond_or1, %cond_or2 + %cond_xor1 = xor i1 %cond5, %var_cond + %cond_and1 = and i1 %cond6, %var_cond + %cond_or4 = or i1 %cond_xor1, %cond_and1 + %cond_or5 = or i1 %cond_or3, %cond_or4 + %cond_or6 = or i1 %cond_or5, %cond4 + br i1 %cond_or6, label %loop_exit, label %do_something +; CHECK: loop_begin: +; CHECK-NEXT: %[[VAR:.*]] = load i32 +; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1 +; CHECK-NEXT: %[[COND_OR1:.*]] = or i1 %[[VAR_COND]], false +; CHECK-NEXT: %[[COND_OR2:.*]] = or i1 false, false +; CHECK-NEXT: %[[COND_OR3:.*]] = or i1 %[[COND_OR1]], %[[COND_OR2]] +; CHECK-NEXT: %[[COND_XOR:.*]] = xor i1 %cond5, %[[VAR_COND]] +; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %cond6, %[[VAR_COND]] +; CHECK-NEXT: %[[COND_OR4:.*]] = or i1 %[[COND_XOR]], %[[COND_AND]] +; CHECK-NEXT: %[[COND_OR5:.*]] = or i1 %[[COND_OR3]], %[[COND_OR4]] +; CHECK-NEXT: %[[COND_OR6:.*]] = or i1 %[[COND_OR5]], false +; CHECK-NEXT: br i1 %[[COND_OR6]], label %loop_exit, label %do_something + +do_something: + call void @some_func() noreturn nounwind + br label %loop_begin +; CHECK: do_something: +; CHECK-NEXT: call +; CHECK-NEXT: br label %loop_begin + +loop_exit: + ret i32 0 +; CHECK: loop_exit.split: +; CHECK-NEXT: ret +} + +define i32 @test_partial_condition_unswitch_with_lcssa_phi1(i32* %var, i1 %cond, i32 %x) { +; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi1( +entry: + br label %loop_begin +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond, label %entry.split, label %loop_exit.split +; +; CHECK: entry.split: +; CHECK-NEXT: br label %loop_begin + +loop_begin: + %var_val = load i32, i32* %var + %var_cond = trunc i32 %var_val to i1 + %cond_and = and i1 %var_cond, %cond + br i1 %cond_and, label %do_something, label %loop_exit +; CHECK: loop_begin: +; CHECK-NEXT: %[[VAR:.*]] = load i32 +; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1 +; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true +; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit + +do_something: + call void @some_func() noreturn nounwind + br label %loop_begin +; CHECK: do_something: +; CHECK-NEXT: call +; CHECK-NEXT: br label %loop_begin + +loop_exit: + %x.lcssa = phi i32 [ %x, %loop_begin ] + ret i32 %x.lcssa +; CHECK: loop_exit: +; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ] +; CHECK-NEXT: br label %loop_exit.split +; +; CHECK: loop_exit.split: +; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ] +; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]] +} + +define i32 @test_partial_condition_unswitch_with_lcssa_phi2(i32* %var, i1 %cond, i32 %x, i32 %y) { +; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi2( +entry: + br label %loop_begin +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond, label %entry.split, label %loop_exit.split +; +; CHECK: entry.split: +; CHECK-NEXT: br label %loop_begin + +loop_begin: + %var_val = load i32, i32* %var + %var_cond = trunc i32 %var_val to i1 + %cond_and = and i1 %var_cond, %cond + br i1 %cond_and, label %do_something, label %loop_exit +; CHECK: loop_begin: +; CHECK-NEXT: %[[VAR:.*]] = load i32 +; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1 +; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true +; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit + +do_something: + call void @some_func() noreturn nounwind + br i1 %var_cond, label %loop_begin, label %loop_exit +; CHECK: do_something: +; CHECK-NEXT: call +; CHECK-NEXT: br i1 %[[VAR_COND]], label %loop_begin, label %loop_exit + +loop_exit: + %xy.lcssa = phi i32 [ %x, %loop_begin ], [ %y, %do_something ] + ret i32 %xy.lcssa +; CHECK: loop_exit: +; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ], [ %y, %do_something ] +; CHECK-NEXT: br label %loop_exit.split +; +; CHECK: loop_exit.split: +; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ] +; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]] +} |