summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/SimpleLoopUnswitch
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/SimpleLoopUnswitch')
-rw-r--r--llvm/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll16
-rw-r--r--llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll176
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]]
+}
OpenPOWER on IntegriCloud