summaryrefslogtreecommitdiff
path: root/test/TableGen/GlobalISelEmitter.td
diff options
context:
space:
mode:
Diffstat (limited to 'test/TableGen/GlobalISelEmitter.td')
-rw-r--r--test/TableGen/GlobalISelEmitter.td61
1 files changed, 47 insertions, 14 deletions
diff --git a/test/TableGen/GlobalISelEmitter.td b/test/TableGen/GlobalISelEmitter.td
index 25be435df2de..8d59036100a9 100644
--- a/test/TableGen/GlobalISelEmitter.td
+++ b/test/TableGen/GlobalISelEmitter.td
@@ -9,6 +9,7 @@ def MyTarget : Target { let InstructionSet = MyTargetISA; }
def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
+def GPR32Op : RegisterOperand<GPR32>;
class I<dag OOps, dag IOps, list<dag> Pat>
: Instruction {
@@ -22,14 +23,38 @@ def complex : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPattern", []> {
let MIOperandInfo = (ops i32imm, i32imm);
}
def gi_complex :
- GIComplexOperandMatcher<s32, (ops i32imm, i32imm), "selectComplexPattern">,
+ GIComplexOperandMatcher<s32, "selectComplexPattern">,
GIComplexPatternEquiv<complex>;
def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>;
def Z : OperandWithDefaultOps <i32, (ops R0)>;
def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>;
-//===- Test the function definition boilerplate. --------------------------===//
+def HasA : Predicate<"Subtarget->hasA()">;
+def HasB : Predicate<"Subtarget->hasB()">;
+
+//===- Test the function boilerplate. -------------------------------------===//
+
+// CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
+// CHECK-NEXT: Feature_HasABit = 0,
+// CHECK-NEXT: Feature_HasBBit = 1,
+// CHECK-NEXT: };
+
+// CHECK-LABEL: static const char *SubtargetFeatureNames[] = {
+// CHECK-NEXT: "Feature_HasA",
+// CHECK-NEXT: "Feature_HasB",
+// CHECK-NEXT: nullptr
+// CHECK-NEXT: };
+
+// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
+// CHECK-NEXT: computeAvailableFeatures(const MachineFunction *MF, const MyTargetSubtarget *Subtarget) const {
+// CHECK-NEXT: PredicateBitset Features;
+// CHECK-NEXT: if (Subtarget->hasA())
+// CHECK-NEXT: Features[Feature_HasABit] = 1;
+// CHECK-NEXT: if (Subtarget->hasB())
+// CHECK-NEXT: Features[Feature_HasBBit] = 1;
+// CHECK-NEXT: return Features;
+// CHECK-NEXT: }
// CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {
// CHECK: MachineFunction &MF = *I.getParent()->getParent();
@@ -48,17 +73,15 @@ def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>;
// CHECK-NEXT: ((/* src1 */ (MRI.getType(MI0.getOperand(1).getReg()) == (LLT::scalar(32))) &&
// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(1).getReg(), MRI, TRI))))) &&
// CHECK-NEXT: ((/* src2 */ (MRI.getType(MI0.getOperand(2).getReg()) == (LLT::scalar(32))) &&
-// CHECK-NEXT: (selectComplexPattern(MI0.getOperand(2), TempOp0, TempOp1)))) &&
+// CHECK-NEXT: ((Renderer0 = selectComplexPattern(MI0.getOperand(2)))))) &&
// CHECK-NEXT: ((/* src3 */ (MRI.getType(MI0.getOperand(3).getReg()) == (LLT::scalar(32))) &&
-// CHECK-NEXT: (selectComplexPattern(MI0.getOperand(3), TempOp2, TempOp3))))) {
+// CHECK-NEXT: ((Renderer1 = selectComplexPattern(MI0.getOperand(3))))))) {
// CHECK-NEXT: // (select:i32 GPR32:i32:$src1, complex:i32:$src2, complex:i32:$src3) => (INSN2:i32 GPR32:i32:$src1, complex:i32:$src3, complex:i32:$src2)
// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::INSN2));
// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/);
// CHECK-NEXT: MIB.add(MI0.getOperand(1)/*src1*/);
-// CHECK-NEXT: MIB.add(TempOp2);
-// CHECK-NEXT: MIB.add(TempOp3);
-// CHECK-NEXT: MIB.add(TempOp0);
-// CHECK-NEXT: MIB.add(TempOp1);
+// CHECK-NEXT: Renderer1(MIB);
+// CHECK-NEXT: Renderer0(MIB);
// CHECK-NEXT: for (const auto *FromMI : {&MI0, })
// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands())
// CHECK-NEXT: MIB.addMemOperand(MMO);
@@ -69,7 +92,7 @@ def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>;
// CHECK-NEXT: }
def : GINodeEquiv<G_SELECT, select>;
-def INSN2 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2, complex:$src3), []>;
+def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>;
def : Pat<(select GPR32:$src1, complex:$src2, complex:$src3),
(INSN2 GPR32:$src1, complex:$src3, complex:$src2)>;
@@ -103,6 +126,9 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
//===- Test a nested instruction match. -----------------------------------===//
// CHECK-LABEL: if ([&]() {
+// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit};
+// CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT: return false;
// CHECK-NEXT: MachineInstr &MI0 = I;
// CHECK-NEXT: if (MI0.getNumOperands() < 3)
// CHECK-NEXT: return false;
@@ -142,6 +168,9 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
// We also get a second rule by commutativity.
// CHECK-LABEL: if ([&]() {
+// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit};
+// CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT: return false;
// CHECK-NEXT: MachineInstr &MI0 = I;
// CHECK-NEXT: if (MI0.getNumOperands() < 3)
// CHECK-NEXT: return false;
@@ -181,11 +210,15 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
[(set GPR32:$dst,
- (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>;
+ (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,
+ Requires<[HasA]>;
//===- Test another simple pattern with regclass operands. ----------------===//
// CHECK-LABEL: if ([&]() {
+// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit};
+// CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT: return false;
// CHECK-NEXT: MachineInstr &MI0 = I;
// CHECK-NEXT: if (MI0.getNumOperands() < 3)
// CHECK-NEXT: return false;
@@ -213,7 +246,8 @@ def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
// CHECK-NEXT: }()) { return true; }
def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
- [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>;
+ [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
+ Requires<[HasA, HasB]>;
//===- Test a pattern with ComplexPattern operands. -----------------------===//
//
@@ -228,13 +262,12 @@ def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
// CHECK-NEXT: ((/* src1 */ (MRI.getType(MI0.getOperand(1).getReg()) == (LLT::scalar(32))) &&
// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(1).getReg(), MRI, TRI))))) &&
// CHECK-NEXT: ((/* src2 */ (MRI.getType(MI0.getOperand(2).getReg()) == (LLT::scalar(32))) &&
-// CHECK-NEXT: (selectComplexPattern(MI0.getOperand(2), TempOp0, TempOp1))))) {
+// CHECK-NEXT: ((Renderer0 = selectComplexPattern(MI0.getOperand(2))))))) {
// CHECK-NEXT: // (sub:i32 GPR32:i32:$src1, complex:i32:$src2) => (INSN1:i32 GPR32:i32:$src1, complex:i32:$src2)
// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::INSN1));
// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/);
// CHECK-NEXT: MIB.add(MI0.getOperand(1)/*src1*/);
-// CHECK-NEXT: MIB.add(TempOp0);
-// CHECK-NEXT: MIB.add(TempOp1);
+// CHECK-NEXT: Renderer0(MIB);
// CHECK-NEXT: for (const auto *FromMI : {&MI0, })
// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands())
// CHECK-NEXT: MIB.addMemOperand(MMO);