Skip to content

Commit 7b19cd0

Browse files
committed
[Statepoints][ISEL] visitGCRelocate: chain to current DAG root.
This is similar to D87251, but for CopyFromRegs nodes. Even for local statepoint uses we generate CopyToRegs/CopyFromRegs nodes. When generating CopyFromRegs in visitGCRelocate, we must chain to current DAG root, not EntryNode, to ensure proper ordering of copy w.r.t. statepoint node producing result for it. Reviewed By: reames Differential Revision: https://reviews.llvm.org/D88639
1 parent c87c017 commit 7b19cd0

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,10 @@ void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) {
11231123
RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
11241124
DAG.getDataLayout(), InReg, Relocate.getType(),
11251125
None); // This is not an ABI copy.
1126-
SDValue Chain = DAG.getEntryNode();
1126+
// We generate copy to/from regs even for local uses, hence we must
1127+
// chain with current root to ensure proper ordering of copies w.r.t.
1128+
// statepoint.
1129+
SDValue Chain = DAG.getRoot();
11271130
SDValue Relocation = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(),
11281131
Chain, nullptr, nullptr);
11291132
setValue(&Relocate, Relocation);

llvm/test/CodeGen/X86/statepoint-vreg-details.ll

+32
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ declare void @consume5(i32 addrspace(1)*, i32 addrspace(1)*, i32 addrspace(1)*,
1818
declare void @use1(i32 addrspace(1)*, i8 addrspace(1)*)
1919
declare i32* @fake_personality_function()
2020
declare i32 @foo(i32, i8 addrspace(1)*, i32, i32, i32)
21+
declare void @bar(i8 addrspace(1)*, i8 addrspace(1)*)
2122

2223
; test most simple relocate
2324
define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" {
@@ -378,6 +379,36 @@ exceptional_return: ; preds = %entry
378379
unreachable
379380
}
380381

382+
; Test that CopyFromReg emitted during ISEL processing of gc.relocate are properly ordered w.r.t. statepoint.
383+
define i8 addrspace(1)* @test_isel_sched(i8 addrspace(1)* %0, i8 addrspace(1)* %1, i32 %2) gc "statepoint-example" {
384+
;CHECK-VREG-LABEL: name: test_isel_sched
385+
;CHECK-VREG: bb.0.entry:
386+
;CHECK-VREG: %2:gr32 = COPY $edx
387+
;CHECK-VREG: %1:gr64 = COPY $rsi
388+
;CHECK-VREG: %0:gr64 = COPY $rdi
389+
;CHECK-VREG: TEST32rr %2, %2, implicit-def $eflags
390+
;CHECK-VREG: %5:gr64 = CMOV64rr %1, %0, 4, implicit $eflags
391+
;CHECK-VREG: MOV64mr %stack.1, 1, $noreg, 0, $noreg, %0 :: (store 8 into %stack.1)
392+
;CHECK-VREG: MOV64mr %stack.0, 1, $noreg, 0, $noreg, %1 :: (store 8 into %stack.0)
393+
;CHECK-VREG: %6:gr32 = MOV32r0 implicit-def dead $eflags
394+
;CHECK-VREG: %7:gr64 = SUBREG_TO_REG 0, killed %6, %subreg.sub_32bit
395+
;CHECK-VREG: $rdi = COPY %7
396+
;CHECK-VREG: $rsi = COPY %5
397+
;CHECK-VREG: %3:gr64, %4:gr64 = STATEPOINT 10, 0, 2, @bar, $rdi, $rsi, 2, 0, 2, 0, 2, 0, 1, 8, %stack.0, 0, %1(tied-def 0), 1, 8, %stack.1, 0, %0(tied-def 1), csr_64, implicit-def $rsp, implicit-def $ssp :: (volatile load store 8 on %stack.0), (volatile load store 8 on %stack.1)
398+
;CHECK-VREG: TEST32rr %2, %2, implicit-def $eflags
399+
;CHECK-VREG: %8:gr64 = CMOV64rr %3, %4, 4, implicit $eflags
400+
;CHECK-VREG: $rax = COPY %8
401+
;CHECK-VREG: RET 0, $rax
402+
entry:
403+
%cmp = icmp eq i32 %2, 0
404+
%ptr = select i1 %cmp, i8 addrspace(1)* %0, i8 addrspace(1)* %1
405+
%token = call token (i64, i32, void (i8 addrspace(1)*, i8 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i8p1i8f(i64 10, i32 0, void (i8 addrspace(1)*, i8 addrspace(1)*)* @bar, i32 2, i32 0, i8 addrspace(1)* null, i8 addrspace(1)* %ptr, i32 0, i32 0) [ "deopt"(), "gc-live"(i8 addrspace(1)* %0, i8 addrspace(1)* %1) ]
406+
%rel0 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %token, i32 0, i32 0)
407+
%rel1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %token, i32 1, i32 1)
408+
%res = select i1 %cmp, i8 addrspace(1)* %rel0, i8 addrspace(1)* %rel1
409+
ret i8 addrspace(1)* %res
410+
}
411+
381412
declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
382413
declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
383414
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
@@ -387,4 +418,5 @@ declare i1 @llvm.experimental.gc.result.i1(token)
387418
declare void @__llvm_deoptimize(i32)
388419
declare token @llvm.experimental.gc.statepoint.p0f_isVoidi32f(i64 immarg, i32 immarg, void (i32)*, i32 immarg, i32 immarg, ...)
389420
declare token @llvm.experimental.gc.statepoint.p0f_i32i32p1i8i32i32i32f(i64 immarg, i32 immarg, i32 (i32, i8 addrspace(1)*, i32, i32, i32)*, i32 immarg, i32 immarg, ...)
421+
declare token @llvm.experimental.gc.statepoint.p0f_isVoidp1i8p1i8f(i64 immarg, i32 immarg, void (i8 addrspace(1)*, i8 addrspace(1)*)*, i32 immarg, i32 immarg, ...)
390422

0 commit comments

Comments
 (0)