diff options
author | Frits van Bommel <fvbommel@gmail.com> | 2010-12-15 09:51:20 +0000 |
---|---|---|
committer | Frits van Bommel <fvbommel@gmail.com> | 2010-12-15 09:51:20 +0000 |
commit | 26e097ca4bdb31000655ff9ec39fe7d9b7ea226d (patch) | |
tree | db522151cd6ccf109a0185760d9f988b783429f0 /test/Transforms/JumpThreading/select.ll | |
parent | 22447ae54bcb8ca94ed994cad103074a24e66781 (diff) | |
download | external_llvm-26e097ca4bdb31000655ff9ec39fe7d9b7ea226d.zip external_llvm-26e097ca4bdb31000655ff9ec39fe7d9b7ea226d.tar.gz external_llvm-26e097ca4bdb31000655ff9ec39fe7d9b7ea226d.tar.bz2 |
Teach jump threading to "look through" a select when the branch direction of a terminator depends on it.
When it sees a promising select it now tries to figure out whether the condition of the select is known in any of the predecessors and if so it maps the operands appropriately.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121859 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/JumpThreading/select.ll')
-rw-r--r-- | test/Transforms/JumpThreading/select.ll | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/test/Transforms/JumpThreading/select.ll b/test/Transforms/JumpThreading/select.ll new file mode 100644 index 0000000..8a81857 --- /dev/null +++ b/test/Transforms/JumpThreading/select.ll @@ -0,0 +1,123 @@ +; RUN: opt -S -jump-threading < %s | FileCheck %s + +declare void @foo() +declare void @bar() +declare void @baz() +declare void @quux() + + +; Jump threading of branch with select as condition. +; Mostly theoretical since instruction combining simplifies all selects of +; booleans where at least one operand is true/false/undef. + +; CHECK: @test_br +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond, label %L1, +define void @test_br(i1 %cond, i1 %value) nounwind { +entry: + br i1 %cond, label %L0, label %L3 +L0: + %expr = select i1 %cond, i1 true, i1 %value + br i1 %expr, label %L1, label %L2 + +L1: + call void @foo() + ret void +L2: + call void @bar() + ret void +L3: + call void @baz() + br label %L0 +} + + +; Jump threading of switch with select as condition. + +; CHECK: @test_switch +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond, label %L1, +define void @test_switch(i1 %cond, i8 %value) nounwind { +entry: + br i1 %cond, label %L0, label %L4 +L0: + %expr = select i1 %cond, i8 1, i8 %value + switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2] + +L1: + call void @foo() + ret void +L2: + call void @bar() + ret void +L3: + call void @baz() + ret void +L4: + call void @quux() + br label %L0 +} + +; Make sure the blocks in the indirectbr test aren't trivially removable as +; successors by taking their addresses. +@anchor = constant [3 x i8*] [ + i8* blockaddress(@test_indirectbr, %L1), + i8* blockaddress(@test_indirectbr, %L2), + i8* blockaddress(@test_indirectbr, %L3) +] + + +; Jump threading of indirectbr with select as address. + +; CHECK: @test_indirectbr +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond, label %L1, label %L3 +define void @test_indirectbr(i1 %cond, i8* %address) nounwind { +entry: + br i1 %cond, label %L0, label %L3 +L0: + %indirect.goto.dest = select i1 %cond, i8* blockaddress(@test_indirectbr, %L1), i8* %address + indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3] + +L1: + call void @foo() + ret void +L2: + call void @bar() + ret void +L3: + call void @baz() + ret void +} + + +; A more complicated case: the condition is a select based on a comparison. + +; CHECK: @test_switch_cmp +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond, label %L0, label %[[THREADED:[A-Za-z.0-9]+]] +; CHECK: [[THREADED]]: +; CHECK-NEXT: call void @quux +; CHECK-NEXT: br label %L1 +define void @test_switch_cmp(i1 %cond, i32 %val, i8 %value) nounwind { +entry: + br i1 %cond, label %L0, label %L4 +L0: + %val.phi = phi i32 [%val, %entry], [-1, %L4] + %cmp = icmp slt i32 %val.phi, 0 + %expr = select i1 %cmp, i8 1, i8 %value + switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2] + +L1: + call void @foo() + ret void +L2: + call void @bar() + ret void +L3: + call void @baz() + ret void +L4: + call void @quux() + br label %L0 +} |