summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll163
1 files changed, 162 insertions, 1 deletions
diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
index 1a14bd209d1..f17676028ac 100644
--- a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
+++ b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
@@ -2662,4 +2662,165 @@ loop_exit:
ret i32 0
; CHECK: loop_exit:
; CHECK-NEXT: ret
-} \ No newline at end of file
+}
+
+; Non-trivial partial loop unswitching of an invariant input to an 'or'.
+define i32 @test25(i1* %ptr, i1 %cond) {
+; CHECK-LABEL: @test25(
+entry:
+ br label %loop_begin
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 %cond, label %entry.split.us, label %entry.split
+
+loop_begin:
+ %v1 = load i1, i1* %ptr
+ %cond_or = or i1 %v1, %cond
+ br i1 %cond_or, label %loop_a, label %loop_b
+
+loop_a:
+ call void @a()
+ br label %latch
+; The 'loop_a' unswitched loop.
+;
+; CHECK: entry.split.us:
+; CHECK-NEXT: br label %loop_begin.us
+;
+; CHECK: loop_begin.us:
+; CHECK-NEXT: %[[V1_US:.*]] = load i1, i1* %ptr
+; CHECK-NEXT: %[[OR_US:.*]] = or i1 %[[V1_US]], true
+; CHECK-NEXT: br label %loop_a.us
+;
+; CHECK: loop_a.us:
+; CHECK-NEXT: call void @a()
+; CHECK-NEXT: br label %latch.us
+;
+; CHECK: latch.us:
+; CHECK-NEXT: %[[V2_US:.*]] = load i1, i1* %ptr
+; CHECK-NEXT: br i1 %[[V2_US]], label %loop_begin.us, label %loop_exit.split.us
+;
+; CHECK: loop_exit.split.us:
+; CHECK-NEXT: br label %loop_exit
+
+loop_b:
+ call void @b()
+ br label %latch
+; The original loop.
+;
+; CHECK: entry.split:
+; CHECK-NEXT: br label %loop_begin
+;
+; CHECK: loop_begin:
+; CHECK-NEXT: %[[V1:.*]] = load i1, i1* %ptr
+; CHECK-NEXT: %[[OR:.*]] = or i1 %[[V1]], false
+; CHECK-NEXT: br i1 %[[OR]], label %loop_a, label %loop_b
+;
+; CHECK: loop_a:
+; CHECK-NEXT: call void @a()
+; CHECK-NEXT: br label %latch
+;
+; CHECK: loop_b:
+; CHECK-NEXT: call void @b()
+; CHECK-NEXT: br label %latch
+
+latch:
+ %v2 = load i1, i1* %ptr
+ br i1 %v2, label %loop_begin, label %loop_exit
+; CHECK: latch:
+; CHECK-NEXT: %[[V2:.*]] = load i1, i1* %ptr
+; CHECK-NEXT: br i1 %[[V2]], label %loop_begin, label %loop_exit.split
+
+loop_exit:
+ ret i32 0
+; CHECK: loop_exit.split:
+; CHECK-NEXT: br label %loop_exit
+;
+; CHECK: loop_exit:
+; CHECK-NEXT: ret
+}
+
+; Non-trivial partial loop unswitching of multiple invariant inputs to an `and`
+; chain.
+define i32 @test26(i1* %ptr1, i1* %ptr2, i1* %ptr3, i1 %cond1, i1 %cond2, i1 %cond3) {
+; CHECK-LABEL: @test26(
+entry:
+ br label %loop_begin
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %[[INV_AND:.*]] = and i1 %cond3, %cond1
+; CHECK-NEXT: br i1 %[[INV_AND]], label %entry.split, label %entry.split.us
+
+loop_begin:
+ %v1 = load i1, i1* %ptr1
+ %v2 = load i1, i1* %ptr2
+ %cond_and1 = and i1 %v1, %cond1
+ %cond_or1 = or i1 %v2, %cond2
+ %cond_and2 = and i1 %cond_and1, %cond_or1
+ %cond_and3 = and i1 %cond_and2, %cond3
+ br i1 %cond_and3, label %loop_a, label %loop_b
+; The 'loop_b' unswitched loop.
+;
+; CHECK: entry.split.us:
+; CHECK-NEXT: br label %loop_begin.us
+;
+; CHECK: loop_begin.us:
+; CHECK-NEXT: %[[V1_US:.*]] = load i1, i1* %ptr1
+; CHECK-NEXT: %[[V2_US:.*]] = load i1, i1* %ptr2
+; CHECK-NEXT: %[[AND1_US:.*]] = and i1 %[[V1_US]], false
+; CHECK-NEXT: %[[OR1_US:.*]] = or i1 %[[V2_US]], %cond2
+; CHECK-NEXT: %[[AND2_US:.*]] = and i1 %[[AND1_US]], %[[OR1_US]]
+; CHECK-NEXT: %[[AND3_US:.*]] = and i1 %[[AND2_US]], false
+; CHECK-NEXT: br label %loop_b.us
+;
+; CHECK: loop_b.us:
+; CHECK-NEXT: call void @b()
+; CHECK-NEXT: br label %latch.us
+;
+; CHECK: latch.us:
+; CHECK-NEXT: %[[V3_US:.*]] = load i1, i1* %ptr3
+; CHECK-NEXT: br i1 %[[V3_US]], label %loop_begin.us, label %loop_exit.split.us
+;
+; CHECK: loop_exit.split.us:
+; CHECK-NEXT: br label %loop_exit
+
+; The original loop.
+;
+; CHECK: entry.split:
+; CHECK-NEXT: br label %loop_begin
+;
+; CHECK: loop_begin:
+; CHECK-NEXT: %[[V1:.*]] = load i1, i1* %ptr1
+; CHECK-NEXT: %[[V2:.*]] = load i1, i1* %ptr2
+; CHECK-NEXT: %[[AND1:.*]] = and i1 %[[V1]], true
+; CHECK-NEXT: %[[OR1:.*]] = or i1 %[[V2]], %cond2
+; CHECK-NEXT: %[[AND2:.*]] = and i1 %[[AND1]], %[[OR1]]
+; CHECK-NEXT: %[[AND3:.*]] = and i1 %[[AND2]], true
+; CHECK-NEXT: br i1 %[[AND3]], label %loop_a, label %loop_b
+
+loop_a:
+ call void @a()
+ br label %latch
+; CHECK: loop_a:
+; CHECK-NEXT: call void @a()
+; CHECK-NEXT: br label %latch
+
+loop_b:
+ call void @b()
+ br label %latch
+; CHECK: loop_b:
+; CHECK-NEXT: call void @b()
+; CHECK-NEXT: br label %latch
+
+latch:
+ %v3 = load i1, i1* %ptr3
+ br i1 %v3, label %loop_begin, label %loop_exit
+; CHECK: latch:
+; CHECK-NEXT: %[[V3:.*]] = load i1, i1* %ptr3
+; CHECK-NEXT: br i1 %[[V3]], label %loop_begin, label %loop_exit.split
+
+loop_exit:
+ ret i32 0
+; CHECK: loop_exit.split:
+; CHECK-NEXT: br label %loop_exit
+;
+; CHECK: loop_exit:
+; CHECK-NEXT: ret
+}
OpenPOWER on IntegriCloud