[StatepointLowering] Handle UNDEF gc values.

Do not spill UNDEF GC values. Instead, replace corresponding
gc.relocate intrinsic with an (arbitrary, but recognizable) constant.

Reviewed By: reames
Differential Revision: https://reviews.llvm.org/D80714
This commit is contained in:
Denis Antrushin 2020-05-28 15:26:56 +03:00
parent 052c962ced
commit fa818ded24
2 changed files with 31 additions and 15 deletions

View File

@ -230,7 +230,7 @@ static void reservePreviousStackSlotForValue(const Value *IncomingValue,
SDValue Incoming = Builder.getValue(IncomingValue);
if (isa<ConstantSDNode>(Incoming) || isa<ConstantFPSDNode>(Incoming) ||
isa<FrameIndexSDNode>(Incoming)) {
isa<FrameIndexSDNode>(Incoming) || Incoming.isUndef()) {
// We won't need to spill this, so no need to check for previously
// allocated stack slots
return;
@ -388,6 +388,15 @@ lowerIncomingStatepointValue(SDValue Incoming, bool RequireSpillSlot,
// doing it here would be a small compile time win at most.
SDValue Chain = Builder.getRoot();
if (Incoming.isUndef() && Incoming.getValueType().getSizeInBits() <= 64) {
// Put an easily recognized constant that's unlikely to be a valid
// value so that uses of undef by the consumer of the stackmap is
// easily recognized. This is legal since the compiler is always
// allowed to chose an arbitrary value for undef.
pushStackMapConstant(Ops, Builder, 0xFEFEFEFE);
return;
}
// If the original value was a constant, make sure it gets recorded as
// such in the stackmap. This is required so that the consumer can
// parse any internal format to the deopt state. It also handles null
@ -1006,6 +1015,13 @@ void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) {
const Value *DerivedPtr = Relocate.getDerivedPtr();
SDValue SD = getValue(DerivedPtr);
if (SD.isUndef() && SD.getValueType().getSizeInBits() <= 64) {
// Lowering relocate(undef) as arbitrary constant. Current constant value
// is chosen such that it's unlikely to be a valid pointer.
setValue(&Relocate, DAG.getTargetConstant(0xFEFEFEFE, SDLoc(SD), MVT::i64));
return;
}
auto &SpillMap = FuncInfo.StatepointSpillMaps[Relocate.getStatepoint()];
auto SlotIt = SpillMap.find(DerivedPtr);
assert(SlotIt != SpillMap.end() && "Relocating not lowered gc value");

View File

@ -14,16 +14,16 @@ declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32) #3
define void @test_gcrelocate_uniqueing(i32 addrspace(1)* %ptr) gc "statepoint-example" {
; CHECK-LABEL: test_gcrelocate_uniqueing:
; CHECK: # %bb.0:
; CHECK-NEXT: subq $24, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp)
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: movq %rdi, (%rsp)
; CHECK-NEXT: callq f
; CHECK-NEXT: .Ltmp0:
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdi
; CHECK-NEXT: movq (%rsp), %rdi
; CHECK-NEXT: movq %rdi, %rsi
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: callq use
; CHECK-NEXT: addq $24, %rsp
; CHECK-NEXT: popq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
%tok = tail call token (i64, i32, void ()*, i32, i32, ...)
@ -38,16 +38,16 @@ define void @test_gcrelocate_uniqueing(i32 addrspace(1)* %ptr) gc "statepoint-ex
define void @test_gcptr_uniqueing(i32 addrspace(1)* %ptr) gc "statepoint-example" {
; CHECK-LABEL: test_gcptr_uniqueing:
; CHECK: # %bb.0:
; CHECK-NEXT: subq $24, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp)
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: movq %rdi, (%rsp)
; CHECK-NEXT: callq f
; CHECK-NEXT: .Ltmp1:
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdi
; CHECK-NEXT: movq (%rsp), %rdi
; CHECK-NEXT: movq %rdi, %rsi
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: callq use
; CHECK-NEXT: addq $24, %rsp
; CHECK-NEXT: popq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
%ptr2 = bitcast i32 addrspace(1)* %ptr to i8 addrspace(1)*
@ -64,12 +64,12 @@ define void @test_gcptr_uniqueing(i32 addrspace(1)* %ptr) gc "statepoint-example
define void @test_deopt_use(i32 addrspace(1)* %ptr) gc "statepoint-example" {
; CHECK-LABEL: test_deopt_use:
; CHECK: # %bb.0:
; CHECK-NEXT: subq $24, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp)
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: movq %rdi, (%rsp)
; CHECK-NEXT: callq f
; CHECK-NEXT: .Ltmp2:
; CHECK-NEXT: addq $24, %rsp
; CHECK-NEXT: popq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
tail call token (i64, i32, void ()*, i32, i32, ...)