diff options
| author | Duncan Sands <baldrick@free.fr> | 2011-10-05 14:28:49 +0000 |
|---|---|---|
| committer | Duncan Sands <baldrick@free.fr> | 2011-10-05 14:28:49 +0000 |
| commit | f4f47ccd1299a83c62680a4871cc46ffec9fa2c4 (patch) | |
| tree | 37ac1f3e747ab26e96ca49b75924c6eb06b75c22 /llvm/test/Transforms/GVN/condprop.ll | |
| parent | e90dd0587e5949aacfdb042cff1de24d0b6a104e (diff) | |
| download | bcm5719-llvm-f4f47ccd1299a83c62680a4871cc46ffec9fa2c4.tar.gz bcm5719-llvm-f4f47ccd1299a83c62680a4871cc46ffec9fa2c4.zip | |
GVN does simple propagation of conditions: when it sees a conditional
branch "br i1 %x, label %if_true, label %if_false" then it replaces
"%x" with "true" in places only reachable via the %if_true arm, and
with "false" in places only reachable via the %if_false arm. Except
that actually it doesn't: if value numbering shows that %y is equal
to %x then, yes, %y will be turned into true/false in this way, but
any occurrences of %x itself are not transformed. Fix this. What's
more, it's often the case that %x is an equality comparison such as
"%x = icmp eq %A, 0", in which case every occurrence of %A that is
only reachable via the %if_true arm can be replaced with 0. Implement
this and a few other variations on this theme. This reduces the number
of lines of LLVM IR in "GCC as one big file" by 0.2%. It has a bigger
impact on Ada code, typically reducing the number of lines of bitcode
by around 0.4% by removing repeated compiler generated checks. Passes
the LLVM nightly testsuite and the Ada ACATS testsuite.
llvm-svn: 141177
Diffstat (limited to 'llvm/test/Transforms/GVN/condprop.ll')
| -rw-r--r-- | llvm/test/Transforms/GVN/condprop.ll | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/llvm/test/Transforms/GVN/condprop.ll b/llvm/test/Transforms/GVN/condprop.ll index b0728565f38..705490b67ff 100644 --- a/llvm/test/Transforms/GVN/condprop.ll +++ b/llvm/test/Transforms/GVN/condprop.ll @@ -2,8 +2,8 @@ @a = external global i32 ; <i32*> [#uses=7] -; CHECK: @foo -define i32 @foo() nounwind { +; CHECK: @test1 +define i32 @test1() nounwind { entry: %0 = load i32* @a, align 4 %1 = icmp eq i32 %0, 4 @@ -54,22 +54,46 @@ return: ; preds = %bb8 ret i32 %.0 } -declare void @ext(i1) +declare void @foo(i1) -; CHECK: @bar -define void @bar(i1 %x, i1 %y) { +; CHECK: @test2 +define void @test2(i1 %x, i1 %y) { %z = or i1 %x, %y br i1 %z, label %true, label %false true: ; CHECK: true: %z2 = or i1 %x, %y - call void @ext(i1 %z2) -; CHECK: call void @ext(i1 true) + call void @foo(i1 %z2) +; CHECK: call void @foo(i1 true) br label %true false: ; CHECK: false: %z3 = or i1 %x, %y - call void @ext(i1 %z3) -; CHECK: call void @ext(i1 false) + call void @foo(i1 %z3) +; CHECK: call void @foo(i1 false) br label %false } + +declare void @bar(i32) + +; CHECK: @test3 +define void @test3(i32 %x, i32 %y) { + %xz = icmp eq i32 %x, 0 + %yz = icmp eq i32 %y, 0 + %z = and i1 %xz, %yz + br i1 %z, label %both_zero, label %nope +both_zero: + call void @foo(i1 %xz) +; CHECK: call void @foo(i1 true) + call void @foo(i1 %yz) +; CHECK: call void @foo(i1 true) + call void @bar(i32 %x) +; CHECK: call void @bar(i32 0) + call void @bar(i32 %y) +; CHECK: call void @bar(i32 0) + ret void +nope: + call void @foo(i1 %z) +; CHECK: call void @foo(i1 false) + ret void +} |

