As part of the optimization in the unreachable code, we remove
tokens, thereby replacing them with undef/poison in intrinsics.
But the verifier falls on the assertion, within of what it sees
token poison in unreachable code, which in turn is incorrect.
bug: 57871, https://github.com/llvm/llvm-project/issues/57871
Differential Revision: https://reviews.llvm.org/D134427
case Intrinsic::experimental_gc_result: {
Check(Call.getParent()->getParent()->hasGC(),
"Enclosing function does not use GC.", Call);
+
+ auto *Statepoint = Call.getArgOperand(0);
+ if (isa<UndefValue>(Statepoint))
+ break;
+
// Are we tied to a statepoint properly?
- const auto *StatepointCall = dyn_cast<CallBase>(Call.getArgOperand(0));
+ const auto *StatepointCall = dyn_cast<CallBase>(Statepoint);
const Function *StatepointFn =
StatepointCall ? StatepointCall->getCalledFunction() : nullptr;
Check(StatepointFn && StatepointFn->isDeclaration() &&
--- /dev/null
+; RUN: opt -S -passes=verify < %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @foo() gc "statepoint_example" personality ptr @P {
+; CHECK-NOT: gc.result operand #1 must be from a statepoint
+entry:
+ br label %label_1
+label_1:
+ ; CHECK: ret void
+ ret void
+
+label_2:
+ ; CHECK: token poison
+ %call = call noundef i32 @llvm.experimental.gc.result.i32(token poison)
+ unreachable
+}
+
+declare i32 @llvm.experimental.gc.result.i32(token)
+
+declare ptr @P()