summaryrefslogtreecommitdiff
path: root/test/Transforms/GVN
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2011-10-05 14:28:49 +0000
committerDuncan Sands <baldrick@free.fr>2011-10-05 14:28:49 +0000
commit02b5e72ac6ec1fe81e1f73f85be436faa078eabf (patch)
treeb134b98f43ec52bd80d331da2a4fa442fc017370 /test/Transforms/GVN
parent452c58f4c45249b5046f74a165430eedaab5f8f6 (diff)
downloadllvm-02b5e72ac6ec1fe81e1f73f85be436faa078eabf.tar.gz
llvm-02b5e72ac6ec1fe81e1f73f85be436faa078eabf.tar.bz2
llvm-02b5e72ac6ec1fe81e1f73f85be436faa078eabf.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141177 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/GVN')
-rw-r--r--test/Transforms/GVN/condprop.ll42
-rw-r--r--test/Transforms/GVN/phi-translate.ll2
2 files changed, 34 insertions, 10 deletions
diff --git a/test/Transforms/GVN/condprop.ll b/test/Transforms/GVN/condprop.ll
index b0728565f3..705490b67f 100644
--- a/test/Transforms/GVN/condprop.ll
+++ b/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
+}
diff --git a/test/Transforms/GVN/phi-translate.ll b/test/Transforms/GVN/phi-translate.ll
index f10537e0c9..fa91d2919e 100644
--- a/test/Transforms/GVN/phi-translate.ll
+++ b/test/Transforms/GVN/phi-translate.ll
@@ -14,7 +14,7 @@ target datalayout = "e-p:64:64:64"
@G = external global [100 x i32]
define i32 @foo(i32 %x, i32 %z) {
entry:
- %tobool = icmp eq i32 %x, 0
+ %tobool = icmp eq i32 %z, 0
br i1 %tobool, label %end, label %then
then: