1 // RUN: llvm-tblgen -gen-global-isel -I %p/../../include %s | FileCheck %s
3 include "llvm/Target/Target.td"
5 //===- Define the necessary boilerplate for our test target. --------------===//
7 def MyTargetISA : InstrInfo;
8 def MyTarget : Target { let InstructionSet = MyTargetISA; }
10 let TargetPrefix = "mytarget" in {
11 def int_mytarget_nop : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
14 def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
15 def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
16 def GPR32Op : RegisterOperand<GPR32>;
17 def F0 : Register<"f0"> { let Namespace = "MyTarget"; }
18 def FPR32 : RegisterClass<"MyTarget", [f32], 32, (add F0)>;
20 class I<dag OOps, dag IOps, list<dag> Pat>
22 let Namespace = "MyTarget";
23 let OutOperandList = OOps;
24 let InOperandList = IOps;
28 def complex : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPattern", []> {
29 let MIOperandInfo = (ops i32imm, i32imm);
32 GIComplexOperandMatcher<s32, "selectComplexPattern">,
33 GIComplexPatternEquiv<complex>;
35 def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>;
36 def Z : OperandWithDefaultOps <i32, (ops R0)>;
37 def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>;
39 def HasA : Predicate<"Subtarget->hasA()">;
40 def HasB : Predicate<"Subtarget->hasB()">;
41 def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
43 //===- Test the function boilerplate. -------------------------------------===//
45 // CHECK: const unsigned MAX_SUBTARGET_PREDICATES = 3;
46 // CHECK: using PredicateBitset = llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
48 // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_DECL
49 // CHECK-NEXT: mutable MatcherState State;
50 // CHECK-NEXT: typedef ComplexRendererFn(MyTargetInstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;
51 // CHECK-NEXT: const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> MatcherInfo;
52 // CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL
54 // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT
55 // CHECK-NEXT: , State(2),
56 // CHECK-NEXT: MatcherInfo({TypeObjects, FeatureBitsets, ImmPredicateFns, {
57 // CHECK-NEXT: nullptr, // GICP_Invalid
58 // CHECK-NEXT: &MyTargetInstructionSelector::selectComplexPattern, // gi_complex
60 // CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT
62 // CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
63 // CHECK-NEXT: Feature_HasABit = 0,
64 // CHECK-NEXT: Feature_HasBBit = 1,
65 // CHECK-NEXT: Feature_HasCBit = 2,
68 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
69 // CHECK-NEXT: computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const {
70 // CHECK-NEXT: PredicateBitset Features;
71 // CHECK-NEXT: if (Subtarget->hasA())
72 // CHECK-NEXT: Features[Feature_HasABit] = 1;
73 // CHECK-NEXT: if (Subtarget->hasB())
74 // CHECK-NEXT: Features[Feature_HasBBit] = 1;
75 // CHECK-NEXT: return Features;
78 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
79 // CHECK-NEXT: computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const {
80 // CHECK-NEXT: PredicateBitset Features;
81 // CHECK-NEXT: if (Subtarget->hasC())
82 // CHECK-NEXT: Features[Feature_HasCBit] = 1;
83 // CHECK-NEXT: return Features;
86 // CHECK-LABEL: // LLT Objects.
88 // CHECK-NEXT: GILLT_s32,
90 // CHECK-NEXT: const static LLT TypeObjects[] = {
91 // CHECK-NEXT: LLT::scalar(32),
94 // CHECK-LABEL: // Feature bitsets.
96 // CHECK-NEXT: GIFBS_Invalid,
97 // CHECK-NEXT: GIFBS_HasA,
98 // CHECK-NEXT: GIFBS_HasA_HasB_HasC,
100 // CHECK-NEXT: const static PredicateBitset FeatureBitsets[] {
101 // CHECK-NEXT: {}, // GIFBS_Invalid
102 // CHECK-NEXT: {Feature_HasABit, },
103 // CHECK-NEXT: {Feature_HasABit, Feature_HasBBit, Feature_HasCBit, },
106 // CHECK-LABEL: // ComplexPattern predicates.
107 // CHECK-NEXT: enum {
108 // CHECK-NEXT: GICP_Invalid,
109 // CHECK-NEXT: GICP_gi_complex,
112 // CHECK-LABEL: // PatFrag predicates.
113 // CHECK-NEXT: enum {
114 // CHECK-NEXT: GIPFP_Predicate_simm8 = GIPFP_Invalid,
116 // CHECK-NEXT: static bool Predicate_simm8(int64_t Imm) { return isInt<8>(Imm); }
117 // CHECK-NEXT: static InstructionSelector::ImmediatePredicateFn ImmPredicateFns[] = {
118 // CHECK-NEXT: Predicate_simm8,
121 // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {
122 // CHECK-NEXT: MachineFunction &MF = *I.getParent()->getParent();
123 // CHECK-NEXT: MachineRegisterInfo &MRI = MF.getRegInfo();
124 // CHECK: AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF);
125 // CHECK-NEXT: const PredicateBitset AvailableFeatures = getAvailableFeatures();
126 // CHECK-NEXT: NewMIVector OutMIs;
127 // CHECK-NEXT: State.MIs.clear();
128 // CHECK-NEXT: State.MIs.push_back(&I);
130 //===- Test a pattern with multiple ComplexPatterns in multiple instrs ----===//
133 // CHECK-LABEL: MatchTable0[] = {
134 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 0*/ [[LABEL:[0-9]+]],
135 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
136 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
137 // CHECK-NEXT: // MIs[0] dst
138 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
139 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
140 // CHECK-NEXT: // MIs[0] src1
141 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
142 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
143 // CHECK-NEXT: // MIs[0] src2
144 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
145 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
146 // CHECK-NEXT: // MIs[0] src3
147 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
148 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/1, GICP_gi_complex,
149 // CHECK-NEXT: // (select:i32 GPR32:i32:$src1, complex:i32:$src2, complex:i32:$src3) => (INSN2:i32 GPR32:i32:$src1, complex:i32:$src3, complex:i32:$src2)
150 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN2,
151 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
152 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
153 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1,
154 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
155 // CHECK-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList,
156 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
157 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
158 // CHECK-NEXT: GIR_Done,
159 // CHECK-NEXT: // Label 0: @[[LABEL]]
161 def INSN3 : I<(outs GPR32:$dst),
162 (ins GPR32Op:$src1, complex:$src2, GPR32:$src3, complex:$src4, complex:$src5), []>;
163 def : Pat<(select GPR32:$src1, complex:$src2, (select GPR32:$src3, complex:$src4, complex:$src5)),
164 (INSN3 GPR32:$src1, complex:$src2, GPR32:$src3, complex:$src4, complex:$src5)>;
166 //===- Test a pattern with multiple ComplexPattern operands. --------------===//
169 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 1*/ [[LABEL:[0-9]+]],
170 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
171 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/3, // MIs[1]
172 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/4,
173 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
174 // CHECK-NEXT: // MIs[0] dst
175 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
176 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
177 // CHECK-NEXT: // MIs[0] src1
178 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
179 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
180 // CHECK-NEXT: // MIs[0] src2
181 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
182 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
183 // CHECK-NEXT: // MIs[0] Operand 3
184 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
185 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SELECT,
186 // CHECK-NEXT: // MIs[1] Operand 0
187 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
188 // CHECK-NEXT: // MIs[1] src3
189 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
190 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
191 // CHECK-NEXT: // MIs[1] src4
192 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
193 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/2, /*Renderer*/1, GICP_gi_complex,
194 // CHECK-NEXT: // MIs[1] src5
195 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/3, /*Type*/GILLT_s32,
196 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/3, /*Renderer*/2, GICP_gi_complex,
197 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
198 // CHECK-NEXT: // (select:i32 GPR32:i32:$src1, complex:i32:$src2, (select:i32 GPR32:i32:$src3, complex:i32:$src4, complex:i32:$src5)) => (INSN3:i32 GPR32:i32:$src1, complex:i32:$src2, GPR32:i32:$src3, complex:i32:$src4, complex:i32:$src5)
199 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN3,
200 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
201 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
202 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
203 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src3
204 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1,
205 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/2,
206 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
207 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
208 // CHECK-NEXT: GIR_Done,
209 // CHECK-NEXT: // Label 1: @[[LABEL]]
211 def : GINodeEquiv<G_SELECT, select>;
213 def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>;
215 def : Pat<(select GPR32:$src1, complex:$src2, complex:$src3),
216 (INSN2 GPR32:$src1, complex:$src3, complex:$src2)>;
218 //===- Test a simple pattern with regclass operands. ----------------------===//
220 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 2*/ [[LABEL:[0-9]+]],
221 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
222 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
223 // CHECK-NEXT: // MIs[0] dst
224 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
225 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
226 // CHECK-NEXT: // MIs[0] src1
227 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
228 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID
229 // CHECK-NEXT: // MIs[0] src2
230 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
231 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
232 // CHECK-NEXT: // (add:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (ADD:i32 GPR32:i32:$src1, GPR32:i32:$src2)
233 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD,
234 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
235 // CHECK-NEXT: GIR_Done,
236 // CHECK-NEXT: // Label 2: @[[LABEL]]
238 def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
239 [(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>;
241 //===- Test a simple pattern with an intrinsic. ---------------------------===//
244 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 3*/ [[LABEL:[0-9]+]],
245 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
246 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC,
247 // CHECK-NEXT: // MIs[0] dst
248 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
249 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
250 // CHECK-NEXT: // MIs[0] Operand 1
251 // CHECK-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, Intrinsic::mytarget_nop,
252 // CHECK-NEXT: // MIs[0] src1
253 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
254 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
255 // CHECK-NEXT: // (intrinsic_wo_chain:i32 [[ID:[0-9]+]]:iPTR, GPR32:i32:$src1) => (MOV:i32 GPR32:i32:$src1)
257 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV,
258 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
259 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src1
260 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
261 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
262 // CHECK-NEXT: GIR_Done,
263 // CHECK-NEXT: // Label 3: @[[LABEL]]
265 def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1),
266 [(set GPR32:$dst, (int_mytarget_nop GPR32:$src1))]>;
268 //===- Test a nested instruction match. -----------------------------------===//
270 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 4*/ [[LABEL:[0-9]+]],
271 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
272 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
273 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
274 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
275 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
276 // CHECK-NEXT: // MIs[0] dst
277 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
278 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
279 // CHECK-NEXT: // MIs[0] Operand 1
280 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
281 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
282 // CHECK-NEXT: // MIs[1] Operand 0
283 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
284 // CHECK-NEXT: // MIs[1] src1
285 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
286 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
287 // CHECK-NEXT: // MIs[1] src2
288 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
289 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
290 // CHECK-NEXT: // MIs[0] src3
291 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
292 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
293 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
294 // 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)
295 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
296 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
297 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
298 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
299 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src3
300 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
301 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
302 // CHECK-NEXT: GIR_Done,
303 // CHECK-NEXT: // Label 4: @[[LABEL]]
305 // We also get a second rule by commutativity.
306 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 5*/ [[LABEL:[0-9]+]],
307 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
308 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
309 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2,
310 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
311 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
312 // CHECK-NEXT: // MIs[0] dst
313 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
314 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
315 // CHECK-NEXT: // MIs[0] src3
316 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
317 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
318 // CHECK-NEXT: // MIs[0] Operand 2
319 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
320 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
321 // CHECK-NEXT: // MIs[1] Operand 0
322 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
323 // CHECK-NEXT: // MIs[1] src1
324 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
325 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
326 // CHECK-NEXT: // MIs[1] src2
327 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
328 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
329 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
330 // 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)
331 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
332 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
333 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
334 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
335 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src3
336 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
337 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
338 // CHECK-NEXT: GIR_Done,
339 // CHECK-NEXT: // Label 5: @[[LABEL]]
341 def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
343 (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,
346 //===- Test another simple pattern with regclass operands. ----------------===//
348 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 6*/ [[LABEL:[0-9]+]],
349 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA_HasB_HasC,
350 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
351 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
352 // CHECK-NEXT: // MIs[0] dst
353 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
354 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
355 // CHECK-NEXT: // MIs[0] src1
356 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
357 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
358 // CHECK-NEXT: // MIs[0] src2
359 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
360 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
361 // CHECK-NEXT: // (mul:i32 GPR32:i32:$src1, GPR32:i32:$src2) => (MUL:i32 GPR32:i32:$src2, GPR32:i32:$src1)
362 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MUL,
363 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
364 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src2
365 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
366 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
367 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
368 // CHECK-NEXT: GIR_Done,
369 // CHECK-NEXT: // Label 6: @[[LABEL]]
371 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
372 [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
373 Requires<[HasA, HasB, HasC]>;
375 //===- Test a more complex multi-instruction match. -----------------------===//
377 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 7*/ [[LABEL:[0-9]+]],
378 // CHECK-NEXT: GIM_CheckFeatures, GIFBS_HasA,
379 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
380 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
381 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
382 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/2, /*MI*/0, /*OpIdx*/2, // MIs[2]
383 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/2, /*Expected*/3,
384 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
385 // CHECK-NEXT: // MIs[0] dst
386 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
387 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
388 // CHECK-NEXT: // MIs[0] Operand 1
389 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
390 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SUB,
391 // CHECK-NEXT: // MIs[1] Operand 0
392 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
393 // CHECK-NEXT: // MIs[1] src1
394 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
395 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
396 // CHECK-NEXT: // MIs[1] src2
397 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
398 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
399 // CHECK-NEXT: // MIs[0] Operand 2
400 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
401 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/2, TargetOpcode::G_SUB,
402 // CHECK-NEXT: // MIs[2] Operand 0
403 // CHECK-NEXT: GIM_CheckType, /*MI*/2, /*Op*/0, /*Type*/GILLT_s32,
404 // CHECK-NEXT: // MIs[2] src3
405 // CHECK-NEXT: GIM_CheckType, /*MI*/2, /*Op*/1, /*Type*/GILLT_s32,
406 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
407 // CHECK-NEXT: // MIs[2] src4
408 // CHECK-NEXT: GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32,
409 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
410 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
411 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/2,
412 // 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)
413 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSNBOB,
414 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
415 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
416 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
417 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/1, // src3
418 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // src4
419 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
420 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
421 // CHECK-NEXT: GIR_Done,
422 // CHECK-NEXT: // Label 7: @[[LABEL]]
424 def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
426 (sub (sub GPR32:$src1, GPR32:$src2), (sub GPR32:$src3, GPR32:$src4)))]>,
429 //===- Test a pattern with ComplexPattern operands. -----------------------===//
432 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 8*/ [[LABEL:[0-9]+]],
433 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
434 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
435 // CHECK-NEXT: // MIs[0] dst
436 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
437 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
438 // CHECK-NEXT: // MIs[0] src1
439 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
440 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
441 // CHECK-NEXT: // MIs[0] src2
442 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
443 // CHECK-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
444 // CHECK-NEXT: // (sub:i32 GPR32:i32:$src1, complex:i32:$src2) => (INSN1:i32 GPR32:i32:$src1, complex:i32:$src2)
445 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN1,
446 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
447 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
448 // CHECK-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
449 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
450 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
451 // CHECK-NEXT: GIR_Done,
452 // CHECK-NEXT: // Label 8: @[[LABEL]]
454 def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>;
455 def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>;
457 //===- Test a simple pattern with a default operand. ----------------------===//
460 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 9*/ [[LABEL:[0-9]+]],
461 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
462 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
463 // CHECK-NEXT: // MIs[0] dst
464 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
465 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
466 // CHECK-NEXT: // MIs[0] src1
467 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
468 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
469 // CHECK-NEXT: // MIs[0] Operand 2
470 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
471 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -2
472 // CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -2:i32) => (XORI:i32 GPR32:i32:$src1)
473 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORI,
474 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
475 // CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
476 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
477 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
478 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
479 // CHECK-NEXT: GIR_Done,
480 // CHECK-NEXT: // Label 9: @[[LABEL]]
482 // The -2 is just to distinguish it from the 'not' case below.
483 def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1),
484 [(set GPR32:$dst, (xor GPR32:$src1, -2))]>;
486 //===- Test a simple pattern with a default register operand. -------------===//
489 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 10*/ [[LABEL:[0-9]+]],
490 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
491 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
492 // CHECK-NEXT: // MIs[0] dst
493 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
494 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
495 // CHECK-NEXT: // MIs[0] src1
496 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
497 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
498 // CHECK-NEXT: // MIs[0] Operand 2
499 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
500 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -3
501 // CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -3:i32) => (XOR:i32 GPR32:i32:$src1)
502 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XOR,
503 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
504 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
505 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
506 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
507 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
508 // CHECK-NEXT: GIR_Done,
509 // CHECK-NEXT: // Label 10: @[[LABEL]]
511 // The -3 is just to distinguish it from the 'not' case below and the other default op case above.
512 def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1),
513 [(set GPR32:$dst, (xor GPR32:$src1, -3))]>;
515 //===- Test a simple pattern with a multiple default operands. ------------===//
518 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 11*/ [[LABEL:[0-9]+]],
519 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
520 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
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] src1
525 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
526 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
527 // CHECK-NEXT: // MIs[0] Operand 2
528 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
529 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -4
530 // CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -4:i32) => (XORlike:i32 GPR32:i32:$src1)
531 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORlike,
532 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
533 // CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
534 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
535 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
536 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
537 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
538 // CHECK-NEXT: GIR_Done,
539 // CHECK-NEXT: // Label 11: @[[LABEL]]
541 // The -4 is just to distinguish it from the other 'not' cases.
542 def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1),
543 [(set GPR32:$dst, (xor GPR32:$src1, -4))]>;
545 //===- Test a simple pattern with multiple operands with defaults. --------===//
548 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 12*/ [[LABEL:[0-9]+]],
549 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
550 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
551 // CHECK-NEXT: // MIs[0] dst
552 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
553 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
554 // CHECK-NEXT: // MIs[0] src1
555 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
556 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
557 // CHECK-NEXT: // MIs[0] Operand 2
558 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
559 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -5,
560 // CHECK-NEXT: // (xor:i32 GPR32:i32:$src1, -5:i32) => (XORManyDefaults:i32 GPR32:i32:$src1)
561 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORManyDefaults,
562 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
563 // CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
564 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
565 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
566 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
567 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
568 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
569 // CHECK-NEXT: GIR_Done,
570 // CHECK-NEXT: // Label 12: @[[LABEL]]
572 // The -5 is just to distinguish it from the other cases.
573 def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1),
574 [(set GPR32:$dst, (xor GPR32:$src1, -5))]>;
576 //===- Test a simple pattern with constant immediate operands. ------------===//
578 // This must precede the 3-register variants because constant immediates have
579 // priority over register banks.
581 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 13*/ [[LABEL:[0-9]+]],
582 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
583 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
584 // CHECK-NEXT: // MIs[0] dst
585 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
586 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
587 // CHECK-NEXT: // MIs[0] Wm
588 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
589 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
590 // CHECK-NEXT: // MIs[0] Operand 2
591 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
592 // CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -1,
593 // CHECK-NEXT: // (xor:i32 GPR32:i32:$Wm, -1:i32) => (ORN:i32 R0:i32, GPR32:i32:$Wm)
594 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::ORN,
595 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
596 // CHECK-NEXT: GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
597 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // Wm
598 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
599 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
600 // CHECK-NEXT: GIR_Done,
601 // CHECK-NEXT: // Label 13: @[[LABEL]]
603 def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;
604 def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>;
606 //===- Test a COPY_TO_REGCLASS --------------------------------------------===//
609 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 14*/ [[LABEL:[0-9]+]],
610 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
611 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST,
612 // CHECK-NEXT: // MIs[0] dst
613 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
614 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
615 // CHECK-NEXT: // MIs[0] src1
616 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
617 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::FPR32RegClassID,
618 // CHECK-NEXT: // (bitconvert:i32 FPR32:f32:$src1) => (COPY_TO_REGCLASS:i32 FPR32:f32:$src1, GPR32:i32)
619 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/TargetOpcode::COPY,
620 // CHECK-NEXT: GIR_ConstrainOperandRC, /*InsnID*/0, /*Op*/0, /*RC GPR32*/1,
621 // CHECK-NEXT: GIR_Done,
622 // CHECK-NEXT: // Label 14: @[[LABEL]]
624 def : Pat<(i32 (bitconvert FPR32:$src1)),
625 (COPY_TO_REGCLASS FPR32:$src1, GPR32)>;
627 //===- Test a simple pattern with just a specific leaf immediate. ---------===//
629 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 15*/ [[LABEL:[0-9]+]],
630 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
631 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
632 // CHECK-NEXT: // MIs[0] dst
633 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
634 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
635 // CHECK-NEXT: // MIs[0] Operand 1
636 // CHECK-NEXT: GIM_CheckLiteralInt, /*MI*/0, /*Op*/1, 1,
637 // CHECK-NEXT: // 1:i32 => (MOV1:i32)
638 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV1,
639 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
640 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
641 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
642 // CHECK-NEXT: GIR_Done,
643 // CHECK-NEXT: // Label 15: @[[LABEL]]
645 def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>;
647 //===- Test a simple pattern with a leaf immediate and a predicate. -------===//
649 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 16*/ [[LABEL:[0-9]+]],
650 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
651 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
652 // CHECK-NEXT: GIM_CheckImmPredicate, /*MI*/0, /*Predicate*/GIPFP_Predicate_simm8,
653 // CHECK-NEXT: // MIs[0] dst
654 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
655 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
656 // CHECK-NEXT: // MIs[0] Operand 1
657 // CHECK-NEXT: // No operand predicates
658 // CHECK-NEXT: // (imm:i32)<<P:Predicate_simm8>>:$imm => (MOVimm8:i32 (imm:i32):$imm)
659 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm8,
660 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
661 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
662 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
663 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
664 // CHECK-NEXT: GIR_Done,
665 // CHECK-NEXT: // Label 16: @[[LABEL]]
667 def simm8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
668 def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$imm)]>;
670 //===- Test a simple pattern with just a leaf immediate. ------------------===//
672 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 17*/ [[LABEL:[0-9]+]],
673 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
674 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
675 // CHECK-NEXT: // MIs[0] dst
676 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
677 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
678 // CHECK-NEXT: // MIs[0] Operand 1
679 // CHECK-NEXT: // No operand predicates
680 // CHECK-NEXT: // (imm:i32):$imm => (MOVimm:i32 (imm:i32):$imm)
681 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm,
682 // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
683 // CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
684 // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0,
685 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
686 // CHECK-NEXT: GIR_Done,
687 // CHECK-NEXT: // Label 17: @[[LABEL]]
689 def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm)]>;
691 //===- Test a pattern with an MBB operand. --------------------------------===//
693 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 18*/ [[LABEL:[0-9]+]],
694 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/1,
695 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR,
696 // CHECK-NEXT: // MIs[0] target
697 // CHECK-NEXT: GIM_CheckIsMBB, /*MI*/0, /*Op*/0,
698 // CHECK-NEXT: // (br (bb:Other):$target) => (BR (bb:Other):$target)
699 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::BR,
700 // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
701 // CHECK-NEXT: GIR_Done,
702 // CHECK-NEXT: // Label 18: @[[LABEL]]
704 def BR : I<(outs), (ins unknown:$target),
707 // CHECK-NEXT: GIM_Reject,
709 // CHECK-NEXT: if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable0, TII, MRI, TRI, RBI, AvailableFeatures)) {
710 // CHECK-NEXT: return true;