diff options
Diffstat (limited to 'test/Transforms/SimplifyCFG/switch-on-const-select.ll')
-rw-r--r-- | test/Transforms/SimplifyCFG/switch-on-const-select.ll | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/test/Transforms/SimplifyCFG/switch-on-const-select.ll b/test/Transforms/SimplifyCFG/switch-on-const-select.ll new file mode 100644 index 000000000000..5494a651d47d --- /dev/null +++ b/test/Transforms/SimplifyCFG/switch-on-const-select.ll @@ -0,0 +1,138 @@ +; RUN: opt < %s -simplifycfg -S | FileCheck %s + +; Test basic folding to a conditional branch. +define i32 @foo(i64 %x, i64 %y) nounwind { +; CHECK: @foo +entry: + %eq = icmp eq i64 %x, %y + br i1 %eq, label %b, label %switch +switch: + %lt = icmp slt i64 %x, %y +; CHECK: br i1 %lt, label %a, label %b + %qux = select i1 %lt, i32 0, i32 2 + switch i32 %qux, label %bees [ + i32 0, label %a + i32 1, label %b + i32 2, label %b + ] +a: + tail call void @bees.a() nounwind + ret i32 1 +; CHECK: b: +; CHECK-NEXT: %retval = phi i32 [ 0, %switch ], [ 2, %entry ] +b: + %retval = phi i32 [0, %switch], [0, %switch], [2, %entry] + tail call void @bees.b() nounwind + ret i32 %retval +; CHECK-NOT: bees: +bees: + tail call void @llvm.trap() nounwind + unreachable +} + +; Test basic folding to an unconditional branch. +define i32 @bar(i64 %x, i64 %y) nounwind { +; CHECK: @bar +entry: +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call void @bees.a() nounwind +; CHECK-NEXT: ret i32 0 + %lt = icmp slt i64 %x, %y + %qux = select i1 %lt, i32 0, i32 2 + switch i32 %qux, label %bees [ + i32 0, label %a + i32 1, label %b + i32 2, label %a + ] +a: + %retval = phi i32 [0, %entry], [0, %entry], [1, %b] + tail call void @bees.a() nounwind + ret i32 0 +b: + tail call void @bees.b() nounwind + br label %a +bees: + tail call void @llvm.trap() nounwind + unreachable +} + +; Test the edge case where both values from the select are the default case. +define void @bazz(i64 %x, i64 %y) nounwind { +; CHECK: @bazz +entry: +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call void @bees.b() nounwind +; CHECK-NEXT: ret void + %lt = icmp slt i64 %x, %y + %qux = select i1 %lt, i32 10, i32 12 + switch i32 %qux, label %b [ + i32 0, label %a + i32 1, label %bees + i32 2, label %bees + ] +a: + tail call void @bees.a() nounwind + ret void +b: + tail call void @bees.b() nounwind + ret void +bees: + tail call void @llvm.trap() + unreachable +} + +; Test the edge case where both values from the select are equal. +define void @quux(i64 %x, i64 %y) nounwind { +; CHECK: @quux +entry: +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call void @bees.a() nounwind +; CHECK-NEXT: ret void + %lt = icmp slt i64 %x, %y + %qux = select i1 %lt, i32 0, i32 0 + switch i32 %qux, label %b [ + i32 0, label %a + i32 1, label %bees + i32 2, label %bees + ] +a: + tail call void @bees.a() nounwind + ret void +b: + tail call void @bees.b() nounwind + ret void +bees: + tail call void @llvm.trap() + unreachable +} + +; A final test, for phi node munging. +define i32 @xyzzy(i64 %x, i64 %y) { +; CHECK: @xyzzy +entry: + %eq = icmp eq i64 %x, %y + br i1 %eq, label %r, label %cont +cont: +; CHECK: %lt = icmp slt i64 %x, %y + %lt = icmp slt i64 %x, %y +; CHECK-NEXT: br i1 %lt, label %a, label %r + %qux = select i1 %lt, i32 0, i32 2 + switch i32 %qux, label %bees [ + i32 0, label %a + i32 1, label %r + i32 2, label %r + ] +r: + %val = phi i32 [0, %entry], [1, %cont], [1, %cont] + ret i32 %val +a: + ret i32 -1 +; CHECK-NOT: bees: +bees: + tail call void @llvm.trap() + unreachable +} + +declare void @llvm.trap() nounwind noreturn +declare void @bees.a() nounwind +declare void @bees.b() nounwind |