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 25 include "llvm/Target/Target.td" 26 27 //===- Define the necessary boilerplate for our test target. --------------===// 28 29 def MyTargetISA : InstrInfo; 30 def MyTarget : Target { let InstructionSet = MyTargetISA; } 31 32 let TargetPrefix = "mytarget" in { 33 def int_mytarget_nop : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>; 34 } 35 36 def R0 : Register<"r0"> { let Namespace = "MyTarget"; } 37 def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>; 38 def GPR32Op : RegisterOperand<GPR32>; 39 def F0 : Register<"f0"> { let Namespace = "MyTarget"; } 40 def FPR32 : RegisterClass<"MyTarget", [f32], 32, (add F0)>; 41 42 class 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 50 def complex : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPattern", []> { 51 let MIOperandInfo = (ops i32imm, i32imm); 52 } 53 def gi_complex : 54 GIComplexOperandMatcher<s32, "selectComplexPattern">, 55 GIComplexPatternEquiv<complex>; 56 def complex_rr : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPatternRR", []> { 57 let MIOperandInfo = (ops GPR32, GPR32); 58 } 59 def gi_complex_rr : 60 GIComplexOperandMatcher<s32, "selectComplexPatternRR">, 61 GIComplexPatternEquiv<complex_rr>; 62 63 def cimm8_xform : SDNodeXForm<imm, [{ 64 uint64_t Val = N->getZExtValue() << 1; 65 return CurDAG->getTargetConstant(Val, SDLoc(N), MVT::i64); 66 }]>; 67 68 def cimm8 : Operand<i32>, ImmLeaf<i32, [{return isInt<8>(Imm);}], cimm8_xform>; 69 70 def gi_cimm8 : GICustomOperandRenderer<"renderImm8">, 71 GISDNodeXFormEquiv<cimm8_xform>; 72 73 def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>; 74 def Z : OperandWithDefaultOps <i32, (ops R0)>; 75 def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>; 76 77 def HasA : Predicate<"Subtarget->hasA()">; 78 def HasB : Predicate<"Subtarget->hasB()">; 79 def 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 327 def INSN3 : I<(outs GPR32:$dst), 328 (ins GPR32Op:$src1, GPR32:$src2a, GPR32:$src2b, GPR32:$scr), []>; 329 def INSN4 : I<(outs GPR32:$scr), 330 (ins GPR32:$src3, complex:$src4, i32imm:$src5a, i32imm:$src5b), []>; 331 def : 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 445 def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>; 446 def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>; 447 448 //===- Test a pattern with multiple ComplexPattern operands. --------------===// 449 // 450 def : GINodeEquiv<G_SELECT, select>; 451 let mayLoad = 1 in { 452 def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>; 453 } 454 def 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 } 459 def : 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 539 def 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 587 def 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. 636 def 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. 665 def 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. 695 def 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. 726 def 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 757 def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>; 758 def : 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 836 def 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 860 def 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 883 def simm8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>; 884 def 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 907 def simm9 : IntImmLeaf<i32, [{ return isInt<9>(Imm->getSExtValue()); }]>; 908 def 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 931 def 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 974 def 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 997 def 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 1021 def 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 1047 def 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 1068 def : 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 1097 def 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 1120 def : 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 1143 def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm)]>; 1144 1145 def fpimmz : FPImmLeaf<f32, [{ return Imm->isExactlyValue(0.0); }]>; 1146 def 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 1162 def 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