[llvm] DAG: Fix latent verifier error in statepoint lowering (PR #222894)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 02:26:39 PDT 2026


================
@@ -931,18 +954,19 @@ SDValue SelectionDAGBuilder::LowerAsSTATEPOINT(
       Record.payload.FI = cast<FrameIndexSDNode>(Loc)->getIndex();
     } else {
       Record.type = RecordType::NoRelocate;
-      // If we didn't relocate a value, we'll essentialy end up inserting an
-      // additional use of the original value when lowering the gc.relocate.
-      // We need to make sure the value is available at the new use, which
-      // might be in another block.
-      if (Relocate->getParent() != StatepointInstr->getParent())
-        ExportFromCurrentBlock(V);
+      assert(willLowerDirectly(SDV) && "NoRelocate value must lower directly");
+
+      // A gc.relocate in another block needs the value there. Exporting it
+      // would define a vreg after the call that does not dominate a use on the
+      // unwind edge, so record the leaf and rebuild it in visitGCRelocate
+      // instead. undef re-lowers trivially and is left to the fallback path.
+      if (Relocate->getParent() != StatepointInstr->getParent() &&
+          !SDV.isUndef())
----------------
kazutakahirata wrote:

Could you try running `statepoint-relocate-eh.ll` with `i64 1` replaced with `i64 undef`? You should observe a verifier crash (`Reading virtual register without a def`).

In `visitGCRelocate`, the `undef` special handling is:

https://github.com/llvm/llvm-project/blob/4bab123e473a97f0afd3a117c361f6d5ede86951/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp#L1329-L1336

When `DerivedPtr` is an `Instruction` in the statepoint block (like `%c = inttoptr i64 undef to ptr addrspace(1)`), `getValue(DerivedPtr)` above returns a `CopyFromReg` node instead of `UNDEF`. So `SD.isUndef()` is `false` and that special handling is never reached:

```text
Initial selection DAG: %bb.2 'relocate_constant_in_landing_pad:exceptional_return'
SelectionDAG has 7 nodes:
  t0: ch,glue = EntryToken
    t2: i64,ch = CopyFromReg t0, Register:i64 %4  <--- returned by getValue(DerivedPtr)
  t5: ch,glue = CopyToReg t0, Register:i64 $rax, t2
  t6: ch = X86ISD::RET_GLUE t5, TargetConstant:i32<0>, Register:i64 $rax, t5:1
```


https://github.com/llvm/llvm-project/pull/222894


More information about the llvm-commits mailing list