-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[GlobalISel] Enhance iPTR type support in SDAG patterns #111503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This adds checks for integer types covered by iPTR type. It is dictated by the fact that insertelt node has SDTCisPtrTy constraint on the immediate operand. At the same time, this constraint can't be replaced by SDTCisInt, as it doesn't reduce the amount of possible types to the only one possible.
@llvm/pr-subscribers-tablegen @llvm/pr-subscribers-llvm-globalisel Author: Evgenii Kudriashov (e-kud) ChangesThis adds checks for integer types covered by iPTR type. It is dictated by the fact that insertelt node has SDTCisPtrTy constraint on the index operand. At the same time, this constraint can't be replaced by SDTCisInt as it doesn't reduce the amount of possible types to the only one possible. Patch is 36.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/111503.diff 6 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
index 7b42722ca8d4f1..95c8574ff27079 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
@@ -237,6 +237,7 @@ enum {
/// - OpIdx(ULEB128) - Operand index
/// - SizeInBits(ULEB128) - The size of the pointer value in bits.
GIM_CheckPointerToAny,
+ GIM_CheckIntPtr,
/// Check the register bank for the specified operand
/// - InsnID(ULEB128) - Instruction ID
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 9f8eb030a96c64..648e9394276470 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -719,14 +719,17 @@ bool GIMatchTableExecutor::executeMatchTable(
}
break;
}
+ case GIM_CheckIntPtr:
case GIM_CheckPointerToAny: {
+ bool IsPointerCheck = MatcherOpcode == GIM_CheckPointerToAny;
uint64_t InsnID = readULEB();
uint64_t OpIdx = readULEB();
uint64_t SizeInBits = readULEB();
DEBUG_WITH_TYPE(TgtExecutor::getName(),
- dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
- << InsnID << "]->getOperand(" << OpIdx
+ dbgs() << CurrentIdx << ": GIM_Check"
+ << (IsPointerCheck ? "PointerToAny" : "IntPtr")
+ << "(MIs[" << InsnID << "]->getOperand(" << OpIdx
<< "), SizeInBits=" << SizeInBits << ")\n");
assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
@@ -735,14 +738,15 @@ bool GIMatchTableExecutor::executeMatchTable(
// iPTR must be looked up in the target.
if (SizeInBits == 0) {
MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
- const unsigned AddrSpace = Ty.getAddressSpace();
+ const unsigned AddrSpace = IsPointerCheck ? Ty.getAddressSpace() : 0;
SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace);
}
assert(SizeInBits != 0 && "Pointer size must be known");
if (MO.isReg()) {
- if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
+ if ((IsPointerCheck && !Ty.isPointer()) ||
+ Ty.getSizeInBits() != SizeInBits)
if (handleReject() == RejectAndGiveUp)
return false;
} else if (handleReject() == RejectAndGiveUp)
diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
index d9121cf166e5aa..33089de2457952 100644
--- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
+++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -145,6 +145,7 @@ def : GINodeEquiv<G_CTTZ_ZERO_UNDEF, cttz_zero_undef>;
def : GINodeEquiv<G_CTPOP, ctpop>;
def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, extractelt>;
def : GINodeEquiv<G_INSERT_VECTOR_ELT, vector_insert>;
+def : GINodeEquiv<G_INSERT_VECTOR_ELT, insertelt>;
def : GINodeEquiv<G_CONCAT_VECTORS, concat_vectors>;
def : GINodeEquiv<G_BUILD_VECTOR, build_vector>;
def : GINodeEquiv<G_FCEIL, fceil>;
diff --git a/llvm/test/TableGen/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter.td
index 7dbaf4390c0f70..13d46d7e792ab2 100644
--- a/llvm/test/TableGen/GlobalISelEmitter.td
+++ b/llvm/test/TableGen/GlobalISelEmitter.td
@@ -95,11 +95,13 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
// CHECK-NEXT: enum {
// CHECK-NEXT: GILLT_p0s32
// CHECK-NEXT: GILLT_s32,
+// CHECK-NEXT: GILLT_v4s32,
// CHECK-NEXT: }
-// CHECK-NEXT: const static size_t NumTypeObjects = 2;
+// CHECK-NEXT: const static size_t NumTypeObjects = 3;
// CHECK-NEXT: const static LLT TypeObjects[] = {
// CHECK-NEXT: LLT::pointer(0, 32),
// CHECK-NEXT: LLT::scalar(32),
+// CHECK-NEXT: LLT::vector(ElementCount::getFixed(4), 32),
// CHECK-NEXT: };
// CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
@@ -242,7 +244,7 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
// R19O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
// R19O-NEXT: GIM_RootCheckType, /*Op*/3, /*Type*/GILLT_s32,
//
-// R19C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
+// R19C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
//
// R19O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
// R19O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
@@ -297,7 +299,7 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
// R19C-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/GIMT_Encode2(0), /*SubOperand*/0, // src2a
// R19C-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/0,
// R19C-NEXT: GIR_RootConstrainSelectedInstOperands,
-// R19C-NEXT: // GIR_Coverage, 20,
+// R19C-NEXT: // GIR_Coverage, [[ID]],
// R19C-NEXT: GIR_EraseRootFromParent_Done,
// R19C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
//
@@ -330,12 +332,12 @@ def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b),
// R21O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
// R21O-NEXT: GIM_RootCheckType, /*Op*/3, /*Type*/GILLT_s32,
//
-// R21C-NEXT: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 20 //
+// R21C-NEXT: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 21 //
// R21C-NOT: GIR_EraseRootFromParent_Done,
-// R21C: // GIR_Coverage, 20,
+// R21C: // GIR_Coverage, 21,
// R21C-NEXT: GIR_EraseRootFromParent_Done,
// R21C-NEXT: // Label [[PREV_NUM]]: @[[PREV]]
-// R21C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 22 //
+// R21C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 23 //
//
// R21O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
// R21O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
@@ -365,7 +367,7 @@ def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b),
// R21C-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/GIMT_Encode2(0),
// R21C-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*NumInsns*/1, /*MergeInsnID's*/0
// R21C-NEXT: GIR_RootConstrainSelectedInstOperands,
-// R21C-NEXT: // GIR_Coverage, 22,
+// R21C-NEXT: // GIR_Coverage, 23,
// R21C-NEXT: GIR_EraseRootFromParent_Done,
// R21C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
//
@@ -389,10 +391,10 @@ def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b),
// R20O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
// R20O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
//
-// R20N: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 22 //
+// R20N: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 23 //
// R20N: // Label [[PREV_NUM]]: @[[PREV]]
//
-// R20C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 21 //
+// R20C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 22 //
//
// R20N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
// R20N-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SUB),
@@ -413,7 +415,7 @@ def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b),
// R20C-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1
// R20C-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/GIMT_Encode2(0),
// R20C-NEXT: GIR_RootConstrainSelectedInstOperands,
-// R20C-NEXT: // GIR_Coverage, 21,
+// R20C-NEXT: // GIR_Coverage, 22,
// R20C-NEXT: GIR_EraseRootFromParent_Done,
// R20C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
//
@@ -453,7 +455,7 @@ def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3),
// R00O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
// R00O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
//
-// R00C: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 21 //
+// R00C: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 22 //
// R00C: // Label [[PREV_NUM]]: @[[PREV]]
//
// R00C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 0 //
@@ -513,7 +515,7 @@ def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3),
// R00O-NEXT: GIM_Reject,
// R00O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
// R00O-NEXT: GIM_Reject,
-// R00O-NEXT: }; // Size: 1832 bytes
+// R00O-NEXT: }; // Size: 1907 bytes
def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
[(set GPR32:$dst,
@@ -733,7 +735,7 @@ def XORIb : I<(outs GPR32:$dst), (ins mb:$src2, GPR32:$src1),
// This must precede the 3-register variants because constant immediates have
// priority over register banks.
//
-// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
+// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_XOR),
// NOOPT-NEXT: // MIs[0] DstI[dst]
@@ -751,16 +753,55 @@ def XORIb : I<(outs GPR32:$dst), (ins mb:$src2, GPR32:$src1),
// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, GIMT_Encode2(MyTarget::R0),
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // Wm
// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,
-// NOOPT-NEXT: // GIR_Coverage, 23,
+// NOOPT-NEXT: // GIR_Coverage, [[ID]],
// NOOPT-NEXT: GIR_EraseRootFromParent_Done,
// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;
def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>;
+//===- Test a pattern with iPTR type of operand. --------------------------===//
+//
+// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
+// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
+// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_INSERT_VECTOR_ELT),
+// NOOPT-NEXT: // MIs[0] DstI[dst]
+// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_v4s32,
+// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::VecReg128RegClassID),
+// NOOPT-NEXT: // MIs[0] src1
+// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_v4s32,
+// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::VecReg128RegClassID),
+// NOOPT-NEXT: // MIs[0] src2
+// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
+// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
+// NOOPT-NEXT: // MIs[0] src3
+// NOOPT-NEXT: GIM_CheckIntPtr, /*MI*/0, /*Op*/3, /*SizeInBits*/0,
+// NOOPT-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/3, // MIs[1]
+// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/2,
+// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_CONSTANT),
+// NOOPT-NEXT: // MIs[1] Operand 0
+// NOOPT-NEXT: GIM_CheckIntPtr, /*MI*/1, /*Op*/0, /*SizeInBits*/0,
+// NOOPT-NEXT: // MIs[1] Operand 1
+// NOOPT-NEXT: // No operand predicates
+// NOOPT-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,
+// NOOPT-NEXT: // (insertelt:{ *:[v4i32] } VecReg128:{ *:[v4i32] }:$src1, GPR32:{ *:[i32] }:$src2, (imm:{ *:[iPTR] }):$src3) => (INSERTELT:{ *:[v4i32] } VecReg128:{ *:[v4i32] }:$src1, GPR32:{ *:[i32] }:$src2, (imm:{ *:[i8] }):$src3)
+// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::INSERTELT),
+// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
+// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1
+// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/2, // src2
+// NOOPT-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/1, // src3
+// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,
+// NOOPT-NEXT: // GIR_Coverage, [[ID]],
+// NOOPT-NEXT: GIR_EraseRootFromParent_Done,
+// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
+
+def INSERTELT : I<(outs VecReg128:$dst),
+ (ins VecReg128:$src1, GPR32:$src2, i8imm:$src3),
+ [(set VecReg128:$dst, (v4i32 (insertelt VecReg128:$src1, GPR32:$src2, imm:$src3)))]>;
+
//===- Test a nested instruction match. -----------------------------------===//
//
-// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
+// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
// NOOPT-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HasA),
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_MUL),
@@ -791,13 +832,13 @@ def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>;
// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/2, // src3
// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,
-// NOOPT-NEXT: // GIR_Coverage, 7,
+// NOOPT-NEXT: // GIR_Coverage, [[ID]],
// NOOPT-NEXT: GIR_EraseRootFromParent_Done,
// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
// We also get a second rule by commutativity.
//
-// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
+// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
// NOOPT-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HasA),
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_MUL),
@@ -828,7 +869,7 @@ def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>;
// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src3
// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,
-// NOOPT-NEXT: // GIR_Coverage, 28,
+// NOOPT-NEXT: // GIR_Coverage, [[ID]],
// NOOPT-NEXT: GIR_EraseRootFromParent_Done,
// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
@@ -839,7 +880,7 @@ def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
//===- Test a simple pattern with just a specific leaf immediate. ---------===//
//
-// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
+// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_CONSTANT),
// NOOPT-NEXT: // MIs[0] DstI[dst]
@@ -851,7 +892,7 @@ def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MOV1),
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,
-// NOOPT-NEXT: // GIR_Coverage, 8,
+// NOOPT-NEXT: // GIR_Coverage, [[ID]],
// NOOPT-NEXT: GIR_EraseRootFromParent_Done,
// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
@@ -859,7 +900,7 @@ def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>;
//===- Test a simple pattern with a leaf immediate and a predicate. -------===//
//
-// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
+// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_CONSTANT),
// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIMT_Encode2(GICXXPred_I64_Predicate_simm8),
@@ -873,7 +914,7 @@ def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>;
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
// NOOPT-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,
-// NOOPT-NEXT: // GIR_Coverage, 9,
+// NOOPT-NEXT: // GIR_Coverage, [[ID]],
// NOOPT-NEXT: GIR_EraseRootFromParent_Done,
// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
@@ -882,7 +923,7 @@ def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$i
//===- Same again but use an IntImmLeaf. ----------------------------------===//
//
-// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
+// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_CONSTANT),
// NOOPT-NEXT: GIM_CheckAPIntImmPredicate, /*MI*/0, /*Predicate*/GIMT_Encode2(GICXXPred_APInt_Predicate_simm9),
@@ -896,7 +937,7 @@ def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$i
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
// NOOPT-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,
-// NOOPT-NEXT: // GIR_Coverage, 10,
+// NOOPT-NEXT: // GIR_Coverage, [[ID]],
// NOOPT-NEXT: GIR_EraseRootFromParent_Done,
// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
@@ -905,7 +946,7 @@ def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$i
//===- Test a pattern with a custom renderer. -----------------------------===//
//
-// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
+// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_CONSTANT),
// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIMT_Encode2(GICXXPred_I64_Predicate_cimm8),
@@ -919,7 +960,7 @@ def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$i
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
// NOOPT-NEXT: GIR_CustomRenderer, /*InsnID*/0, /*OldInsnID*/0, /*Renderer*/GIMT_Encode2(GICR_renderImm), // imm
// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,
-// NOOPT-NEXT: // GIR_Coverage, 11,
+// NOOPT-NEXT: // GIR_Coverage, [[ID]],
// NOOPT-NEXT: GIR_EraseRootFromParent_Done,
// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
@@ -927,7 +968,7 @@ def MOVcimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, cimm8:$
//===- Test a simple pattern with a FP immediate and a predicate. ---------===//
//
-// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
+// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID [[ID:[0-9]+]]
// NOO...
[truncated]
|
This is just a bug, the vector index type is separate from the pointer type |
We can't simply change the constraint in general
Most of the target have already accepted the idea of Then I tried to change the element type to i32 only on X86 (we need some common type for 32bit and 64bit platforms). It caused a lot of regressions since we have some combines that assume only for I'll try to solve them one by one before migrating to i32 index type. If anyone has better ideas on how to proceed, I'd appreciate it. Closing for now, as migration to |
@arsenm if this is a bug it's already buried too deep.
So each target that has vectors implemented in SDAG must overwrite default interface and whole SDAG implementation to enable vector patterns in GlobalISel. It looks like supporting |
The default implementation happens to use the address space 0 pointer type, that's not very deep.
I think we should just remove the SDTCisPtrTy constraint from the vector nodes. It's simply not correct. If we wanted to, we could have a parallel mechanism for the vector index type |
Yes, this is an entry point. After removing or replacing it with For targets with multi-width pointers we need to set a type Now, having About x86 in particular. Let's override |
This adds a check for integer types covered by iPTR type. It is dictated by the fact that insertelt node has SDTCisPtrTy constraint on the index operand. At the same time, this constraint can't be replaced by SDTCisInt as it doesn't reduce the amount of possible types to the only one possible.