[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / TableGen / GlobalISelEmitter.td
blobef5c25ac4b5f1ae4cfd3fb7aa4c555a8f20f9672
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);
37 def gi_complex :
38     GIComplexOperandMatcher<s32, "selectComplexPattern">,
39     GIComplexPatternEquiv<complex>;
40 def complex_rr : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPatternRR", []> {
41   let MIOperandInfo = (ops GPR32, GPR32);
43 def gi_complex_rr :
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);
50   }]>;
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)>;
63 def HasA : Predicate<"Subtarget->hasA()">;
64 def HasB : Predicate<"Subtarget->hasB()">;
65 def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
67 //===- Test the function boilerplate. -------------------------------------===//
69 // CHECK: const unsigned MAX_SUBTARGET_PREDICATES = 3;
70 // CHECK: using PredicateBitset = llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
72 // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_DECL
73 // CHECK-NEXT:    mutable MatcherState State;
74 // CHECK-NEXT:    typedef ComplexRendererFns(MyTargetInstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;
75 // CHECK-NEXT:    typedef void(MyTargetInstructionSelector::*CustomRendererFn)(MachineInstrBuilder &, const MachineInstr &, int) const;
76 // CHECK-NEXT:    const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn> ISelInfo;
77 // CHECK-NEXT:    static MyTargetInstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];
78 // CHECK-NEXT:    static MyTargetInstructionSelector::CustomRendererFn CustomRenderers[];
79 // CHECK-NEXT:    bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const override;
80 // CHECK-NEXT:    bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) const override;
81 // CHECK-NEXT:    bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat &Imm) const override;
82 // CHECK-NEXT:    const int64_t *getMatchTable() const override;
83 // CHECK-NEXT:    bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI, const std::array<const MachineOperand *, 3> &Operands) const override;
84 // CHECK-NEXT:  #endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL
86 // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT
87 // CHECK-NEXT:    , State(2),
88 // CHECK-NEXT:    ISelInfo(TypeObjects, NumTypeObjects, FeatureBitsets, ComplexPredicateFns, CustomRenderers)
89 // CHECK-NEXT:  #endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT
91 // CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
92 // CHECK-NEXT:    Feature_HasABit = 0,
93 // CHECK-NEXT:    Feature_HasBBit = 1,
94 // CHECK-NEXT:    Feature_HasCBit = 2,
95 // CHECK-NEXT:  };
97 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
98 // CHECK-NEXT:  computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const {
99 // CHECK-NEXT:    PredicateBitset Features;
100 // CHECK-NEXT:    if (Subtarget->hasA())
101 // CHECK-NEXT:      Features.set(Feature_HasABit);
102 // CHECK-NEXT:    if (Subtarget->hasB())
103 // CHECK-NEXT:      Features.set(Feature_HasBBit);
104 // CHECK-NEXT:    return Features;
105 // CHECK-NEXT:  }
107 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
108 // CHECK-NEXT:  computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const {
109 // CHECK-NEXT:    PredicateBitset Features;
110 // CHECK-NEXT:    if (Subtarget->hasC())
111 // CHECK-NEXT:      Features.set(Feature_HasCBit);
112 // CHECK-NEXT:    return Features;
113 // CHECK-NEXT:  }
115 // CHECK-LABEL: // LLT Objects.
116 // CHECK-NEXT:  enum {
117 // CHECK-NEXT:    GILLT_p0s32
118 // CHECK-NEXT:    GILLT_s32,
119 // CHECK-NEXT:  }
120 // CHECK-NEXT:  const static size_t NumTypeObjects = 2;
121 // CHECK-NEXT:  const static LLT TypeObjects[] = {
122 // CHECK-NEXT:    LLT::pointer(0, 32),
123 // CHECK-NEXT:    LLT::scalar(32),
124 // CHECK-NEXT:  };
126 // CHECK-LABEL: // Feature bitsets.
127 // CHECK-NEXT:  enum {
128 // CHECK-NEXT:    GIFBS_Invalid,
129 // CHECK-NEXT:    GIFBS_HasA,
130 // CHECK-NEXT:    GIFBS_HasA_HasB_HasC,
131 // CHECK-NEXT:  }
132 // CHECK-NEXT:  const static PredicateBitset FeatureBitsets[] {
133 // CHECK-NEXT:    {}, // GIFBS_Invalid
134 // CHECK-NEXT:    {Feature_HasABit, },
135 // CHECK-NEXT:    {Feature_HasABit, Feature_HasBBit, Feature_HasCBit, },
136 // CHECK-NEXT:  };
138 // CHECK-LABEL: // ComplexPattern predicates.
139 // CHECK-NEXT:  enum {
140 // CHECK-NEXT:    GICP_Invalid,
141 // CHECK-NEXT:    GICP_gi_complex,
142 // CHECK-NEXT:    GICP_gi_complex_rr,
143 // CHECK-NEXT:  };
145 // CHECK-LABEL: // PatFrag predicates.
146 // CHECK-NEXT:  enum {
147 // CHECK-NEXT:    GIPFP_I64_Predicate_cimm8 = GIPFP_I64_Invalid + 1,
148 // CHECK-NEXT:    GIPFP_I64_Predicate_simm8,
149 // CHECK-NEXT:  };
152 // CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const {
153 // CHECK-NEXT:   switch (PredicateID) {
154 // CHECK-NEXT:   case GIPFP_I64_Predicate_cimm8: {
155 // CHECK-NEXT:     return isInt<8>(Imm);
156 // CHECK-NEXT:     llvm_unreachable("ImmediateCode should have returned");
157 // CHECK-NEXT:     return false;
158 // CHECK-NEXT:   }
159 // CHECK-NEXT:   case GIPFP_I64_Predicate_simm8: {
160 // CHECK-NEXT:      return isInt<8>(Imm);
161 // CHECK-NEXT:     llvm_unreachable("ImmediateCode should have returned");
162 // CHECK-NEXT:     return false;
163 // CHECK-NEXT:   }
164 // CHECK-NEXT:   }
165 // CHECK-NEXT:   llvm_unreachable("Unknown predicate");
166 // CHECK-NEXT:   return false;
167 // CHECK-NEXT: }
169 // CHECK-LABEL: // PatFrag predicates.
170 // CHECK-NEXT:  enum {
171 // CHECK-NEXT:    GIPFP_APFloat_Predicate_fpimmz = GIPFP_APFloat_Invalid + 1,
172 // CHECK-NEXT:  };
173 // CHECK-NEXT:  bool MyTargetInstructionSelector::testImmPredicate_APFloat(unsigned PredicateID, const APFloat & Imm) const {
174 // CHECK-NEXT:    switch (PredicateID) {
175 // CHECK-NEXT:    case GIPFP_APFloat_Predicate_fpimmz: {
176 // CHECK-NEXT:      return Imm->isExactlyValue(0.0);
177 // CHECK-NEXT:      llvm_unreachable("ImmediateCode should have returned");
178 // CHECK-NEXT:      return false;
179 // CHECK-NEXT:    }
180 // CHECK-NEXT:    }
181 // CHECK-NEXT:    llvm_unreachable("Unknown predicate");
182 // CHECK-NEXT:    return false;
183 // CHECK-NEXT:  }
185 // CHECK-LABEL: // PatFrag predicates.
186 // CHECK-NEXT:  enum {
187 // CHECK-NEXT:    GIPFP_APInt_Predicate_simm9 = GIPFP_APInt_Invalid + 1,
188 // CHECK-NEXT:  };
189 // CHECK-NEXT:  bool MyTargetInstructionSelector::testImmPredicate_APInt(unsigned PredicateID, const APInt & Imm) const {
190 // CHECK-NEXT:    switch (PredicateID) {
191 // CHECK-NEXT:    case GIPFP_APInt_Predicate_simm9: {
192 // CHECK-NEXT:      return isInt<9>(Imm->getSExtValue());
193 // CHECK-NEXT:      llvm_unreachable("ImmediateCode should have returned");
194 // CHECK-NEXT:      return false;
195 // CHECK-NEXT:    }
196 // CHECK-NEXT:    }
197 // CHECK-NEXT:    llvm_unreachable("Unknown predicate");
198 // CHECK-NEXT:    return false;
199 // CHECK-NEXT:  }
201 // CHECK-LABEL: MyTargetInstructionSelector::ComplexMatcherMemFn
202 // CHECK-NEXT:  MyTargetInstructionSelector::ComplexPredicateFns[] = {
203 // CHECK-NEXT:    nullptr, // GICP_Invalid
204 // CHECK-NEXT:    &MyTargetInstructionSelector::selectComplexPattern, // gi_complex
205 // CHECK-NEXT:    &MyTargetInstructionSelector::selectComplexPatternRR, // gi_complex_rr
206 // CHECK-NEXT:  }
208 // CHECK-LABEL: // Custom renderers.
209 // CHECK-NEXT: enum {
210 // CHECK-NEXT:   GICR_Invalid,
211 // CHECK-NEXT:   GICR_renderImm,
212 // CHECK-NEXT: };
213 // CHECK-NEXT: MyTargetInstructionSelector::CustomRendererFn
214 // CHECK-NEXT: MyTargetInstructionSelector::CustomRenderers[] = {
215 // CHECK-NEXT:   nullptr, // GICR_Invalid
216 // CHECK-NEXT:   &MyTargetInstructionSelector::renderImm,
217 // CHECK-NEXT: };
219 // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const {
220 // CHECK-NEXT: MachineFunction &MF = *I.getParent()->getParent();
221 // CHECK-NEXT: MachineRegisterInfo &MRI = MF.getRegInfo();
222 // CHECK-NEXT: const PredicateBitset AvailableFeatures = getAvailableFeatures();
223 // CHECK-NEXT: NewMIVector OutMIs;
224 // CHECK-NEXT: State.MIs.clear();
225 // CHECK-NEXT: State.MIs.push_back(&I);
227 // CHECK:      if (executeMatchTable(*this, OutMIs, State, ISelInfo, getMatchTable(), TII, MRI, TRI, RBI, AvailableFeatures, CoverageInfo)) {
228 // CHECK-NEXT:   return true;
229 // CHECK-NEXT: }
231 // CHECK: const int64_t *
232 // CHECK-LABEL: MyTargetInstructionSelector::getMatchTable() const {
233 // CHECK-NEXT: MatchTable0[] = {
235 //===- Test a pattern with multiple ComplexPatterns in multiple instrs ----===//
237 // R19O-NEXT:  GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]],
238 // R19O-NEXT:  /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]],
239 // R19O:       /*TargetOpcode::G_SELECT*//*Label [[CASE_SELECT_NUM:[0-9]+]]*/ [[CASE_SELECT:[0-9]+]],
240 // R19O:       // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]
241 // R19O:       // Label [[CASE_SELECT_NUM]]: @[[CASE_SELECT]]
242 // R19O-NEXT:  GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]],
243 // R19O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
244 // R19O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
245 // R19O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
246 // R19O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
248 // R19C-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
250 // R19O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
251 // R19O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
252 // R19N-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
253 // R19N-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
254 // R19N-NEXT:    // MIs[0] dst
255 // R19N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
256 // R19N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
257 // R19N-NEXT:    // MIs[0] src1
258 // R19N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
259 // R19N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
260 // R19N-NEXT:    // MIs[0] complex_rr:src2a:src2b
261 // R19N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
263 // R19N-NEXT:    GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex_rr,
264 // R19N-NEXT:    // MIs[0] Operand 3
265 // R19N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
266 // R19C-NEXT:    GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/3, // MIs[1]
267 // R19N-NEXT:    GIM_CheckNumOperands, /*MI*/1, /*Expected*/4,
268 // R19C-NEXT:    GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SELECT,
269 // R19N-NEXT:    // MIs[1] Operand 0
270 // R19N-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
271 // R19N-NEXT:    // MIs[1] src3
272 // R19C-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
273 // R19O-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
274 // R19O-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/3, /*Type*/GILLT_s32,
275 // R19N-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
276 // R19N-NEXT:    // MIs[1] src4
277 // R19N-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
278 // R19N-NEXT:    GIM_CheckComplexPattern, /*MI*/1, /*Op*/2, /*Renderer*/1, GICP_gi_complex,
279 // R19N-NEXT:    // MIs[1] complex:src5a:src5b
280 // R19N-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/3, /*Type*/GILLT_s32,
281 // R19N-NEXT:    GIM_CheckComplexPattern, /*MI*/1, /*Op*/3, /*Renderer*/2, GICP_gi_complex,
282 // R19O-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
283 // R19C-NEXT:    GIM_CheckIsSafeToFold, /*InsnID*/1,
284 // R19O-NEXT:    GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex_rr,
285 // R19O-NEXT:    GIM_CheckComplexPattern, /*MI*/1, /*Op*/2, /*Renderer*/1, GICP_gi_complex,
286 // R19O-NEXT:    GIM_CheckComplexPattern, /*MI*/1, /*Op*/3, /*Renderer*/2, GICP_gi_complex,
287 // 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))
288 // R19C-NEXT:    GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,
289 // R19C-NEXT:    GIR_BuildMI, /*InsnID*/1, /*Opcode*/MyTarget::INSN4,
290 // R19C-NEXT:    GIR_AddTempRegister, /*InsnID*/1, /*TempRegID*/0, /*TempRegFlags*/RegState::Define,
291 // R19C-NEXT:    GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // src3
292 // R19C-NEXT:    GIR_ComplexRenderer, /*InsnID*/1, /*RendererID*/1,
293 // R19C-NEXT:    GIR_ComplexSubOperandRenderer, /*InsnID*/1, /*RendererID*/2, /*SubOperand*/0, // src5a
294 // R19C-NEXT:    GIR_ComplexSubOperandRenderer, /*InsnID*/1, /*RendererID*/2, /*SubOperand*/1, // src5b
295 // R19C-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/1,
296 // R19C-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN3,
297 // R19C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
298 // R19C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
299 // R19C-NEXT:    GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/1, // src2b
300 // R19C-NEXT:    GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/0, /*SubOperand*/0, // src2a
301 // R19C-NEXT:    GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/0,
302 // R19C-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
303 // R19C-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
304 // R19C-NEXT:    // GIR_Coverage, 19,
305 // R19C-NEXT:    GIR_Done,
306 // R19C-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
308 // R19O:       // Label [[GROUP_NUM]]: @[[GROUP]]
309 // R19O-NEXT:  GIM_Reject,
310 // R19O:       // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
311 // R19O-NEXT:  GIM_Reject,
312 // R19O-NEXT:  };
314 def INSN3 : I<(outs GPR32:$dst),
315               (ins GPR32Op:$src1, GPR32:$src2a, GPR32:$src2b, GPR32:$scr), []>;
316 def INSN4 : I<(outs GPR32:$scr),
317               (ins GPR32:$src3, complex:$src4, i32imm:$src5a, i32imm:$src5b), []>;
318 def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b),
319                                (select GPR32:$src3,
320                                        complex:$src4,
321                                        (complex i32imm:$src5a, i32imm:$src5b))),
322           (INSN3 GPR32:$src1, GPR32:$src2b, GPR32:$src2a,
323                  (INSN4 GPR32:$src3, complex:$src4, i32imm:$src5a,
324                         i32imm:$src5b))>;
326 // R21O-NEXT:  GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]],
327 // R21O-NEXT:  /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]],
328 // R21O:       /*TargetOpcode::G_SELECT*//*Label [[CASE_SELECT_NUM:[0-9]+]]*/ [[CASE_SELECT:[0-9]+]],
329 // R21O:       // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]
330 // R21O:       // Label [[CASE_SELECT_NUM]]: @[[CASE_SELECT]]
331 // R21O-NEXT:  GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]],
332 // R21O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
333 // R21O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
334 // R21O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
335 // R21O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
337 // R21C-NEXT:  GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 19 //
338 // R21C-NOT:     GIR_Done,
339 // R21C:         // GIR_Coverage, 19,
340 // R21C-NEXT:    GIR_Done,
341 // R21C-NEXT:  // Label [[PREV_NUM]]: @[[PREV]]
342 // R21C-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 21 //
344 // R21O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
345 // R21O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
346 // R21N-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
347 // R21N-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SELECT,
348 // R21N-NEXT:    // MIs[0] dst
349 // R21N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
350 // R21N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
351 // R21N-NEXT:    // MIs[0] src1
352 // R21N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
353 // R21N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
354 // R21N-NEXT:    // MIs[0] src2
355 // R21N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
357 // R21O-NEXT:    GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_frag,
358 // R21C-NEXT:    GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
359 // R21N-NEXT:    // MIs[0] src3
360 // R21N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/3, /*Type*/GILLT_s32,
361 // R21C-NEXT:    GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/1, GICP_gi_complex,
362 // R21N-NEXT:    GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_frag,
363 // 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)
365 // R21C-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN2,
366 // R21C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
367 // R21C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
368 // R21C-NEXT:    GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/1,
369 // R21C-NEXT:    GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
370 // R21C-NEXT:    GIR_MergeMemOperands, /*InsnID*/0, /*MergeInsnID's*/0, GIU_MergeMemOperands_EndOfList,
371 // R21C-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
372 // R21C-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
373 // R21C-NEXT:    // GIR_Coverage, 21,
374 // R21C-NEXT:    GIR_Done,
375 // R21C-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
377 // R21O-NEXT:  GIM_Reject,
378 // R21O-NEXT:  // Label [[GROUP_NUM]]: @[[GROUP]]
379 // R21O-NEXT:  GIM_Reject,
380 // R21O:       // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
381 // R21O-NEXT:  GIM_Reject,
382 // R21O-NEXT:  };
384 //===- Test a pattern with ComplexPattern operands. -----------------------===//
386 // R20O-NEXT:  GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]],
387 // R20O-NEXT:  /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]],
388 // R20O:       /*TargetOpcode::G_SUB*//*Label [[CASE_SUB_NUM:[0-9]+]]*/ [[CASE_SUB:[0-9]+]],
389 // R20O:       // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]
390 // R20O:       // Label [[CASE_SUB_NUM]]: @[[CASE_SUB]]
391 // R20O-NEXT:  GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]],
392 // R20O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
393 // R20O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
394 // R20O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
395 // R20O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
397 // R20N:       GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 21 //
398 // R20N:       // Label [[PREV_NUM]]: @[[PREV]]
400 // R20C-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 20 //
402 // R20N-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
403 // R20N-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
404 // R20N-NEXT:    // MIs[0] dst
405 // R20N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
406 // R20N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
407 // R20N-NEXT:    // MIs[0] src1
408 // R20N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
410 // R20N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
411 // R20N-NEXT:    // MIs[0] src2
412 // R20N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
413 // R20O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
414 // R20C-NEXT:    GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/0, GICP_gi_complex,
415 // R20C-NEXT:    // (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2) => (INSN1:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2)
416 // R20C-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSN1,
417 // R20C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
418 // R20C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
419 // R20C-NEXT:    GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/0,
420 // R20C-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
421 // R20C-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
422 // R20C-NEXT:    // GIR_Coverage, 20,
423 // R20C-NEXT:    GIR_Done,
424 // R20C-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
426 // R20O:       // Label [[GROUP_NUM]]: @[[GROUP]]
427 // R20O-NEXT:  GIM_Reject,
428 // R20O:       // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
429 // R20O-NEXT:  GIM_Reject,
430 // R20O-NEXT:  };
432 def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>;
433 def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>;
435 //===- Test a pattern with multiple ComplexPattern operands. --------------===//
437 def : GINodeEquiv<G_SELECT, select>;
438 let mayLoad = 1 in {
439   def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>;
441 def frag : PatFrag<(ops node:$a, node:$b, node:$c),
442                    (select node:$a, node:$b, node:$c),
443                    [{ return true; // C++ code }]> {
444   let GISelPredicateCode = [{ return true; // C++ code }];
446 def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3),
447           (INSN2 GPR32:$src1, complex:$src3, complex:$src2)>;
449 //===- Test a more complex multi-instruction match. -----------------------===//
451 // R00O-NEXT:  GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]],
452 // R00O-NEXT:  /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]],
453 // R00O:       /*TargetOpcode::G_SUB*//*Label [[CASE_SUB_NUM:[0-9]+]]*/ [[CASE_SUB:[0-9]+]],
454 // R00O:       // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]
455 // R00O:       // Label [[CASE_SUB_NUM]]: @[[CASE_SUB]]
456 // R00O-NEXT:  GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]],
457 // R00O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
458 // R00O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
459 // R00O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
460 // R00O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
462 // R00C:       GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 20 //
463 // R00C:       // Label [[PREV_NUM]]: @[[PREV]]
465 // R00C-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 0 //
466 // R00C-NEXT:    GIM_CheckFeatures, GIFBS_HasA,
467 // R00N-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
468 // R00N-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
469 // R00N-NEXT:    // MIs[0] dst
470 // R00N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
471 // R00N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
472 // R00N-NEXT:    // MIs[0] Operand 1
473 // R00N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
474 // R00C-NEXT:    GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
475 // R00N-NEXT:    GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
476 // R00C-NEXT:    GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SUB,
477 // R00N-NEXT:    // MIs[1] Operand 0
478 // R00N-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
479 // R00N-NEXT:    // MIs[1] src1
480 // R00C-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
481 // R00O-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
482 // R00N-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
483 // R00N-NEXT:    // MIs[1] src2
484 // R00N-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
485 // R00N-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
486 // R00N-NEXT:    // MIs[0] Operand 2
487 // R00N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
488 // R00O-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
489 // R00O-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
490 // R00C-NEXT:    GIM_RecordInsn, /*DefineMI*/2, /*MI*/0, /*OpIdx*/2, // MIs[2]
491 // R00N-NEXT:    GIM_CheckNumOperands, /*MI*/2, /*Expected*/3,
492 // R00C-NEXT:    GIM_CheckOpcode, /*MI*/2, TargetOpcode::G_SUB,
493 // R00N-NEXT:    // MIs[2] Operand 0
494 // R00N-NEXT:    GIM_CheckType, /*MI*/2, /*Op*/0, /*Type*/GILLT_s32,
495 // R00N-NEXT:    // MIs[2] src3
496 // R00C-NEXT:    GIM_CheckType, /*MI*/2, /*Op*/1, /*Type*/GILLT_s32,
497 // R00O-NEXT:    GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32,
498 // R00N-NEXT:    GIM_CheckRegBankForClass, /*MI*/2, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
499 // R00N-NEXT:    // MIs[2] src4
500 // R00N-NEXT:    GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32,
501 // R00N-NEXT:    GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
502 // R00O-NEXT:    GIM_CheckRegBankForClass, /*MI*/2, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
503 // R00O-NEXT:    GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
504 // R00C-NEXT:    GIM_CheckIsSafeToFold, /*InsnID*/1,
505 // R00C-NEXT:    GIM_CheckIsSafeToFold, /*InsnID*/2,
506 // 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)
507 // R00C-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::INSNBOB,
508 // R00C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
509 // R00C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
510 // R00C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
511 // R00C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/1, // src3
512 // R00C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // src4
513 // R00C-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
514 // R00C-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
515 // R00C-NEXT:    // GIR_Coverage, 0,
516 // R00C-NEXT:    GIR_Done,
517 // R00C-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
519 // R00O-NEXT:  GIM_Reject,
520 // R00O-NEXT:  // Label [[GROUP_NUM]]: @[[GROUP]]
521 // R00O-NEXT:  GIM_Reject,
522 // R00O:       // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
523 // R00O-NEXT:  GIM_Reject,
524 // R00O-NEXT:  };
526 def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
527                  [(set GPR32:$dst,
528                       (sub (sub GPR32:$src1, GPR32:$src2), (sub GPR32:$src3, GPR32:$src4)))]>,
529                Requires<[HasA]>;
531 //===- Test a simple pattern with an intrinsic. ---------------------------===//
533 // R01O-NEXT:  GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]],
534 // R01O-NEXT:  /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]],
535 // R01O:       /*TargetOpcode::G_INTRINSIC*//*Label [[CASE_INTRINSIC_NUM:[0-9]+]]*/ [[CASE_INTRINSIC:[0-9]+]],
536 // R01O:       // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]
537 // R01O:       // Label [[CASE_INTRINSIC_NUM]]: @[[CASE_INTRINSIC]]
539 // R01N:       GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 0 //
540 // R01N:       // Label [[PREV_NUM]]: @[[PREV]]
542 // R01C-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 1 //
543 // R01C-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
545 // R01O-NEXT:    GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, Intrinsic::mytarget_nop,
546 // R01O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
547 // R01O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
548 // R01O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
550 // R01N-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC,
551 // R01N-NEXT:    // MIs[0] dst
552 // R01N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
553 // R01N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
554 // R01N-NEXT:    // MIs[0] Operand 1
555 // R01N-NEXT:    GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, Intrinsic::mytarget_nop,
556 // R01N-NEXT:    // MIs[0] src1
557 // R01N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
559 // R01C-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
560 // R01C-NEXT:    // (intrinsic_wo_chain:{ *:[i32] } [[ID:[0-9]+]]:{ *:[iPTR] }, GPR32:{ *:[i32] }:$src1) => (MOV:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
561 // R01C-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV,
562 // R01C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
563 // R01C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src1
564 // R01C-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
565 // R01C-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
566 // R01C-NEXT:    // GIR_Coverage, 1,
567 // R01C-NEXT:    GIR_Done,
568 // R01C-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
570 // R01O-NEXT:  GIM_Reject,
571 // R01O:       // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
572 // R01O-NEXT:  GIM_Reject,
574 def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1),
575             [(set GPR32:$dst, (int_mytarget_nop GPR32:$src1))]>;
577 //===- Test a simple pattern with a default operand. ----------------------===//
579 // R02O-NEXT:  GIM_SwitchOpcode, /*MI*/0, /*[*/{{[0-9]+}}, {{[0-9]+}}, /*)*//*default:*//*Label [[DEFAULT_NUM:[0-9]+]]*/ [[DEFAULT:[0-9]+]],
580 // R02O-NEXT:  /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ [[CASE_ADD:[0-9]+]],
581 // R02O:       /*TargetOpcode::G_XOR*//*Label [[CASE_XOR_NUM:[0-9]+]]*/ [[CASE_XOR:[0-9]+]],
582 // R02O:       // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]
583 // R02O:       // Label [[CASE_XOR_NUM]]: @[[CASE_XOR]]
584 // R02O-NEXT:  GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ [[GROUP:[0-9]+]],
585 // R02O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
586 // R02O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
587 // R02O-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
588 // R02O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
589 // R02O-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
591 // R02N:       GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ [[PREV:[0-9]+]], // Rule ID 1 //
592 // R02N:       // Label [[PREV_NUM]]: @[[PREV]]
594 // R02C-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]], // Rule ID 2 //
596 // R02N-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
597 // R02N-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
598 // R02N-NEXT:    // MIs[0] dst
599 // R02N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
600 // R02N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
601 // R02N-NEXT:    // MIs[0] src1
602 // R02N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
603 // R02N-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
604 // R02N-NEXT:    // MIs[0] Operand 2
605 // R02N-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
607 // R02C-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -2
608 // R02C-NEXT:    // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -2:{ *:[i32] }) => (XORI:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
609 // R02C-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORI,
610 // R02C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
611 // R02C-NEXT:    GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
612 // R02C-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
613 // R02C-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
614 // R02C-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
615 // R02C-NEXT:    // GIR_Coverage, 2,
616 // R02C-NEXT:    GIR_Done,
617 // R02C-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
619 // R02O:       // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
620 // R02O-NEXT:  GIM_Reject,
622 // The -2 is just to distinguish it from the 'not' case below.
623 def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1),
624              [(set GPR32:$dst, (xor GPR32:$src1, -2))]>;
626 //===- Test a simple pattern with a default register operand. -------------===//
628 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
629 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
630 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
631 // NOOPT-NEXT:    // MIs[0] dst
632 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
633 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
634 // NOOPT-NEXT:    // MIs[0] src1
635 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
636 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
637 // NOOPT-NEXT:    // MIs[0] Operand 2
638 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
639 // NOOPT-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -3
640 // NOOPT-NEXT:    // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -3:{ *:[i32] }) => (XOR:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
641 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XOR,
642 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
643 // NOOPT-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
644 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
645 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
646 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
647 // NOOPT-NEXT:    // GIR_Coverage, 3,
648 // NOOPT-NEXT:    GIR_Done,
649 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
651 // The -3 is just to distinguish it from the 'not' case below and the other default op case above.
652 def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1),
653             [(set GPR32:$dst, (xor GPR32:$src1, -3))]>;
655 //===- Test a simple pattern with a multiple default operands. ------------===//
657 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
658 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
659 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
660 // NOOPT-NEXT:    // MIs[0] dst
661 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
662 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
663 // NOOPT-NEXT:    // MIs[0] src1
664 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
665 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
666 // NOOPT-NEXT:    // MIs[0] Operand 2
667 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
668 // NOOPT-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -4
669 // NOOPT-NEXT:    // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -4:{ *:[i32] }) => (XORlike:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
670 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORlike,
671 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
672 // NOOPT-NEXT:    GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
673 // NOOPT-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
674 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
675 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
676 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
677 // NOOPT-NEXT:    // GIR_Coverage, 4,
678 // NOOPT-NEXT:    GIR_Done,
679 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
681 // The -4 is just to distinguish it from the other 'not' cases.
682 def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1),
683                 [(set GPR32:$dst, (xor GPR32:$src1, -4))]>;
685 //===- Test a simple pattern with multiple operands with defaults. --------===//
687 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
688 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
689 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
690 // NOOPT-NEXT:    // MIs[0] dst
691 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
692 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
693 // NOOPT-NEXT:    // MIs[0] src1
694 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
695 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
696 // NOOPT-NEXT:    // MIs[0] Operand 2
697 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
698 // NOOPT-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -5,
699 // NOOPT-NEXT:    // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -5:{ *:[i32] }) => (XORManyDefaults:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
700 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::XORManyDefaults,
701 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
702 // NOOPT-NEXT:    GIR_AddImm, /*InsnID*/0, /*Imm*/-1,
703 // NOOPT-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
704 // NOOPT-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
705 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
706 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
707 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
708 // NOOPT-NEXT:    // GIR_Coverage, 5,
709 // NOOPT-NEXT:    GIR_Done,
710 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
712 // The -5 is just to distinguish it from the other cases.
713 def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1),
714                         [(set GPR32:$dst, (xor GPR32:$src1, -5))]>;
716 //===- Test a simple pattern with constant immediate operands. ------------===//
718 // This must precede the 3-register variants because constant immediates have
719 // priority over register banks.
721 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
722 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
723 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_XOR,
724 // NOOPT-NEXT:    // MIs[0] dst
725 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
726 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
727 // NOOPT-NEXT:    // MIs[0] Wm
728 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
729 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
730 // NOOPT-NEXT:    // MIs[0] Operand 2
731 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
732 // NOOPT-NEXT:    GIM_CheckConstantInt, /*MI*/0, /*Op*/2, -1,
733 // NOOPT-NEXT:    // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$Wm, -1:{ *:[i32] }) => (ORN:{ *:[i32] } R0:{ *:[i32] }, GPR32:{ *:[i32] }:$Wm)
734 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::ORN,
735 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
736 // NOOPT-NEXT:    GIR_AddRegister, /*InsnID*/0, MyTarget::R0,
737 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // Wm
738 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
739 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
740 // NOOPT-NEXT:    // GIR_Coverage, 22,
741 // NOOPT-NEXT:    GIR_Done,
742 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
744 def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;
745 def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>;
747 //===- Test a nested instruction match. -----------------------------------===//
749 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
750 // NOOPT-NEXT:    GIM_CheckFeatures, GIFBS_HasA,
751 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
752 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
753 // NOOPT-NEXT:    // MIs[0] dst
754 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
755 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
756 // NOOPT-NEXT:    // MIs[0] Operand 1
757 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
758 // NOOPT-NEXT:    GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
759 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
760 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
761 // NOOPT-NEXT:    // MIs[1] Operand 0
762 // NOOPT-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
763 // NOOPT-NEXT:    // MIs[1] src1
764 // NOOPT-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
765 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
766 // NOOPT-NEXT:    // MIs[1] src2
767 // NOOPT-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
768 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
769 // NOOPT-NEXT:    // MIs[0] src3
770 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
771 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
772 // NOOPT-NEXT:    GIM_CheckIsSafeToFold, /*InsnID*/1,
773 // 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)
774 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
775 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
776 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
777 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
778 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src3
779 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
780 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
781 // NOOPT-NEXT:    // GIR_Coverage, 6,
782 // NOOPT-NEXT:    GIR_Done,
783 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
785 // We also get a second rule by commutativity.
787 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
788 // NOOPT-NEXT:    GIM_CheckFeatures, GIFBS_HasA,
789 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
790 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
791 // NOOPT-NEXT:    // MIs[0] dst
792 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
793 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
794 // NOOPT-NEXT:    // MIs[0] src3
795 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
796 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
797 // NOOPT-NEXT:    // MIs[0] Operand 2
798 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
799 // NOOPT-NEXT:    GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2,
800 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
801 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_ADD,
802 // NOOPT-NEXT:    // MIs[1] Operand 0
803 // NOOPT-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
804 // NOOPT-NEXT:    // MIs[1] src1
805 // NOOPT-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
806 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
807 // NOOPT-NEXT:    // MIs[1] src2
808 // NOOPT-NEXT:    GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
809 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
810 // NOOPT-NEXT:    GIM_CheckIsSafeToFold, /*InsnID*/1,
811 // 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)
812 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MULADD,
813 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
814 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1
815 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2
816 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src3
817 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
818 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
819 // NOOPT-NEXT:    // GIR_Coverage, 26,
820 // NOOPT-NEXT:    GIR_Done,
821 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
823 def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
824                [(set GPR32:$dst,
825                      (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,
826              Requires<[HasA]>;
828 //===- Test a simple pattern with just a specific leaf immediate. ---------===//
830 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
831 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
832 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
833 // NOOPT-NEXT:    // MIs[0] dst
834 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
835 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
836 // NOOPT-NEXT:    // MIs[0] Operand 1
837 // NOOPT-NEXT:    GIM_CheckLiteralInt, /*MI*/0, /*Op*/1, 1,
838 // NOOPT-NEXT:    // 1:{ *:[i32] }  =>  (MOV1:{ *:[i32] })
839 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOV1,
840 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
841 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
842 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
843 // NOOPT-NEXT:    // GIR_Coverage, 7,
844 // NOOPT-NEXT:    GIR_Done,
845 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
847 def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>;
849 //===- Test a simple pattern with a leaf immediate and a predicate. -------===//
851 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
852 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
853 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
854 // NOOPT-NEXT:    GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_simm8,
855 // NOOPT-NEXT:    // MIs[0] dst
856 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
857 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
858 // NOOPT-NEXT:    // MIs[0] Operand 1
859 // NOOPT-NEXT:    // No operand predicates
860 // NOOPT-NEXT:    // (imm:{ *:[i32] })<<P:Predicate_simm8>>:$imm => (MOVimm8:{ *:[i32] } (imm:{ *:[i32] }):$imm)
861 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm8,
862 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
863 // NOOPT-NEXT:    GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
864 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
865 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
866 // NOOPT-NEXT:    // GIR_Coverage, 8,
867 // NOOPT-NEXT:    GIR_Done,
868 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
870 def simm8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
871 def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$imm)]>;
873 //===- Same again but use an IntImmLeaf. ----------------------------------===//
875 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
876 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
877 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
878 // NOOPT-NEXT:    GIM_CheckAPIntImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APInt_Predicate_simm9,
879 // NOOPT-NEXT:    // MIs[0] dst
880 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
881 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
882 // NOOPT-NEXT:    // MIs[0] Operand 1
883 // NOOPT-NEXT:    // No operand predicates
884 // NOOPT-NEXT:    // (imm:{ *:[i32] })<<P:Predicate_simm9>>:$imm =>  (MOVimm9:{ *:[i32] } (imm:{ *:[i32] }):$imm)
885 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm9,
886 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
887 // NOOPT-NEXT:    GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
888 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
889 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
890 // NOOPT-NEXT:    // GIR_Coverage, 9,
891 // NOOPT-NEXT:    GIR_Done,
892 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
894 def simm9 : IntImmLeaf<i32, [{ return isInt<9>(Imm->getSExtValue()); }]>;
895 def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$imm)]>;
897 //===- Test a pattern with a custom renderer. -----------------------------===//
899 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
900 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
901 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
902 // NOOPT-NEXT:    GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIPFP_I64_Predicate_cimm8,
903 // NOOPT-NEXT:    // MIs[0] dst
904 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
905 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
906 // NOOPT-NEXT:    // MIs[0] Operand 1
907 // NOOPT-NEXT:    // No operand predicates
908 // NOOPT-NEXT:    // (imm:{ *:[i32] })<<P:Predicate_cimm8>><<X:cimm8_xform>>:$imm  =>  (MOVcimm8:{ *:[i32] } (cimm8_xform:{ *:[i32] } (imm:{ *:[i32] }):$imm))
909 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVcimm8,
910 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
911 // NOOPT-NEXT:    GIR_CustomRenderer, /*InsnID*/0, /*OldInsnID*/0, /*Renderer*/GICR_renderImm, // imm
912 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
913 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
914 // NOOPT-NEXT:    // GIR_Coverage, 10,
915 // NOOPT-NEXT:    GIR_Done,
916 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
918 def MOVcimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, cimm8:$imm)]>;
920 //===- Test a simple pattern with a FP immediate and a predicate. ---------===//
922 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
923 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
924 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCONSTANT,
925 // NOOPT-NEXT:    GIM_CheckAPFloatImmPredicate, /*MI*/0, /*Predicate*/GIPFP_APFloat_Predicate_fpimmz,
926 // NOOPT-NEXT:    // MIs[0] dst
927 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
928 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::FPR32RegClassID,
929 // NOOPT-NEXT:    // MIs[0] Operand 1
930 // NOOPT-NEXT:    // No operand predicates
931 // NOOPT-NEXT:    // (fpimm:{ *:[f32] })<<P:Predicate_fpimmz>>:$imm =>  (MOVfpimmz:{ *:[f32] } (fpimm:{ *:[f32] }):$imm)
932 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVfpimmz,
933 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
934 // NOOPT-NEXT:    GIR_CopyFConstantAsFPImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
935 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
936 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
937 // NOOPT-NEXT:    // GIR_Coverage, 17,
938 // NOOPT-NEXT:    GIR_Done,
939 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
941 //===- Test a simple pattern with inferred pointer operands. ---------------===//
943 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
944 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
945 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,
946 // NOOPT-NEXT:    GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
947 // NOOPT-NEXT:    GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic,
948 // NOOPT-NEXT:    // MIs[0] dst
949 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
950 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
951 // NOOPT-NEXT:    // MIs[0] src1
952 // NOOPT-NEXT:    GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
953 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
954 // NOOPT-NEXT:    // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
955 // NOOPT-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD,
956 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
957 // NOOPT-NEXT:    // GIR_Coverage, 11,
958 // NOOPT-NEXT:    GIR_Done,
959 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
961 def LOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),
962             [(set GPR32:$dst, (load GPR32:$src1))]>;
964 //===- Test a simple pattern with explicit pointer operands. ---------------===//
966 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
967 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
968 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_LOAD,
969 // NOOPT-NEXT:    GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
970 // NOOPT-NEXT:    GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic,
971 // NOOPT-NEXT:    // MIs[0] dst
972 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_p0s32,
973 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
974 // NOOPT-NEXT:    // MIs[0] src
975 // NOOPT-NEXT:    GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
976 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
977 // NOOPT-NEXT:    // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src)<<P:Predicate_unindexedload>><<P:Predicate_load>>  =>  (LOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src)
978 // NOOPT-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::LOAD,
979 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
980 // NOOPT-NEXT:    // GIR_Coverage, 23,
981 // NOOPT-NEXT:    GIR_Done,
982 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
984 def : Pat<(load GPR32:$src),
985           (p0 (LOAD GPR32:$src))>;
987 //===- Test a simple pattern with a sextload -------------------------------===//
989 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
990 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
991 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SEXTLOAD,
992 // NOOPT-NEXT:    GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/2,
993 // NOOPT-NEXT:    GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic,
994 // NOOPT-NEXT:    // MIs[0] dst
995 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
996 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
997 // NOOPT-NEXT:    // MIs[0] src1
998 // NOOPT-NEXT:    GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
999 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
1000 // NOOPT-NEXT:    // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedload>><<P:Predicate_sextload>><<P:Predicate_sextloadi16>>  =>  (SEXTLOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
1001 // NOOPT-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::SEXTLOAD,
1002 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
1003 // NOOPT-NEXT:    // GIR_Coverage, 12,
1004 // NOOPT-NEXT:    GIR_Done,
1005 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
1007 def SEXTLOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),
1008                  [(set GPR32:$dst, (sextloadi16 GPR32:$src1))]>;
1010 //===- Test a simple pattern with regclass operands. ----------------------===//
1012 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
1013 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
1014 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
1015 // NOOPT-NEXT:    // MIs[0] dst
1016 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
1017 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
1018 // NOOPT-NEXT:    // MIs[0] src1
1019 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
1020 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID
1021 // NOOPT-NEXT:    // MIs[0] src2
1022 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
1023 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
1024 // NOOPT-NEXT:    // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2)
1025 // NOOPT-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD,
1026 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
1027 // NOOPT-NEXT:    // GIR_Coverage, 13,
1028 // NOOPT-NEXT:    GIR_Done,
1029 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
1031 def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
1032             [(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>;
1034 //===- Test a pattern with a tied operand in the matcher ------------------===//
1036 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
1037 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
1038 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
1039 // NOOPT-NEXT:    // MIs[0] dst
1040 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
1041 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
1042 // NOOPT-NEXT:    // MIs[0] src{{$}}
1043 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
1044 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
1045 // NOOPT-NEXT:    // MIs[0] src{{$}}
1046 // NOOPT-NEXT:    GIM_CheckIsSameOperand, /*MI*/0, /*OpIdx*/2, /*OtherMI*/0, /*OtherOpIdx*/1,
1047 // NOOPT-NEXT:    // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src, GPR32:{ *:[i32] }:$src) => (DOUBLE:{ *:[i32] } GPR32:{ *:[i32] }:$src)
1048 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::DOUBLE,
1049 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
1050 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src
1051 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
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 DOUBLE : I<(outs GPR32:$dst), (ins GPR32:$src), [(set GPR32:$dst, (add GPR32:$src, GPR32:$src))]>;
1059 //===- Test a simple pattern with ValueType operands. ----------------------===//
1061 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
1062 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
1063 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ADD,
1064 // NOOPT-NEXT:    // MIs[0] dst
1065 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
1066 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
1067 // NOOPT-NEXT:    // MIs[0] src1
1068 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
1069 // NOOPT-NEXT:    // MIs[0] src2
1070 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
1071 // NOOPT-NEXT:    // (add:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)
1072 // NOOPT-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::ADD,
1073 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
1074 // NOOPT-NEXT:    // GIR_Coverage, 24,
1075 // NOOPT-NEXT:    GIR_Done,
1076 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
1078 def : Pat<(add i32:$src1, i32:$src2),
1079           (ADD i32:$src1, i32:$src2)>;
1081 //===- Test another simple pattern with regclass operands. ----------------===//
1083 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
1084 // NOOPT-NEXT:    GIM_CheckFeatures, GIFBS_HasA_HasB_HasC,
1085 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
1086 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_MUL,
1087 // NOOPT-NEXT:    // MIs[0] dst
1088 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
1089 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
1090 // NOOPT-NEXT:    // MIs[0] src1
1091 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
1092 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR32RegClassID,
1093 // NOOPT-NEXT:    // MIs[0] src2
1094 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
1095 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/MyTarget::GPR32RegClassID,
1096 // NOOPT-NEXT:    // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (MUL:{ *:[i32] } GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src1)
1097 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MUL,
1098 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
1099 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/2, // src2
1100 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src1
1101 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
1102 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
1103 // NOOPT-NEXT:    // GIR_Coverage, 15,
1104 // NOOPT-NEXT:    GIR_Done,
1105 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
1107 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
1108              [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
1109           Requires<[HasA, HasB, HasC]>;
1111 //===- Test a COPY_TO_REGCLASS --------------------------------------------===//
1114 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
1115 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
1116 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BITCAST,
1117 // NOOPT-NEXT:    // MIs[0] dst
1118 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
1119 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
1120 // NOOPT-NEXT:    // MIs[0] src1
1121 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
1122 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::FPR32RegClassID,
1123 // NOOPT-NEXT:    // (bitconvert:{ *:[i32] } FPR32:{ *:[f32] }:$src1) => (COPY_TO_REGCLASS:{ *:[i32] } FPR32:{ *:[f32] }:$src1, GPR32:{ *:[i32] })
1124 // NOOPT-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/TargetOpcode::COPY,
1125 // NOOPT-NEXT:    GIR_ConstrainOperandRC, /*InsnID*/0, /*Op*/0, MyTarget::GPR32RegClassID,
1126 // NOOPT-NEXT:    // GIR_Coverage, 25,
1127 // NOOPT-NEXT:    GIR_Done,
1128 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
1130 def : Pat<(i32 (bitconvert FPR32:$src1)),
1131           (COPY_TO_REGCLASS FPR32:$src1, GPR32)>;
1133 //===- Test a simple pattern with just a leaf immediate. ------------------===//
1135 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
1136 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
1137 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT,
1138 // NOOPT-NEXT:    // MIs[0] dst
1139 // NOOPT-NEXT:    GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
1140 // NOOPT-NEXT:    GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID,
1141 // NOOPT-NEXT:    // MIs[0] Operand 1
1142 // NOOPT-NEXT:    // No operand predicates
1143 // NOOPT-NEXT:    // (imm:{ *:[i32] }):$imm =>  (MOVimm:{ *:[i32] } (imm:{ *:[i32] }):$imm)
1144 // NOOPT-NEXT:    GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm,
1145 // NOOPT-NEXT:    GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst
1146 // NOOPT-NEXT:    GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm
1147 // NOOPT-NEXT:    GIR_EraseFromParent, /*InsnID*/0,
1148 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
1149 // NOOPT-NEXT:    // GIR_Coverage, 16,
1150 // NOOPT-NEXT:    GIR_Done,
1151 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
1153 def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm)]>;
1155 def fpimmz : FPImmLeaf<f32, [{ return Imm->isExactlyValue(0.0); }]>;
1156 def MOVfpimmz : I<(outs FPR32:$dst), (ins f32imm:$imm), [(set FPR32:$dst, fpimmz:$imm)]>;
1158 //===- Test a pattern with an MBB operand. --------------------------------===//
1160 // NOOPT-NEXT:  GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ [[LABEL:[0-9]+]],
1161 // NOOPT-NEXT:    GIM_CheckNumOperands, /*MI*/0, /*Expected*/1,
1162 // NOOPT-NEXT:    GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR,
1163 // NOOPT-NEXT:    // MIs[0] target
1164 // NOOPT-NEXT:    GIM_CheckIsMBB, /*MI*/0, /*Op*/0,
1165 // NOOPT-NEXT:    // (br (bb:{ *:[Other] }):$target) => (BR (bb:{ *:[Other] }):$target)
1166 // NOOPT-NEXT:    GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::BR,
1167 // NOOPT-NEXT:    GIR_ConstrainSelectedInstOperands, /*InsnID*/0,
1168 // NOOPT-NEXT:    // GIR_Coverage, 18,
1169 // NOOPT-NEXT:    GIR_Done,
1170 // NOOPT-NEXT:  // Label [[LABEL_NUM]]: @[[LABEL]]
1172 def BR : I<(outs), (ins unknown:$target),
1173             [(br bb:$target)]>;
1175 // NOOPT-NEXT:    GIM_Reject,
1176 // NOOPT-NEXT:  };
1177 // NOOPT-NEXT:  return MatchTable0;