From fa818ded24413c8b9722dd564b04d9ffc50743b5 Mon Sep 17 00:00:00 2001 From: Denis Antrushin Date: Thu, 28 May 2020 15:26:56 +0300 Subject: [PATCH] [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 --- .../CodeGen/SelectionDAG/StatepointLowering.cpp | 18 +++++++++++++- llvm/test/CodeGen/X86/statepoint-uniqueing.ll | 28 +++++++++++----------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index 3e89118..522fc88 100644 --- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -230,7 +230,7 @@ static void reservePreviousStackSlotForValue(const Value *IncomingValue, SDValue Incoming = Builder.getValue(IncomingValue); if (isa(Incoming) || isa(Incoming) || - isa(Incoming)) { + isa(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"); diff --git a/llvm/test/CodeGen/X86/statepoint-uniqueing.ll b/llvm/test/CodeGen/X86/statepoint-uniqueing.ll index 2a2fb10..2b0e376 100644 --- a/llvm/test/CodeGen/X86/statepoint-uniqueing.ll +++ b/llvm/test/CodeGen/X86/statepoint-uniqueing.ll @@ -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, ...) -- 2.7.4