[llvm] 2a52c33 - [Statepoints] Properly handle const base pointer.

Denis Antrushin via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 9 00:08:09 PDT 2020


Author: Denis Antrushin
Date: 2020-09-09T14:07:00+07:00
New Revision: 2a52c3301a5254d4614401b4aa12ab7c841d7340

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

LOG: [Statepoints] Properly handle const base pointer.

Current code in InstEmitter assumes all GC pointers are either
VRegs or stack slots - hence, taking only one operand.
But it is possible to have constant base, in which case it
occupies two machine operands.

Add a convinience function to StackMaps to get index of next
meta argument and use it in InsrEmitter to properly advance to
the next statepoint meta operand.

Reviewed By: reames

Differential Revision: https://reviews.llvm.org/D87252

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/StackMaps.h
    llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
    llvm/lib/CodeGen/StackMaps.cpp
    llvm/test/CodeGen/X86/statepoint-vreg.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/StackMaps.h b/llvm/include/llvm/CodeGen/StackMaps.h
index ce4eb85d6452..578bc0e161a6 100644
--- a/llvm/include/llvm/CodeGen/StackMaps.h
+++ b/llvm/include/llvm/CodeGen/StackMaps.h
@@ -261,6 +261,10 @@ class StackMaps {
 
   StackMaps(AsmPrinter &AP);
 
+  /// Get index of next meta operand.
+  /// Similar to parseOperand, but does not actually parses operand meaning.
+  static unsigned getNextMetaArgIdx(MachineInstr *MI, unsigned CurIdx);
+
   void reset() {
     CSInfos.clear();
     ConstPool.clear();

diff  --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index ff84fdd62075..e2da367cfe3f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -89,18 +89,9 @@ static unsigned getStatepointGCArgStartIdx(MachineInstr *MI) {
          "STATEPOINT node expected");
   unsigned OperIdx = StatepointOpers(MI).getNumDeoptArgsIdx();
   unsigned NumDeopts = MI->getOperand(OperIdx).getImm();
-  // At this point stack references has not been lowered yet, so they
-  // take single operand.
   ++OperIdx;
-  while (NumDeopts--) {
-    MachineOperand &MO = MI->getOperand(OperIdx);
-    if (MO.isImm() && MO.getImm() == StackMaps::ConstantOp) {
-      ++OperIdx;
-      assert(MI->getOperand(OperIdx).isImm() &&
-             "Unexpected statepoint operand");
-    }
-    ++OperIdx;
-  }
+  while (NumDeopts--)
+    OperIdx = StackMaps::getNextMetaArgIdx(MI, OperIdx);
   return OperIdx;
 }
 
@@ -1002,11 +993,14 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
     assert(!HasPhysRegOuts && "STATEPOINT mishandled");
     MachineInstr *MI = MIB;
     unsigned Def = 0;
-    unsigned Use = getStatepointGCArgStartIdx(MI) + 1;
+    unsigned Use = getStatepointGCArgStartIdx(MI);
+    Use = StackMaps::getNextMetaArgIdx(MI, Use); // first derived
+    assert(Use < MI->getNumOperands());
     while (Def < NumDefs) {
       if (MI->getOperand(Use).isReg())
         MI->tieOperands(Def++, Use);
-      Use += 2;
+      Use = StackMaps::getNextMetaArgIdx(MI, Use); // next base
+      Use = StackMaps::getNextMetaArgIdx(MI, Use); // next derived
     }
   }
 

diff  --git a/llvm/lib/CodeGen/StackMaps.cpp b/llvm/lib/CodeGen/StackMaps.cpp
index 113d477ec80a..806ba1aa9822 100644
--- a/llvm/lib/CodeGen/StackMaps.cpp
+++ b/llvm/lib/CodeGen/StackMaps.cpp
@@ -88,6 +88,29 @@ StackMaps::StackMaps(AsmPrinter &AP) : AP(AP) {
     llvm_unreachable("Unsupported stackmap version!");
 }
 
+unsigned StackMaps::getNextMetaArgIdx(MachineInstr *MI, unsigned CurIdx) {
+  assert(CurIdx < MI->getNumOperands() && "Bad meta arg index");
+  const auto &MO = MI->getOperand(CurIdx);
+  if (MO.isImm()) {
+    switch (MO.getImm()) {
+    default:
+      llvm_unreachable("Unrecognized operand type.");
+    case StackMaps::DirectMemRefOp:
+      CurIdx += 2;
+      break;
+    case StackMaps::IndirectMemRefOp:
+      CurIdx += 3;
+      break;
+    case StackMaps::ConstantOp:
+      ++CurIdx;
+      break;
+    }
+  }
+  ++CurIdx;
+  assert(CurIdx < MI->getNumOperands() && "points past operand list");
+  return CurIdx;
+}
+
 /// Go up the super-register chain until we hit a valid dwarf register number.
 static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI) {
   int RegNum = TRI->getDwarfRegNum(Reg, false);

diff  --git a/llvm/test/CodeGen/X86/statepoint-vreg.ll b/llvm/test/CodeGen/X86/statepoint-vreg.ll
index b613a949c273..66b984b90536 100644
--- a/llvm/test/CodeGen/X86/statepoint-vreg.ll
+++ b/llvm/test/CodeGen/X86/statepoint-vreg.ll
@@ -47,6 +47,7 @@ entry:
   call void @consume(i32 addrspace(1)* %rel1)
   ret i1 %res1
 }
+
 ; test pointer variables intermixed with pointer constants
 define void @test_mixed(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) gc "statepoint-example" {
 ; CHECK-LABEL: test_mixed:
@@ -567,6 +568,28 @@ exceptional_return.right:
   ret i64 addrspace(1)* %val.relocated3
 }
 
+; test ISEL for constant base pointer - must properly tie operands
+define void @test_const_base(i32 addrspace(1)* %a) gc "statepoint-example" {
+; CHECK-LABEL: test_const_base:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    .cfi_offset %rbx, -16
+; CHECK-NEXT:    movq %rdi, %rbx
+; CHECK-NEXT:    callq func
+; CHECK-NEXT:  .Ltmp24:
+; CHECK-NEXT:    movq %rbx, %rdi
+; CHECK-NEXT:    callq consume
+; CHECK-NEXT:    popq %rbx
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    retq
+entry:
+  %token1 = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 0, i32 1, i32 7, i32 addrspace(1)* null, i32 9), "gc-live" (i32 addrspace(1)* null, i32 addrspace(1)* %a)]
+  %rel = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %token1,  i32 0, i32 1)
+  call void @consume(i32 addrspace(1)* %rel)
+  ret void
+}
+
 declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
 declare token @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...)


        


More information about the llvm-commits mailing list