diff options
| author | Max Kazantsev <max.kazantsev@azul.com> | 2017-12-25 09:35:10 +0000 | 
|---|---|---|
| committer | Max Kazantsev <max.kazantsev@azul.com> | 2017-12-25 09:35:10 +0000 | 
| commit | ddb096853d008b54788eb427dd1d56387996f00a (patch) | |
| tree | 96dded39bc2f80f8e703572ed8f1dbff38887c0e /llvm/test | |
| parent | 705fef3ef3d26718f34de45e1d4c2ef0f37c9bb2 (diff) | |
| download | bcm5719-llvm-ddb096853d008b54788eb427dd1d56387996f00a.tar.gz bcm5719-llvm-ddb096853d008b54788eb427dd1d56387996f00a.zip | |
[SafepointIRVerifier] Allow non-dereferencing uses of unrelocated or poisoned PHI nodes
PHI that has at least one unrelocated input cannot cause any issues by itself,
though its uses should be carefully verified. With this patch PHIs are allowed
to have any inputs but when all inputs are unrelocated the PHI is marked as
unrelocated and if not all inputs are unrelocated then the PHI is marked as
poisoned. Poisoned pointers can be used only in three ways: to derive new
pointers, in PHIs or in comparisons against constants that are exclusively
derived from null.
Patch by Daniil Suchkov!
Differential Revision: https://reviews.llvm.org/D41006
llvm-svn: 321438
Diffstat (limited to 'llvm/test')
3 files changed, 129 insertions, 8 deletions
| diff --git a/llvm/test/SafepointIRVerifier/from-same-relocation-in-phi-nodes.ll b/llvm/test/SafepointIRVerifier/from-same-relocation-in-phi-nodes.ll new file mode 100644 index 00000000000..4df19b2d726 --- /dev/null +++ b/llvm/test/SafepointIRVerifier/from-same-relocation-in-phi-nodes.ll @@ -0,0 +1,26 @@ +; XFAIL: * +; RUN: opt -safepoint-ir-verifier-print-only -verify-safepoint-ir -S %s 2>&1 | FileCheck %s + +; In %merge %val.unrelocated, %ptr and %arg should be unrelocated. +; FIXME: if this test fails it is a false-positive alarm. IR is correct. +define void @test.unrelocated-phi.ok(i8 addrspace(1)* %arg) gc "statepoint-example" { +; CHECK-LABEL: Verifying gc pointers in function: test.unrelocated-phi.ok + bci_0: +  %ptr = getelementptr i8, i8 addrspace(1)* %arg, i64 4 +  br i1 undef, label %left, label %right + + left: +  %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0) +  br label %merge + + right: +  br label %merge + + merge: +; CHECK: No illegal uses found by SafepointIRVerifier in: test.unrelocated-phi.ok +  %val.unrelocated = phi i8 addrspace(1)* [ %arg, %left ], [ %ptr, %right ] +  %c = icmp eq i8 addrspace(1)* %val.unrelocated, %arg +  ret void +} + +declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) diff --git a/llvm/test/SafepointIRVerifier/unrecorded-live-at-sp.ll b/llvm/test/SafepointIRVerifier/unrecorded-live-at-sp.ll index e3f21c3e713..5cd4aa74145 100644 --- a/llvm/test/SafepointIRVerifier/unrecorded-live-at-sp.ll +++ b/llvm/test/SafepointIRVerifier/unrecorded-live-at-sp.ll @@ -1,8 +1,9 @@  ; RUN: opt %s -safepoint-ir-verifier-print-only -verify-safepoint-ir -S 2>&1 | FileCheck %s  ; CHECK:      Illegal use of unrelocated value found! -; CHECK-NEXT: Def:   %base_phi3 = phi %jObject addrspace(1)* [ %obj609.relocated, %not_zero146 ], [ %base_phi2, %bci_37-aload ], !is_base_value !0 -; CHECK-NEXT: Use:   %base_phi2 = phi %jObject addrspace(1)* [ %base_phi3, %not_zero179 ], [ %cast5, %bci_0 ], !is_base_value !0 +; CHECK-NEXT: Def:   %base_phi4 = phi %jObject addrspace(1)* addrspace(1)* [ %addr98.relocated, %not_zero146 ], [ %cast6, %bci_37-aload ], !is_base_value !0 +; CHECK-NEXT: Use:   %safepoint_token = tail call token (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 0, i32 0, i32 0, i32 0, %jObject addrspace(1)* %base_phi1, %jObject addrspace(1)* addrspace(1)* %base_phi4, %jObject addrspace(1)* addrspace(1)* %relocated4, %jObject addrspace(1)* %relocated7) +  %jObject = type { [8 x i8] } diff --git a/llvm/test/SafepointIRVerifier/uses-in-phi-nodes.ll b/llvm/test/SafepointIRVerifier/uses-in-phi-nodes.ll index d06eb6e0d9a..bbf98577230 100644 --- a/llvm/test/SafepointIRVerifier/uses-in-phi-nodes.ll +++ b/llvm/test/SafepointIRVerifier/uses-in-phi-nodes.ll @@ -14,9 +14,9 @@ define i8 addrspace(1)* @test.not.ok.0(i8 addrspace(1)* %arg) gc "statepoint-exa   merge:  ; CHECK: Illegal use of unrelocated value found! -; CHECK-NEXT: Def: i8 addrspace(1)* %arg -; CHECK-NEXT: Use:   %val = phi i8 addrspace(1)* [ %arg, %left ], [ %arg, %right ] -  %val = phi i8 addrspace(1)* [ %arg, %left ], [ %arg, %right] +; CHECK-NEXT: Def:   %val = phi i8 addrspace(1)* [ %arg, %left ], [ %arg, %right ] +; CHECK-NEXT: Use:   ret i8 addrspace(1)* %val +  %val = phi i8 addrspace(1)* [ %arg, %left ], [ %arg, %right ]    ret i8 addrspace(1)* %val  } @@ -34,9 +34,9 @@ define i8 addrspace(1)* @test.not.ok.1(i8 addrspace(1)* %arg) gc "statepoint-exa   merge:  ; CHECK: Illegal use of unrelocated value found! -; CHECK-NEXT: Def: i8 addrspace(1)* %arg -; CHECK-NEXT: Use:   %val = phi i8 addrspace(1)* [ %arg, %left ], [ null, %right ] -  %val = phi i8 addrspace(1)* [ %arg, %left ], [ null, %right] +; CHECK-NEXT: Def:   %val = phi i8 addrspace(1)* [ %arg, %left ], [ null, %right ] +; CHECK-NEXT: Use:   ret i8 addrspace(1)* %val +  %val = phi i8 addrspace(1)* [ %arg, %left ], [ null, %right ]    ret i8 addrspace(1)* %val  } @@ -74,5 +74,99 @@ define i8 addrspace(1)* @test.ok.1(i8 addrspace(1)* %arg) gc "statepoint-example    ret i8 addrspace(1)* %val  } +; It should be allowed to compare poisoned ptr with null. +define void @test.poisoned.cmp.ok(i8 addrspace(1)* %arg) gc "statepoint-example" { +; CHECK-LABEL: Verifying gc pointers in function: test.poisoned.cmp.ok + bci_0: +  br i1 undef, label %left, label %right + + left: +  %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0) +  %arg.relocated = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 7, i32 7) ; arg, arg +  br label %merge + + right: +  %safepoint_token2 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0) +  br label %merge + + merge: +; CHECK: No illegal uses found by SafepointIRVerifier in: test.poisoned.cmp.ok +  %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ] +  %c = icmp eq i8 addrspace(1)* %val.poisoned, null +  ret void +} + +; It is illegal to compare poisoned ptr and relocated. +define void @test.poisoned.cmp.fail.0(i8 addrspace(1)* %arg) gc "statepoint-example" { +; CHECK-LABEL: Verifying gc pointers in function: test.poisoned.cmp.fail.0 + bci_0: +  br i1 undef, label %left, label %right + + left: +  %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0) +  %arg.relocated = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 7, i32 7) ; arg, arg +  br label %merge + + right: +  %safepoint_token2 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0) +  %arg.relocated2 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token2, i32 7, i32 7) ; arg, arg +  br label %merge + + merge: +; CHECK: Illegal use of unrelocated value found! +; CHECK-NEXT: Def:   %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ] +; CHECK-NEXT: Use:   %c = icmp eq i8 addrspace(1)* %val.poisoned, %val +  %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ] +  %val = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg.relocated2, %right ] +  %c = icmp eq i8 addrspace(1)* %val.poisoned, %val +  ret void +} + +; It is illegal to compare poisoned ptr and unrelocated. +define void @test.poisoned.cmp.fail.1(i8 addrspace(1)* %arg) gc "statepoint-example" { +; CHECK-LABEL: Verifying gc pointers in function: test.poisoned.cmp.fail.1 + bci_0: +  br i1 undef, label %left, label %right + + left: +  %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0) +  %arg.relocated = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 7, i32 7) ; arg, arg +  br label %merge + + right: +  %safepoint_token2 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0) +  %arg.relocated2 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token2, i32 7, i32 7) ; arg, arg +  br label %merge + + merge: +; CHECK: Illegal use of unrelocated value found! +; CHECK-NEXT: Def:   %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ] +; CHECK-NEXT: Use:   %c = icmp eq i8 addrspace(1)* %val.poisoned, %arg +  %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ] +  %c = icmp eq i8 addrspace(1)* %val.poisoned, %arg +  ret void +} + +; It should be allowed to compare unrelocated phi with unrelocated value. +define void @test.unrelocated-phi.cmp.ok(i8 addrspace(1)* %arg) gc "statepoint-example" { +; CHECK-LABEL: Verifying gc pointers in function: test.unrelocated-phi.cmp.ok + bci_0: +  br i1 undef, label %left, label %right + + left: +  %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0) +  br label %merge + + right: +  br label %merge + + merge: +; CHECK: No illegal uses found by SafepointIRVerifier in: test.unrelocated-phi.cmp.ok +  %val.unrelocated = phi i8 addrspace(1)* [ %arg, %left ], [ null, %right ] +  %c = icmp eq i8 addrspace(1)* %val.unrelocated, %arg +  ret void +} +  declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) +declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32)  declare void @not_statepoint() | 

