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