diff options
Diffstat (limited to 'test/Transforms/SimplifyCFG')
| -rw-r--r-- | test/Transforms/SimplifyCFG/implied-and-or.ll | 183 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/sink-common-code.ll | 24 |
2 files changed, 207 insertions, 0 deletions
diff --git a/test/Transforms/SimplifyCFG/implied-and-or.ll b/test/Transforms/SimplifyCFG/implied-and-or.ll new file mode 100644 index 000000000000..e615f302feef --- /dev/null +++ b/test/Transforms/SimplifyCFG/implied-and-or.ll @@ -0,0 +1,183 @@ +; RUN: opt %s -S -simplifycfg | FileCheck %s + +declare void @foo() +declare void @bar() + + +; CHECK-LABEL: @test_and1 +; CHECK: taken: +; CHECK-NOT: cmp3 +; CHECK: call void @bar() +; CHECK-NEXT: call void @foo() +; CHECK: ret +define void @test_and1(i32 %a, i32 %b) { +entry: + %cmp1 = icmp eq i32 %a, 0 + %cmp2 = icmp eq i32 %b, 0 + %and = and i1 %cmp1, %cmp2 + br i1 %and, label %taken, label %end + +taken: + call void @bar() + %cmp3 = icmp eq i32 %a, 0 ;; <-- implied true + br i1 %cmp3, label %if.then, label %end + +if.then: + call void @foo() + br label %end + +end: + ret void +} + +; We can't infer anything if the result of the 'and' is false +; CHECK-LABEL: @test_and2 +; CHECK: taken: +; CHECK: call void @bar() +; CHECK: %cmp3 +; CHECK: br i1 %cmp3 +; CHECK: if.then: +; CHECK: call void @foo() +; CHECK: ret +define void @test_and2(i32 %a, i32 %b) { +entry: + %cmp1 = icmp eq i32 %a, 0 + %cmp2 = icmp eq i32 %b, 0 + %and = and i1 %cmp1, %cmp2 + br i1 %and, label %end, label %taken + +taken: + call void @bar() + %cmp3 = icmp eq i32 %a, 0 + br i1 %cmp3, label %if.then, label %end + +if.then: + call void @foo() + br label %end + +end: + ret void +} + +; CHECK-LABEL: @test_or1 +; CHECK: taken: +; CHECK-NOT: cmp3 +; CHECK: call void @bar() +; CHECK-NEXT: call void @foo() +; CHECK: ret +define void @test_or1(i32 %a, i32 %b) { +entry: + %cmp1 = icmp eq i32 %a, 0 + %cmp2 = icmp eq i32 %b, 0 + %or = or i1 %cmp1, %cmp2 + br i1 %or, label %end, label %taken + +taken: + call void @bar() + %cmp3 = icmp ne i32 %a, 0 ;; <-- implied true + br i1 %cmp3, label %if.then, label %end + +if.then: + call void @foo() + br label %end + +end: + ret void +} + +; We can't infer anything if the result of the 'or' is true +; CHECK-LABEL: @test_or2 +; CHECK: call void @bar() +; CHECK: %cmp3 +; CHECK: br i1 %cmp3 +; CHECK: if.then: +; CHECK: call void @foo() +; CHECK: ret +define void @test_or2(i32 %a, i32 %b) { +entry: + %cmp1 = icmp eq i32 %a, 0 + %cmp2 = icmp eq i32 %b, 0 + %or = or i1 %cmp1, %cmp2 + br i1 %or, label %taken, label %end + +taken: + call void @bar() + %cmp3 = icmp eq i32 %a, 0 + br i1 %cmp3, label %if.then, label %end + +if.then: + call void @foo() + br label %end + +end: + ret void +} + +; We can recurse a tree of 'and' or 'or's. +; CHECK-LABEL: @test_and_recurse1 +; CHECK: taken: +; CHECK-NEXT: call void @bar() +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label %end +; CHECK: ret +define void @test_and_recurse1(i32 %a, i32 %b, i32 %c) { +entry: + %cmpa = icmp eq i32 %a, 0 + %cmpb = icmp eq i32 %b, 0 + %cmpc = icmp eq i32 %c, 0 + %and1 = and i1 %cmpa, %cmpb + %and2 = and i1 %and1, %cmpc + br i1 %and2, label %taken, label %end + +taken: + call void @bar() + %cmp3 = icmp eq i32 %a, 0 + br i1 %cmp3, label %if.then, label %end + +if.then: + call void @foo() + br label %end + +end: + ret void +} + +; Check to make sure we don't recurse too deep. +; CHECK-LABEL: @test_and_recurse2 +; CHECK: taken: +; CHECK-NEXT: call void @bar() +; CHECK-NEXT: %cmp3 = icmp eq i32 %a, 0 +; CHECK-NEXT: br i1 %cmp3, label %if.then, label %end +; CHECK: ret +define void @test_and_recurse2(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, + i32 %g, i32 %h) { +entry: + %cmpa = icmp eq i32 %a, 0 + %cmpb = icmp eq i32 %b, 0 + %cmpc = icmp eq i32 %c, 0 + %cmpd = icmp eq i32 %d, 0 + %cmpe = icmp eq i32 %e, 0 + %cmpf = icmp eq i32 %f, 0 + %cmpg = icmp eq i32 %g, 0 + %cmph = icmp eq i32 %h, 0 + %and1 = and i1 %cmpa, %cmpb + %and2 = and i1 %and1, %cmpc + %and3 = and i1 %and2, %cmpd + %and4 = and i1 %and3, %cmpe + %and5 = and i1 %and4, %cmpf + %and6 = and i1 %and5, %cmpg + %and7 = and i1 %and6, %cmph + br i1 %and7, label %taken, label %end + +taken: + call void @bar() + %cmp3 = icmp eq i32 %a, 0 ; <-- can be implied true + br i1 %cmp3, label %if.then, label %end + +if.then: + call void @foo() + br label %end + +end: + ret void +} diff --git a/test/Transforms/SimplifyCFG/sink-common-code.ll b/test/Transforms/SimplifyCFG/sink-common-code.ll index 0f7bfa8516c9..513da477607b 100644 --- a/test/Transforms/SimplifyCFG/sink-common-code.ll +++ b/test/Transforms/SimplifyCFG/sink-common-code.ll @@ -818,6 +818,30 @@ merge: ; CHECK: right: ; CHECK-NEXT: %val1 = call i32 @call_target() [ "deopt"(i32 20) ] +%T = type {i32, i32} + +define i32 @test_insertvalue(i1 zeroext %flag, %T %P) { +entry: + br i1 %flag, label %if.then, label %if.else + +if.then: + %t1 = insertvalue %T %P, i32 0, 0 + br label %if.end + +if.else: + %t2 = insertvalue %T %P, i32 1, 0 + br label %if.end + +if.end: + %t = phi %T [%t1, %if.then], [%t2, %if.else] + ret i32 1 +} + +; CHECK-LABEL: @test_insertvalue +; CHECK: select +; CHECK: insertvalue +; CHECK-NOT: insertvalue + ; CHECK: ![[TBAA]] = !{![[TYPE:[0-9]]], ![[TYPE]], i64 0} ; CHECK: ![[TYPE]] = !{!"float", ![[TEXT:[0-9]]]} ; CHECK: ![[TEXT]] = !{!"an example type tree"} |
