Files
clang-p2996/llvm/test/SafepointIRVerifier/uses-in-phi-nodes.ll
Lee Wei 1469d82e1c Remove br i1 undef from some regression tests [NFC] (#115130)
As defined in LangRef, branching on `undef` is undefined behavior.
This PR aims to remove undefined behavior from tests. As UB tests break
Alive2 and may be the root cause of breaking future optimizations.

Here's an Alive2 proof for one of the examples:
https://alive2.llvm.org/ce/z/TncxhP
2024-11-07 08:11:15 +00:00

173 lines
7.3 KiB
LLVM

; RUN: opt -safepoint-ir-verifier-print-only -verify-safepoint-ir -S %s 2>&1 | FileCheck %s
define ptr addrspace(1) @test.not.ok.0(ptr addrspace(1) %arg, i1 %new_arg) gc "statepoint-example" {
; CHECK-LABEL: Verifying gc pointers in function: test.not.ok.0
bci_0:
br i1 %new_arg, label %left, label %right
left:
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, i32 0, i32 0, i32 0)
br label %merge
right:
br label %merge
merge:
; CHECK: Illegal use of unrelocated value found!
; CHECK-NEXT: Def: %val = phi ptr addrspace(1) [ %arg, %left ], [ %arg, %right ]
; CHECK-NEXT: Use: ret ptr addrspace(1) %val
%val = phi ptr addrspace(1) [ %arg, %left ], [ %arg, %right ]
ret ptr addrspace(1) %val
}
define ptr addrspace(1) @test.not.ok.1(ptr addrspace(1) %arg, i1 %new_arg) gc "statepoint-example" {
; CHECK-LABEL: Verifying gc pointers in function: test.not.ok.1
bci_0:
br i1 %new_arg, label %left, label %right
left:
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, i32 0, i32 0, i32 0)
br label %merge
right:
br label %merge
merge:
; CHECK: Illegal use of unrelocated value found!
; CHECK-NEXT: Def: %val = phi ptr addrspace(1) [ %arg, %left ], [ null, %right ]
; CHECK-NEXT: Use: ret ptr addrspace(1) %val
%val = phi ptr addrspace(1) [ %arg, %left ], [ null, %right ]
ret ptr addrspace(1) %val
}
define ptr addrspace(1) @test.ok.0(ptr addrspace(1) %arg, i1 %new_arg) gc "statepoint-example" {
; CHECK: No illegal uses found by SafepointIRVerifier in: test.ok.0
bci_0:
br i1 %new_arg, label %left, label %right
left:
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, i32 0, i32 0, i32 0)
br label %merge
right:
br label %merge
merge:
%val = phi ptr addrspace(1) [ null, %left ], [ null, %right]
ret ptr addrspace(1) %val
}
define ptr addrspace(1) @test.ok.1(ptr addrspace(1) %arg, i1 %new_arg) gc "statepoint-example" {
; CHECK: No illegal uses found by SafepointIRVerifier in: test.ok.1
bci_0:
br i1 %new_arg, label %left, label %right
left:
call void @not_statepoint()
br label %merge
right:
br label %merge
merge:
%val = phi ptr addrspace(1) [ %arg, %left ], [ %arg, %right]
ret ptr addrspace(1) %val
}
; It should be allowed to compare poisoned ptr with null.
define void @test.poisoned.cmp.ok(ptr addrspace(1) %arg, i1 %new_arg) gc "statepoint-example" {
; CHECK-LABEL: Verifying gc pointers in function: test.poisoned.cmp.ok
bci_0:
br i1 %new_arg, label %left, label %right
left:
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg)]
%arg.relocated = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) ; arg, arg
br label %merge
right:
%safepoint_token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg)]
br label %merge
merge:
; CHECK: No illegal uses found by SafepointIRVerifier in: test.poisoned.cmp.ok
%val.poisoned = phi ptr addrspace(1) [ %arg.relocated, %left ], [ %arg, %right ]
%c = icmp eq ptr addrspace(1) %val.poisoned, null
ret void
}
; It is illegal to compare poisoned ptr and relocated.
define void @test.poisoned.cmp.fail.0(ptr addrspace(1) %arg, i1 %new_arg) gc "statepoint-example" {
; CHECK-LABEL: Verifying gc pointers in function: test.poisoned.cmp.fail.0
bci_0:
br i1 %new_arg, label %left, label %right
left:
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg)]
%arg.relocated = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) ; arg, arg
br label %merge
right:
%safepoint_token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg), "deopt"(i32 -1, i32 0, i32 0, i32 0)]
%arg.relocated2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 0) ; arg, arg
br label %merge
merge:
; CHECK: Illegal use of unrelocated value found!
; CHECK-NEXT: Def: %val.poisoned = phi ptr addrspace(1) [ %arg.relocated, %left ], [ %arg, %right ]
; CHECK-NEXT: Use: %c = icmp eq ptr addrspace(1) %val.poisoned, %val
%val.poisoned = phi ptr addrspace(1) [ %arg.relocated, %left ], [ %arg, %right ]
%val = phi ptr addrspace(1) [ %arg.relocated, %left ], [ %arg.relocated2, %right ]
%c = icmp eq ptr addrspace(1) %val.poisoned, %val
ret void
}
; It is illegal to compare poisoned ptr and unrelocated.
define void @test.poisoned.cmp.fail.1(ptr addrspace(1) %arg, i1 %new_arg) gc "statepoint-example" {
; CHECK-LABEL: Verifying gc pointers in function: test.poisoned.cmp.fail.1
bci_0:
br i1 %new_arg, label %left, label %right
left:
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg)]
%arg.relocated = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) ; arg, arg
br label %merge
right:
%safepoint_token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg), "deopt"(i32 -1, i32 0, i32 0, i32 0)]
%arg.relocated2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 0) ; arg, arg
br label %merge
merge:
; CHECK: Illegal use of unrelocated value found!
; CHECK-NEXT: Def: %val.poisoned = phi ptr addrspace(1) [ %arg.relocated, %left ], [ %arg, %right ]
; CHECK-NEXT: Use: %c = icmp eq ptr addrspace(1) %val.poisoned, %arg
%val.poisoned = phi ptr addrspace(1) [ %arg.relocated, %left ], [ %arg, %right ]
%c = icmp eq ptr 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(ptr addrspace(1) %arg, i1 %new_arg) gc "statepoint-example" {
; CHECK-LABEL: Verifying gc pointers in function: test.unrelocated-phi.cmp.ok
bci_0:
br i1 %new_arg, label %left, label %right
left:
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) undef, i32 0, 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 ptr addrspace(1) [ %arg, %left ], [ null, %right ]
%c = icmp eq ptr addrspace(1) %val.unrelocated, %arg
ret void
}
declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)
declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32)
declare void @not_statepoint()