1// RUN: llvm-tblgen -gen-global-isel -I %p/../../include -optimize-match-table=false %s -o %T/non-optimized.cpp 2// RUN: llvm-tblgen -gen-global-isel -I %p/../../include -optimize-match-table=true %s -o %T/optimized.cpp 3// RUN: llvm-tblgen -gen-global-isel -I %p/../../include %s -o %T/default.cpp 4 5// RUN: FileCheck %s --check-prefixes=CHECK,R19C,R19N -input-file=%T/non-optimized.cpp 6// RUN: FileCheck %s --check-prefixes=CHECK,R19C,R19O -input-file=%T/optimized.cpp 7 8// RUN: FileCheck %s --check-prefixes=CHECK,R21C,R21N -input-file=%T/non-optimized.cpp 9// RUN: FileCheck %s --check-prefixes=CHECK,R21C,R21O -input-file=%T/optimized.cpp 10 11// RUN: FileCheck %s --check-prefixes=CHECK,R20C,R20N -input-file=%T/non-optimized.cpp 12// RUN: FileCheck %s --check-prefixes=CHECK,R20C,R20O -input-file=%T/optimized.cpp 13 14// RUN: FileCheck %s --check-prefixes=CHECK,R00C,R00N -input-file=%T/non-optimized.cpp 15// RUN: FileCheck %s --check-prefixes=CHECK,R00C,R00O -input-file=%T/optimized.cpp 16 17// RUN: FileCheck %s --check-prefixes=CHECK,R01C,R01N -input-file=%T/non-optimized.cpp 18// RUN: FileCheck %s --check-prefixes=CHECK,R01C,R01O -input-file=%T/optimized.cpp 19 20// RUN: FileCheck %s --check-prefixes=CHECK,R02C,R02N,NOOPT -input-file=%T/non-optimized.cpp 21// RUN: FileCheck %s --check-prefixes=CHECK,R02C,R02O -input-file=%T/optimized.cpp 22 23// RUN: diff %T/default.cpp %T/optimized.cpp 24 25include "llvm/Target/Target.td" 26 27//===- Define the necessary boilerplate for our test target. --------------===// 28 29def MyTargetISA : InstrInfo; 30def MyTarget : Target { let InstructionSet = MyTargetISA; } 31 32let TargetPrefix = "mytarget" in { 33def int_mytarget_nop : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>; 34} 35 36def R0 : Register<"r0"> { let Namespace = "MyTarget"; } 37def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>; 38def GPR32Op : RegisterOperand<GPR32>; 39def F0 : Register<"f0"> { let Namespace = "MyTarget"; } 40def FPR32 : RegisterClass<"MyTarget", [f32], 32, (add F0)>; 41 42class I<dag OOps, dag IOps, list<dag> Pat> 43 : Instruction { 44 let Namespace = "MyTarget"; 45 let OutOperandList = OOps; 46 let InOperandList = IOps; 47 let Pattern = Pat; 48} 49 50def complex : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPattern", []> { 51 let MIOperandInfo = (ops i32imm, i32imm); 52} 53def gi_complex : 54 GIComplexOperandMatcher<s32, "selectComplexPattern">, 55 GIComplexPatternEquiv<complex>; 56def complex_rr : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPatternRR", []> { 57 let MIOperandInfo = (ops GPR32, GPR32); 58} 59def gi_complex_rr : 60 GIComplexOperandMatcher<s32, "selectComplexPatternRR">, 61 GIComplexPatternEquiv<complex_rr>; 62 63def cimm8_xform : SDNodeXForm<imm, [{ 64 uint64_t Val = N->getZExtValue() << 1; 65 return CurDAG->getTargetConstant(Val, SDLoc(N), MVT::i64); 66 }]>; 67 68def cimm8 : Operand<i32>, ImmLeaf<i32, [{return isInt<8>(Imm);}], cimm8_xform>; 69 70def gi_cimm8 : GICustomOperandRenderer<"renderImm8">, 71 GISDNodeXFormEquiv<cimm8_xform>; 72 73def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>; 74def Z : OperandWithDefaultOps <i32, (ops R0)>; 75def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>; 76 77def HasA : Predicate<"Subtarget->hasA()">; 78def HasB : Predicate<"Subtarget->hasB()">; 79def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } 80 81//===- Test the function boilerplate. -------------------------------------===// 82 83// CHECK: const unsigned MAX_SUBTARGET_PREDICATES = 3; 84// CHECK: using PredicateBitset = llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>; 85 86// CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_DECL 87// CHECK-NEXT: mutable MatcherState State; 88// CHECK-NEXT: typedef ComplexRendererFns(MyTargetInstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const; 89// CHECK-NEXT: typedef void(MyTargetInstructionSelector::*CustomRendererFn)(MachineInstrBuilder &, const MachineInstr&) const; 90// CHECK-NEXT: const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn> ISelInfo; 91// CHECK-NEXT: static MyTargetInstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[]; 92// CHECK-NEXT: static MyTargetInstructionSelector::CustomRendererFn CustomRenderers[]; 93// CHECK-NEXT: bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const override; 94// CHECK-NEXT: bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) const override; 95// CHECK-NEXT: bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat &Imm) const override; 96// CHECK-NEXT: const int64_t *getMatchTable() const override; 97// CHECK-NEXT: bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI) const override; 98// CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL 99 100// CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT 101// CHECK-NEXT: , State(2), 102// CHECK-NEXT: ISelInfo(TypeObjects, NumTypeObjects, FeatureBitsets, ComplexPredicateFns, CustomRenderers) 103// CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT 104 105// CHECK-LABEL: enum SubtargetFeatureBits : uint8_t { 106// CHECK-NEXT: Feature_HasABit = 0, 107// CHECK-NEXT: Feature_HasBBit = 1, 108// CHECK-NEXT: Feature_HasCBit = 2, 109// CHECK-NEXT: }; 110 111// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector:: 112// CHECK-NEXT: computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const { 113// CHECK-NEXT: PredicateBitset Features; 114// CHECK-NEXT: if (Subtarget->hasA()) 115// CHECK-NEXT: Features[Feature_HasABit] = 1; 116// CHECK-NEXT: if (Subtarget->hasB()) 117// CHECK-NEXT: Features[Feature_HasBBit] = 1; 118// CHECK-NEXT: return Features; 119// CHECK-NEXT: } 120 121// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector:: 122// CHECK-NEXT: computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const { 123// CHECK-NEXT: PredicateBitset Features; 124// CHECK-NEXT: if (Subtarget->hasC()) 125// CHECK-NEXT: Features[Feature_HasCBit] = 1; 126// CHECK-NEXT: return Features; 127// CHECK-NEXT: } 128 129// CHECK-LABEL: // LLT Objects. 130// CHECK-NEXT: enum { 131// CHECK-NEXT: GILLT_s32, 132// CHECK-NEXT: } 133// CHECK-NEXT: const static size_t NumTypeObjects = 1; 134// CHECK-NEXT: const static LLT TypeObjects[] = { 135// CHECK-NEXT: LLT::scalar(32), 136// CHECK-NEXT: }; 137 138// CHECK-LABEL: // Feature bitsets. 139// CHECK-NEXT: enum { 140// CHECK-NEXT: GIFBS_Invalid, 141// CHECK-NEXT: GIFBS_HasA, 142// CHECK-NEXT: GIFBS_HasA_HasB_HasC, 143// CHECK-NEXT: } 144// CHECK-NEXT: const static PredicateBitset FeatureBitsets[] { 145// CHECK-NEXT: {}, // GIFBS_Invalid 146// CHECK-NEXT: {Feature_HasABit, }, 147// CHECK-NEXT: {Feature_HasABit, Feature_HasBBit, Feature_HasCBit, }, 148// CHECK-NEXT: }; 149 150// CHECK-LABEL: // ComplexPattern predicates. 151// CHECK-NEXT: enum { 152// CHECK-NEXT: GICP_Invalid, 153// CHECK-NEXT: GICP_gi_complex, 154// CHECK-NEXT: GICP_gi_complex_rr, 155// CHECK-NEXT: }; 156 157// CHECK-LABEL: // PatFrag predicates. 158// CHECK-NEXT: enum { 159// CHECK-NEXT: GIPFP_I64_Predicate_cimm8 = GIPFP_I64_Invalid + 1, 160// CHECK-NEXT: GIPFP_I64_Predicate_simm8, 161// CHECK-NEXT: }; 162 163 164// CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const { 165// CHECK-NEXT: switch (PredicateID) { 166// CHECK-NEXT: case GIPFP_I64_Predicate_cimm8: { 167// CHECK-NEXT: return isInt<8>(Imm); 168// CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned"); 169// CHECK-NEXT: return false; 170// CHECK-NEXT: } 171// CHECK-NEXT: case GIPFP_I64_Predicate_simm8: { 172// CHECK-NEXT: return isInt<8>(Imm); 173// CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned"); 174// CHECK-NEXT: return false; 175// CHECK-NEXT: } 176// CHECK-NEXT: } 177// CHECK-NEXT: llvm_unreachable("Unknown predicate"); 178// CHECK-NEXT: return false; 179// CHECK-NEXT: } 180 181// CHECK-LABEL: // PatFrag predicates. 182// CHECK-NEXT: enum { 183// CHECK-NEXT: GIPFP_APFloat_Predicate_fpimmz = GIPFP_APFloat_Invalid + 1, 184// CHECK-NEXT: }; 185// CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_APFloat(unsigned PredicateID, const APFloat & Imm) const { 186// CHECK-NEXT: switch (PredicateID) { 187// CHECK-NEXT: case GIPFP_APFloat_Predicate_fpimmz: { 188// CHECK-NEXT: return Imm->isExactlyValue(0.0); 189// CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned"); 190// CHECK-NEXT: return false; 191// CHECK-NEXT: } 192// CHECK-NEXT: } 193// CHECK-NEXT: llvm_unreachable("Unknown predicate"); 194// CHECK-NEXT: return false; 195// CHECK-NEXT: } 196 197// CHECK-LABEL: // PatFrag predicates. 198// CHECK-NEXT: enum { 199// CHECK-NEXT: GIPFP_APInt_Predicate_simm9 = GIPFP_APInt_Invalid + 1, 200// CHECK-NEXT: }; 201// CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_APInt(unsigned PredicateID, const APInt & Imm) const { 202// CHECK-NEXT: switch (PredicateID) { 203// CHECK-NEXT: case GIPFP_APInt_Predicate_simm9: { 204// CHECK-NEXT: return isInt<9>(Imm->getSExtValue()); 205// CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned"); 206// CHECK-NEXT: return false; 207// CHECK-NEXT: } 208// CHECK-NEXT: } 209// CHECK-NEXT: llvm_unreachable("Unknown predicate"); 210// CHECK-NEXT: return false; 211// CHECK-NEXT: } 212 213// CHECK-LABEL: MyTargetInstructionSelector::ComplexMatcherMemFn 214// CHECK-NEXT: MyTargetInstructionSelector::ComplexPredicateFns[] = { 215// CHECK-NEXT: nullptr, // GICP_Invalid 216// CHECK-NEXT: &MyTargetInstructionSelector::selectComplexPattern, // gi_complex 217// CHECK-NEXT: &MyTargetInstructionSelector::selectComplexPatternRR, // gi_complex_rr 218// CHECK-NEXT: } 219 220// CHECK-LABEL: // Custom renderers. 221// CHECK-NEXT: enum { 222// CHECK-NEXT: GICR_Invalid, 223// CHECK-NEXT: GICR_renderImm8, 224// CHECK-NEXT: }; 225// CHECK-NEXT: MyTargetInstructionSelector::CustomRendererFn 226// CHECK-NEXT: MyTargetInstructionSelector::CustomRenderers[] = { 227// CHECK-NEXT: nullptr, // GICP_Invalid 228// CHECK-NEXT: &MyTargetInstructionSelector::renderImm8, // gi_cimm8 229// CHECK-NEXT: }; 230 231// CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const { 232// CHECK-NEXT: MachineFunction &MF = *I.getParent()->getParent(); 233// CHECK-NEXT: MachineRegisterInfo &MRI = MF.getRegInfo(); 234// CHECK: AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF); 235// CHECK-NEXT: const PredicateBitset AvailableFeatures = getAvailableFeatures(); 236// CHECK-NEXT: NewMIVector OutMIs; 237// CHECK-NEXT: State.MIs.clear(); 238// CHECK-NEXT: State.MIs.push_back(&I); 239 240// CHECK: if (executeMatchTable(*this, OutMIs, State, ISelInfo, getMatchTable(), TII, MRI, TRI, RBI, AvailableFeatures, CoverageInfo)) { 241// CHECK-NEXT: return true; 242// CHECK-NEXT: } 243 244// CHECK: const int64_t * 245// CHECK-LABEL: MyTargetInstructionSelector::getMatchTable() const { 246// CHECK-NEXT: MatchTable0[] = { 247 248//===- Test a pattern with multiple ComplexPatterns in multiple instrs ----===// 249// 250// R19O-NEXT: GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]], 251// R19O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]], 252// R19O: /*TargetOpcode::G_SELECT*//*Label [[CASE_SELECT_NUM:[0-9]+]]*/ [[CASE_SELECT:[0-9]+]], 253// R19O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]] 254// R19O: // Label [[CASE_SELECT_NUM]]: @[[CASE_SELECT]] 255// R19O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]], 256// R19O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 257// R19O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 258// R19O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 259// R19O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32, 260// 261// R19C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 262// 263// R19O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 264// R19O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 265// R19N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4, 266// R19N-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT, 267// R19N-NEXT: // MIs[0] dst 268// R19N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 269// R19N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 270// R19N-NEXT: // MIs[0] src1 271// R19N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 272// R19N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 273// R19N-NEXT: // MIs[0] Operand 2 274// R19N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 275// 276// R19N-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex_rr, 277// R19N-NEXT: // MIs[0] Operand 3 278// R19N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32, 279// R19C-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/3, // MIs[1] 280// R19N-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/4, 281// R19C-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SELECT, 282// R19N-NEXT: // MIs[1] Operand 0 283// R19N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, 284// R19N-NEXT: // MIs[1] src3 285// R19C-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, 286// R19O-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 287// R19O-NEXT: GIM_CheckType, /*MI*/1, /*Op*/3, /*Type*/GILLT_s32, 288// R19N-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 289// R19N-NEXT: // MIs[1] src4 290// R19N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 291// R19N-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/2, /*Renderer*/1, GICP_gi_complex, 292// R19N-NEXT: // MIs[1] Operand 3 293// R19N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/3, /*Type*/GILLT_s32, 294// R19N-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/3, /*Renderer*/2, GICP_gi_complex, 295// R19O-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 296// R19C-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, 297// R19O-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex_rr, 298// R19O-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/2, /*Renderer*/1, GICP_gi_complex, 299// R19O-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/3, /*Renderer*/2, GICP_gi_complex, 300// R19C-NEXT: // (select:{ *:[i32] } GPR32:{ *:[i32] }:$src1, (complex_rr:{ *:[i32] } GPR32:{ *:[i32] }:$src2a, GPR32:{ *:[i32] }:$src2b), (select:{ *:[i32] } GPR32:{ *:[i32] }:$src3, complex:{ *:[i32] }:$src4, (complex:{ *:[i32] } i32imm:{ *:[i32] }:$src5a, i32imm:{ *:[i32] }:$src5b))) => (INSN3:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2b, GPR32:{ *:[i32] }:$src2a, (INSN4:{ *:[i32] } GPR32:{ *:[i32] }:$src3, complex:{ *:[i32] }:$src4, i32imm:{ *:[i32] }:$src5a, i32imm:{ *:[i32] }:$src5b)) 301// R19C-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32, 302// R19C-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/MyTarget::INSN4, 303// R19C-NEXT: GIR_AddTempRegister, /*InsnID*/1, /*TempRegID*/0, /*TempRegFlags*/RegState::Define, 304// R19C-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // src3 305// R19C-NEXT: GIR_ComplexRenderer, /*InsnID*/1, /*RendererID*/1, 306// R19C-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/1, /*RendererID*/2, /*SubOperand*/0, // src5a 307// R19C-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/1, /*RendererID*/2, /*SubOperand*/1, // src5b 308// R19C-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/1, 309// R19C-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN3, 310// R19C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 311// R19C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1 312// R19C-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // src2b 313// R19C-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src2a 314// R19C-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/0, 315// R19C-NEXT: GIR_EraseFromParent, /*InsnID*/0, 316// R19C-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 317// R19C-NEXT: // GIR_Coverage, 19, 318// R19C-NEXT: GIR_Done, 319// R19C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 320// 321// R19O: // Label [[GROUP_NUM]]: @[[GROUP]] 322// R19O-NEXT: GIM_Reject, 323// R19O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]] 324// R19O-NEXT: GIM_Reject, 325// R19O-NEXT: }; 326 327def INSN3 : I<(outs GPR32:$dst), 328 (ins GPR32Op:$src1, GPR32:$src2a, GPR32:$src2b, GPR32:$scr), []>; 329def INSN4 : I<(outs GPR32:$scr), 330 (ins GPR32:$src3, complex:$src4, i32imm:$src5a, i32imm:$src5b), []>; 331def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b), 332 (select GPR32:$src3, 333 complex:$src4, 334 (complex i32imm:$src5a, i32imm:$src5b))), 335 (INSN3 GPR32:$src1, GPR32:$src2b, GPR32:$src2a, 336 (INSN4 GPR32:$src3, complex:$src4, i32imm:$src5a, 337 i32imm:$src5b))>; 338 339// R21O-NEXT: GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]], 340// R21O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]], 341// R21O: /*TargetOpcode::G_SELECT*//*Label [[CASE_SELECT_NUM:[0-9]+]]*/ [[CASE_SELECT:[0-9]+]], 342// R21O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]] 343// R21O: // Label [[CASE_SELECT_NUM]]: @[[CASE_SELECT]] 344// R21O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]], 345// R21O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 346// R21O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 347// R21O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 348// R21O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32, 349// 350// R21C-NEXT: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 19 // 351// R21C-NOT: GIR_Done, 352// R21C: // GIR_Coverage, 19, 353// R21C-NEXT: GIR_Done, 354// R21C-NEXT: // Label [[PREV_NUM]]: @[[PREV]] 355// R21C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 21 // 356// 357// R21O-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_frag, 358// R21O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 359// R21O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 360// R21N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4, 361// R21N-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT, 362// R21N-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_frag, 363// R21N-NEXT: // MIs[0] dst 364// R21N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 365// R21N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 366// R21N-NEXT: // MIs[0] src1 367// R21N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 368// R21N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 369// R21N-NEXT: // MIs[0] src2 370// R21N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 371// 372// R21C-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex, 373// R21N-NEXT: // MIs[0] src3 374// R21N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32, 375// R21C-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/1, GICP_gi_complex, 376// R21C-NEXT: // (select:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2, complex:{ *:[i32] }:$src3)<<P:Predicate_frag>> => (INSN2:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src3, complex:{ *:[i32] }:$src2) 377 378// R21C-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN2, 379// R21C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 380// R21C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1 381// R21C-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1, 382// R21C-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0, 383// R21C-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList, 384// R21C-NEXT: GIR_EraseFromParent, /*InsnID*/0, 385// R21C-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 386// R21C-NEXT: // GIR_Coverage, 21, 387// R21C-NEXT: GIR_Done, 388// R21C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 389// 390// R21O-NEXT: GIM_Reject, 391// R21O-NEXT: // Label [[GROUP_NUM]]: @[[GROUP]] 392// R21O-NEXT: GIM_Reject, 393// R21O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]] 394// R21O-NEXT: GIM_Reject, 395// R21O-NEXT: }; 396 397//===- Test a pattern with ComplexPattern operands. -----------------------===// 398// 399// R20O-NEXT: GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]], 400// R20O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]], 401// R20O: /*TargetOpcode::G_SUB*//*Label [[CASE_SUB_NUM:[0-9]+]]*/ [[CASE_SUB:[0-9]+]], 402// R20O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]] 403// R20O: // Label [[CASE_SUB_NUM]]: @[[CASE_SUB]] 404// R20O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]], 405// R20O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 406// R20O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 407// R20O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 408// R20O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 409// 410// R20N: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 21 // 411// R20N: // Label [[PREV_NUM]]: @[[PREV]] 412// 413// R20C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 20 // 414// 415// R20N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 416// R20N-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB, 417// R20N-NEXT: // MIs[0] dst 418// R20N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 419// R20N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 420// R20N-NEXT: // MIs[0] src1 421// R20N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 422// 423// R20N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 424// R20N-NEXT: // MIs[0] src2 425// R20N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 426// R20O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 427// R20C-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex, 428// R20C-NEXT: // (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2) => (INSN1:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2) 429// R20C-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN1, 430// R20C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 431// R20C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1 432// R20C-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0, 433// R20C-NEXT: GIR_EraseFromParent, /*InsnID*/0, 434// R20C-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 435// R20C-NEXT: // GIR_Coverage, 20, 436// R20C-NEXT: GIR_Done, 437// R20C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 438// 439// R20O: // Label [[GROUP_NUM]]: @[[GROUP]] 440// R20O-NEXT: GIM_Reject, 441// R20O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]] 442// R20O-NEXT: GIM_Reject, 443// R20O-NEXT: }; 444 445def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>; 446def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>; 447 448//===- Test a pattern with multiple ComplexPattern operands. --------------===// 449// 450def : GINodeEquiv<G_SELECT, select>; 451let mayLoad = 1 in { 452 def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>; 453} 454def frag : PatFrag<(ops node:$a, node:$b, node:$c), 455 (select node:$a, node:$b, node:$c), 456 [{ return true; // C++ code }]> { 457 let GISelPredicateCode = [{ return true; // C++ code }]; 458} 459def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3), 460 (INSN2 GPR32:$src1, complex:$src3, complex:$src2)>; 461 462//===- Test a more complex multi-instruction match. -----------------------===// 463// 464// R00O-NEXT: GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]], 465// R00O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]], 466// R00O: /*TargetOpcode::G_SUB*//*Label [[CASE_SUB_NUM:[0-9]+]]*/ [[CASE_SUB:[0-9]+]], 467// R00O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]] 468// R00O: // Label [[CASE_SUB_NUM]]: @[[CASE_SUB]] 469// R00O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]], 470// R00O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 471// R00O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 472// R00O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 473// R00O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 474// 475// R00C: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 20 // 476// R00C: // Label [[PREV_NUM]]: @[[PREV]] 477// 478// R00C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 0 // 479// R00C-NEXT: GIM_CheckFeatures, GIFBS_HasA, 480// R00N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 481// R00N-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB, 482// R00N-NEXT: // MIs[0] dst 483// R00N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 484// R00N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 485// R00N-NEXT: // MIs[0] Operand 1 486// R00N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 487// R00C-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] 488// R00N-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, 489// R00C-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SUB, 490// R00N-NEXT: // MIs[1] Operand 0 491// R00N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, 492// R00N-NEXT: // MIs[1] src1 493// R00C-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, 494// R00O-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 495// R00N-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 496// R00N-NEXT: // MIs[1] src2 497// R00N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 498// R00N-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 499// R00N-NEXT: // MIs[0] Operand 2 500// R00N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 501// R00O-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 502// R00O-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 503// R00C-NEXT: GIM_RecordInsn, /*DefineMI*/2, /*MI*/0, /*OpIdx*/2, // MIs[2] 504// R00N-NEXT: GIM_CheckNumOperands, /*MI*/2, /*Expected*/3, 505// R00C-NEXT: GIM_CheckOpcode, /*MI*/2, TargetOpcode::G_SUB, 506// R00N-NEXT: // MIs[2] Operand 0 507// R00N-NEXT: GIM_CheckType, /*MI*/2, /*Op*/0, /*Type*/GILLT_s32, 508// R00N-NEXT: // MIs[2] src3 509// R00C-NEXT: GIM_CheckType, /*MI*/2, /*Op*/1, /*Type*/GILLT_s32, 510// R00O-NEXT: GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32, 511// R00N-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 512// R00N-NEXT: // MIs[2] src4 513// R00N-NEXT: GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32, 514// R00N-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 515// R00O-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 516// R00O-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 517// R00C-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, 518// R00C-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/2, 519// R00C-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) 520// R00C-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSNBOB, 521// R00C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 522// R00C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1 523// R00C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2 524// R00C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/1, // src3 525// R00C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // src4 526// R00C-NEXT: GIR_EraseFromParent, /*InsnID*/0, 527// R00C-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 528// R00C-NEXT: // GIR_Coverage, 0, 529// R00C-NEXT: GIR_Done, 530// R00C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 531// 532// R00O-NEXT: GIM_Reject, 533// R00O-NEXT: // Label [[GROUP_NUM]]: @[[GROUP]] 534// R00O-NEXT: GIM_Reject, 535// R00O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]] 536// R00O-NEXT: GIM_Reject, 537// R00O-NEXT: }; 538 539def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4), 540 [(set GPR32:$dst, 541 (sub (sub GPR32:$src1, GPR32:$src2), (sub GPR32:$src3, GPR32:$src4)))]>, 542 Requires<[HasA]>; 543 544//===- Test a simple pattern with an intrinsic. ---------------------------===// 545// 546// R01O-NEXT: GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]], 547// R01O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]], 548// R01O: /*TargetOpcode::G_INTRINSIC*//*Label [[CASE_INTRINSIC_NUM:[0-9]+]]*/ [[CASE_INTRINSIC:[0-9]+]], 549// R01O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]] 550// R01O: // Label [[CASE_INTRINSIC_NUM]]: @[[CASE_INTRINSIC]] 551// 552// R01N: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 0 // 553// R01N: // Label [[PREV_NUM]]: @[[PREV]] 554// 555// R01C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 1 // 556// R01C-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 557// 558// R01O-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, Intrinsic::mytarget_nop, 559// R01O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 560// R01O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 561// R01O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 562// 563// R01N-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC, 564// R01N-NEXT: // MIs[0] dst 565// R01N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 566// R01N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 567// R01N-NEXT: // MIs[0] Operand 1 568// R01N-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, Intrinsic::mytarget_nop, 569// R01N-NEXT: // MIs[0] src1 570// R01N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 571// 572// R01C-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 573// R01C-NEXT: // (intrinsic_wo_chain:{ *:[i32] } [[ID:[0-9]+]]:{ *:[iPTR] }, GPR32:{ *:[i32] }:$src1) => (MOV:{ *:[i32] } GPR32:{ *:[i32] }:$src1) 574// R01C-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV, 575// R01C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 576// R01C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src1 577// R01C-NEXT: GIR_EraseFromParent, /*InsnID*/0, 578// R01C-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 579// R01C-NEXT: // GIR_Coverage, 1, 580// R01C-NEXT: GIR_Done, 581// R01C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 582// 583// R01O-NEXT: GIM_Reject, 584// R01O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]] 585// R01O-NEXT: GIM_Reject, 586 587def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1), 588 [(set GPR32:$dst, (int_mytarget_nop GPR32:$src1))]>; 589 590//===- Test a simple pattern with a default operand. ----------------------===// 591// 592// R02O-NEXT: GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]], 593// R02O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]], 594// R02O: /*TargetOpcode::G_XOR*//*Label [[CASE_XOR_NUM:[0-9]+]]*/ [[CASE_XOR:[0-9]+]], 595// R02O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]] 596// R02O: // Label [[CASE_XOR_NUM]]: @[[CASE_XOR]] 597// R02O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]], 598// R02O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 599// R02O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 600// R02O-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 601// R02O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 602// R02O-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 603// 604// R02N: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 1 // 605// R02N: // Label [[PREV_NUM]]: @[[PREV]] 606// 607// R02C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 2 // 608// 609// R02N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 610// R02N-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, 611// R02N-NEXT: // MIs[0] dst 612// R02N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 613// R02N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 614// R02N-NEXT: // MIs[0] src1 615// R02N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 616// R02N-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 617// R02N-NEXT: // MIs[0] Operand 2 618// R02N-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 619// 620// R02C-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -2 621// R02C-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -2:{ *:[i32] }) => (XORI:{ *:[i32] } GPR32:{ *:[i32] }:$src1) 622// R02C-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORI, 623// R02C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 624// R02C-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/-1, 625// R02C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1 626// R02C-NEXT: GIR_EraseFromParent, /*InsnID*/0, 627// R02C-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 628// R02C-NEXT: // GIR_Coverage, 2, 629// R02C-NEXT: GIR_Done, 630// R02C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 631// 632// R02O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]] 633// R02O-NEXT: GIM_Reject, 634 635// The -2 is just to distinguish it from the 'not' case below. 636def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1), 637 [(set GPR32:$dst, (xor GPR32:$src1, -2))]>; 638 639//===- Test a simple pattern with a default register operand. -------------===// 640// 641// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 642// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 643// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, 644// NOOPT-NEXT: // MIs[0] dst 645// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 646// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 647// NOOPT-NEXT: // MIs[0] src1 648// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 649// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 650// NOOPT-NEXT: // MIs[0] Operand 2 651// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 652// NOOPT-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -3 653// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -3:{ *:[i32] }) => (XOR:{ *:[i32] } GPR32:{ *:[i32] }:$src1) 654// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XOR, 655// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 656// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0, 657// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1 658// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 659// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 660// NOOPT-NEXT: // GIR_Coverage, 3, 661// NOOPT-NEXT: GIR_Done, 662// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 663 664// The -3 is just to distinguish it from the 'not' case below and the other default op case above. 665def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1), 666 [(set GPR32:$dst, (xor GPR32:$src1, -3))]>; 667 668//===- Test a simple pattern with a multiple default operands. ------------===// 669// 670// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 671// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 672// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, 673// NOOPT-NEXT: // MIs[0] dst 674// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 675// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 676// NOOPT-NEXT: // MIs[0] src1 677// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 678// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 679// NOOPT-NEXT: // MIs[0] Operand 2 680// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 681// NOOPT-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -4 682// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -4:{ *:[i32] }) => (XORlike:{ *:[i32] } GPR32:{ *:[i32] }:$src1) 683// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORlike, 684// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 685// NOOPT-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/-1, 686// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0, 687// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1 688// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 689// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 690// NOOPT-NEXT: // GIR_Coverage, 4, 691// NOOPT-NEXT: GIR_Done, 692// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 693 694// The -4 is just to distinguish it from the other 'not' cases. 695def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1), 696 [(set GPR32:$dst, (xor GPR32:$src1, -4))]>; 697 698//===- Test a simple pattern with multiple operands with defaults. --------===// 699// 700// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 701// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 702// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, 703// NOOPT-NEXT: // MIs[0] dst 704// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 705// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 706// NOOPT-NEXT: // MIs[0] src1 707// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 708// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 709// NOOPT-NEXT: // MIs[0] Operand 2 710// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 711// NOOPT-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -5, 712// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -5:{ *:[i32] }) => (XORManyDefaults:{ *:[i32] } GPR32:{ *:[i32] }:$src1) 713// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORManyDefaults, 714// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 715// NOOPT-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/-1, 716// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0, 717// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0, 718// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1 719// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 720// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 721// NOOPT-NEXT: // GIR_Coverage, 5, 722// NOOPT-NEXT: GIR_Done, 723// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 724 725// The -5 is just to distinguish it from the other cases. 726def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1), 727 [(set GPR32:$dst, (xor GPR32:$src1, -5))]>; 728 729//===- Test a simple pattern with constant immediate operands. ------------===// 730// 731// This must precede the 3-register variants because constant immediates have 732// priority over register banks. 733// 734// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 735// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 736// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR, 737// NOOPT-NEXT: // MIs[0] dst 738// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 739// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 740// NOOPT-NEXT: // MIs[0] Wm 741// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 742// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 743// NOOPT-NEXT: // MIs[0] Operand 2 744// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 745// NOOPT-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -1, 746// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$Wm, -1:{ *:[i32] }) => (ORN:{ *:[i32] } R0:{ *:[i32] }, GPR32:{ *:[i32] }:$Wm) 747// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::ORN, 748// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 749// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0, 750// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // Wm 751// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 752// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 753// NOOPT-NEXT: // GIR_Coverage, 22, 754// NOOPT-NEXT: GIR_Done, 755// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 756 757def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>; 758def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>; 759 760//===- Test a nested instruction match. -----------------------------------===// 761// 762// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 763// NOOPT-NEXT: GIM_CheckFeatures, GIFBS_HasA, 764// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 765// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL, 766// NOOPT-NEXT: // MIs[0] dst 767// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 768// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 769// NOOPT-NEXT: // MIs[0] Operand 1 770// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 771// NOOPT-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] 772// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, 773// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD, 774// NOOPT-NEXT: // MIs[1] Operand 0 775// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, 776// NOOPT-NEXT: // MIs[1] src1 777// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, 778// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 779// NOOPT-NEXT: // MIs[1] src2 780// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 781// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 782// NOOPT-NEXT: // MIs[0] src3 783// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 784// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 785// NOOPT-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, 786// NOOPT-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) 787// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD, 788// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 789// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1 790// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2 791// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src3 792// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 793// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 794// NOOPT-NEXT: // GIR_Coverage, 6, 795// NOOPT-NEXT: GIR_Done, 796// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 797 798// We also get a second rule by commutativity. 799// 800// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 801// NOOPT-NEXT: GIM_CheckFeatures, GIFBS_HasA, 802// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 803// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL, 804// NOOPT-NEXT: // MIs[0] dst 805// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 806// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 807// NOOPT-NEXT: // MIs[0] src3 808// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 809// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 810// NOOPT-NEXT: // MIs[0] Operand 2 811// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 812// NOOPT-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2, 813// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, 814// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD, 815// NOOPT-NEXT: // MIs[1] Operand 0 816// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, 817// NOOPT-NEXT: // MIs[1] src1 818// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, 819// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 820// NOOPT-NEXT: // MIs[1] src2 821// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 822// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 823// NOOPT-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, 824// NOOPT-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) 825// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD, 826// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 827// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1 828// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2 829// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src3 830// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 831// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 832// NOOPT-NEXT: // GIR_Coverage, 25, 833// NOOPT-NEXT: GIR_Done, 834// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 835 836def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3), 837 [(set GPR32:$dst, 838 (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>, 839 Requires<[HasA]>; 840 841//===- Test a simple pattern with just a specific leaf immediate. ---------===// 842// 843// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 844// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, 845// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, 846// NOOPT-NEXT: // MIs[0] dst 847// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 848// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 849// NOOPT-NEXT: // MIs[0] Operand 1 850// NOOPT-NEXT: GIM_CheckLiteralInt, /*MI*/0, /*Op*/1, 1, 851// NOOPT-NEXT: // 1:{ *:[i32] } => (MOV1:{ *:[i32] }) 852// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV1, 853// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 854// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 855// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 856// NOOPT-NEXT: // GIR_Coverage, 7, 857// NOOPT-NEXT: GIR_Done, 858// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 859 860def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>; 861 862//===- Test a simple pattern with a leaf immediate and a predicate. -------===// 863// 864// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 865// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, 866// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, 867// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_simm8, 868// NOOPT-NEXT: // MIs[0] dst 869// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 870// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 871// NOOPT-NEXT: // MIs[0] Operand 1 872// NOOPT-NEXT: // No operand predicates 873// NOOPT-NEXT: // (imm:{ *:[i32] })<<P:Predicate_simm8>>:$imm => (MOVimm8:{ *:[i32] } (imm:{ *:[i32] }):$imm) 874// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm8, 875// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 876// NOOPT-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm 877// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 878// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 879// NOOPT-NEXT: // GIR_Coverage, 8, 880// NOOPT-NEXT: GIR_Done, 881// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 882 883def simm8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>; 884def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$imm)]>; 885 886//===- Same again but use an IntImmLeaf. ----------------------------------===// 887// 888// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 889// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, 890// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, 891// NOOPT-NEXT: GIM_CheckAPIntImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APInt_Predicate_simm9, 892// NOOPT-NEXT: // MIs[0] dst 893// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 894// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 895// NOOPT-NEXT: // MIs[0] Operand 1 896// NOOPT-NEXT: // No operand predicates 897// NOOPT-NEXT: // (imm:{ *:[i32] })<<P:Predicate_simm9>>:$imm => (MOVimm9:{ *:[i32] } (imm:{ *:[i32] }):$imm) 898// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm9, 899// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 900// NOOPT-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm 901// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 902// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 903// NOOPT-NEXT: // GIR_Coverage, 9, 904// NOOPT-NEXT: GIR_Done, 905// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 906 907def simm9 : IntImmLeaf<i32, [{ return isInt<9>(Imm->getSExtValue()); }]>; 908def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$imm)]>; 909 910//===- Test a pattern with a custom renderer. -----------------------------===// 911// 912// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 913// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, 914// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, 915// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_cimm8, 916// NOOPT-NEXT: // MIs[0] dst 917// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 918// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 919// NOOPT-NEXT: // MIs[0] Operand 1 920// NOOPT-NEXT: // No operand predicates 921// NOOPT-NEXT: // (imm:{ *:[i32] })<<P:Predicate_cimm8>><<X:cimm8_xform>>:$imm => (MOVcimm8:{ *:[i32] } (cimm8_xform:{ *:[i32] } (imm:{ *:[i32] }):$imm)) 922// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVcimm8, 923// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 924// NOOPT-NEXT: GIR_CustomRenderer, /*InsnID*/0, /*OldInsnID*/0, /*Renderer*/GICR_renderImm8, // imm 925// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 926// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 927// NOOPT-NEXT: // GIR_Coverage, 10, 928// NOOPT-NEXT: GIR_Done, 929// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 930 931def MOVcimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, cimm8:$imm)]>; 932 933//===- Test a simple pattern with a FP immediate and a predicate. ---------===// 934// 935// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 936// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, 937// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCONSTANT, 938// NOOPT-NEXT: GIM_CheckAPFloatImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APFloat_Predicate_fpimmz, 939// NOOPT-NEXT: // MIs[0] dst 940// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 941// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::FPR32RegClassID, 942// NOOPT-NEXT: // MIs[0] Operand 1 943// NOOPT-NEXT: // No operand predicates 944// NOOPT-NEXT: // (fpimm:{ *:[f32] })<<P:Predicate_fpimmz>>:$imm => (MOVfpimmz:{ *:[f32] } (fpimm:{ *:[f32] }):$imm) 945// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVfpimmz, 946// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 947// NOOPT-NEXT: GIR_CopyFConstantAsFPImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm 948// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 949// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 950// NOOPT-NEXT: // GIR_Coverage, 17, 951// NOOPT-NEXT: GIR_Done, 952// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 953 954//===- Test a simple pattern with inferred pointer operands. ---------------===// 955// 956// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 957// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, 958// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD, 959// NOOPT-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0, 960// NOOPT-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic, 961// NOOPT-NEXT: // MIs[0] dst 962// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 963// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 964// NOOPT-NEXT: // MIs[0] src1 965// NOOPT-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32, 966// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 967// NOOPT-NEXT: // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1) 968// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD, 969// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 970// NOOPT-NEXT: // GIR_Coverage, 11, 971// NOOPT-NEXT: GIR_Done, 972// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 973 974def LOAD : I<(outs GPR32:$dst), (ins GPR32:$src1), 975 [(set GPR32:$dst, (load GPR32:$src1))]>; 976 977//===- Test a simple pattern with a sextload -------------------------------===// 978// 979// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 980// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, 981// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SEXTLOAD, 982// NOOPT-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/2, 983// NOOPT-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic, 984// NOOPT-NEXT: // MIs[0] dst 985// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 986// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 987// NOOPT-NEXT: // MIs[0] src1 988// NOOPT-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32, 989// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 990// NOOPT-NEXT: // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedload>><<P:Predicate_sextload>><<P:Predicate_sextloadi16>> => (SEXTLOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1) 991// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::SEXTLOAD, 992// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 993// NOOPT-NEXT: // GIR_Coverage, 12, 994// NOOPT-NEXT: GIR_Done, 995// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 996 997def SEXTLOAD : I<(outs GPR32:$dst), (ins GPR32:$src1), 998 [(set GPR32:$dst, (sextloadi16 GPR32:$src1))]>; 999 1000//===- Test a simple pattern with regclass operands. ----------------------===// 1001// 1002// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 1003// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 1004// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD, 1005// NOOPT-NEXT: // MIs[0] dst 1006// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 1007// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 1008// NOOPT-NEXT: // MIs[0] src1 1009// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 1010// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID 1011// NOOPT-NEXT: // MIs[0] src2 1012// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 1013// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 1014// NOOPT-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) 1015// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD, 1016// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 1017// NOOPT-NEXT: // GIR_Coverage, 13, 1018// NOOPT-NEXT: GIR_Done, 1019// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 1020 1021def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), 1022 [(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>; 1023 1024//===- Test a pattern with a tied operand in the matcher ------------------===// 1025// 1026// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 1027// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 1028// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD, 1029// NOOPT-NEXT: // MIs[0] dst 1030// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 1031// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 1032// NOOPT-NEXT: // MIs[0] src{{$}} 1033// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 1034// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 1035// NOOPT-NEXT: // MIs[0] src{{$}} 1036// NOOPT-NEXT: GIM_CheckIsSameOperand, /*MI*/0, /*OpIdx*/2, /*OtherMI*/0, /*OtherOpIdx*/1, 1037// NOOPT-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src, GPR32:{ *:[i32] }:$src) => (DOUBLE:{ *:[i32] } GPR32:{ *:[i32] }:$src) 1038// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::DOUBLE, 1039// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 1040// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src 1041// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 1042// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 1043// NOOPT-NEXT: // GIR_Coverage, 14, 1044// NOOPT-NEXT: GIR_Done, 1045// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 1046 1047def DOUBLE : I<(outs GPR32:$dst), (ins GPR32:$src), [(set GPR32:$dst, (add GPR32:$src, GPR32:$src))]>; 1048 1049//===- Test a simple pattern with ValueType operands. ----------------------===// 1050// 1051// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 1052// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 1053// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD, 1054// NOOPT-NEXT: // MIs[0] dst 1055// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 1056// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 1057// NOOPT-NEXT: // MIs[0] src1 1058// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 1059// NOOPT-NEXT: // MIs[0] src2 1060// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 1061// NOOPT-NEXT: // (add:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) 1062// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD, 1063// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 1064// NOOPT-NEXT: // GIR_Coverage, 23, 1065// NOOPT-NEXT: GIR_Done, 1066// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 1067 1068def : Pat<(add i32:$src1, i32:$src2), 1069 (ADD i32:$src1, i32:$src2)>; 1070 1071//===- Test another simple pattern with regclass operands. ----------------===// 1072// 1073// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 1074// NOOPT-NEXT: GIM_CheckFeatures, GIFBS_HasA_HasB_HasC, 1075// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 1076// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL, 1077// NOOPT-NEXT: // MIs[0] dst 1078// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 1079// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 1080// NOOPT-NEXT: // MIs[0] src1 1081// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 1082// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID, 1083// NOOPT-NEXT: // MIs[0] src2 1084// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 1085// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID, 1086// NOOPT-NEXT: // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (MUL:{ *:[i32] } GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src1) 1087// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MUL, 1088// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 1089// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src2 1090// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1 1091// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 1092// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 1093// NOOPT-NEXT: // GIR_Coverage, 15, 1094// NOOPT-NEXT: GIR_Done, 1095// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 1096 1097def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1), 1098 [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>, 1099 Requires<[HasA, HasB, HasC]>; 1100 1101//===- Test a COPY_TO_REGCLASS --------------------------------------------===// 1102// 1103// 1104// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 1105// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, 1106// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST, 1107// NOOPT-NEXT: // MIs[0] dst 1108// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 1109// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 1110// NOOPT-NEXT: // MIs[0] src1 1111// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 1112// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::FPR32RegClassID, 1113// NOOPT-NEXT: // (bitconvert:{ *:[i32] } FPR32:{ *:[f32] }:$src1) => (COPY_TO_REGCLASS:{ *:[i32] } FPR32:{ *:[f32] }:$src1, GPR32:{ *:[i32] }) 1114// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/TargetOpcode::COPY, 1115// NOOPT-NEXT: GIR_ConstrainOperandRC, /*InsnID*/0, /*Op*/0, /*RC GPR32*/1, 1116// NOOPT-NEXT: // GIR_Coverage, 24, 1117// NOOPT-NEXT: GIR_Done, 1118// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 1119 1120def : Pat<(i32 (bitconvert FPR32:$src1)), 1121 (COPY_TO_REGCLASS FPR32:$src1, GPR32)>; 1122 1123//===- Test a simple pattern with just a leaf immediate. ------------------===// 1124// 1125// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 1126// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, 1127// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, 1128// NOOPT-NEXT: // MIs[0] dst 1129// NOOPT-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 1130// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, 1131// NOOPT-NEXT: // MIs[0] Operand 1 1132// NOOPT-NEXT: // No operand predicates 1133// NOOPT-NEXT: // (imm:{ *:[i32] }):$imm => (MOVimm:{ *:[i32] } (imm:{ *:[i32] }):$imm) 1134// NOOPT-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm, 1135// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst 1136// NOOPT-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm 1137// NOOPT-NEXT: GIR_EraseFromParent, /*InsnID*/0, 1138// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 1139// NOOPT-NEXT: // GIR_Coverage, 16, 1140// NOOPT-NEXT: GIR_Done, 1141// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 1142 1143def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm)]>; 1144 1145def fpimmz : FPImmLeaf<f32, [{ return Imm->isExactlyValue(0.0); }]>; 1146def MOVfpimmz : I<(outs FPR32:$dst), (ins f32imm:$imm), [(set FPR32:$dst, fpimmz:$imm)]>; 1147 1148//===- Test a pattern with an MBB operand. --------------------------------===// 1149// 1150// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], 1151// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/1, 1152// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR, 1153// NOOPT-NEXT: // MIs[0] target 1154// NOOPT-NEXT: GIM_CheckIsMBB, /*MI*/0, /*Op*/0, 1155// NOOPT-NEXT: // (br (bb:{ *:[Other] }):$target) => (BR (bb:{ *:[Other] }):$target) 1156// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::BR, 1157// NOOPT-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, 1158// NOOPT-NEXT: // GIR_Coverage, 18, 1159// NOOPT-NEXT: GIR_Done, 1160// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]] 1161 1162def BR : I<(outs), (ins unknown:$target), 1163 [(br bb:$target)]>; 1164 1165// NOOPT-NEXT: GIM_Reject, 1166// NOOPT-NEXT: }; 1167// NOOPT-NEXT: return MatchTable0; 1168