summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms
diff options
context:
space:
mode:
authorAnna Thomas <anna@azul.com>2017-06-12 21:26:53 +0000
committerAnna Thomas <anna@azul.com>2017-06-12 21:26:53 +0000
commit4b027e8f89a273fdfb275a5eee20a3eea078e4ad (patch)
tree6c001ca4c88e312bef11673110db913e8bc41dda /llvm/test/Transforms
parent13073a6425e1971dcc3a905bd5e997870ad25cb3 (diff)
downloadbcm5719-llvm-4b027e8f89a273fdfb275a5eee20a3eea078e4ad.tar.gz
bcm5719-llvm-4b027e8f89a273fdfb275a5eee20a3eea078e4ad.zip
[RS4GC] Drop invalid metadata after pointers are relocated
Summary: After RS4GC, we should drop metadata that is no longer valid. These metadata is used by optimizations scheduled after RS4GC, and can cause a miscompile. One such metadata is invariant.load which is used by LICM sinking transform. After rewriting statepoints, the address of a load maybe relocated. With invariant.load metadata on a load instruction, LICM sinking assumes the loaded value (from a dererenceable address) to be invariant, and rematerializes the load operand and the load at the exit block. This transforms the IR to have an unrelocated use of the address after a statepoint, which is incorrect. Other metadata we conservatively remove are related to dereferenceability and noalias metadata. This patch drops such metadata on store and load instructions after rewriting statepoints. Reviewers: reames, sanjoy, apilipenko Reviewed by: reames Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33756 llvm-svn: 305234
Diffstat (limited to 'llvm/test/Transforms')
-rw-r--r--llvm/test/Transforms/RewriteStatepointsForGC/drop-invalid-metadata.ll92
1 files changed, 92 insertions, 0 deletions
diff --git a/llvm/test/Transforms/RewriteStatepointsForGC/drop-invalid-metadata.ll b/llvm/test/Transforms/RewriteStatepointsForGC/drop-invalid-metadata.ll
new file mode 100644
index 00000000000..105afa9def5
--- /dev/null
+++ b/llvm/test/Transforms/RewriteStatepointsForGC/drop-invalid-metadata.ll
@@ -0,0 +1,92 @@
+; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
+
+; This test checks that metadata that's invalid after RS4GC is dropped.
+; We can miscompile if optimizations scheduled after RS4GC uses the
+; metadata that's infact invalid.
+
+declare void @bar()
+
+declare void @baz(i32)
+; Confirm that loadedval instruction does not contain invariant.load metadata.
+; but contains the range metadata.
+; Since loadedval is not marked invariant, it will prevent incorrectly sinking
+; %loadedval in LICM and avoid creation of an unrelocated use of %baseaddr.
+define void @test_invariant_load() gc "statepoint-example" {
+; CHECK-LABEL: @test_invariant_load
+; CHECK: %loadedval = load i32, i32 addrspace(1)* %baseaddr, align 8, !range !0
+bb:
+ br label %outerloopHdr
+
+outerloopHdr: ; preds = %bb6, %bb
+ %baseaddr = phi i32 addrspace(1)* [ undef, %bb ], [ %tmp4, %bb6 ]
+; LICM may sink this load to exit block after RS4GC because it's tagged invariant.
+ %loadedval = load i32, i32 addrspace(1)* %baseaddr, align 8, !range !0, !invariant.load !1
+ br label %innerloopHdr
+
+innerloopHdr: ; preds = %innerlooplatch, %outerloopHdr
+ %tmp4 = phi i32 addrspace(1)* [ %baseaddr, %outerloopHdr ], [ %gep, %innerlooplatch ]
+ br label %innermostloophdr
+
+innermostloophdr: ; preds = %bb6, %innerloopHdr
+ br i1 undef, label %exitblock, label %bb6
+
+bb6: ; preds = %innermostloophdr
+ switch i32 undef, label %innermostloophdr [
+ i32 0, label %outerloopHdr
+ i32 1, label %innerlooplatch
+ ]
+
+innerlooplatch: ; preds = %bb6
+ call void @bar()
+ %gep = getelementptr inbounds i32, i32 addrspace(1)* %tmp4, i64 8
+ br label %innerloopHdr
+
+exitblock: ; preds = %innermostloophdr
+ %tmp13 = add i32 42, %loadedval
+ call void @baz(i32 %tmp13)
+ unreachable
+}
+
+; drop the noalias metadata.
+define void @test_noalias(i32 %x, i32 addrspace(1)* %p, i32 addrspace(1)* %q) gc "statepoint-example" {
+; CHECK-LABEL: test_noalias
+; CHECK: %y = load i32, i32 addrspace(1)* %q, align 16
+; CHECK: gc.statepoint
+; CHECK: %p.relocated
+; CHECK-NEXT: %p.relocated.casted = bitcast i8 addrspace(1)* %p.relocated to i32 addrspace(1)*
+; CHECK-NEXT: store i32 %x, i32 addrspace(1)* %p.relocated.casted, align 16
+entry:
+ %y = load i32, i32 addrspace(1)* %q, align 16, !noalias !3
+ call void @baz(i32 %x)
+ store i32 %x, i32 addrspace(1)* %p, align 16, !noalias !4
+ ret void
+}
+
+; drop the dereferenceable metadata
+define void @test_dereferenceable(i32 addrspace(1)* addrspace(1)* %p, i32 %x, i32 addrspace(1)* %q) gc "statepoint-example" {
+; CHECK-LABEL: test_dereferenceable
+; CHECK: %v1 = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %p
+; CHECK-NEXT: %v2 = load i32, i32 addrspace(1)* %v1
+; CHECK: gc.statepoint
+ %v1 = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(1)* %p, !dereferenceable !5
+ %v2 = load i32, i32 addrspace(1)* %v1
+ call void @baz(i32 %x)
+ store i32 %v2, i32 addrspace(1)* %q, align 16
+ ret void
+}
+
+declare token @llvm.experimental.gc.statepoint.p0f_isVoidi32f(i64, i32, void (i32)*, i32, i32, ...)
+
+; Function Attrs: nounwind readonly
+declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32) #0
+
+declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
+
+attributes #0 = { nounwind readonly }
+
+!0 = !{i32 0, i32 2147483647}
+!1 = !{}
+!2 = !{i32 10, i32 1}
+!3 = !{!3}
+!4 = !{!4}
+!5 = !{i64 8}
OpenPOWER on IntegriCloud