1262 lines · plain
1// RUN: llvm-tblgen -gen-global-isel -I %p/../../../include -I %p/../Common -optimize-match-table=false %s -o %t.non-optimized.cpp2// RUN: llvm-tblgen -gen-global-isel -I %p/../../../include -I %p/../Common -optimize-match-table=true %s -o %t.optimized.cpp3// RUN: llvm-tblgen -gen-global-isel -I %p/../../../include -I %p/../Common %s -o %t.default.cpp4 5// RUN: FileCheck %s --check-prefixes=CHECK,R19C,R19N -input-file=%t.non-optimized.cpp6// RUN: FileCheck %s --check-prefixes=CHECK,R19C,R19O -input-file=%t.optimized.cpp7 8// RUN: FileCheck %s --check-prefixes=CHECK,R21C,R21N -input-file=%t.non-optimized.cpp9// RUN: FileCheck %s --check-prefixes=CHECK,R21C,R21O -input-file=%t.optimized.cpp10 11// RUN: FileCheck %s --check-prefixes=CHECK,R20C,R20N -input-file=%t.non-optimized.cpp12// RUN: FileCheck %s --check-prefixes=CHECK,R20C,R20O -input-file=%t.optimized.cpp13 14// RUN: FileCheck %s --check-prefixes=CHECK,R00C,R00N -input-file=%t.non-optimized.cpp15// RUN: FileCheck %s --check-prefixes=CHECK,R00C,R00O -input-file=%t.optimized.cpp16 17// RUN: FileCheck %s --check-prefixes=CHECK,R01C,R01N -input-file=%t.non-optimized.cpp18// RUN: FileCheck %s --check-prefixes=CHECK,R01C,R01O -input-file=%t.optimized.cpp19 20// RUN: FileCheck %s --check-prefixes=CHECK,R02C,R02N,NOOPT -input-file=%t.non-optimized.cpp21// RUN: FileCheck %s --check-prefixes=CHECK,R02C,R02O -input-file=%t.optimized.cpp22 23// RUN: diff %t.default.cpp %t.optimized.cpp24 25include "llvm/Target/Target.td"26include "GlobalISelEmitterCommon.td"27 28//===- Define the necessary boilerplate for our test target. --------------===//29 30let TargetPrefix = "mytarget" in {31def int_mytarget_nop : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;32}33 34def complex : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPattern", []> {35 let MIOperandInfo = (ops i32imm, i32imm);36}37def gi_complex :38 GIComplexOperandMatcher<s32, "selectComplexPattern">,39 GIComplexPatternEquiv<complex>;40def complex_rr : Operand<i32>, ComplexPattern<i32, 2, "SelectComplexPatternRR", []> {41 let MIOperandInfo = (ops GPR32, GPR32);42}43def gi_complex_rr :44 GIComplexOperandMatcher<s32, "selectComplexPatternRR">,45 GIComplexPatternEquiv<complex_rr>;46 47def cimm8_xform : SDNodeXForm<imm, [{48 uint64_t Val = N->getZExtValue() << 1;49 return CurDAG->getTargetConstant(Val, SDLoc(N), MVT::i64);50 }]>;51 52def cimm8 : Operand<i32>, ImmLeaf<i32, [{return isInt<8>(Imm);}], cimm8_xform>;53 54def gi_cimm8 : GICustomOperandRenderer<"renderImm">,55 GISDNodeXFormEquiv<cimm8_xform>;56 57def gi_cimm9 : GICustomOperandRenderer<"renderImm">;58 59def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>;60def Z : OperandWithDefaultOps <i32, (ops R0)>;61def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>;62def mb : OperandWithDefaultOps <i32, (ops (i32 0b1101))>;63 64def HasA : Predicate<"Subtarget->hasA()">;65def HasB : Predicate<"Subtarget->hasB()">;66def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }67 68//===- Test the function boilerplate. -------------------------------------===//69 70// CHECK: const unsigned MAX_SUBTARGET_PREDICATES = 3;71// CHECK: using PredicateBitset = llvm::Bitset<MAX_SUBTARGET_PREDICATES>;72 73// CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_DECL74// 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 testMOPredicate_MO(unsigned PredicateID, const MachineOperand &MO, const MatcherState &State) const override;86// CHECK-NEXT: bool testSimplePredicate(unsigned PredicateID) const override;87// CHECK-NEXT: bool runCustomAction(unsigned FnID, const MatcherState &State, NewMIVector &OutMIs) const override;88// CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL89 90// CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT91// CHECK-NEXT: , State(3),92// CHECK-NEXT: ExecInfo(TypeObjects, NumTypeObjects, FeatureBitsets, ComplexPredicateFns, CustomRenderers)93// CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT94 95// CHECK-LABEL: // LLT Objects.96// CHECK-NEXT: enum {97// CHECK-NEXT: GILLT_p0s3298// CHECK-NEXT: GILLT_s32,99// CHECK-NEXT: }100// CHECK-NEXT: const static size_t NumTypeObjects = 2;101// CHECK-NEXT: const static LLT TypeObjects[] = {102// CHECK-NEXT: LLT::pointer(0, 32),103// CHECK-NEXT: LLT::scalar(32),104// CHECK-NEXT: };105 106// CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {107// CHECK-NEXT: Feature_HasABit = 0,108// CHECK-NEXT: Feature_HasBBit = 1,109// CHECK-NEXT: Feature_HasCBit = 2,110// CHECK-NEXT: };111 112// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::113// CHECK-NEXT: computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const {114// CHECK-NEXT: PredicateBitset Features{};115// CHECK-NEXT: if (Subtarget->hasA())116// CHECK-NEXT: Features.set(Feature_HasABit);117// CHECK-NEXT: if (Subtarget->hasB())118// CHECK-NEXT: Features.set(Feature_HasBBit);119// CHECK-NEXT: return Features;120// CHECK-NEXT: }121 122// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::123// CHECK-NEXT: computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const {124// CHECK-NEXT: PredicateBitset Features{};125// CHECK-NEXT: if (Subtarget->hasC())126// CHECK-NEXT: Features.set(Feature_HasCBit);127// CHECK-NEXT: return Features;128// CHECK-NEXT: }129 130// CHECK-LABEL: // Feature bitsets.131// CHECK-NEXT: enum {132// CHECK-NEXT: GIFBS_Invalid,133// CHECK-NEXT: GIFBS_HasA,134// CHECK-NEXT: GIFBS_HasA_HasB_HasC,135// CHECK-NEXT: }136// CHECK-NEXT: constexpr static PredicateBitset FeatureBitsets[] {137// CHECK-NEXT: {}, // GIFBS_Invalid138// CHECK-NEXT: {Feature_HasABit, },139// CHECK-NEXT: {Feature_HasABit, Feature_HasBBit, Feature_HasCBit, },140// CHECK-NEXT: };141 142// CHECK-LABEL: // ComplexPattern predicates.143// CHECK-NEXT: enum {144// CHECK-NEXT: GICP_Invalid,145// CHECK-NEXT: GICP_gi_complex,146// CHECK-NEXT: GICP_gi_complex_rr,147// CHECK-NEXT: };148 149// CHECK-LABEL: MyTargetInstructionSelector::ComplexMatcherMemFn150// CHECK-NEXT: MyTargetInstructionSelector::ComplexPredicateFns[] = {151// CHECK-NEXT: nullptr, // GICP_Invalid152// CHECK-NEXT: &MyTargetInstructionSelector::selectComplexPattern, // gi_complex153// CHECK-NEXT: &MyTargetInstructionSelector::selectComplexPatternRR, // gi_complex_rr154// CHECK-NEXT: }155 156// CHECK-LABEL: // PatFrag predicates.157// CHECK-NEXT: enum {158// CHECK-NEXT: GICXXPred_MI_Predicate_frag = GICXXPred_Invalid + 1,159// CHECK-NEXT: GICXXPred_MI_Predicate_or_disjoint,160// CHECK-NEXT: };161 162// CHECK-LABEL: // PatFrag predicates.163// CHECK-NEXT: enum {164// CHECK-NEXT: GICXXPred_MO_Predicate_leaf = GICXXPred_Invalid + 1,165// CHECK-NEXT: };166 167// CHECK-LABEL: bool MyTargetInstructionSelector::testMOPredicate_MO(unsigned PredicateID, const MachineOperand & MO, const MatcherState &State) const {168// CHECK-NEXT: const auto &Operands = State.RecordedOperands; 169// CHECK-NEXT: Register Reg = MO.getReg();170// CHECK-NEXT: (void)Operands; 171// CHECK-NEXT: (void)Reg;172// CHECK-NEXT: switch (PredicateID) {173// CHECK-NEXT: case GICXXPred_MO_Predicate_leaf: {174// CHECK-NEXT: return true;175// CHECK-NEXT: }176// CHECK-NEXT: }177// CHECK-NEXT: llvm_unreachable("Unknown predicate");178// CHECK-NEXT: return false;179// CHECK-NEXT: }180 181 182// CHECK-LABEL: // PatFrag predicates.183// CHECK-NEXT: enum {184// CHECK-NEXT: GICXXPred_I64_Predicate_cimm8 = GICXXPred_Invalid + 1,185// CHECK-NEXT: GICXXPred_I64_Predicate_simm8,186// CHECK-NEXT: };187 188// CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const {189// CHECK-NEXT: switch (PredicateID) {190// CHECK-NEXT: case GICXXPred_I64_Predicate_cimm8: {191// CHECK-NEXT: return isInt<8>(Imm);192// CHECK-NEXT: }193// CHECK-NEXT: case GICXXPred_I64_Predicate_simm8: {194// CHECK-NEXT: return isInt<8>(Imm);195// CHECK-NEXT: }196// CHECK-NEXT: }197// CHECK-NEXT: llvm_unreachable("Unknown predicate");198// CHECK-NEXT: return false;199// CHECK-NEXT: }200 201// CHECK-LABEL: // PatFrag predicates.202// CHECK-NEXT: enum {203// CHECK-NEXT: GICXXPred_APFloat_Predicate_fpimmz = GICXXPred_Invalid + 1,204// CHECK-NEXT: };205// CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_APFloat(unsigned PredicateID, const APFloat & Imm) const {206// CHECK-NEXT: switch (PredicateID) {207// CHECK-NEXT: case GICXXPred_APFloat_Predicate_fpimmz: {208// CHECK-NEXT: return Imm->isExactlyValue(0.0);209// CHECK-NEXT: }210// CHECK-NEXT: }211// CHECK-NEXT: llvm_unreachable("Unknown predicate");212// CHECK-NEXT: return false;213// CHECK-NEXT: }214 215// CHECK-LABEL: // PatFrag predicates.216// CHECK-NEXT: enum {217// CHECK-NEXT: GICXXPred_APInt_Predicate_simm9 = GICXXPred_Invalid + 1,218// CHECK-NEXT: };219// CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_APInt(unsigned PredicateID, const APInt & Imm) const {220// CHECK-NEXT: switch (PredicateID) {221// CHECK-NEXT: case GICXXPred_APInt_Predicate_simm9: {222// CHECK-NEXT: return isInt<9>(Imm->getSExtValue());223// CHECK-NEXT: }224// CHECK-NEXT: }225// CHECK-NEXT: llvm_unreachable("Unknown predicate");226// CHECK-NEXT: return false;227// CHECK-NEXT: }228 229// CHECK-LABEL: // Custom renderers.230// CHECK-NEXT: enum {231// CHECK-NEXT: GICR_Invalid,232// CHECK-NEXT: GICR_renderImm,233// CHECK-NEXT: };234// CHECK-NEXT: MyTargetInstructionSelector::CustomRendererFn235// CHECK-NEXT: MyTargetInstructionSelector::CustomRenderers[] = {236// CHECK-NEXT: nullptr, // GICR_Invalid237// CHECK-NEXT: &MyTargetInstructionSelector::renderImm,238// CHECK-NEXT: };239 240// CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const {241// CHECK-NEXT: const PredicateBitset AvailableFeatures = getAvailableFeatures();242// CHECK-NEXT: MachineIRBuilder B(I);243// CHECK-NEXT: State.MIs.clear();244// CHECK-NEXT: State.MIs.push_back(&I);245 246// CHECK: if (executeMatchTable(*this, State, ExecInfo, B, getMatchTable(), TII, MF->getRegInfo(), TRI, RBI, AvailableFeatures, &CoverageInfo)) {247// CHECK-NEXT: return true;248// CHECK-NEXT: }249 250// CHECK: const uint8_t *251// CHECK-LABEL: MyTargetInstructionSelector::getMatchTable() const {252// CHECK-NEXT: MatchTable0[] = {253 254//===- Test a pattern with multiple ComplexPatterns in multiple instrs ----===//255//256// 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]+]]),257// R19O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_ADD:[0-9]+]]),258// R19O: /*TargetOpcode::G_SELECT*//*Label [[CASE_SELECT_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_SELECT:[0-9]+]]),259// R19O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]260// R19O: // Label [[CASE_SELECT_NUM]]: @[[CASE_SELECT]]261// R19O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ GIMT_Encode4([[GROUP:[0-9]+]]),262// R19O-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,263// R19O-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,264// R19O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,265// R19O-NEXT: GIM_RootCheckType, /*Op*/3, /*Type*/GILLT_s32,266//267// R19C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),268//269// R19O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),270// R19O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),271// R19N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,272// R19N-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SELECT),273// R19N-NEXT: // MIs[0] DstI[dst]274// R19N-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,275// R19N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),276// R19N-NEXT: // MIs[0] src1277// R19N-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,278// R19N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),279// R19N-NEXT: // MIs[0] complex_rr:src2a:src2b280// R19N-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,281//282// R19N-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/GIMT_Encode2(0), GIMT_Encode2(GICP_gi_complex_rr),283// R19N-NEXT: // MIs[0] Operand 3284// R19N-NEXT: GIM_RootCheckType, /*Op*/3, /*Type*/GILLT_s32,285// R19C-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/3, // MIs[1]286// R19N-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/4,287// R19C-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_SELECT),288// R19N-NEXT: // MIs[1] Operand 0289// R19N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,290// R19N-NEXT: // MIs[1] src3291// R19C-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,292// R19O-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,293// R19O-NEXT: GIM_CheckType, /*MI*/1, /*Op*/3, /*Type*/GILLT_s32,294// R19N-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),295// R19N-NEXT: // MIs[1] src4296// R19N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,297// R19N-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/2, /*Renderer*/GIMT_Encode2(1), GIMT_Encode2(GICP_gi_complex),298// R19N-NEXT: // MIs[1] complex:src5a:src5b299// R19N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/3, /*Type*/GILLT_s32,300// R19N-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/3, /*Renderer*/GIMT_Encode2(2), GIMT_Encode2(GICP_gi_complex),301// R19O-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),302// R19C-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,303// R19O-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/GIMT_Encode2(0), GIMT_Encode2(GICP_gi_complex_rr),304// R19O-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/2, /*Renderer*/GIMT_Encode2(1), GIMT_Encode2(GICP_gi_complex),305// R19O-NEXT: GIM_CheckComplexPattern, /*MI*/1, /*Op*/3, /*Renderer*/GIMT_Encode2(2), GIMT_Encode2(GICP_gi_complex),306// 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))307// R19C-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/GILLT_s32,308// R19C-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(MyTarget::INSN4),309// R19C-NEXT: GIR_AddTempRegister, /*InsnID*/1, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(RegState::Define),310// R19C-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // src3311// R19C-NEXT: GIR_ComplexRenderer, /*InsnID*/1, /*RendererID*/GIMT_Encode2(1),312// R19C-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/1, /*RendererID*/GIMT_Encode2(2), /*SubOperand*/0, // src5a313// R19C-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/1, /*RendererID*/GIMT_Encode2(2), /*SubOperand*/1, // src5b314// R19C-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/1,315// R19C-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::INSN3),316// R19C-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]317// R19C-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1318// R19C-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/GIMT_Encode2(0), /*SubOperand*/1, // src2b319// R19C-NEXT: GIR_ComplexSubOperandRenderer, /*InsnID*/0, /*RendererID*/GIMT_Encode2(0), /*SubOperand*/0, // src2a320// R19C-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/0, /*TempRegID*/0,321// R19C-NEXT: GIR_RootConstrainSelectedInstOperands,322// R19C-NEXT: // GIR_Coverage, 20,323// R19C-NEXT: GIR_EraseRootFromParent_Done,324// R19C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]325//326// R19O: // Label [[GROUP_NUM]]: @[[GROUP]]327// R19O-NEXT: GIM_Reject,328// R19O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]329// R19O-NEXT: GIM_Reject,330// R19O-NEXT: };331 332def INSN3 : I<(outs GPR32:$dst),333 (ins GPR32Op:$src1, GPR32:$src2a, GPR32:$src2b, GPR32:$scr), []>;334def INSN4 : I<(outs GPR32:$scr),335 (ins GPR32:$src3, complex:$src4, i32imm:$src5a, i32imm:$src5b), []>;336def : Pat<(select GPR32:$src1, (complex_rr GPR32:$src2a, GPR32:$src2b),337 (select GPR32:$src3,338 complex:$src4,339 (complex i32imm:$src5a, i32imm:$src5b))),340 (INSN3 GPR32:$src1, GPR32:$src2b, GPR32:$src2a,341 (INSN4 GPR32:$src3, complex:$src4, i32imm:$src5a,342 i32imm:$src5b))>;343 344// 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]+]]),345// R21O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_ADD:[0-9]+]]),346// R21O: /*TargetOpcode::G_SELECT*//*Label [[CASE_SELECT_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_SELECT:[0-9]+]]),347// R21O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]348// R21O: // Label [[CASE_SELECT_NUM]]: @[[CASE_SELECT]]349// R21O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ GIMT_Encode4([[GROUP:[0-9]+]]),350// R21O-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,351// R21O-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,352// R21O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,353// R21O-NEXT: GIM_RootCheckType, /*Op*/3, /*Type*/GILLT_s32,354//355// R21C-NEXT: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 20 //356// R21C-NOT: GIR_EraseRootFromParent_Done,357// R21C: // GIR_Coverage, 20,358// R21C-NEXT: GIR_EraseRootFromParent_Done,359// R21C-NEXT: // Label [[PREV_NUM]]: @[[PREV]]360// R21C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 22 //361//362// R21O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),363// R21O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),364// R21N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,365// R21N-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SELECT),366// R21N-NEXT: // MIs[0] DstI[dst]367// R21N-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,368// R21N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),369// R21N-NEXT: // MIs[0] src1370// R21N-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,371// R21N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),372// R21N-NEXT: // MIs[0] src2373// R21N-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,374//375// R21O-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_frag),376// R21C-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/GIMT_Encode2(0), GIMT_Encode2(GICP_gi_complex),377// R21N-NEXT: // MIs[0] src3378// R21N-NEXT: GIM_RootCheckType, /*Op*/3, /*Type*/GILLT_s32,379// R21C-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/3, /*Renderer*/GIMT_Encode2(1), GIMT_Encode2(GICP_gi_complex),380// R21N-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_frag),381// 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)382 383// R21C-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::INSN2),384// R21C-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]385// R21C-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1386// R21C-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/GIMT_Encode2(1),387// R21C-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/GIMT_Encode2(0),388// R21C-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*NumInsns*/1, /*MergeInsnID's*/0389// R21C-NEXT: GIR_RootConstrainSelectedInstOperands,390// R21C-NEXT: // GIR_Coverage, 22,391// R21C-NEXT: GIR_EraseRootFromParent_Done,392// R21C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]393//394// R21O-NEXT: GIM_Reject,395// R21O-NEXT: // Label [[GROUP_NUM]]: @[[GROUP]]396// R21O-NEXT: GIM_Reject,397// R21O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]398// R21O-NEXT: GIM_Reject,399// R21O-NEXT: };400 401//===- Test a pattern with ComplexPattern operands. -----------------------===//402//403// 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]+]]),404// R20O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_ADD:[0-9]+]]),405// R20O: /*TargetOpcode::G_SUB*//*Label [[CASE_SUB_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_SUB:[0-9]+]]),406// R20O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]407// R20O: // Label [[CASE_SUB_NUM]]: @[[CASE_SUB]]408// R20O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ GIMT_Encode4([[GROUP:[0-9]+]]),409// R20O-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,410// R20O-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,411// R20O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,412// R20O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),413//414// R20N: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 22 //415// R20N: // Label [[PREV_NUM]]: @[[PREV]]416//417// R20C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 21 //418//419// R20N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,420// R20N-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SUB),421// R20N-NEXT: // MIs[0] DstI[dst]422// R20N-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,423// R20N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),424// R20N-NEXT: // MIs[0] src1425// R20N-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,426//427// R20N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),428// R20N-NEXT: // MIs[0] src2429// R20N-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,430// R20O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),431// R20C-NEXT: GIM_CheckComplexPattern, /*MI*/0, /*Op*/2, /*Renderer*/GIMT_Encode2(0), GIMT_Encode2(GICP_gi_complex),432// R20C-NEXT: // (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2) => (INSN1:{ *:[i32] } GPR32:{ *:[i32] }:$src1, complex:{ *:[i32] }:$src2)433// R20C-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::INSN1),434// R20C-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]435// R20C-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1436// R20C-NEXT: GIR_ComplexRenderer, /*InsnID*/0, /*RendererID*/GIMT_Encode2(0),437// R20C-NEXT: GIR_RootConstrainSelectedInstOperands,438// R20C-NEXT: // GIR_Coverage, 21,439// R20C-NEXT: GIR_EraseRootFromParent_Done,440// R20C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]441//442// R20O: // Label [[GROUP_NUM]]: @[[GROUP]]443// R20O-NEXT: GIM_Reject,444// R20O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]445// R20O-NEXT: GIM_Reject,446// R20O-NEXT: };447 448def INSN1 : I<(outs GPR32:$dst), (ins GPR32:$src1, complex:$src2), []>;449def : Pat<(sub GPR32:$src1, complex:$src2), (INSN1 GPR32:$src1, complex:$src2)>;450 451//===- Test a pattern with multiple ComplexPattern operands. --------------===//452//453def : GINodeEquiv<G_SELECT, select>;454let mayLoad = 1 in {455 def INSN2 : I<(outs GPR32:$dst), (ins GPR32Op:$src1, complex:$src2, complex:$src3), []>;456}457def frag : PatFrag<(ops node:$a, node:$b, node:$c),458 (select node:$a, node:$b, node:$c),459 [{ return true; // C++ code }]> {460 let GISelPredicateCode = [{ return true; // C++ code }];461}462def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3),463 (INSN2 GPR32:$src1, complex:$src3, complex:$src2)>;464 465//===- Test a more complex multi-instruction match. -----------------------===//466//467// 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]+]]),468// R00O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_ADD:[0-9]+]]),469// R00O: /*TargetOpcode::G_SUB*//*Label [[CASE_SUB_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_SUB:[0-9]+]]),470// R00O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]471// R00O: // Label [[CASE_SUB_NUM]]: @[[CASE_SUB]]472// R00O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ GIMT_Encode4([[GROUP:[0-9]+]]),473// R00O-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,474// R00O-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,475// R00O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,476// R00O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),477//478// R00C: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 21 //479// R00C: // Label [[PREV_NUM]]: @[[PREV]]480//481// R00C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 0 //482// R00C-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HasA),483// R00N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,484// R00N-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SUB),485// R00N-NEXT: // MIs[0] DstI[dst]486// R00N-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,487// R00N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),488// R00N-NEXT: // MIs[0] Operand 1489// R00N-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,490// R00C-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]491// R00N-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,492// R00C-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_SUB),493// R00N-NEXT: // MIs[1] Operand 0494// R00N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,495// R00N-NEXT: // MIs[1] src1496// R00C-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,497// R00O-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,498// R00N-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),499// R00N-NEXT: // MIs[1] src2500// R00N-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,501// R00N-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),502// R00N-NEXT: // MIs[0] Operand 2503// R00N-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,504// R00O-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),505// R00O-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),506// R00C-NEXT: GIM_RecordInsn, /*DefineMI*/2, /*MI*/0, /*OpIdx*/2, // MIs[2]507// R00N-NEXT: GIM_CheckNumOperands, /*MI*/2, /*Expected*/3,508// R00C-NEXT: GIM_CheckOpcode, /*MI*/2, GIMT_Encode2(TargetOpcode::G_SUB),509// R00N-NEXT: // MIs[2] Operand 0510// R00N-NEXT: GIM_CheckType, /*MI*/2, /*Op*/0, /*Type*/GILLT_s32,511// R00N-NEXT: // MIs[2] src3512// R00C-NEXT: GIM_CheckType, /*MI*/2, /*Op*/1, /*Type*/GILLT_s32,513// R00O-NEXT: GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32,514// R00N-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),515// R00N-NEXT: // MIs[2] src4516// R00N-NEXT: GIM_CheckType, /*MI*/2, /*Op*/2, /*Type*/GILLT_s32,517// R00N-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),518// R00O-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),519// R00O-NEXT: GIM_CheckRegBankForClass, /*MI*/2, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),520// R00C-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/2,521// R00C-NEXT: // (sub:{ *:[i32] } (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2), (sub:{ *:[i32] } GPR32:{ *:[i32] }:$src3, GPR32:{ *:[i32] }:$src4)) => (INSNBOB:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src3, GPR32:{ *:[i32] }:$src4)522// R00C-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::INSNBOB),523// R00C-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]524// R00C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1525// R00C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2526// R00C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/1, // src3527// R00C-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/2, /*OpIdx*/2, // src4528// R00C-NEXT: GIR_RootConstrainSelectedInstOperands,529// R00C-NEXT: // GIR_Coverage, 0,530// R00C-NEXT: GIR_EraseRootFromParent_Done,531// R00C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]532//533// R00O: GIM_Reject,534// R00O-NEXT: // Label [[GROUP_NUM]]: @[[GROUP]]535// R00O-NEXT: GIM_Reject,536// R00O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]537// R00O-NEXT: GIM_Reject,538// R00O-NEXT: }; // Size: 1918 bytes539 540def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),541 [(set GPR32:$dst,542 (sub (sub GPR32:$src1, GPR32:$src2), (sub GPR32:$src3, GPR32:$src4)))]>,543 Requires<[HasA]>;544 545//===- Test a simple pattern with an intrinsic. ---------------------------===//546//547// 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]+]]),548// R01O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_ADD:[0-9]+]]),549// R01O: /*TargetOpcode::G_INTRINSIC*//*Label [[CASE_INTRINSIC_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_INTRINSIC:[0-9]+]]),550// R01O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]551// R01O: // Label [[CASE_INTRINSIC_NUM]]: @[[CASE_INTRINSIC]]552//553// R01N: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 0 //554// R01N: // Label [[PREV_NUM]]: @[[PREV]]555//556// R01C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 1 //557// R01C-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,558//559// R01O-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, GIMT_Encode2(Intrinsic::mytarget_nop),560// R01O-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,561// R01O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,562// R01O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),563//564// R01N-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_INTRINSIC),565// R01N-NEXT: // MIs[0] DstI[dst]566// R01N-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,567// R01N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),568// R01N-NEXT: // MIs[0] Operand 1569// R01N-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, GIMT_Encode2(Intrinsic::mytarget_nop),570// R01N-NEXT: // MIs[0] src1571// R01N-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,572//573// R01C-NEXT: GIM_RootCheckRegBankForClass, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),574// R01C-NEXT: // (intrinsic_wo_chain:{ *:[i32] } [[ID:[0-9]+]]:{ *:[iPTR] }, GPR32:{ *:[i32] }:$src1) => (MOV:{ *:[i32] } GPR32:{ *:[i32] }:$src1)575// R01C-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MOV),576// R01C-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]577// R01C-NEXT: GIR_RootToRootCopy, /*OpIdx*/2, // src1578// R01C-NEXT: GIR_RootConstrainSelectedInstOperands,579// R01C-NEXT: // GIR_Coverage, 1,580// R01C-NEXT: GIR_EraseRootFromParent_Done,581// R01C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]582//583// R01O-NEXT: GIM_Reject,584// R01O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]585// R01O-NEXT: GIM_Reject,586 587def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1),588 [(set GPR32:$dst, (int_mytarget_nop GPR32:$src1))]>;589 590//===- Test a simple pattern with a default operand. ----------------------===//591//592// 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]+]]),593// R02O-NEXT: /*TargetOpcode::G_ADD*//*Label [[CASE_ADD_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_ADD:[0-9]+]]),594// R02O: /*TargetOpcode::G_XOR*//*Label [[CASE_XOR_NUM:[0-9]+]]*/ GIMT_Encode4([[CASE_XOR:[0-9]+]]),595// R02O: // Label [[CASE_ADD_NUM]]: @[[CASE_ADD]]596// R02O: // Label [[CASE_XOR_NUM]]: @[[CASE_XOR]]597// R02O-NEXT: GIM_Try, /*On fail goto*//*Label [[GROUP_NUM:[0-9]+]]*/ GIMT_Encode4([[GROUP:[0-9]+]]),598// R02O-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,599// R02O-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,600// R02O-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,601// R02O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),602// R02O-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),603//604// R02N: GIM_Try, /*On fail goto*//*Label [[PREV_NUM:[0-9]+]]*/ GIMT_Encode4([[PREV:[0-9]+]]), // Rule ID 1 //605// R02N: // Label [[PREV_NUM]]: @[[PREV]]606//607// R02C-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]), // Rule ID 2 //608//609// R02N-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,610// R02N-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_XOR),611// R02N-NEXT: // MIs[0] DstI[dst]612// R02N-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,613// R02N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),614// R02N-NEXT: // MIs[0] src1615// R02N-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,616// R02N-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),617// R02N-NEXT: // MIs[0] Operand 2618// R02N-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,619//620// R02C-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 254,621// R02C-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -2:{ *:[i32] }) => (XORI:{ *:[i32] } GPR32:{ *:[i32] }:$src1)622// R02C-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XORI),623// R02C-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]624// R02C-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/255,625// R02C-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1626// R02C-NEXT: GIR_RootConstrainSelectedInstOperands,627// R02C-NEXT: // GIR_Coverage, 2,628// R02C-NEXT: GIR_EraseRootFromParent_Done,629// R02C-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]630//631// R02O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]632// R02O-NEXT: GIM_Reject,633 634// The -2 is just to distinguish it from the 'not' case below.635def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1),636 [(set GPR32:$dst, (xor GPR32:$src1, -2))]>;637 638//===- Test a simple pattern with a default register operand. -------------===//639//640// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),641// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,642// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_XOR),643// NOOPT-NEXT: // MIs[0] DstI[dst]644// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,645// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),646// NOOPT-NEXT: // MIs[0] src1647// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,648// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),649// NOOPT-NEXT: // MIs[0] Operand 2650// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,651// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 253,652// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -3:{ *:[i32] }) => (XOR:{ *:[i32] } GPR32:{ *:[i32] }:$src1)653// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XOR),654// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]655// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, GIMT_Encode2(MyTarget::R0),656// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1657// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,658// NOOPT-NEXT: // GIR_Coverage, 3,659// NOOPT-NEXT: GIR_EraseRootFromParent_Done,660// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]661 662// The -3 is just to distinguish it from the 'not' case below and the other default op case above.663def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1),664 [(set GPR32:$dst, (xor GPR32:$src1, -3))]>;665 666//===- Test a simple pattern with a multiple default operands. ------------===//667//668// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),669// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,670// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_XOR),671// NOOPT-NEXT: // MIs[0] DstI[dst]672// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,673// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),674// NOOPT-NEXT: // MIs[0] src1675// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,676// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),677// NOOPT-NEXT: // MIs[0] Operand 2678// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,679// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 252,680// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -4:{ *:[i32] }) => (XORlike:{ *:[i32] } GPR32:{ *:[i32] }:$src1)681// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XORlike),682// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]683// NOOPT-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/255,684// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, GIMT_Encode2(MyTarget::R0),685// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1686// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,687// NOOPT-NEXT: // GIR_Coverage, 4,688// NOOPT-NEXT: GIR_EraseRootFromParent_Done,689// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]690 691// The -4 is just to distinguish it from the other 'not' cases.692def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1),693 [(set GPR32:$dst, (xor GPR32:$src1, -4))]>;694 695//===- Test a simple pattern with multiple operands with defaults. --------===//696//697// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),698// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,699// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_XOR),700// NOOPT-NEXT: // MIs[0] DstI[dst]701// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,702// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),703// NOOPT-NEXT: // MIs[0] src1704// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,705// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),706// NOOPT-NEXT: // MIs[0] Operand 2707// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,708// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 251,709// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -5:{ *:[i32] }) => (XORManyDefaults:{ *:[i32] } GPR32:{ *:[i32] }:$src1)710// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XORManyDefaults),711// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]712// NOOPT-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/255,713// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, GIMT_Encode2(MyTarget::R0),714// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, GIMT_Encode2(MyTarget::R0),715// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1716// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,717// NOOPT-NEXT: // GIR_Coverage, 5,718// NOOPT-NEXT: GIR_EraseRootFromParent_Done,719// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]720 721// The -5 is just to distinguish it from the other cases.722def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1),723 [(set GPR32:$dst, (xor GPR32:$src1, -5))]>;724 725//===- Test a simple pattern with a default bits operand. -----------------===//726//727// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),728// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,729// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_XOR),730// NOOPT-NEXT: // MIs[0] DstI[dst]731// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,732// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),733// NOOPT-NEXT: // MIs[0] src1734// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,735// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),736// NOOPT-NEXT: // MIs[0] Operand 2737// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,738// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 250,739// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -6:{ *:[i32] }) => (XORIb:{ *:[i32] } GPR32:{ *:[i32] }:$src1)740// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XORIb),741// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]742// NOOPT-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/13,743// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1744// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,745// NOOPT-NEXT: // GIR_Coverage, 6,746// NOOPT-NEXT: GIR_EraseRootFromParent_Done,747// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]748 749// The -6 is just to distinguish it from the other cases.750def XORIb : I<(outs GPR32:$dst), (ins mb:$src2, GPR32:$src1),751 [(set GPR32:$dst, (xor GPR32:$src1, -6))]>;752 753//===- Test a simple pattern with constant immediate operands. ------------===//754//755// This must precede the 3-register variants because constant immediates have756// priority over register banks.757//758// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),759// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,760// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_XOR),761// NOOPT-NEXT: // MIs[0] DstI[dst]762// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,763// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),764// NOOPT-NEXT: // MIs[0] Wm765// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,766// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),767// NOOPT-NEXT: // MIs[0] Operand 2768// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,769// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 255,770// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$Wm, -1:{ *:[i32] }) => (ORN:{ *:[i32] } R0:{ *:[i32] }, GPR32:{ *:[i32] }:$Wm)771// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::ORN),772// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]773// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, GIMT_Encode2(MyTarget::R0),774// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // Wm775// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,776// NOOPT-NEXT: // GIR_Coverage, 23,777// NOOPT-NEXT: GIR_EraseRootFromParent_Done,778// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]779 780def ORN : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;781def : Pat<(not GPR32:$Wm), (ORN R0, GPR32:$Wm)>;782 783//===- Test a nested instruction match. -----------------------------------===//784//785// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),786// NOOPT-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HasA),787// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,788// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_MUL),789// NOOPT-NEXT: // MIs[0] DstI[dst]790// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,791// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),792// NOOPT-NEXT: // MIs[0] Operand 1793// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,794// NOOPT-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]795// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,796// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_ADD),797// NOOPT-NEXT: // MIs[1] Operand 0798// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,799// NOOPT-NEXT: // MIs[1] src1800// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,801// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),802// NOOPT-NEXT: // MIs[1] src2803// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,804// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),805// NOOPT-NEXT: // MIs[0] src3806// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,807// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),808// NOOPT-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,809// 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)810// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MULADD),811// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]812// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1813// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2814// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/2, // src3815// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,816// NOOPT-NEXT: // GIR_Coverage, 7,817// NOOPT-NEXT: GIR_EraseRootFromParent_Done,818// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]819 820// We also get a second rule by commutativity.821//822// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),823// NOOPT-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HasA),824// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,825// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_MUL),826// NOOPT-NEXT: // MIs[0] DstI[dst]827// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,828// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),829// NOOPT-NEXT: // MIs[0] src3830// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,831// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),832// NOOPT-NEXT: // MIs[0] Operand 2833// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,834// NOOPT-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2,835// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,836// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_ADD),837// NOOPT-NEXT: // MIs[1] Operand 0838// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,839// NOOPT-NEXT: // MIs[1] src1840// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,841// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),842// NOOPT-NEXT: // MIs[1] src2843// NOOPT-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,844// NOOPT-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),845// NOOPT-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,846// 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)847// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MULADD),848// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]849// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/1, // src1850// NOOPT-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/1, /*OpIdx*/2, // src2851// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src3852// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,853// NOOPT-NEXT: // GIR_Coverage, 29,854// NOOPT-NEXT: GIR_EraseRootFromParent_Done,855// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]856 857def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),858 [(set GPR32:$dst,859 (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,860 Requires<[HasA]>;861 862//===- Test a simple pattern with a PatLeaf and a predicate. ---------===//863//864// NOOPT-NEXT: /* 882 */ GIM_Try, /*On fail goto*//*Label 13*/ GIMT_Encode4(924), // Rule ID 24 //865// NOOPT-NEXT: /* 887 */ GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,866// NOOPT-NEXT: /* 890 */ GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SUB),867// NOOPT-NEXT: /* 894 */ // MIs[0] DstI[dst]868// NOOPT-NEXT: /* 894 */ GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,869// NOOPT-NEXT: /* 897 */ GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),870// NOOPT-NEXT: /* 901 */ // MIs[0] src1871// NOOPT-NEXT: /* 901 */ GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,872// NOOPT-NEXT: /* 904 */ GIM_CheckLeafOperandPredicate, /*MI*/0, /*MO*/1, /*Predicate*/GIMT_Encode2(GICXXPred_MO_Predicate_leaf),873// NOOPT-NEXT: /* 909 */ // MIs[0] src2874// NOOPT-NEXT: /* 909 */ GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,875// NOOPT-NEXT: /* 912 */ GIM_CheckLeafOperandPredicate, /*MI*/0, /*MO*/2, /*Predicate*/GIMT_Encode2(GICXXPred_MO_Predicate_leaf),876// NOOPT-NEXT: /* 917 */ // (sub:{ *:[i32] } GPR32:{ *:[i32] }<<P:Predicate_leaf>>:$src1, GPR32:{ *:[i32] }<<P:Predicate_leaf>>:$src2) => (INSN5:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2)877// NOOPT-NEXT: /* 917 */ GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::INSN5),878// NOOPT-NEXT: /* 922 */ GIR_RootConstrainSelectedInstOperands,879// NOOPT-NEXT: /* 923 */ // GIR_Coverage, 24,880// NOOPT-NEXT: /* 923 */ GIR_Done,881// NOOPT-NEXT: /* 924 */ // Label 13: @924882 883def leaf: PatLeaf<(i32 GPR32:$src), [{ return true; // C++ code }]> {884 let GISelLeafPredicateCode = [{ return true; }];885}886def INSN5 : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;887def : Pat<(sub leaf:$src1, leaf:$src2), (INSN5 GPR32:$src1, GPR32:$src2)>;888 889 890 891//===- Test a simple pattern with just a specific leaf immediate. ---------===//892//893// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),894// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,895// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_CONSTANT),896// NOOPT-NEXT: // MIs[0] DstI[dst]897// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,898// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),899// NOOPT-NEXT: // MIs[0] Operand 1900// NOOPT-NEXT: GIM_CheckLiteralInt, /*MI*/0, /*Op*/1, GIMT_Encode8(1),901// NOOPT-NEXT: // 1:{ *:[i32] } => (MOV1:{ *:[i32] })902// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MOV1),903// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]904// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,905// NOOPT-NEXT: // GIR_Coverage, 8,906// NOOPT-NEXT: GIR_EraseRootFromParent_Done,907// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]908 909def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>;910 911//===- Test a simple pattern with a leaf immediate and a predicate. -------===//912//913// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),914// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,915// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_CONSTANT),916// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIMT_Encode2(GICXXPred_I64_Predicate_simm8),917// NOOPT-NEXT: // MIs[0] DstI[dst]918// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,919// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),920// NOOPT-NEXT: // MIs[0] Operand 1921// NOOPT-NEXT: // No operand predicates922// NOOPT-NEXT: // (imm:{ *:[i32] })<<P:Predicate_simm8>>:$imm => (MOVimm8:{ *:[i32] } (imm:{ *:[i32] }):$imm)923// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MOVimm8),924// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]925// NOOPT-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm926// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,927// NOOPT-NEXT: // GIR_Coverage, 9,928// NOOPT-NEXT: GIR_EraseRootFromParent_Done,929// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]930 931def simm8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;932def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$imm)]>;933 934//===- Same again but use an IntImmLeaf. ----------------------------------===//935//936// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),937// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,938// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_CONSTANT),939// NOOPT-NEXT: GIM_CheckAPIntImmPredicate, /*MI*/0, /*Predicate*/GIMT_Encode2(GICXXPred_APInt_Predicate_simm9),940// NOOPT-NEXT: // MIs[0] DstI[dst]941// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,942// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),943// NOOPT-NEXT: // MIs[0] Operand 1944// NOOPT-NEXT: // No operand predicates945// NOOPT-NEXT: // (imm:{ *:[i32] })<<P:Predicate_simm9>>:$imm => (MOVimm9:{ *:[i32] } (imm:{ *:[i32] }):$imm)946// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MOVimm9),947// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]948// NOOPT-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm949// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,950// NOOPT-NEXT: // GIR_Coverage, 10,951// NOOPT-NEXT: GIR_EraseRootFromParent_Done,952// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]953 954def simm9 : IntImmLeaf<i32, [{ return isInt<9>(Imm->getSExtValue()); }]>;955def MOVimm9 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm9:$imm)]>;956 957//===- Test a pattern with a custom renderer. -----------------------------===//958//959// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),960// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,961// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_CONSTANT),962// NOOPT-NEXT: GIM_CheckI64ImmPredicate, /*MI*/0, /*Predicate*/GIMT_Encode2(GICXXPred_I64_Predicate_cimm8),963// NOOPT-NEXT: // MIs[0] DstI[dst]964// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,965// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),966// NOOPT-NEXT: // MIs[0] Operand 1967// NOOPT-NEXT: // No operand predicates968// NOOPT-NEXT: // (imm:{ *:[i32] })<<P:Predicate_cimm8>><<X:cimm8_xform>>:$imm => (MOVcimm8:{ *:[i32] } (cimm8_xform:{ *:[i32] } (imm:{ *:[i32] }):$imm))969// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MOVcimm8),970// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]971// NOOPT-NEXT: GIR_CustomRenderer, /*InsnID*/0, /*OldInsnID*/0, /*Renderer*/GIMT_Encode2(GICR_renderImm), // imm972// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,973// NOOPT-NEXT: // GIR_Coverage, 11,974// NOOPT-NEXT: GIR_EraseRootFromParent_Done,975// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]976 977def MOVcimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, cimm8:$imm)]>;978 979//===- Test a simple pattern with a FP immediate and a predicate. ---------===//980//981// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),982// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,983// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_FCONSTANT),984// NOOPT-NEXT: GIM_CheckAPFloatImmPredicate, /*MI*/0, /*Predicate*/GIMT_Encode2(GICXXPred_APFloat_Predicate_fpimmz),985// NOOPT-NEXT: // MIs[0] DstI[dst]986// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,987// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::FPR32RegClassID),988// NOOPT-NEXT: // MIs[0] Operand 1989// NOOPT-NEXT: // No operand predicates990// NOOPT-NEXT: // (fpimm:{ *:[f32] })<<P:Predicate_fpimmz>>:$imm => (MOVfpimmz:{ *:[f32] } (fpimm:{ *:[f32] }):$imm)991// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MOVfpimmz),992// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]993// NOOPT-NEXT: GIR_CopyFConstantAsFPImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm994// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,995// NOOPT-NEXT: // GIR_Coverage, 18,996// NOOPT-NEXT: GIR_EraseRootFromParent_Done,997// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]998 999//===- Test a simple pattern with inferred pointer operands. ---------------===//1000//1001// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1002// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,1003// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),1004// NOOPT-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,1005// NOOPT-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,1006// NOOPT-NEXT: // MIs[0] DstI[dst]1007// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,1008// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1009// NOOPT-NEXT: // MIs[0] src11010// NOOPT-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,1011// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1012// NOOPT-NEXT: // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1)1013// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::LOAD),1014// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1015// NOOPT-NEXT: // GIR_Coverage, 12,1016// NOOPT-NEXT: GIR_Done,1017// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1018 1019def LOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),1020 [(set GPR32:$dst, (load GPR32:$src1))]>;1021 1022//===- Test a simple pattern with explicit pointer operands. ---------------===//1023 1024// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1025// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,1026// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),1027// NOOPT-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,1028// NOOPT-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,1029// NOOPT-NEXT: // MIs[0] DstI[dst]1030// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_p0s32,1031// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1032// NOOPT-NEXT: // MIs[0] src1033// NOOPT-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,1034// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1035// NOOPT-NEXT: // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src)1036// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::LOAD),1037// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1038// NOOPT-NEXT: // GIR_Coverage, 25,1039// NOOPT-NEXT: GIR_Done,1040// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1041 1042def : Pat<(load GPR32:$src),1043 (p0 (LOAD GPR32:$src))>;1044 1045//===- Test a simple pattern with a sextload -------------------------------===//1046//1047// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1048// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,1049// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SEXTLOAD),1050// NOOPT-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,1051// NOOPT-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/GIMT_Encode4(2),1052// NOOPT-NEXT: // MIs[0] DstI[dst]1053// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,1054// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1055// NOOPT-NEXT: // MIs[0] src11056// NOOPT-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,1057// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1058// NOOPT-NEXT: // (ld:{ *:[i32] } GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedload>><<P:Predicate_sextload>><<P:Predicate_sextloadi16>> => (SEXTLOAD:{ *:[i32] } GPR32:{ *:[i32] }:$src1)1059// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::SEXTLOAD),1060// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1061// NOOPT-NEXT: // GIR_Coverage, 13,1062// NOOPT-NEXT: GIR_Done,1063// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1064 1065def SEXTLOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),1066 [(set GPR32:$dst, (sextloadi16 GPR32:$src1))]>;1067 1068//===- Test a simple pattern with regclass operands. ----------------------===//1069//1070// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1071// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,1072// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_ADD),1073// NOOPT-NEXT: // MIs[0] DstI[dst]1074// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,1075// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1076// NOOPT-NEXT: // MIs[0] src11077// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,1078// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID)1079// NOOPT-NEXT: // MIs[0] src21080// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,1081// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1082// NOOPT-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2)1083// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::ADD),1084// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1085// NOOPT-NEXT: // GIR_Coverage, 14,1086// NOOPT-NEXT: GIR_Done,1087// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1088 1089def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),1090 [(set GPR32:$dst, (add GPR32:$src1, GPR32:$src2))]>;1091 1092//===- Test a pattern with a tied operand in the matcher ------------------===//1093//1094// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1095// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,1096// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_ADD),1097// NOOPT-NEXT: // MIs[0] DstI[dst]1098// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,1099// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1100// NOOPT-NEXT: // MIs[0] src{{$}}1101// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,1102// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1103// NOOPT-NEXT: // MIs[0] src{{$}}1104// NOOPT-NEXT: GIM_CheckIsSameOperand, /*MI*/0, /*OpIdx*/2, /*OtherMI*/0, /*OtherOpIdx*/1,1105// NOOPT-NEXT: // (add:{ *:[i32] } GPR32:{ *:[i32] }:$src, GPR32:{ *:[i32] }:$src) => (DOUBLE:{ *:[i32] } GPR32:{ *:[i32] }:$src)1106// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::DOUBLE),1107// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]1108// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1109// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1110// NOOPT-NEXT: // GIR_Coverage, 15,1111// NOOPT-NEXT: GIR_EraseRootFromParent_Done,1112// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1113 1114def DOUBLE : I<(outs GPR32:$dst), (ins GPR32:$src), [(set GPR32:$dst, (add GPR32:$src, GPR32:$src))]>;1115 1116//===- Test a pattern with unintended operand name clash. ----------------===//1117 1118// Check that using the same name for1119// - Def operand of the instruction corresponding to the root node of the1120// pattern's destination1121// - one of operands in the pattern itself1122// does not introduce unexpected GIM_CheckIsSameOperand predicate.1123 1124// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1125// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,1126// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_ADD),1127// NOOPT-NEXT: // MIs[0] DstI[samename]1128// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,1129// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1130// NOOPT-NEXT: // MIs[0] samename1131// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,1132// NOOPT-NEXT: // MIs[0] othername1133// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,1134// NOOPT-NEXT: // (add:{ *:[i32] } i32:{ *:[i32] }:$samename, i32:{ *:[i32] }:$othername) => (InsnWithSpeciallyNamedDef:{ *:[i32] } i32:{ *:[i32] }:$samename, i32:{ *:[i32] }:$othername)1135// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::InsnWithSpeciallyNamedDef),1136// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1137// NOOPT-NEXT: // GIR_Coverage, 26,1138// NOOPT-NEXT: GIR_Done,1139// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1140 1141def InsnWithSpeciallyNamedDef : I<(outs GPR32:$samename), (ins GPR32:$src1, GPR32:$src2), []>;1142def : Pat<(add i32:$samename, i32:$othername),1143 (InsnWithSpeciallyNamedDef i32:$samename, i32:$othername)>;1144 1145//===- Test a simple pattern with ValueType operands. ----------------------===//1146//1147// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1148// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,1149// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_ADD),1150// NOOPT-NEXT: // MIs[0] DstI[dst]1151// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,1152// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1153// NOOPT-NEXT: // MIs[0] src11154// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,1155// NOOPT-NEXT: // MIs[0] src21156// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,1157// NOOPT-NEXT: // (add:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) => (ADD:{ *:[i32] } i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)1158// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::ADD),1159// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1160// NOOPT-NEXT: // GIR_Coverage, 27,1161// NOOPT-NEXT: GIR_Done,1162// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1163 1164def : Pat<(add i32:$src1, i32:$src2),1165 (ADD i32:$src1, i32:$src2)>;1166 1167//===- Test another simple pattern with regclass operands. ----------------===//1168//1169// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1170// NOOPT-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HasA_HasB_HasC),1171// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,1172// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_MUL),1173// NOOPT-NEXT: // MIs[0] DstI[dst]1174// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,1175// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1176// NOOPT-NEXT: // MIs[0] src11177// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,1178// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1179// NOOPT-NEXT: // MIs[0] src21180// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,1181// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1182// NOOPT-NEXT: // (mul:{ *:[i32] } GPR32:{ *:[i32] }:$src1, GPR32:{ *:[i32] }:$src2) => (MUL:{ *:[i32] } GPR32:{ *:[i32] }:$src2, GPR32:{ *:[i32] }:$src1)1183// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MUL),1184// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]1185// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/2, // src21186// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src11187// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1188// NOOPT-NEXT: // GIR_Coverage, 16,1189// NOOPT-NEXT: GIR_EraseRootFromParent_Done,1190// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1191 1192def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),1193 [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,1194 Requires<[HasA, HasB, HasC]>;1195 1196//===- Test a COPY_TO_REGCLASS --------------------------------------------===//1197//1198//1199// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1200// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,1201// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_BITCAST),1202// NOOPT-NEXT: // MIs[0] DstI[dst]1203// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,1204// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1205// NOOPT-NEXT: // MIs[0] src11206// NOOPT-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32,1207// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::FPR32RegClassID),1208// NOOPT-NEXT: // (bitconvert:{ *:[i32] } FPR32:{ *:[f32] }:$src1) => (COPY_TO_REGCLASS:{ *:[i32] } FPR32:{ *:[f32] }:$src1, GPR32:{ *:[i32] })1209// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),1210// NOOPT-NEXT: GIR_ConstrainOperandRC, /*InsnID*/0, /*Op*/0, GIMT_Encode2(MyTarget::GPR32RegClassID),1211// NOOPT-NEXT: // GIR_Coverage, 28,1212// NOOPT-NEXT: GIR_Done,1213// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1214 1215def : Pat<(i32 (bitconvert FPR32:$src1)),1216 (COPY_TO_REGCLASS FPR32:$src1, GPR32)>;1217 1218//===- Test a simple pattern with just a leaf immediate. ------------------===//1219//1220// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1221// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,1222// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_CONSTANT),1223// NOOPT-NEXT: // MIs[0] DstI[dst]1224// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,1225// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),1226// NOOPT-NEXT: // MIs[0] Operand 11227// NOOPT-NEXT: // No operand predicates1228// NOOPT-NEXT: // (imm:{ *:[i32] }):$imm => (MOVimm:{ *:[i32] } (imm:{ *:[i32] }):$imm)1229// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MOVimm),1230// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]1231// NOOPT-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm1232// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1233// NOOPT-NEXT: // GIR_Coverage, 17,1234// NOOPT-NEXT: GIR_EraseRootFromParent_Done,1235// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1236 1237def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm)]>;1238 1239def fpimmz : FPImmLeaf<f32, [{ return Imm->isExactlyValue(0.0); }]>;1240def MOVfpimmz : I<(outs FPR32:$dst), (ins f32imm:$imm), [(set FPR32:$dst, fpimmz:$imm)]>;1241 1242//===- Test a pattern with an MBB operand. --------------------------------===//1243//1244// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),1245// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/1,1246// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_BR),1247// NOOPT-NEXT: // MIs[0] target1248// NOOPT-NEXT: GIM_CheckIsMBB, /*MI*/0, /*Op*/0,1249// NOOPT-NEXT: // (br (bb:{ *:[Other] }):$target) => (BR (bb:{ *:[Other] }):$target)1250// NOOPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::BR),1251// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,1252// NOOPT-NEXT: // GIR_Coverage, 19,1253// NOOPT-NEXT: GIR_Done,1254// NOOPT-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]1255 1256def BR : I<(outs), (ins unknown:$target),1257 [(br bb:$target)]>;1258 1259// NOOPT-NEXT: GIM_Reject,1260// NOOPT-NEXT: }; // Size: 1501 bytes1261// NOOPT-NEXT: return MatchTable0;1262