[llvm] 2fccd1b - [Statepoint Lowering] Fix the crash with gc.relocate in a separate block

Serguei Katkov via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 10 04:51:36 PST 2021


Author: Serguei Katkov
Date: 2021-03-10T19:51:04+07:00
New Revision: 2fccd1b00a7667228a0b5f167b2936b69b717372

URL: https://github.com/llvm/llvm-project/commit/2fccd1b00a7667228a0b5f167b2936b69b717372
DIFF: https://github.com/llvm/llvm-project/commit/2fccd1b00a7667228a0b5f167b2936b69b717372.diff

LOG: [Statepoint Lowering] Fix the crash with gc.relocate in a separate block

If it was decided to relocate derived pointer using the spill its value is
not exported in general case.
When gc.relocate is located in an another block than a statepoint we cannot
get SD for derived value but for spill case it is not required at all.
However implementation of gc.relocate lowering unconditionally request SD value
causing the assert triggering.

The CL fixes this by handling spill case earlier than SD is really required.

Reviewers: reames, dantrushin
Reviewed By: dantrushin
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D98324

Added: 
    llvm/test/CodeGen/X86/statepoint-spill-lowering.ll

Modified: 
    llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index 9b5ff38d311d..aed2ff420fd4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -1210,7 +1210,40 @@ void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) {
     setValue(&Relocate, Relocation);
     return;
   }
-  
+
+  if (Record.type == RecordType::Spill) {
+    unsigned Index = Record.payload.FI;
+    SDValue SpillSlot = DAG.getTargetFrameIndex(Index, getFrameIndexTy());
+
+    // All the reloads are independent and are reading memory only modified by
+    // statepoints (i.e. no other aliasing stores); informing SelectionDAG of
+    // this this let's CSE kick in for free and allows reordering of
+    // instructions if possible.  The lowering for statepoint sets the root,
+    // so this is ordering all reloads with the either
+    // a) the statepoint node itself, or
+    // b) the entry of the current block for an invoke statepoint.
+    const SDValue Chain = DAG.getRoot(); // != Builder.getRoot()
+
+    auto &MF = DAG.getMachineFunction();
+    auto &MFI = MF.getFrameInfo();
+    auto PtrInfo = MachinePointerInfo::getFixedStack(MF, Index);
+    auto *LoadMMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad,
+                                            MFI.getObjectSize(Index),
+                                            MFI.getObjectAlign(Index));
+
+    auto LoadVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
+                                                           Relocate.getType());
+
+    SDValue SpillLoad =
+        DAG.getLoad(LoadVT, getCurSDLoc(), Chain, SpillSlot, LoadMMO);
+    PendingLoads.push_back(SpillLoad.getValue(1));
+
+    assert(SpillLoad.getNode());
+    setValue(&Relocate, SpillLoad);
+    return;
+  }
+
+  assert(Record.type == RecordType::NoRelocate);
   SDValue SD = getValue(DerivedPtr);
 
   if (SD.isUndef() && SD.getValueType().getSizeInBits() <= 64) {
@@ -1220,43 +1253,9 @@ void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) {
     return;
   }
 
-
   // We didn't need to spill these special cases (constants and allocas).
   // See the handling in spillIncomingValueForStatepoint for detail.
