summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms
diff options
context:
space:
mode:
authorAnna Thomas <anna@azul.com>2017-11-02 16:23:31 +0000
committerAnna Thomas <anna@azul.com>2017-11-02 16:23:31 +0000
commit486a7aaa31eb86f93802ed0b0d343c376b4f0231 (patch)
treeb75c3f8f6300c59c7acb52a81f6ea2f54fb9142f /llvm/test/Transforms
parent238a6b7f09421006b2b16db6ccd82a89a13b2ca2 (diff)
downloadbcm5719-llvm-486a7aaa31eb86f93802ed0b0d343c376b4f0231.tar.gz
bcm5719-llvm-486a7aaa31eb86f93802ed0b0d343c376b4f0231.zip
[RS4GC] Strip off invariant.start because memory locations arent invariant
Summary: Invariant.start on memory locations has the property that the memory location is unchanging. However, this is not true in the face of rewriting statepoints for GC. Teach RS4GC about removing invariant.start so that optimizations after RS4GC does not incorrect sink a load from the memory location past a statepoint. Added test showcasing the issue. Reviewers: reames, apilipenko, dneilson Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39388 llvm-svn: 317215
Diffstat (limited to 'llvm/test/Transforms')
-rw-r--r--llvm/test/Transforms/RewriteStatepointsForGC/drop-invalid-metadata.ll53
1 files changed, 53 insertions, 0 deletions
diff --git a/llvm/test/Transforms/RewriteStatepointsForGC/drop-invalid-metadata.ll b/llvm/test/Transforms/RewriteStatepointsForGC/drop-invalid-metadata.ll
index 105afa9def5..4f3ab6a4beb 100644
--- a/llvm/test/Transforms/RewriteStatepointsForGC/drop-invalid-metadata.ll
+++ b/llvm/test/Transforms/RewriteStatepointsForGC/drop-invalid-metadata.ll
@@ -75,6 +75,59 @@ define void @test_dereferenceable(i32 addrspace(1)* addrspace(1)* %p, i32 %x, i3
ret void
}
+; invariant.start allows us to sink the load past the baz statepoint call into taken block, which is
+; incorrect. remove the invariant.start and RAUW undef.
+define void @test_inv_start(i1 %cond, i32 addrspace(1)* addrspace(1)* %p, i32 %x, i32 addrspace(1)* %q) gc "statepoint-example" {
+; CHECK-LABEL: test_inv_start
+; CHECK-NOT: invariant.start
+; CHECK: gc.statepoint
+ %v1 = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %p
+ %invst = call {}* @llvm.invariant.start.p1i32(i64 1, i32 addrspace(1)* %v1)
+ %v2 = load i32, i32 addrspace(1)* %v1
+ call void @baz(i32 %x)
+ br i1 %cond, label %taken, label %untaken
+
+; CHECK-LABEL: taken:
+; CHECK-NOT: llvm.invariant.end
+taken:
+ store i32 %v2, i32 addrspace(1)* %q, align 16
+ call void @llvm.invariant.end.p1i32({}* %invst, i64 4, i32 addrspace(1)* %v1)
+ ret void
+
+; CHECK-LABEL: untaken:
+; CHECK: gc.statepoint
+untaken:
+ %foo = call i32 @escaping.invariant.start({}* %invst)
+ call void @dummy(i32 %foo)
+ ret void
+}
+
+; invariant.start and end is removed. No other uses.
+define void @test_inv_start2(i1 %cond, i32 addrspace(1)* addrspace(1)* %p, i32 %x, i32 addrspace(1)* %q) gc "statepoint-example" {
+; CHECK-LABEL: test_inv_start2
+; CHECK-NOT: invariant.start
+; CHECK: gc.statepoint
+ %v1 = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %p
+ %invst = call {}* @llvm.invariant.start.p1i32(i64 1, i32 addrspace(1)* %v1)
+ %v2 = load i32, i32 addrspace(1)* %v1
+ call void @baz(i32 %x)
+ br i1 %cond, label %taken, label %untaken
+
+; CHECK-LABEL: taken:
+; CHECK-NOT: llvm.invariant.end
+taken:
+ store i32 %v2, i32 addrspace(1)* %q, align 16
+ call void @llvm.invariant.end.p1i32({}* %invst, i64 4, i32 addrspace(1)* %v1)
+ ret void
+
+; CHECK-LABEL: untaken:
+untaken:
+ ret void
+}
+declare {}* @llvm.invariant.start.p1i32(i64, i32 addrspace(1)* nocapture) nounwind readonly
+declare void @llvm.invariant.end.p1i32({}*, i64, i32 addrspace(1)* nocapture) nounwind
+declare i32 @escaping.invariant.start({}*) nounwind
+declare void @dummy(i32)
declare token @llvm.experimental.gc.statepoint.p0f_isVoidi32f(i64, i32, void (i32)*, i32, i32, ...)
; Function Attrs: nounwind readonly
OpenPOWER on IntegriCloud