[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