-  if (Record.type == RecordType::NoRelocate) {
-    setValue(&Relocate, SD);
-    return;
-  }
-
-  assert(Record.type == RecordType::Spill);
-
-  unsigned Index = Record.payload.FI;;
-  SDValue SpillSlot = DAG.getTargetFrameIndex(Index, getFrameIndexTy());
-
-  // All the reloads are independent and are reading memory only modified by
-  // statepoints (i.e. no other aliasing stores); informing SelectionDAG of
-  // this this let's CSE kick in for free and allows reordering of instructions
-  // if possible.  The lowering for statepoint sets the root, so this is
-  // ordering all reloads with the either a) the statepoint node itself, or b)
-  // the entry of the current block for an invoke statepoint.
-  const SDValue Chain = DAG.getRoot(); // != Builder.getRoot()
-
-  auto &MF = DAG.getMachineFunction();
-  auto &MFI = MF.getFrameInfo();
-  auto PtrInfo = MachinePointerInfo::getFixedStack(MF, Index);
-  auto *LoadMMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad,
-                                          MFI.getObjectSize(Index),
-                                          MFI.getObjectAlign(Index));
-
-  auto LoadVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
-                                                         Relocate.getType());
-
-  SDValue SpillLoad = DAG.getLoad(LoadVT, getCurSDLoc(), Chain,
-                                  SpillSlot, LoadMMO);
-  PendingLoads.push_back(SpillLoad.getValue(1));
-
-  assert(SpillLoad.getNode());
-  setValue(&Relocate, SpillLoad);
+  setValue(&Relocate, SD);
 }
 
 void SelectionDAGBuilder::LowerDeoptimizeCall(const CallInst *CI) {

diff  --git a/llvm/test/CodeGen/X86/statepoint-spill-lowering.ll b/llvm/test/CodeGen/X86/statepoint-spill-lowering.ll
new file mode 100644
index 000000000000..8f460a394a88
--- /dev/null
+++ b/llvm/test/CodeGen/X86/statepoint-spill-lowering.ll
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs < %s | FileCheck %s
+
+; Check that we can handle gc.relocate in a separate block in spill mode.
+
+target triple = "x86_64-pc-linux-gnu"
+
+declare void @"some_call"(i8 addrspace(1)*)
+declare i32 @"personality_function"()
+
+; CHECK-LABEL: test_invoke:
+define i8 addrspace(1)* @test_invoke(i8 addrspace(1)* %a, i8 addrspace(1)* %b, i8 addrspace(1)* %c, i8 addrspace(1)* %d, i8 addrspace(1)* %e, i8 addrspace(1)* %f, i8 addrspace(1)* %g, i8 addrspace(1)* %h, i8 addrspace(1)* %j, i8 addrspace(1)* %k, i8 addrspace(1)* %l, i8 addrspace(1)* %m, i8 addrspace(1)* %n, i8 addrspace(1)* %o, i8 addrspace(1)* %p, i8 addrspace(1)* %q, i8 addrspace(1)* %r, i8 addrspace(1)* %s, i8 addrspace(1)* %t)
+gc "statepoint-example" personality i32 ()* @"personality_function" {
+entry:
+  %0 = invoke token (i64, i32, void (i8 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i8f(i64 0, i32 0, void (i8 addrspace(1)*)* @some_call, i32 1, i32 0, i8 addrspace(1)* %t, i32 0, i32 0) ["gc-live" (i8 addrspace(1)* %t)]
+          to label %invoke_safepoint_normal_dest unwind label %exceptional_return
+
+invoke_safepoint_normal_dest:
+  %t.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 0, i32 0)
+  ret i8 addrspace(1)* %t.relocated
+
+exceptional_return:
+  %landing_pad = landingpad token
+          cleanup
+  ret i8 addrspace(1)* null
+}
+
+; CHECK-LABEL: test_call:
+define i8 addrspace(1)* @test_call(i8 addrspace(1)* %a, i8 addrspace(1)* %b, i8 addrspace(1)* %c, i8 addrspace(1)* %d, i8 addrspace(1)* %e, i8 addrspace(1)* %f, i8 addrspace(1)* %g, i8 addrspace(1)* %h, i8 addrspace(1)* %j, i8 addrspace(1)* %k, i8 addrspace(1)* %l, i8 addrspace(1)* %m, i8 addrspace(1)* %n, i8 addrspace(1)* %o, i8 addrspace(1)* %p, i8 addrspace(1)* %q, i8 addrspace(1)* %r, i8 addrspace(1)* %s, i8 addrspace(1)* %t)
+gc "statepoint-example" personality i32 ()* @"personality_function" {
+entry:
+  %0 = call token (i64, i32, void (i8 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i8f(i64 0, i32 0, void (i8 addrspace(1)*)* @some_call, i32 1, i32 0, i8 addrspace(1)* %t, i32 0, i32 0) ["gc-live" (i8 addrspace(1)* %t)]
+  br label %other_block
+
+other_block:
+  %t.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 0, i32 0)
+  ret i8 addrspace(1)* %t.relocated
+}
+declare token @llvm.experimental.gc.statepoint.p0f_isVoidp1i8f(i64, i32, void (i8 addrspace(1)*)*, i32, i32, ...)
+declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32)


        


More information about the llvm-commits mailing list