summaryrefslogtreecommitdiff
path: root/test/Transforms/GVN
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-06-04 22:44:21 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-06-04 22:44:21 +0000
commit06c6791742dfdd54b51441589e1c0921f9851675 (patch)
treedb3ee9b1cdab05564c62d68b6877e20e780180b3 /test/Transforms/GVN
parent15f1d8c557c217b90a82599d5f0f849f8340a1e3 (diff)
downloadllvm-06c6791742dfdd54b51441589e1c0921f9851675.tar.gz
llvm-06c6791742dfdd54b51441589e1c0921f9851675.tar.bz2
llvm-06c6791742dfdd54b51441589e1c0921f9851675.tar.xz
When gvn decides to replace an instruction with another, we have to patch the
replacement to make it at least as generic as the instruction being replaced. This includes: * dropping nsw/nuw flags * getting the least restrictive tbaa and fpmath metadata * merging ranges Fixes PR12979. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157958 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/GVN')
-rw-r--r--test/Transforms/GVN/fpmath.ll45
-rw-r--r--test/Transforms/GVN/pr12979.ll79
-rw-r--r--test/Transforms/GVN/range.ll101
-rw-r--r--test/Transforms/GVN/tbaa.ll81
4 files changed, 306 insertions, 0 deletions
diff --git a/test/Transforms/GVN/fpmath.ll b/test/Transforms/GVN/fpmath.ll
new file mode 100644
index 0000000000..8ab285448f
--- /dev/null
+++ b/test/Transforms/GVN/fpmath.ll
@@ -0,0 +1,45 @@
+; RUN: opt %s -gvn -S -o - | FileCheck %s
+
+define double @test1(double %x, double %y) {
+; CHECK: @test1(double %x, double %y)
+; CHECK: %add1 = fadd double %x, %y
+; CHECK-NOT: fpmath
+; CHECK: %foo = fadd double %add1, %add1
+ %add1 = fadd double %x, %y, !fpmath !0
+ %add2 = fadd double %x, %y
+ %foo = fadd double %add1, %add2
+ ret double %foo
+}
+
+define double @test2(double %x, double %y) {
+; CHECK: @test2(double %x, double %y)
+; CHECK: %add1 = fadd double %x, %y, !fpmath !0
+; CHECK: %foo = fadd double %add1, %add1
+ %add1 = fadd double %x, %y, !fpmath !0
+ %add2 = fadd double %x, %y, !fpmath !0
+ %foo = fadd double %add1, %add2
+ ret double %foo
+}
+
+define double @test3(double %x, double %y) {
+; CHECK: @test3(double %x, double %y)
+; CHECK: %add1 = fadd double %x, %y, !fpmath !1
+; CHECK: %foo = fadd double %add1, %add1
+ %add1 = fadd double %x, %y, !fpmath !1
+ %add2 = fadd double %x, %y, !fpmath !0
+ %foo = fadd double %add1, %add2
+ ret double %foo
+}
+
+define double @test4(double %x, double %y) {
+; CHECK: @test4(double %x, double %y)
+; CHECK: %add1 = fadd double %x, %y, !fpmath !1
+; CHECK: %foo = fadd double %add1, %add1
+ %add1 = fadd double %x, %y, !fpmath !0
+ %add2 = fadd double %x, %y, !fpmath !1
+ %foo = fadd double %add1, %add2
+ ret double %foo
+}
+
+!0 = metadata !{ float 5.0 }
+!1 = metadata !{ float 2.5 }
diff --git a/test/Transforms/GVN/pr12979.ll b/test/Transforms/GVN/pr12979.ll
new file mode 100644
index 0000000000..669da9127d
--- /dev/null
+++ b/test/Transforms/GVN/pr12979.ll
@@ -0,0 +1,79 @@
+; RUN: opt %s -gvn -S -o - | FileCheck %s
+
+define i32 @test1(i32 %x, i32 %y) {
+; CHECK: @test1(i32 %x, i32 %y)
+; CHECK: %add1 = add i32 %x, %y
+; CHECK: %foo = add i32 %add1, %add1
+
+ %add1 = add nsw i32 %x, %y
+ %add2 = add i32 %x, %y
+ %foo = add i32 %add1, %add2
+ ret i32 %foo
+}
+
+define i32 @test2(i32 %x, i32 %y) {
+; CHECK: @test2(i32 %x, i32 %y)
+; CHECK: %add1 = add i32 %x, %y
+; CHECK: %foo = add i32 %add1, %add1
+
+ %add1 = add nuw i32 %x, %y
+ %add2 = add i32 %x, %y
+ %foo = add i32 %add1, %add2
+ ret i32 %foo
+}
+
+define i32 @test3(i32 %x, i32 %y) {
+; CHECK: @test3(i32 %x, i32 %y)
+; CHECK: %add1 = add i32 %x, %y
+; CHECK: %foo = add i32 %add1, %add1
+
+ %add1 = add nuw nsw i32 %x, %y
+ %add2 = add i32 %x, %y
+ %foo = add i32 %add1, %add2
+ ret i32 %foo
+}
+
+define i32 @test4(i32 %x, i32 %y) {
+; CHECK: @test4(i32 %x, i32 %y)
+; CHECK: %add1 = add nsw i32 %x, %y
+; CHECK: %foo = add i32 %add1, %add1
+
+ %add1 = add nsw i32 %x, %y
+ %add2 = add nsw i32 %x, %y
+ %foo = add i32 %add1, %add2
+ ret i32 %foo
+}
+
+define i32 @test5(i32 %x, i32 %y) {
+; CHECK: @test5(i32 %x, i32 %y)
+; CHECK: %add1 = add i32 %x, %y
+; CHECK: %foo = add i32 %add1, %add1
+
+ %add1 = add nuw i32 %x, %y
+ %add2 = add nsw i32 %x, %y
+ %foo = add i32 %add1, %add2
+ ret i32 %foo
+}
+
+define i32 @test6(i32 %x, i32 %y) {
+; CHECK: @test6(i32 %x, i32 %y)
+; CHECK: %add1 = add nsw i32 %x, %y
+; CHECK: %foo = add i32 %add1, %add1
+
+ %add1 = add nuw nsw i32 %x, %y
+ %add2 = add nsw i32 %x, %y
+ %foo = add i32 %add1, %add2
+ ret i32 %foo
+}
+
+define i32 @test7(i32 %x, i32 %y) {
+; CHECK: @test7(i32 %x, i32 %y)
+; CHECK: %add1 = add i32 %x, %y
+; CHECK-NOT: what_is_this
+; CHECK: %foo = add i32 %add1, %add1
+
+ %add1 = add i32 %x, %y, !what_is_this !{}
+ %add2 = add i32 %x, %y
+ %foo = add i32 %add1, %add2
+ ret i32 %foo
+}
diff --git a/test/Transforms/GVN/range.ll b/test/Transforms/GVN/range.ll
new file mode 100644
index 0000000000..3759c415da
--- /dev/null
+++ b/test/Transforms/GVN/range.ll
@@ -0,0 +1,101 @@
+; RUN: opt %s -basicaa -gvn -S -o - | FileCheck %s
+
+define i32 @test1(i32* %p) {
+; CHECK: @test1(i32* %p)
+; CHECK: %a = load i32* %p, !range !0
+; CHECK: %c = add i32 %a, %a
+ %a = load i32* %p, !range !0
+ %b = load i32* %p, !range !0
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test2(i32* %p) {
+; CHECK: @test2(i32* %p)
+; CHECK: %a = load i32* %p
+; CHECK-NOT: range
+; CHECK: %c = add i32 %a, %a
+ %a = load i32* %p, !range !0
+ %b = load i32* %p
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test3(i32* %p) {
+; CHECK: @test3(i32* %p)
+; CHECK: %a = load i32* %p, !range ![[DISJOINT_RANGE:[0-9]+]]
+; CHECK: %c = add i32 %a, %a
+ %a = load i32* %p, !range !0
+ %b = load i32* %p, !range !1
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test4(i32* %p) {
+; CHECK: @test4(i32* %p)
+; CHECK: %a = load i32* %p, !range ![[MERGED_RANGE:[0-9]+]]
+; CHECK: %c = add i32 %a, %a
+ %a = load i32* %p, !range !0
+ %b = load i32* %p, !range !2
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test5(i32* %p) {
+; CHECK: @test5(i32* %p)
+; CHECK: %a = load i32* %p, !range ![[MERGED_SIGNED_RANGE:[0-9]+]]
+; CHECK: %c = add i32 %a, %a
+ %a = load i32* %p, !range !3
+ %b = load i32* %p, !range !4
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test6(i32* %p) {
+; CHECK: @test6(i32* %p)
+; CHECK: %a = load i32* %p, !range ![[MERGED_TEST6:[0-9]+]]
+; CHECK: %c = add i32 %a, %a
+ %a = load i32* %p, !range !5
+ %b = load i32* %p, !range !6
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test7(i32* %p) {
+; CHECK: @test7(i32* %p)
+; CHECK: %a = load i32* %p, !range ![[MERGED_TEST7:[0-9]+]]
+; CHECK: %c = add i32 %a, %a
+ %a = load i32* %p, !range !7
+ %b = load i32* %p, !range !8
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test8(i32* %p) {
+; CHECK: @test8(i32* %p)
+; CHECK: %a = load i32* %p
+; CHECK-NOT: range
+; CHECK: %c = add i32 %a, %a
+ %a = load i32* %p, !range !9
+ %b = load i32* %p, !range !10
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+; CHECK: ![[DISJOINT_RANGE]] = metadata !{i32 0, i32 2, i32 3, i32 5}
+; CHECK: ![[MERGED_RANGE]] = metadata !{i32 0, i32 5}
+; CHECK: ![[MERGED_SIGNED_RANGE]] = metadata !{i32 -3, i32 -2, i32 1, i32 2}
+; CHECK: ![[MERGED_TEST6]] = metadata !{i32 10, i32 1}
+; CHECK: ![[MERGED_TEST7]] = metadata !{i32 3, i32 4, i32 5, i32 2}
+
+!0 = metadata !{i32 0, i32 2}
+!1 = metadata !{i32 3, i32 5}
+!2 = metadata !{i32 2, i32 5}
+!3 = metadata !{i32 -3, i32 -2}
+!4 = metadata !{i32 1, i32 2}
+!5 = metadata !{i32 10, i32 1}
+!6 = metadata !{i32 12, i32 13}
+!7 = metadata !{i32 1, i32 2, i32 3, i32 4}
+!8 = metadata !{i32 5, i32 1}
+!9 = metadata !{i32 1, i32 5}
+!10 = metadata !{i32 5, i32 1}
diff --git a/test/Transforms/GVN/tbaa.ll b/test/Transforms/GVN/tbaa.ll
new file mode 100644
index 0000000000..90661c6250
--- /dev/null
+++ b/test/Transforms/GVN/tbaa.ll
@@ -0,0 +1,81 @@
+; RUN: opt %s -basicaa -gvn -S -o - | FileCheck %s
+
+define i32 @test1(i8* %p, i8* %q) {
+; CHECK: @test1(i8* %p, i8* %q)
+; CHECK: call i32 @foo(i8* %p)
+; CHECK-NOT: tbaa
+; CHECK: %c = add i32 %a, %a
+ %a = call i32 @foo(i8* %p), !tbaa !0
+ %b = call i32 @foo(i8* %p)
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test2(i8* %p, i8* %q) {
+; CHECK: @test2(i8* %p, i8* %q)
+; CHECK: call i32 @foo(i8* %p), !tbaa !0
+; CHECK: %c = add i32 %a, %a
+ %a = call i32 @foo(i8* %p), !tbaa !0
+ %b = call i32 @foo(i8* %p), !tbaa !0
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test3(i8* %p, i8* %q) {
+; CHECK: @test3(i8* %p, i8* %q)
+; CHECK: call i32 @foo(i8* %p), !tbaa !3
+; CHECK: %c = add i32 %a, %a
+ %a = call i32 @foo(i8* %p), !tbaa !3
+ %b = call i32 @foo(i8* %p), !tbaa !3
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test4(i8* %p, i8* %q) {
+; CHECK: @test4(i8* %p, i8* %q)
+; CHECK: call i32 @foo(i8* %p), !tbaa !1
+; CHECK: %c = add i32 %a, %a
+ %a = call i32 @foo(i8* %p), !tbaa !1
+ %b = call i32 @foo(i8* %p), !tbaa !0
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test5(i8* %p, i8* %q) {
+; CHECK: @test5(i8* %p, i8* %q)
+; CHECK: call i32 @foo(i8* %p), !tbaa !1
+; CHECK: %c = add i32 %a, %a
+ %a = call i32 @foo(i8* %p), !tbaa !0
+ %b = call i32 @foo(i8* %p), !tbaa !1
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test6(i8* %p, i8* %q) {
+; CHECK: @test6(i8* %p, i8* %q)
+; CHECK: call i32 @foo(i8* %p), !tbaa !1
+; CHECK: %c = add i32 %a, %a
+ %a = call i32 @foo(i8* %p), !tbaa !0
+ %b = call i32 @foo(i8* %p), !tbaa !3
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+define i32 @test7(i8* %p, i8* %q) {
+; CHECK: @test7(i8* %p, i8* %q)
+; CHECK: call i32 @foo(i8* %p)
+; CHECK-NOT: tbaa
+; CHECK: %c = add i32 %a, %a
+ %a = call i32 @foo(i8* %p), !tbaa !4
+ %b = call i32 @foo(i8* %p), !tbaa !3
+ %c = add i32 %a, %b
+ ret i32 %c
+}
+
+declare i32 @foo(i8*) readonly
+
+!0 = metadata !{metadata !"C", metadata !1}
+!1 = metadata !{metadata !"A", metadata !2}
+!2 = metadata !{metadata !"tbaa root", null}
+!3 = metadata !{metadata !"B", metadata !1}
+!4 = metadata !{metadata !"another root", null}