1 // RUN: llvm-tblgen -optimize-match-table=false -gen-global-isel -I %p/../../include %s | FileCheck %s --check-prefix=CHECK --check-prefix=NOOPT
3 // The optimized table can reorder predicates between rules, but the rules
4 // order must remain the same.
5 // RUN: llvm-tblgen -optimize-match-table=true -gen-global-isel -I %p/../../include %s | FileCheck %s --check-prefix=CHECK --check-prefix=OPT
7 // Make sure the default is to optimize the table.
8 // RUN: llvm-tblgen -gen-global-isel -I %p/../../include %s | FileCheck %s --check-prefix=CHECK --check-prefix=OPT
10 include "llvm/Target/Target.td"
12 //===- Define the necessary boilerplate for our test target. --------------===//
14 def MyTargetISA : InstrInfo;
15 def MyTarget : Target { let InstructionSet = MyTargetISA; }
17 let TargetPrefix = "mytarget" in {
18 def int_mytarget_nop : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
21 def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
22 def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
23 def GPR32Op : RegisterOperand<GPR32>;
24 def F0 : Register<"f0"> { let Namespace = "MyTarget"; }
25 def FPR32 : RegisterClass<"MyTarget", [f32], 32, (add F0)>;
27 class I<dag OOps, dag IOps, list<dag> Pat>
29 let Namespace = "MyTarget";
30 let OutOperandList = OOps;
31 let InOperandList = IOps;
35 def complex : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPattern", []> {
36 let MIOperandInfo = (ops i32imm, i32imm);
39 GIComplexOperandMatcher<s32, "selectComplexPattern">,
40 GIComplexPatternEquiv<complex>;
41 def complex_rr : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPatternRR", []> {
42 let MIOperandInfo = (ops GPR32, GPR32);
45 GIComplexOperandMatcher<s32, "selectComplexPatternRR">,
46 GIComplexPatternEquiv<complex_rr>;
48 def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>;
49 def Z : OperandWithDefaultOps <i32, (ops R0)>;
50 def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>;
52 def HasA : Predicate<"Subtarget->hasA()">;
53 def HasB : Predicate<"Subtarget->hasB()">;
54 def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
56 //===- Test the function boilerplate. -------------------------------------===//
58 // CHECK: const unsigned MAX_SUBTARGET_PREDICATES = 3;
59 // CHECK: using PredicateBitset = llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
61 // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_DECL
62 // CHECK-NEXT: mutable MatcherState State;
63 // CHECK-NEXT: typedef ComplexRendererFns(MyTargetInstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;
64 // CHECK-NEXT: const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> MatcherInfo;
65 // CHECK-NEXT: static MyTargetInstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];
66 // CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL
68 // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT
69 // CHECK-NEXT: , State(2),
70 // CHECK-NEXT: MatcherInfo({TypeObjects, FeatureBitsets, I64ImmPredicateFns, APIntImmPredicateFns, APFloatImmPredicateFns, ComplexPredicateFns})
71 // CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT
73 // CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
74 // CHECK-NEXT: Feature_HasABit = 0,
75 // CHECK-NEXT: Feature_HasBBit = 1,
76 // CHECK-NEXT: Feature_HasCBit = 2,
79 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
80 // CHECK-NEXT: computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const {
81 // CHECK-NEXT: PredicateBitset Features;
82 // CHECK-NEXT: if (Subtarget->hasA())
83 // CHECK-NEXT: Features[Feature_HasABit] = 1;
84 // CHECK-NEXT: if (Subtarget->hasB())
85 // CHECK-NEXT: Features[Feature_HasBBit] = 1;
86 // CHECK-NEXT: return Features;
89 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
90 // CHECK-NEXT: computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const {
91 // CHECK-NEXT: PredicateBitset Features;
92 // CHECK-NEXT: if (Subtarget->hasC())
93 // CHECK-NEXT: Features[Feature_HasCBit] = 1;
94 // CHECK-NEXT: return Features;
97 // CHECK-LABEL: // LLT Objects.
99 // CHECK-NEXT: GILLT_s16,
100 // CHECK-NEXT: GILLT_s32,
102 // CHECK-NEXT: const static LLT TypeObjects[] = {
103 // CHECK-NEXT: LLT::scalar(16),
104 // CHECK-NEXT: LLT::scalar(32),
107 // CHECK-LABEL: // Feature bitsets.
108 // CHECK-NEXT: enum {
109 // CHECK-NEXT: GIFBS_Invalid,
110 // CHECK-NEXT: GIFBS_HasA,
111 // CHECK-NEXT: GIFBS_HasA_HasB_HasC,
113 // CHECK-NEXT: const static PredicateBitset FeatureBitsets[] {
114 // CHECK-NEXT: {}, // GIFBS_Invalid
115 // CHECK-NEXT: {Feature_HasABit, },
116 // CHECK-NEXT: {Feature_HasABit, Feature_HasBBit, Feature_HasCBit, },
119 // CHECK-LABEL: // ComplexPattern predicates.
120 // CHECK-NEXT: enum {
121 // CHECK-NEXT: GICP_Invalid,
122 // CHECK-NEXT: GICP_gi_complex,
123 // CHECK-NEXT: GICP_gi_complex_rr,
126 // CHECK-LABEL: // PatFrag predicates.
127 // CHECK-NEXT: enum {
128 // CHECK-NEXT: GIPFP_I64_Predicate_simm8 = GIPFP_I64_Invalid + 1,
130 // CHECK-NEXT: static bool Predicate_simm8(int64_t Imm) { return isInt<8>(Imm); }
131 // CHECK-NEXT: static InstructionSelector::I64ImmediatePredicateFn I64ImmPredicateFns[] = {
132 // CHECK-NEXT: nullptr,
133 // CHECK-NEXT: Predicate_simm8,
136 // CHECK-LABEL: // PatFrag predicates.
137 // CHECK-NEXT: enum {
138 // CHECK-NEXT: GIPFP_APFloat_Predicate_fpimmz = GIPFP_APFloat_Invalid + 1,
140 // CHECK-NEXT: static bool Predicate_fpimmz(const APFloat & Imm) { return Imm->isExactlyValue(0.0); }
141 // CHECK-NEXT: static InstructionSelector::APFloatImmediatePredicateFn APFloatImmPredicateFns[] = {
142 // CHECK-NEXT: nullptr,
143 // CHECK-NEXT: Predicate_fpimmz,
146 // CHECK-LABEL: // PatFrag predicates.
147 // CHECK-NEXT: enum {
148 // CHECK-NEXT: GIPFP_APInt_Predicate_simm9 = GIPFP_APInt_Invalid + 1,
150 // CHECK-NEXT: static bool Predicate_simm9(const APInt & Imm) { return isInt<9>(Imm->getSExtValue()); }
151 // CHECK-NEXT: static InstructionSelector::APIntImmediatePredicateFn APIntImmPredicateFns[] = {
152 // CHECK-NEXT: nullptr,
153 // CHECK-NEXT: Predicate_simm9,
156 // CHECK-LABEL: MyTargetInstructionSelector::ComplexMatcherMemFn
157 // CHECK-NEXT: MyTargetInstructionSelector::ComplexPredicateFns[] = {
158 // CHECK-NEXT: nullptr, // GICP_Invalid
159 // CHECK-NEXT: &MyTargetInstructionSelector::selectComplexPattern, // gi_complex
160 // CHECK-NEXT: &MyTargetInstructionSelector::selectComplexPatternRR, // gi_complex_rr
163 // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const {
164 // CHECK-NEXT: MachineFunction &MF = *I.getParent()->getParent();
165 // CHECK-NEXT: MachineRegisterInfo &MRI = MF.getRegInfo();
166 // CHECK: AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF);
167 // CHECK-NEXT: const PredicateBitset AvailableFeatures = getAvailableFeatures();
168 // CHECK-NEXT: NewMIVector OutMIs;
169 // CHECK-NEXT: State.MIs.clear();
170 // CHECK-NEXT: State.MIs.push_back(&I);
172 //===- Test a pattern with multiple ComplexPatterns in multiple instrs ----===//
175 // CHECK-LABEL: MatchTable0[] = {
176 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
177 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
178 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
179 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
180 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
181 // OPT-NEXT: // No instruction predicates
182 // CHECK-NEXT: // MIs[0] dst
183 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
184 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
185 // CHECK-NEXT: // MIs[0] src1
186 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
187 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
188 // CHECK-NEXT: // MIs[0] src2
189 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
190 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
191 // CHECK-NEXT: // MIs[0] src3
192 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
193 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/1, GICP_gi_complex,
194 // CHECK-NEXT: // (select:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2, complex:{ *:[i32] }:$src3) => (INSN2:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src3, complex:{ *:[i32] }:$src2)
195 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN2,
196 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
197 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
198 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1,
199 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
200 // CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList,
201 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
202 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
203 // CHECK-NEXT: GIR_Done,
204 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
206 def INSN3 : I<(outs GPR32:$dst),
207 (ins GPR32Op:$src1, GPR32:$src2a, GPR32:$src2b, GPR32:$scr), []>;
208 def INSN4 : I<(outs GPR32:$scr),
209 (ins GPR32:$src3, complex:$src4, i32imm:$src5a, i32imm:$src5b), []>;
210 def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b),
213 (complex i32imm:$src5a, i32imm:$src5b))),
214 (INSN3 GPR32:$src1, GPR32:$src2b, GPR32:$src2a,
215 (INSN4 GPR32:$src3, complex:$src4, i32imm:$src5a,
218 //===- Test a pattern with multiple ComplexPattern operands. --------------===//
221 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
222 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
223 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/3, // MIs[1]
224 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/4,
225 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
226 // OPT-NEXT: // No instruction predicates
227 // CHECK-NEXT: // MIs[0] dst
228 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
229 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
230 // CHECK-NEXT: // MIs[0] src1
231 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
232 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
233 // CHECK-NEXT: // MIs[0] Operand 2
234 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
235 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex_rr,
236 // CHECK-NEXT: // MIs[0] Operand 3
237 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
238 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SELECT,
239 // CHECK-NEXT: // MIs[1] Operand 0
240 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
241 // CHECK-NEXT: // MIs[1] src3
242 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
243 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
244 // CHECK-NEXT: // MIs[1] src4
245 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
246 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/2, /*Renderer*/1, GICP_gi_complex,
247 // CHECK-NEXT: // MIs[1] Operand 3
248 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/3, /*Type*/GILLT_s32,
249 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/3, /*Renderer*/2, GICP_gi_complex,
250 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
251 // CHECK-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))
252 // CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
253 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/MyTarget::INSN4,
254 // CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/1, /*TempRegID*/0, /*TempRegFlags*/RegState::Define,
255 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // src3
256 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/1, /*RendererID*/1,
257 // CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/1, /*RendererID*/2, /*SubOperand*/0, // src5a
258 // CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/1, /*RendererID*/2, /*SubOperand*/1, // src5b
259 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN3,
260 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
261 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
262 // CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // src2b
263 // CHECK-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src2a
264 // CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/0,
265 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
266 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
267 // CHECK-NEXT: GIR_Done,
268 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
269 // Closing the G_SELECT group.
270 // OPT-NEXT: GIM_Reject,
271 // OPT-NEXT: GIR_Done,
272 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
274 def : GINodeEquiv<G_SELECT, select>;
276 def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>;
278 def : Pat<(select GPR32:$src1, complex:$src2, complex:$src3),
279 (INSN2 GPR32:$src1, complex:$src3, complex:$src2)>;
281 //===- Test a simple pattern with regclass operands. ----------------------===//
283 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
284 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
285 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
286 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
287 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
288 // OPT-NEXT: // No instruction predicates
289 // CHECK-NEXT: // MIs[0] dst
290 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
291 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
292 // CHECK-NEXT: // MIs[0] src1
293 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
294 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID
295 // CHECK-NEXT: // MIs[0] src2
296 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
297 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
298 // CHECK-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2)
299 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD,
300 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
301 // CHECK-NEXT: GIR_Done,
302 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
304 def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
305 [(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>;
307 //===- Test a pattern with a tied operand in the matcher ------------------===//
309 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
310 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
311 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
312 // OPT-NEXT: // No instruction predicates
313 // CHECK-NEXT: // MIs[0] dst
314 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
315 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
316 // CHECK-NEXT: // MIs[0] src{{$}}
317 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
318 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
319 // CHECK-NEXT: // MIs[0] src{{$}}
320 // CHECK-NEXT: GIM_CheckIsSameOperand, /*MI*/0, /*OpIdx*/2, /*OtherMI*/0, /*OtherOpIdx*/1,
321 // CHECK-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src, GPR32:{ *:[i32] }:$src) => (DOUBLE:{ *:[i32] } GPR32:{ *:[i32] }:$src)
322 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::DOUBLE,
323 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
324 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src
325 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
326 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
327 // CHECK-NEXT: GIR_Done,
328 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
330 def DOUBLE : I<(outs GPR32:$dst), (ins GPR32:$src), [(set GPR32:$dst, (add GPR32:$src, GPR32:$src))]>;
332 //===- Test a simple pattern with ValueType operands. ----------------------===//
334 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
335 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
336 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
337 // OPT-NEXT: // No instruction predicates
338 // CHECK-NEXT: // MIs[0] dst
339 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
340 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
341 // CHECK-NEXT: // MIs[0] src1
342 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
343 // CHECK-NEXT: // MIs[0] src2
344 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
345 // CHECK-NEXT: // (add:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)
346 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD,
347 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
348 // CHECK-NEXT: GIR_Done,
349 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
350 // Closing the G_ADD group.
351 // OPT-NEXT: GIM_Reject,
352 // OPT-NEXT: GIR_Done,
353 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
355 def : Pat<(add i32:$src1, i32:$src2),
356 (ADD i32:$src1, i32:$src2)>;
358 //===- Test a simple pattern with an intrinsic. ---------------------------===//
361 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
362 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC,
363 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
364 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
365 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC,
366 // OPT-NEXT: // No instruction predicates
367 // CHECK-NEXT: // MIs[0] dst
368 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
369 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
370 // CHECK-NEXT: // MIs[0] Operand 1
371 // CHECK-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, Intrinsic::mytarget_nop,
372 // CHECK-NEXT: // MIs[0] src1
373 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
374 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
375 // CHECK-NEXT: // (intrinsic_wo_chain:{ *:[i32] } [[ID:[0-9]+]]:{ *:[iPTR] }, GPR32:{ *:[i32] }:$src1) => (MOV:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
377 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV,
378 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
379 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src1
380 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
381 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
382 // CHECK-NEXT: GIR_Done,
383 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
384 // Closing the G_INTRINSIC group.
385 // OPT-NEXT: GIM_Reject,
386 // OPT-NEXT: GIR_Done,
387 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
389 def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1),
390 [(set GPR32:$dst, (int_mytarget_nop GPR32:$src1))]>;
392 //===- Test a nested instruction match. -----------------------------------===//
394 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
395 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
396 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
397 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
398 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
399 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
400 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
401 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
402 // OPT-NEXT: // No instruction predicates
403 // CHECK-NEXT: // MIs[0] dst
404 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
405 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
406 // CHECK-NEXT: // MIs[0] Operand 1
407 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
408 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
409 // CHECK-NEXT: // MIs[1] Operand 0
410 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
411 // CHECK-NEXT: // MIs[1] src1
412 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
413 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
414 // CHECK-NEXT: // MIs[1] src2
415 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
416 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
417 // CHECK-NEXT: // MIs[0] src3
418 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
419 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
420 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
421 // CHECK-NEXT: // (mul:{ *:[i32] } (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2), GPR32:{ *:[i32] }:$src3) => (MULADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src3)
422 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
423 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
424 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
425 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
426 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src3
427 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
428 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
429 // CHECK-NEXT: GIR_Done,
430 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
432 // We also get a second rule by commutativity.
433 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
434 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
435 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
436 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2,
437 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
438 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
439 // OPT-NEXT: // No instruction predicates
440 // CHECK-NEXT: // MIs[0] dst
441 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
442 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
443 // CHECK-NEXT: // MIs[0] src3
444 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
445 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
446 // CHECK-NEXT: // MIs[0] Operand 2
447 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
448 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
449 // CHECK-NEXT: // MIs[1] Operand 0
450 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
451 // CHECK-NEXT: // MIs[1] src1
452 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
453 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
454 // CHECK-NEXT: // MIs[1] src2
455 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
456 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
457 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
458 // CHECK-NEXT: // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src3, (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2)) => (MULADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src3)
459 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
460 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
461 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
462 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
463 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src3
464 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
465 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
466 // CHECK-NEXT: GIR_Done,
467 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
469 def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
471 (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,
474 //===- Test another simple pattern with regclass operands. ----------------===//
476 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
477 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA_HasB_HasC,
478 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
479 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
480 // OPT-NEXT: // No instruction predicates
481 // CHECK-NEXT: // MIs[0] dst
482 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
483 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
484 // CHECK-NEXT: // MIs[0] src1
485 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
486 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
487 // CHECK-NEXT: // MIs[0] src2
488 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
489 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
490 // CHECK-NEXT: // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (MUL:{ *:[i32] } GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src1)
491 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MUL,
492 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
493 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src2
494 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
495 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
496 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
497 // CHECK-NEXT: GIR_Done,
498 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
499 // Closing the G_MUL group.
500 // OPT-NEXT: GIM_Reject,
501 // OPT-NEXT: GIR_Done,
502 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
504 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
505 [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
506 Requires<[HasA, HasB, HasC]>;
508 //===- Test a more complex multi-instruction match. -----------------------===//
510 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
511 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
512 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
513 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
514 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
515 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
516 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
517 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/2, /*MI*/0, /*OpIdx*/2, // MIs[2]
518 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/2, /*Expected*/3,
519 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
520 // OPT-NEXT: // No instruction predicates
521 // CHECK-NEXT: // MIs[0] dst
522 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
523 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
524 // CHECK-NEXT: // MIs[0] Operand 1
525 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
526 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SUB,
527 // CHECK-NEXT: // MIs[1] Operand 0
528 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
529 // CHECK-NEXT: // MIs[1] src1
530 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
531 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
532 // CHECK-NEXT: // MIs[1] src2
533 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
534 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
535 // CHECK-NEXT: // MIs[0] Operand 2
536 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
537 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/2, TargetOpcode::G_SUB,
538 // CHECK-NEXT: // MIs[2] Operand 0
539 // CHECK-NEXT: GIM_CheckType, /*MI*/2, /*Op*/0, /*Type*/GILLT_s32,
540 // CHECK-NEXT: // MIs[2] src3
541 // CHECK-NEXT: GIM_CheckType, /*MI*/2, /*Op*/1, /*Type*/GILLT_s32,
542 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
543 // CHECK-NEXT: // MIs[2] src4
544 // CHECK-NEXT: GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32,
545 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
546 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
547 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/2,
548 // CHECK-NEXT: // (sub:{ *:[i32] } (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2), (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src3, GPR32:{ *:[i32] }:$src4)) => (INSNBOB:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src3, GPR32:{ *:[i32] }:$src4)
549 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSNBOB,
550 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
551 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
552 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
553 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/1, // src3
554 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // src4
555 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
556 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
557 // CHECK-NEXT: GIR_Done,
558 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
560 def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
562 (sub (sub GPR32:$src1, GPR32:$src2), (sub GPR32:$src3, GPR32:$src4)))]>,
565 //===- Test a pattern with ComplexPattern operands. -----------------------===//
568 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
569 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
570 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
571 // OPT-NEXT: // No instruction predicates
572 // CHECK-NEXT: // MIs[0] dst
573 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
574 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
575 // CHECK-NEXT: // MIs[0] src1
576 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
577 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
578 // CHECK-NEXT: // MIs[0] src2
579 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
580 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
581 // CHECK-NEXT: // (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2) => (INSN1:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2)
582 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN1,
583 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
584 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
585 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
586 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
587 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
588 // CHECK-NEXT: GIR_Done,
589 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
590 // Closing the G_SUB group.
591 // OPT-NEXT: GIM_Reject,
592 // OPT-NEXT: GIR_Done,
593 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
595 def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>;
596 def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>;
598 //===- Test a simple pattern with a default operand. ----------------------===//
601 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
602 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
603 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
604 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
605 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
606 // OPT-NEXT: // No instruction predicates
607 // CHECK-NEXT: // MIs[0] dst
608 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
609 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
610 // CHECK-NEXT: // MIs[0] src1
611 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
612 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
613 // CHECK-NEXT: // MIs[0] Operand 2
614 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
615 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -2
616 // CHECK-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -2:{ *:[i32] }) => (XORI:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
617 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORI,
618 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
619 // CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
620 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
621 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
622 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
623 // CHECK-NEXT: GIR_Done,
624 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
626 // The -2 is just to distinguish it from the 'not' case below.
627 def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1),
628 [(set GPR32:$dst, (xor GPR32:$src1, -2))]>;
630 //===- Test a simple pattern with a default register operand. -------------===//
633 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
634 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
635 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
636 // OPT-NEXT: // No instruction predicates
637 // CHECK-NEXT: // MIs[0] dst
638 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
639 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
640 // CHECK-NEXT: // MIs[0] src1
641 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
642 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
643 // CHECK-NEXT: // MIs[0] Operand 2
644 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
645 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -3
646 // CHECK-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -3:{ *:[i32] }) => (XOR:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
647 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XOR,
648 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
649 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
650 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
651 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
652 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
653 // CHECK-NEXT: GIR_Done,
654 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
656 // The -3 is just to distinguish it from the 'not' case below and the other default op case above.
657 def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1),
658 [(set GPR32:$dst, (xor GPR32:$src1, -3))]>;
660 //===- Test a simple pattern with a multiple default operands. ------------===//
663 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
664 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
665 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
666 // OPT-NEXT: // No instruction predicates
667 // CHECK-NEXT: // MIs[0] dst
668 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
669 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
670 // CHECK-NEXT: // MIs[0] src1
671 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
672 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
673 // CHECK-NEXT: // MIs[0] Operand 2
674 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
675 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -4
676 // CHECK-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -4:{ *:[i32] }) => (XORlike:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
677 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORlike,
678 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
679 // CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
680 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
681 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
682 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
683 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
684 // CHECK-NEXT: GIR_Done,
685 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
687 // The -4 is just to distinguish it from the other 'not' cases.
688 def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1),
689 [(set GPR32:$dst, (xor GPR32:$src1, -4))]>;
691 //===- Test a simple pattern with multiple operands with defaults. --------===//
694 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
695 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
696 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
697 // OPT-NEXT: // No instruction predicates
698 // CHECK-NEXT: // MIs[0] dst
699 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
700 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
701 // CHECK-NEXT: // MIs[0] src1
702 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
703 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
704 // CHECK-NEXT: // MIs[0] Operand 2
705 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
706 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -5,
707 // CHECK-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -5:{ *:[i32] }) => (XORManyDefaults:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
708 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORManyDefaults,
709 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
710 // CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
711 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
712 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
713 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
714 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
715 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
716 // CHECK-NEXT: GIR_Done,
717 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
719 // The -5 is just to distinguish it from the other cases.
720 def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1),
721 [(set GPR32:$dst, (xor GPR32:$src1, -5))]>;
723 //===- Test a simple pattern with constant immediate operands. ------------===//
725 // This must precede the 3-register variants because constant immediates have
726 // priority over register banks.
728 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
729 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
730 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
731 // OPT-NEXT: // No instruction predicates
732 // CHECK-NEXT: // MIs[0] dst
733 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
734 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
735 // CHECK-NEXT: // MIs[0] Wm
736 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
737 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
738 // CHECK-NEXT: // MIs[0] Operand 2
739 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
740 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -1,
741 // CHECK-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$Wm, -1:{ *:[i32] }) => (ORN:{ *:[i32] } R0:{ *:[i32] }, GPR32:{ *:[i32] }:$Wm)
742 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::ORN,
743 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
744 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
745 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // Wm
746 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
747 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
748 // CHECK-NEXT: GIR_Done,
749 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
750 // Closing the G_XOR group.
751 // OPT-NEXT: GIM_Reject,
752 // OPT-NEXT: GIR_Done,
753 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
755 def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;
756 def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>;
758 //===- Test a COPY_TO_REGCLASS --------------------------------------------===//
761 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
762 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST,
763 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
764 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
765 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST,
766 // OPT-NEXT: // No instruction predicates
767 // CHECK-NEXT: // MIs[0] dst
768 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
769 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
770 // CHECK-NEXT: // MIs[0] src1
771 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
772 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::FPR32RegClassID,
773 // CHECK-NEXT: // (bitconvert:{ *:[i32] } FPR32:{ *:[f32] }:$src1) => (COPY_TO_REGCLASS:{ *:[i32] } FPR32:{ *:[f32] }:$src1, GPR32:{ *:[i32] })
774 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/TargetOpcode::COPY,
775 // CHECK-NEXT: GIR_ConstrainOperandRC, /*InsnID*/0, /*Op*/0, /*RC GPR32*/1,
776 // CHECK-NEXT: GIR_Done,
777 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
778 // Closing the G_BITCAST group.
779 // OPT-NEXT: GIM_Reject,
780 // OPT-NEXT: GIR_Done,
781 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
783 def : Pat<(i32 (bitconvert FPR32:$src1)),
784 (COPY_TO_REGCLASS FPR32:$src1, GPR32)>;
786 //===- Test a simple pattern with just a specific leaf immediate. ---------===//
788 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
789 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
790 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
791 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
792 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
793 // OPT-NEXT: // No instruction predicates
794 // CHECK-NEXT: // MIs[0] dst
795 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
796 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
797 // CHECK-NEXT: // MIs[0] Operand 1
798 // CHECK-NEXT: GIM_CheckLiteralInt, /*MI*/0, /*Op*/1, 1,
799 // CHECK-NEXT: // 1:{ *:[i32] } => (MOV1:{ *:[i32] })
800 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV1,
801 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
802 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
803 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
804 // CHECK-NEXT: GIR_Done,
805 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
807 def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>;
809 //===- Test a simple pattern with a leaf immediate and a predicate. -------===//
811 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
812 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
813 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
814 // CHECK-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_simm8,
815 // CHECK-NEXT: // MIs[0] dst
816 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
817 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
818 // CHECK-NEXT: // MIs[0] Operand 1
819 // CHECK-NEXT: // No operand predicates
820 // CHECK-NEXT: // (imm:{ *:[i32] })<<P:Predicate_simm8>>:$imm => (MOVimm8:{ *:[i32] } (imm:{ *:[i32] }):$imm)
821 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm8,
822 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
823 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
824 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
825 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
826 // CHECK-NEXT: GIR_Done,
827 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
829 def simm8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
830 def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$imm)]>;
832 //===- Same again but use an IntImmLeaf. ----------------------------------===//
834 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
835 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
836 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
837 // CHECK-NEXT: GIM_CheckAPIntImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APInt_Predicate_simm9,
838 // CHECK-NEXT: // MIs[0] dst
839 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
840 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
841 // CHECK-NEXT: // MIs[0] Operand 1
842 // CHECK-NEXT: // No operand predicates
843 // CHECK-NEXT: // (imm:{ *:[i32] })<<P:Predicate_simm9>>:$imm => (MOVimm9:{ *:[i32] } (imm:{ *:[i32] }):$imm)
844 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm9,
845 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
846 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
847 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
848 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
849 // CHECK-NEXT: GIR_Done,
850 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
852 def simm9 : IntImmLeaf<i32, [{ return isInt<9>(Imm->getSExtValue()); }]>;
853 def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$imm)]>;
855 //===- Test a simple pattern with just a leaf immediate. ------------------===//
857 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
858 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
859 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
860 // OPT-NEXT: // No instruction predicates
861 // CHECK-NEXT: // MIs[0] dst
862 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
863 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
864 // CHECK-NEXT: // MIs[0] Operand 1
865 // CHECK-NEXT: // No operand predicates
866 // CHECK-NEXT: // (imm:{ *:[i32] }):$imm => (MOVimm:{ *:[i32] } (imm:{ *:[i32] }):$imm)
867 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm,
868 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
869 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
870 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
871 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
872 // CHECK-NEXT: GIR_Done,
873 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
874 // Closing the G_CONSTANT group.
875 // OPT-NEXT: GIM_Reject,
876 // OPT-NEXT: GIR_Done,
877 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
879 def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm)]>;
881 //===- Test a simple pattern with a FP immediate and a predicate. ---------===//
883 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
884 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCONSTANT,
885 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
886 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
887 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCONSTANT,
888 // CHECK-NEXT: GIM_CheckAPFloatImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APFloat_Predicate_fpimmz,
889 // CHECK-NEXT: // MIs[0] dst
890 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
891 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::FPR32RegClassID,
892 // CHECK-NEXT: // MIs[0] Operand 1
893 // CHECK-NEXT: // No operand predicates
894 // CHECK-NEXT: // (fpimm:{ *:[f32] })<<P:Predicate_fpimmz>>:$imm => (MOVfpimmz:{ *:[f32] } (fpimm:{ *:[f32] }):$imm)
895 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVfpimmz,
896 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
897 // CHECK-NEXT: GIR_CopyFConstantAsFPImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
898 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
899 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
900 // CHECK-NEXT: GIR_Done,
901 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
902 // Closing the G_FCONSTANT group.
903 // OPT-NEXT: GIM_Reject,
904 // OPT-NEXT: GIR_Done,
905 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
907 def fpimmz : FPImmLeaf<f32, [{ return Imm->isExactlyValue(0.0); }]>;
908 def MOVfpimmz : I<(outs FPR32:$dst), (ins f32imm:$imm), [(set FPR32:$dst, fpimmz:$imm)]>;
910 //===- Test a simple pattern with inferred pointer operands. ---------------===//
912 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
913 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,
914 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
915 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
916 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,
917 // CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic,
918 // CHECK-NEXT: // MIs[0] dst
919 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
920 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
921 // CHECK-NEXT: // MIs[0] src1
922 // CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
923 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
924 // CHECK-NEXT: // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
925 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD,
926 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
927 // CHECK-NEXT: GIR_Done,
928 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
929 // Closing the G_LOAD group.
930 // OPT-NEXT: GIM_Reject,
931 // OPT-NEXT: GIR_Done,
932 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
934 def LOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),
935 [(set GPR32:$dst, (load GPR32:$src1))]>;
937 //===- Test a simple pattern with a sextload -------------------------------===//
939 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
940 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SEXT,
941 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
942 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
943 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
944 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/2,
945 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SEXT,
946 // OPT-NEXT: // No instruction predicates
947 // CHECK-NEXT: // MIs[0] dst
948 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
949 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
950 // CHECK-NEXT: // MIs[0] Operand 1
951 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s16,
952 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_LOAD,
953 // CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/1, /*Order*/(int64_t)AtomicOrdering::NotAtomic,
954 // CHECK-NEXT: // MIs[1] Operand 0
955 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s16,
956 // CHECK-NEXT: // MIs[1] src1
957 // CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/1, /*Op*/1, /*SizeInBits*/32,
958 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
959 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
960 // CHECK-NEXT: // (sext:{ *:[i32] } (ld:{ *:[i16] } GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedload>>) => (SEXTLOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
961 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::SEXTLOAD,
962 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
963 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
964 // CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, 1, GIU_MergeMemOperands_EndOfList,
965 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
966 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
967 // CHECK-NEXT: GIR_Done,
968 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
969 // Closing the G_SEXT group.
970 // OPT-NEXT: GIM_Reject,
971 // OPT-NEXT: GIR_Done,
972 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
974 def SEXTLOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),
975 [(set GPR32:$dst, (sextloadi16 GPR32:$src1))]>;
977 //===- Test a pattern with an MBB operand. --------------------------------===//
979 // OPT-NEXT: GIM_Try, /*On fail goto*//*Label [[GRP_LABEL_NUM:[0-9]+]]*/ [[GRP_LABEL:[0-9]+]],
980 // OPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR,
981 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
982 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/1,
983 // NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR,
984 // OPT-NEXT: // No instruction predicates
985 // CHECK-NEXT: // MIs[0] target
986 // CHECK-NEXT: GIM_CheckIsMBB, /*MI*/0, /*Op*/0,
987 // CHECK-NEXT: // (br (bb:{ *:[Other] }):$target) => (BR (bb:{ *:[Other] }):$target)
988 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::BR,
989 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
990 // CHECK-NEXT: GIR_Done,
991 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
992 // Closing the G_BR group.
993 // OPT-NEXT: GIM_Reject,
994 // OPT-NEXT: GIR_Done,
995 // OPT-NEXT: // Label [[GRP_LABEL_NUM]]: @[[GRP_LABEL]]
997 def BR : I<(outs), (ins unknown:$target),
1000 // CHECK-NEXT: GIM_Reject,
1002 // CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable0, TII, MRI, TRI, RBI, AvailableFeatures, CoverageInfo)) {
1003 // CHECK-NEXT: return true;