[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