[StatepointLowering] Handle UNDEF gc values.
authorDenis Antrushin <dantrushin@gmail.com>
Thu, 28 May 2020 12:26:56 +0000 (15:26 +0300)
committerDenis Antrushin <dantrushin@gmail.com>
Tue, 2 Jun 2020 07:18:33 +0000 (10:18 +0300)
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

llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
llvm/test/CodeGen/X86/statepoint-uniqueing.ll

index 3e89118..522fc88 100644 (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");
index 2a2fb10..2b0e376 100644 (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, ...)