diff options
author | Anna Thomas <anna@azul.com> | 2017-06-12 21:26:53 +0000 |
---|---|---|
committer | Anna Thomas <anna@azul.com> | 2017-06-12 21:26:53 +0000 |
commit | 4b027e8f89a273fdfb275a5eee20a3eea078e4ad (patch) | |
tree | 6c001ca4c88e312bef11673110db913e8bc41dda /llvm/test/Transforms | |
parent | 13073a6425e1971dcc3a905bd5e997870ad25cb3 (diff) | |
download | bcm5719-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.ll | 92 |
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} |