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