diff options
author | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-07-04 14:35:06 +0000 |
---|---|---|
committer | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-07-04 14:35:06 +0000 |
commit | 8175dca9957d927702d4803216af96027fff692c (patch) | |
tree | 839af9615e2aab58a8c44113450bb620eaa950a1 /test/TableGen | |
parent | ae593118ab5519b9964c98eafc386f02be89d8f9 (diff) | |
download | llvm-8175dca9957d927702d4803216af96027fff692c.tar.gz |
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307079 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/TableGen')
-rw-r--r-- | test/TableGen/GlobalISelEmitter.td | 858 |
1 files changed, 495 insertions, 363 deletions
diff --git a/test/TableGen/GlobalISelEmitter.td b/test/TableGen/GlobalISelEmitter.td index 7c09b97a5e9..599cf863fdc 100644 --- a/test/TableGen/GlobalISelEmitter.td +++ b/test/TableGen/GlobalISelEmitter.td @@ -38,6 +38,23 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } //===- Test the function boilerplate. -------------------------------------===// +// CHECK: const unsigned MAX_SUBTARGET_PREDICATES = 3; +// CHECK: using PredicateBitset = llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>; + +// CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_DECL +// CHECK-NEXT: mutable MatcherState State; +// CHECK-NEXT: typedef ComplexRendererFn(MyTargetInstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const; +// CHECK-NEXT: const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> MatcherInfo; +// CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL + +// CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT +// CHECK-NEXT: , State(2), +// CHECK-NEXT: MatcherInfo({TypeObjects, FeatureBitsets, { +// CHECK-NEXT: nullptr, // GICP_Invalid +// CHECK-NEXT: &MyTargetInstructionSelector::selectComplexPattern, // gi_complex +// CHECK-NEXT: }}) +// CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT + // CHECK-LABEL: enum SubtargetFeatureBits : uint8_t { // CHECK-NEXT: Feature_HasABit = 0, // CHECK-NEXT: Feature_HasBBit = 1, @@ -64,38 +81,47 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const { // CHECK: MachineFunction &MF = *I.getParent()->getParent(); -// CHECK: const MachineRegisterInfo &MRI = MF.getRegInfo(); +// CHECK: MachineRegisterInfo &MRI = MF.getRegInfo(); +// CHECK: AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF); +// CHECK: const PredicateBitset AvailableFeatures = getAvailableFeatures(); //===- Test a pattern with multiple ComplexPattern operands. --------------===// // -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 4) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_SELECT) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// 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: ((Renderer0 = selectComplexPattern(MI0.getOperand(2)))))) && -// CHECK-NEXT: ((/* src3 */ (MRI.getType(MI0.getOperand(3).getReg()) == (LLT::scalar(32))) && -// 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: 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); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-LABEL: MatchTable0[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex, +// CHECK-NEXT: // MIs[0] src3 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/1, GICP_gi_complex, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable0, MRI, TRI, RBI, AvailableFeatures)) { +// 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(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(1)/*src1*/); +// CHECK-NEXT: Renderers[1](MIB); +// CHECK-NEXT: Renderers[0](MIB); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } def : GINodeEquiv<G_SELECT, select>; def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>; @@ -104,112 +130,118 @@ def : Pat<(select GPR32:$src1, complex:$src2, complex:$src3), //===- Test a simple pattern with regclass operands. ----------------------===// -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 3) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_ADD) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// 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: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(2).getReg(), MRI, TRI)))))) { - -// CHECK-NEXT: // (add:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (ADD:i32 GPR32:i32:$src1, GPR32:i32:$src2) -// CHECK-NEXT: I.setDesc(TII.get(MyTarget::ADD)); -// CHECK-NEXT: MachineInstr &NewI = I; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } - +// CHECK-LABEL: MatchTable1[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID +// CHECK-NEXT: // MIs[0] src2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable1, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // (add:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (ADD:i32 GPR32:i32:$src1, GPR32:i32:$src2) +// CHECK-NEXT: I.setDesc(TII.get(MyTarget::ADD)); +// CHECK-NEXT: MachineInstr &NewI = I; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), [(set GPR32:$dst, (add 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; -// CHECK-NEXT: if (!MI0.getOperand(1).isReg()) -// CHECK-NEXT: return false; -// CHECK-NEXT: if (TRI.isPhysicalRegister(MI0.getOperand(1).getReg())) -// CHECK-NEXT: return false; -// CHECK-NEXT: MachineInstr &MI1 = *MRI.getVRegDef(MI0.getOperand(1).getReg()); -// CHECK-NEXT: if (MI1.getNumOperands() < 3) +// CHECK-LABEL: MatchTable2[] = { +// CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA, +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD, +// CHECK-NEXT: // MIs[1] Operand 0 +// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: // MIs[1] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[1] src2 +// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src3 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable2, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: if (!isObviouslySafeToFold(*State.MIs[1])) // CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_MUL) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// CHECK-NEXT: ((/* Operand 1 */ (MRI.getType(MI0.getOperand(1).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: (((MI1.getOpcode() == TargetOpcode::G_ADD) && -// CHECK-NEXT: ((/* Operand 0 */ (MRI.getType(MI1.getOperand(0).getReg()) == (LLT::scalar(32))))) && -// CHECK-NEXT: ((/* src1 */ (MRI.getType(MI1.getOperand(1).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI1.getOperand(1).getReg(), MRI, TRI))))) && -// CHECK-NEXT: ((/* src2 */ (MRI.getType(MI1.getOperand(2).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI1.getOperand(2).getReg(), MRI, TRI)))))) -// CHECK-NEXT: ))) && -// CHECK-NEXT: ((/* src3 */ (MRI.getType(MI0.getOperand(2).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(2).getReg(), MRI, TRI)))))) { -// CHECK-NEXT: if (!isObviouslySafeToFold(MI1)) return false; -// CHECK-NEXT: // (mul:i32 (add:i32 GPR32:i32:$src1, GPR32:i32:$src2), GPR32:i32:$src3) => (MULADD:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3) -// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::MULADD)); -// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/); -// CHECK-NEXT: MIB.add(MI1.getOperand(1)/*src1*/); -// CHECK-NEXT: MIB.add(MI1.getOperand(2)/*src2*/); -// CHECK-NEXT: MIB.add(MI0.getOperand(2)/*src3*/); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, &MI1, }) -// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) -// CHECK-NEXT: MIB.addMemOperand(MMO); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-NEXT: // (mul:i32 (add:i32 GPR32:i32:$src1, GPR32:i32:$src2), GPR32:i32:$src3) => (MULADD:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3) +// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::MULADD)); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.add(State.MIs[1]->getOperand(1)/*src1*/); +// CHECK-NEXT: MIB.add(State.MIs[1]->getOperand(2)/*src2*/); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(2)/*src3*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], State.MIs[1], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } // 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; -// CHECK-NEXT: if (!MI0.getOperand(2).isReg()) -// CHECK-NEXT: return false; -// CHECK-NEXT: if (TRI.isPhysicalRegister(MI0.getOperand(2).getReg())) -// CHECK-NEXT: return false; -// CHECK-NEXT: MachineInstr &MI1 = *MRI.getVRegDef(MI0.getOperand(2).getReg()); -// CHECK-NEXT: if (MI1.getNumOperands() < 3) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_MUL) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// CHECK-NEXT: ((/* src3 */ (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: ((/* Operand 2 */ (MRI.getType(MI0.getOperand(2).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: (((MI1.getOpcode() == TargetOpcode::G_ADD) && -// CHECK-NEXT: ((/* Operand 0 */ (MRI.getType(MI1.getOperand(0).getReg()) == (LLT::scalar(32))))) && -// CHECK-NEXT: ((/* src1 */ (MRI.getType(MI1.getOperand(1).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI1.getOperand(1).getReg(), MRI, TRI))))) && -// CHECK-NEXT: ((/* src2 */ (MRI.getType(MI1.getOperand(2).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI1.getOperand(2).getReg(), MRI, TRI)))))) -// CHECK-NEXT: )))) { -// CHECK-NEXT: if (!isObviouslySafeToFold(MI1)) return false; -// CHECK-NEXT: // (mul:i32 GPR32:i32:$src3, (add:i32 GPR32:i32:$src1, GPR32:i32:$src2)) => (MULADD:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3) +// CHECK-LABEL: MatchTable3[] = { +// CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA, +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2, +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src3 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD, +// CHECK-NEXT: // MIs[1] Operand 0 +// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: // MIs[1] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[1] src2 +// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable3, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: if (!isObviouslySafeToFold(*State.MIs[1])) +// CHECK-NEXT: return false; +// CHECK-NEXT: // (mul:i32 GPR32:i32:$src3, (add:i32 GPR32:i32:$src1, GPR32:i32:$src2)) => (MULADD:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3) // CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::MULADD)); -// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/); -// CHECK-NEXT: MIB.add(MI1.getOperand(1)/*src1*/); -// CHECK-NEXT: MIB.add(MI1.getOperand(2)/*src2*/); -// CHECK-NEXT: MIB.add(MI0.getOperand(1)/*src3*/); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, &MI1, }) +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.add(State.MIs[1]->getOperand(1)/*src1*/); +// CHECK-NEXT: MIB.add(State.MIs[1]->getOperand(2)/*src2*/); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(1)/*src3*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], State.MIs[1], }) // CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) // CHECK-NEXT: MIB.addMemOperand(MMO); // CHECK-NEXT: I.eraseFromParent(); @@ -225,67 +257,140 @@ def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3), //===- Test another simple pattern with regclass operands. ----------------===// -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit, Feature_HasCBit}; -// 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; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_MUL) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// 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: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(2).getReg(), MRI, TRI)))))) { -// CHECK-NEXT: // (mul:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (MUL:i32 GPR32:i32:$src2, GPR32:i32:$src1) -// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::MUL)); -// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/); -// CHECK-NEXT: MIB.add(MI0.getOperand(2)/*src2*/); -// CHECK-NEXT: MIB.add(MI0.getOperand(1)/*src1*/); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, }) -// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) -// CHECK-NEXT: MIB.addMemOperand(MMO); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } +// CHECK-LABEL: MatchTable4[] = { +// CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA_HasB_HasC, +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable4, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // (mul:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (MUL:i32 GPR32:i32:$src2, GPR32:i32:$src1) +// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::MUL)); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(2)/*src2*/); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(1)/*src1*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1), [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>, Requires<[HasA, HasB, HasC]>; +//===- Test a more complex multi-instruction match. -----------------------===// + +// CHECK-LABEL: MatchTable5[] = { +// CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA, +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, +// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/2, /*MI*/0, /*OpIdx*/2, // MIs[2] +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/2, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SUB, +// CHECK-NEXT: // MIs[1] Operand 0 +// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: // MIs[1] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[1] src2 +// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/2, TargetOpcode::G_SUB, +// CHECK-NEXT: // MIs[2] Operand 0 +// CHECK-NEXT: GIM_CheckType, /*MI*/2, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: // MIs[2] src3 +// CHECK-NEXT: GIM_CheckType, /*MI*/2, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[2] src4 +// CHECK-NEXT: GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable5, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: if (!isObviouslySafeToFold(*State.MIs[1])) +// CHECK-NEXT: return false; +// CHECK-NEXT: if (!isObviouslySafeToFold(*State.MIs[2])) +// CHECK-NEXT: return false; +// CHECK-NEXT: // (sub:i32 (sub:i32 GPR32:i32:$src1, GPR32:i32:$src2), (sub:i32 GPR32:i32:$src3, GPR32:i32:$src4)) => (INSNBOB:i32 GPR32:i32:$src1, GPR32:i32:$src2, GPR32:i32:$src3, GPR32:i32:$src4) +// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::INSNBOB)); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.add(State.MIs[1]->getOperand(1)/*src1*/); +// CHECK-NEXT: MIB.add(State.MIs[1]->getOperand(2)/*src2*/); +// CHECK-NEXT: MIB.add(State.MIs[2]->getOperand(1)/*src3*/); +// CHECK-NEXT: MIB.add(State.MIs[2]->getOperand(2)/*src4*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], State.MIs[1], State.MIs[2], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } + +def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4), + [(set GPR32:$dst, + (sub (sub GPR32:$src1, GPR32:$src2), (sub GPR32:$src3, GPR32:$src4)))]>, + Requires<[HasA]>; + //===- Test a pattern with ComplexPattern operands. -----------------------===// // -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 3) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_SUB) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// 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: ((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: Renderer0(MIB); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, }) -// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) -// CHECK-NEXT: MIB.addMemOperand(MMO); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } +// CHECK-LABEL: MatchTable6[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable6, MRI, TRI, RBI, AvailableFeatures)) { +// 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(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(1)/*src1*/); +// CHECK-NEXT: Renderers[0](MIB); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>; def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>; @@ -293,32 +398,36 @@ def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>; //===- Test a simple pattern with a default operand. ----------------------===// // -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 3) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_XOR) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// 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: ((/* Operand 2 */ (MRI.getType(MI0.getOperand(2).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: (isOperandImmEqual(MI0.getOperand(2), -2, MRI))))) { -// CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -2:i32) => (XORI:i32 GPR32:i32:$src1) -// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::XORI)); -// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/); -// CHECK-NEXT: MIB.addImm(-1); -// CHECK-NEXT: MIB.add(MI0.getOperand(1)/*src1*/); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, }) -// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) -// CHECK-NEXT: MIB.addMemOperand(MMO); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } +// CHECK-LABEL: MatchTable7[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -2 +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable7, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -2:i32) => (XORI:i32 GPR32:i32:$src1) +// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::XORI)); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.addImm(-1); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(1)/*src1*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } // The -2 is just to distinguish it from the 'not' case below. def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1), @@ -327,32 +436,36 @@ def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1), //===- Test a simple pattern with a default register operand. -------------===// // -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 3) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_XOR) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// 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: ((/* Operand 2 */ (MRI.getType(MI0.getOperand(2).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: (isOperandImmEqual(MI0.getOperand(2), -3, MRI))))) { -// CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -3:i32) => (XOR:i32 GPR32:i32:$src1) -// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::XOR)); -// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/); -// CHECK-NEXT: MIB.addReg(MyTarget::R0); -// CHECK-NEXT: MIB.add(MI0.getOperand(1)/*src1*/); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, }) -// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) -// CHECK-NEXT: MIB.addMemOperand(MMO); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } +// CHECK-LABEL: MatchTable8[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -3 +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable8, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -3:i32) => (XOR:i32 GPR32:i32:$src1) +// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::XOR)); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.addReg(MyTarget::R0); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(1)/*src1*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } // The -3 is just to distinguish it from the 'not' case below and the other default op case above. def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1), @@ -361,33 +474,37 @@ def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1), //===- Test a simple pattern with a multiple default operands. ------------===// // -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 3) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_XOR) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// 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: ((/* Operand 2 */ (MRI.getType(MI0.getOperand(2).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: (isOperandImmEqual(MI0.getOperand(2), -4, MRI))))) { -// CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -4:i32) => (XORlike:i32 GPR32:i32:$src1) -// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::XORlike)); -// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/); -// CHECK-NEXT: MIB.addImm(-1); -// CHECK-NEXT: MIB.addReg(MyTarget::R0); -// CHECK-NEXT: MIB.add(MI0.getOperand(1)/*src1*/); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, }) -// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) -// CHECK-NEXT: MIB.addMemOperand(MMO); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } +// CHECK-LABEL: MatchTable9[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -4 +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable9, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -4:i32) => (XORlike:i32 GPR32:i32:$src1) +// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::XORlike)); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.addImm(-1); +// CHECK-NEXT: MIB.addReg(MyTarget::R0); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(1)/*src1*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } // The -4 is just to distinguish it from the other 'not' cases. def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1), @@ -396,34 +513,38 @@ def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1), //===- Test a simple pattern with multiple operands with defaults. --------===// // -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 3) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_XOR) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// 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: ((/* Operand 2 */ (MRI.getType(MI0.getOperand(2).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: (isOperandImmEqual(MI0.getOperand(2), -5, MRI))))) { -// CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -5:i32) => (XORManyDefaults:i32 GPR32:i32:$src1) -// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::XORManyDefaults)); -// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/); -// CHECK-NEXT: MIB.addImm(-1); -// CHECK-NEXT: MIB.addReg(MyTarget::R0); -// CHECK-NEXT: MIB.addReg(MyTarget::R0); -// CHECK-NEXT: MIB.add(MI0.getOperand(1)/*src1*/); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, }) -// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) -// CHECK-NEXT: MIB.addMemOperand(MMO); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } +// CHECK-LABEL: MatchTable10[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -5, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable10, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -5:i32) => (XORManyDefaults:i32 GPR32:i32:$src1) +// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::XORManyDefaults)); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.addImm(-1); +// CHECK-NEXT: MIB.addReg(MyTarget::R0); +// CHECK-NEXT: MIB.addReg(MyTarget::R0); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(1)/*src1*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } // The -5 is just to distinguish it from the other cases. def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1), @@ -434,32 +555,36 @@ def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1) // This must precede the 3-register variants because constant immediates have // priority over register banks. -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 3) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_XOR) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// CHECK-NEXT: ((/* Wm */ (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: ((/* Operand 2 */ (MRI.getType(MI0.getOperand(2).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: (isOperandImmEqual(MI0.getOperand(2), -1, MRI))))) { -// CHECK-NEXT: // (xor:i32 GPR32:i32:$Wm, -1:i32) => (ORN:i32 R0:i32, GPR32:i32:$Wm) -// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::ORN)); -// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/); -// CHECK-NEXT: MIB.addReg(MyTarget::R0); -// CHECK-NEXT: MIB.add(MI0.getOperand(1)/*Wm*/); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, }) -// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) -// CHECK-NEXT: MIB.addMemOperand(MMO); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } +// CHECK-LABEL: MatchTable11[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Wm +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 2 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -1, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable11, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // (xor:i32 GPR32:i32:$Wm, -1:i32) => (ORN:i32 R0:i32, GPR32:i32:$Wm) +// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::ORN)); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: MIB.addReg(MyTarget::R0); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(1)/*Wm*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>; def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>; @@ -467,70 +592,77 @@ def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>; //===- Test a COPY_TO_REGCLASS --------------------------------------------===// // -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 2) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_BITCAST) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// CHECK-NEXT: ((/* src1 */ (MRI.getType(MI0.getOperand(1).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::FPR32RegClass) == RBI.getRegBank(MI0.getOperand(1).getReg(), MRI, TRI)))))) -// CHECK-NEXT: // (bitconvert:i32 FPR32:f32:$src1) => (COPY_TO_REGCLASS:i32 FPR32:f32:$src1, GPR32:i32) -// CHECK-NEXT: I.setDesc(TII.get(TargetOpcode::COPY)); -// CHECK-NEXT: MachineInstr &NewI = I; -// CHECK-NEXT: constrainOperandRegToRegClass(NewI, 0, MyTarget::GPR32RegClass, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } +// CHECK-LABEL: MatchTable12[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src1 +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::FPR32RegClassID, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable12, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // (bitconvert:i32 FPR32:f32:$src1) => (COPY_TO_REGCLASS:i32 FPR32:f32:$src1, GPR32:i32) +// CHECK-NEXT: I.setDesc(TII.get(TargetOpcode::COPY)); +// CHECK-NEXT: MachineInstr &NewI = I; +// CHECK-NEXT: constrainOperandRegToRegClass(NewI, 0, MyTarget::GPR32RegClass, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } def : Pat<(i32 (bitconvert FPR32:$src1)), (COPY_TO_REGCLASS FPR32:$src1, GPR32)>; //===- Test a simple pattern with just a leaf immediate. ------------------===// -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 2) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_CONSTANT) && -// CHECK-NEXT: ((/* dst */ (MRI.getType(MI0.getOperand(0).getReg()) == (LLT::scalar(32))) && -// CHECK-NEXT: ((&RBI.getRegBankFromRegClass(MyTarget::GPR32RegClass) == RBI.getRegBank(MI0.getOperand(0).getReg(), MRI, TRI))))) && -// CHECK-NEXT: ((/* Operand 1 */ (MI0.getOperand(1).isCImm() && MI0.getOperand(1).getCImm()->equalsInt(1))))) { -// CHECK-NEXT: // 1:i32 => (MOV1:i32) -// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::MOV1)); -// CHECK-NEXT: MIB.add(MI0.getOperand(0)/*dst*/); -// CHECK-NEXT: for (const auto *FromMI : {&MI0, }) -// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) -// CHECK-NEXT: MIB.addMemOperand(MMO); -// CHECK-NEXT: I.eraseFromParent(); -// CHECK-NEXT: MachineInstr &NewI = *MIB; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } +// CHECK-LABEL: MatchTable13[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] Operand 1 +// CHECK-NEXT: GIM_CheckLiteralInt, /*MI*/0, /*Op*/1, 1, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable13, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // 1:i32 => (MOV1:i32) +// CHECK-NEXT: MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(MyTarget::MOV1)); +// CHECK-NEXT: MIB.add(State.MIs[0]->getOperand(0)/*dst*/); +// CHECK-NEXT: for (const auto *FromMI : {State.MIs[0], }) +// CHECK-NEXT: for (const auto &MMO : FromMI->memoperands()) +// CHECK-NEXT: MIB.addMemOperand(MMO); +// CHECK-NEXT: I.eraseFromParent(); +// CHECK-NEXT: MachineInstr &NewI = *MIB; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>; //===- Test a pattern with an MBB operand. --------------------------------===// -// CHECK-LABEL: if ([&]() { -// CHECK-NEXT: MachineInstr &MI0 = I; -// CHECK-NEXT: if (MI0.getNumOperands() < 1) -// CHECK-NEXT: return false; -// CHECK-NEXT: if ((MI0.getOpcode() == TargetOpcode::G_BR) && -// CHECK-NEXT: ((/* target */ (MI0.getOperand(0).isMBB())))) { - -// CHECK-NEXT: // (br (bb:Other):$target) => (BR (bb:Other):$target) -// CHECK-NEXT: I.setDesc(TII.get(MyTarget::BR)); -// CHECK-NEXT: MachineInstr &NewI = I; -// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); -// CHECK-NEXT: return true; -// CHECK-NEXT: } -// CHECK-NEXT: return false; -// CHECK-NEXT: }()) { return true; } +// CHECK-LABEL: MatchTable14[] = { +// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/1, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR, +// CHECK-NEXT: // MIs[0] target +// CHECK-NEXT: GIM_CheckIsMBB, /*MI*/0, /*Op*/0, +// CHECK-NEXT: GIM_Accept, +// CHECK-NEXT: }; +// CHECK-NEXT: MIs.clear(); +// CHECK-NEXT: MIs.push_back(&I); +// CHECK-NEXT: if (executeMatchTable(*this, State, MatcherInfo, MatchTable14, MRI, TRI, RBI, AvailableFeatures)) { +// CHECK-NEXT: // (br (bb:Other):$target) => (BR (bb:Other):$target) +// CHECK-NEXT: I.setDesc(TII.get(MyTarget::BR)); +// CHECK-NEXT: MachineInstr &NewI = I; +// CHECK-NEXT: constrainSelectedInstRegOperands(NewI, TII, TRI, RBI); +// CHECK-NEXT: return true; +// CHECK-NEXT: } def BR : I<(outs), (ins unknown:$target), [(br bb:$target)]>; |