[llvm] DAG: Fix cross-block gc.relocate of constants and allocas (PR #222894)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 11:54:50 PDT 2026


================
@@ -0,0 +1,127 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -early-live-intervals < %s | FileCheck %s
+
+; A gc.relocate of a directly-lowered value (a constant, an alloca, or
+; undef) in an invoke's landing pad must materialize the value at the
+; relocate, not insert a def after the statepoint call in the invoke
+; block.
+
+target triple = "x86_64-pc-linux-gnu"
+
+declare void @foo()
+
+define ptr addrspace(1) @relocate_constant_in_landing_pad() gc "statepoint-example" personality ptr null {
+; CHECK-LABEL: relocate_constant_in_landing_pad:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:  .Ltmp0: # EH_LABEL
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    callq *%rax
+; CHECK-NEXT:  .Ltmp3:
+; CHECK-NEXT:  .Ltmp1: # EH_LABEL
+; CHECK-NEXT:  # %bb.1: # %common.ret
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB0_2: # %exceptional_return
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:  .Ltmp2: # EH_LABEL
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+entry:
+  %c = inttoptr i64 1 to ptr addrspace(1)
+  %sp = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (ptr addrspace(1))) null, i32 1, i32 0, ptr addrspace(1) null, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) null, ptr addrspace(1) %c) ]
+          to label %common.ret unwind label %exceptional_return
+
+common.ret:
+  ret ptr addrspace(1) null
+
+exceptional_return:
+  %landing_pad = landingpad token
+          cleanup
+  %c.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %landing_pad, i32 0, i32 1)
+  ret ptr addrspace(1) %c.relocated
+}
+
+define ptr addrspace(1) @relocate_alloca_in_landing_pad() gc "statepoint-example" personality ptr null {
+; CHECK-LABEL: relocate_alloca_in_landing_pad:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:  .Ltmp4: # EH_LABEL
+; CHECK-NEXT:    callq foo at PLT
+; CHECK-NEXT:  .Ltmp7:
+; CHECK-NEXT:  .Ltmp5: # EH_LABEL
+; CHECK-NEXT:  # %bb.1: # %normal
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB1_2: # %lpad
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:  .Ltmp6: # EH_LABEL
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
+; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+entry:
+  %a = alloca i32
+  %ac = addrspacecast ptr %a to ptr addrspace(1)
+  %sp = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) %ac) ]
+          to label %normal unwind label %lpad
+
+normal:
+  ret ptr addrspace(1) null
+
+lpad:
+  %lp = landingpad token cleanup
+  %ac.rel = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %lp, i32 0, i32 0)
+  ret ptr addrspace(1) %ac.rel
+}
+
+; A gc.relocate of a value that lowers to undef in a landing pad must
----------------
kazutakahirata wrote:

Same here for `undef deprecator`:
```suggestion
; A gc.relocate of a value that lowers to poison in a landing pad must
```

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


More information about the llvm-commits mailing list