xref: /openbsd-src/gnu/llvm/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h --------*- C++ -*-===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick /// \file This file declares the API for the instruction selector.
1009467b48Spatrick /// This class is responsible for selecting machine instructions.
1109467b48Spatrick /// It's implemented by the target. It's used by the InstructionSelect pass.
1209467b48Spatrick //
1309467b48Spatrick //===----------------------------------------------------------------------===//
1409467b48Spatrick 
1509467b48Spatrick #ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
1609467b48Spatrick #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
1709467b48Spatrick 
1809467b48Spatrick #include "llvm/ADT/SmallVector.h"
1909467b48Spatrick #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
2009467b48Spatrick #include "llvm/CodeGen/GlobalISel/Utils.h"
2109467b48Spatrick #include "llvm/CodeGen/MachineInstrBuilder.h"
2209467b48Spatrick #include "llvm/CodeGen/MachineOperand.h"
2309467b48Spatrick #include "llvm/CodeGen/MachineRegisterInfo.h"
24*d415bd75Srobert #include "llvm/CodeGen/RegisterBankInfo.h"
2509467b48Spatrick #include "llvm/CodeGen/TargetInstrInfo.h"
2609467b48Spatrick #include "llvm/CodeGen/TargetOpcodes.h"
2709467b48Spatrick #include "llvm/CodeGen/TargetRegisterInfo.h"
2809467b48Spatrick #include "llvm/IR/Constants.h"
2909467b48Spatrick #include "llvm/IR/DataLayout.h"
30*d415bd75Srobert #include "llvm/Support/CodeGenCoverage.h"
3109467b48Spatrick #include "llvm/Support/Debug.h"
3209467b48Spatrick #include "llvm/Support/ErrorHandling.h"
3309467b48Spatrick #include "llvm/Support/raw_ostream.h"
3409467b48Spatrick #include <cassert>
3509467b48Spatrick #include <cstddef>
3609467b48Spatrick #include <cstdint>
3709467b48Spatrick 
3809467b48Spatrick namespace llvm {
3909467b48Spatrick 
4009467b48Spatrick /// GlobalISel PatFrag Predicates
4109467b48Spatrick enum {
4209467b48Spatrick   GIPFP_I64_Invalid = 0,
4309467b48Spatrick   GIPFP_APInt_Invalid = 0,
4409467b48Spatrick   GIPFP_APFloat_Invalid = 0,
4509467b48Spatrick   GIPFP_MI_Invalid = 0,
4609467b48Spatrick };
4709467b48Spatrick 
4809467b48Spatrick template <class TgtInstructionSelector, class PredicateBitset,
4909467b48Spatrick           class ComplexMatcherMemFn, class CustomRendererFn>
executeMatchTable(TgtInstructionSelector & ISel,NewMIVector & OutMIs,MatcherState & State,const ISelInfoTy<PredicateBitset,ComplexMatcherMemFn,CustomRendererFn> & ISelInfo,const int64_t * MatchTable,const TargetInstrInfo & TII,MachineRegisterInfo & MRI,const TargetRegisterInfo & TRI,const RegisterBankInfo & RBI,const PredicateBitset & AvailableFeatures,CodeGenCoverage & CoverageInfo)5009467b48Spatrick bool InstructionSelector::executeMatchTable(
5109467b48Spatrick     TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
5209467b48Spatrick     const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
5309467b48Spatrick         &ISelInfo,
5409467b48Spatrick     const int64_t *MatchTable, const TargetInstrInfo &TII,
5509467b48Spatrick     MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
5609467b48Spatrick     const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures,
5709467b48Spatrick     CodeGenCoverage &CoverageInfo) const {
5809467b48Spatrick 
5909467b48Spatrick   uint64_t CurrentIdx = 0;
6009467b48Spatrick   SmallVector<uint64_t, 4> OnFailResumeAt;
6109467b48Spatrick 
62097a140dSpatrick   // Bypass the flag check on the instruction, and only look at the MCInstrDesc.
63097a140dSpatrick   bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
64097a140dSpatrick 
65097a140dSpatrick   const uint16_t Flags = State.MIs[0]->getFlags();
66097a140dSpatrick 
6709467b48Spatrick   enum RejectAction { RejectAndGiveUp, RejectAndResume };
6809467b48Spatrick   auto handleReject = [&]() -> RejectAction {
6909467b48Spatrick     DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
7009467b48Spatrick                     dbgs() << CurrentIdx << ": Rejected\n");
7109467b48Spatrick     if (OnFailResumeAt.empty())
7209467b48Spatrick       return RejectAndGiveUp;
7309467b48Spatrick     CurrentIdx = OnFailResumeAt.pop_back_val();
7409467b48Spatrick     DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
7509467b48Spatrick                     dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " ("
7609467b48Spatrick                            << OnFailResumeAt.size() << " try-blocks remain)\n");
7709467b48Spatrick     return RejectAndResume;
7809467b48Spatrick   };
7909467b48Spatrick 
80097a140dSpatrick   auto propagateFlags = [=](NewMIVector &OutMIs) {
81097a140dSpatrick     for (auto MIB : OutMIs) {
82097a140dSpatrick       // Set the NoFPExcept flag when no original matched instruction could
83097a140dSpatrick       // raise an FP exception, but the new instruction potentially might.
84097a140dSpatrick       uint16_t MIBFlags = Flags;
85097a140dSpatrick       if (NoFPException && MIB->mayRaiseFPException())
86097a140dSpatrick         MIBFlags |= MachineInstr::NoFPExcept;
87097a140dSpatrick       MIB.setMIFlags(MIBFlags);
88097a140dSpatrick     }
89097a140dSpatrick 
90097a140dSpatrick     return true;
91097a140dSpatrick   };
92097a140dSpatrick 
9309467b48Spatrick   while (true) {
9409467b48Spatrick     assert(CurrentIdx != ~0u && "Invalid MatchTable index");
9509467b48Spatrick     int64_t MatcherOpcode = MatchTable[CurrentIdx++];
9609467b48Spatrick     switch (MatcherOpcode) {
9709467b48Spatrick     case GIM_Try: {
9809467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
9909467b48Spatrick                       dbgs() << CurrentIdx << ": Begin try-block\n");
10009467b48Spatrick       OnFailResumeAt.push_back(MatchTable[CurrentIdx++]);
10109467b48Spatrick       break;
10209467b48Spatrick     }
10309467b48Spatrick 
10409467b48Spatrick     case GIM_RecordInsn: {
10509467b48Spatrick       int64_t NewInsnID = MatchTable[CurrentIdx++];
10609467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
10709467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
10809467b48Spatrick 
10909467b48Spatrick       // As an optimisation we require that MIs[0] is always the root. Refuse
11009467b48Spatrick       // any attempt to modify it.
11109467b48Spatrick       assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
11209467b48Spatrick 
11309467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
11409467b48Spatrick       if (!MO.isReg()) {
11509467b48Spatrick         DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
11609467b48Spatrick                         dbgs() << CurrentIdx << ": Not a register\n");
11709467b48Spatrick         if (handleReject() == RejectAndGiveUp)
11809467b48Spatrick           return false;
11909467b48Spatrick         break;
12009467b48Spatrick       }
121*d415bd75Srobert       if (MO.getReg().isPhysical()) {
12209467b48Spatrick         DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
12309467b48Spatrick                         dbgs() << CurrentIdx << ": Is a physical register\n");
12409467b48Spatrick         if (handleReject() == RejectAndGiveUp)
12509467b48Spatrick           return false;
12609467b48Spatrick         break;
12709467b48Spatrick       }
12809467b48Spatrick 
12909467b48Spatrick       MachineInstr *NewMI = MRI.getVRegDef(MO.getReg());
13009467b48Spatrick       if ((size_t)NewInsnID < State.MIs.size())
13109467b48Spatrick         State.MIs[NewInsnID] = NewMI;
13209467b48Spatrick       else {
13309467b48Spatrick         assert((size_t)NewInsnID == State.MIs.size() &&
13409467b48Spatrick                "Expected to store MIs in order");
13509467b48Spatrick         State.MIs.push_back(NewMI);
13609467b48Spatrick       }
13709467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
13809467b48Spatrick                       dbgs() << CurrentIdx << ": MIs[" << NewInsnID
13909467b48Spatrick                              << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
14009467b48Spatrick                              << ")\n");
14109467b48Spatrick       break;
14209467b48Spatrick     }
14309467b48Spatrick 
14409467b48Spatrick     case GIM_CheckFeatures: {
14509467b48Spatrick       int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
14609467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
14709467b48Spatrick                       dbgs() << CurrentIdx
14809467b48Spatrick                              << ": GIM_CheckFeatures(ExpectedBitsetID="
14909467b48Spatrick                              << ExpectedBitsetID << ")\n");
15009467b48Spatrick       if ((AvailableFeatures & ISelInfo.FeatureBitsets[ExpectedBitsetID]) !=
15109467b48Spatrick           ISelInfo.FeatureBitsets[ExpectedBitsetID]) {
15209467b48Spatrick         if (handleReject() == RejectAndGiveUp)
15309467b48Spatrick           return false;
15409467b48Spatrick       }
15509467b48Spatrick       break;
15609467b48Spatrick     }
15709467b48Spatrick 
15873471bf0Spatrick     case GIM_CheckOpcode:
15973471bf0Spatrick     case GIM_CheckOpcodeIsEither: {
16009467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
16173471bf0Spatrick       int64_t Expected0 = MatchTable[CurrentIdx++];
16273471bf0Spatrick       int64_t Expected1 = -1;
16373471bf0Spatrick       if (MatcherOpcode == GIM_CheckOpcodeIsEither)
16473471bf0Spatrick         Expected1 = MatchTable[CurrentIdx++];
16509467b48Spatrick 
16609467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
16709467b48Spatrick       unsigned Opcode = State.MIs[InsnID]->getOpcode();
16809467b48Spatrick 
16909467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
17009467b48Spatrick         dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
17173471bf0Spatrick         << "], ExpectedOpcode=" << Expected0;
17273471bf0Spatrick         if (MatcherOpcode == GIM_CheckOpcodeIsEither)
17373471bf0Spatrick           dbgs() << " || " << Expected1;
17473471bf0Spatrick         dbgs() << ") // Got=" << Opcode << "\n";
17573471bf0Spatrick       );
17673471bf0Spatrick 
17773471bf0Spatrick       if (Opcode != Expected0 && Opcode != Expected1) {
17809467b48Spatrick         if (handleReject() == RejectAndGiveUp)
17909467b48Spatrick           return false;
18009467b48Spatrick       }
18109467b48Spatrick       break;
18209467b48Spatrick     }
18309467b48Spatrick     case GIM_SwitchOpcode: {
18409467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
18509467b48Spatrick       int64_t LowerBound = MatchTable[CurrentIdx++];
18609467b48Spatrick       int64_t UpperBound = MatchTable[CurrentIdx++];
18709467b48Spatrick       int64_t Default = MatchTable[CurrentIdx++];
18809467b48Spatrick 
18909467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
19009467b48Spatrick       const int64_t Opcode = State.MIs[InsnID]->getOpcode();
19109467b48Spatrick 
19209467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), {
19309467b48Spatrick         dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
19409467b48Spatrick                << LowerBound << ", " << UpperBound << "), Default=" << Default
19509467b48Spatrick                << ", JumpTable...) // Got=" << Opcode << "\n";
19609467b48Spatrick       });
19709467b48Spatrick       if (Opcode < LowerBound || UpperBound <= Opcode) {
19809467b48Spatrick         CurrentIdx = Default;
19909467b48Spatrick         break;
20009467b48Spatrick       }
20109467b48Spatrick       CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)];
20209467b48Spatrick       if (!CurrentIdx) {
20309467b48Spatrick         CurrentIdx = Default;
20409467b48Spatrick         break;
20509467b48Spatrick       }
20609467b48Spatrick       OnFailResumeAt.push_back(Default);
20709467b48Spatrick       break;
20809467b48Spatrick     }
20909467b48Spatrick 
21009467b48Spatrick     case GIM_SwitchType: {
21109467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
21209467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
21309467b48Spatrick       int64_t LowerBound = MatchTable[CurrentIdx++];
21409467b48Spatrick       int64_t UpperBound = MatchTable[CurrentIdx++];
21509467b48Spatrick       int64_t Default = MatchTable[CurrentIdx++];
21609467b48Spatrick 
21709467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
21809467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
21909467b48Spatrick 
22009467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), {
22109467b48Spatrick         dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID
22209467b48Spatrick                << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", "
22309467b48Spatrick                << UpperBound << "), Default=" << Default
22409467b48Spatrick                << ", JumpTable...) // Got=";
22509467b48Spatrick         if (!MO.isReg())
22609467b48Spatrick           dbgs() << "Not a VReg\n";
22709467b48Spatrick         else
22809467b48Spatrick           dbgs() << MRI.getType(MO.getReg()) << "\n";
22909467b48Spatrick       });
23009467b48Spatrick       if (!MO.isReg()) {
23109467b48Spatrick         CurrentIdx = Default;
23209467b48Spatrick         break;
23309467b48Spatrick       }
23409467b48Spatrick       const LLT Ty = MRI.getType(MO.getReg());
23509467b48Spatrick       const auto TyI = ISelInfo.TypeIDMap.find(Ty);
23609467b48Spatrick       if (TyI == ISelInfo.TypeIDMap.end()) {
23709467b48Spatrick         CurrentIdx = Default;
23809467b48Spatrick         break;
23909467b48Spatrick       }
24009467b48Spatrick       const int64_t TypeID = TyI->second;
24109467b48Spatrick       if (TypeID < LowerBound || UpperBound <= TypeID) {
24209467b48Spatrick         CurrentIdx = Default;
24309467b48Spatrick         break;
24409467b48Spatrick       }
24509467b48Spatrick       CurrentIdx = MatchTable[CurrentIdx + (TypeID - LowerBound)];
24609467b48Spatrick       if (!CurrentIdx) {
24709467b48Spatrick         CurrentIdx = Default;
24809467b48Spatrick         break;
24909467b48Spatrick       }
25009467b48Spatrick       OnFailResumeAt.push_back(Default);
25109467b48Spatrick       break;
25209467b48Spatrick     }
25309467b48Spatrick 
25409467b48Spatrick     case GIM_CheckNumOperands: {
25509467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
25609467b48Spatrick       int64_t Expected = MatchTable[CurrentIdx++];
25709467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
25809467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs["
25909467b48Spatrick                              << InsnID << "], Expected=" << Expected << ")\n");
26009467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
26109467b48Spatrick       if (State.MIs[InsnID]->getNumOperands() != Expected) {
26209467b48Spatrick         if (handleReject() == RejectAndGiveUp)
26309467b48Spatrick           return false;
26409467b48Spatrick       }
26509467b48Spatrick       break;
26609467b48Spatrick     }
26773471bf0Spatrick     case GIM_CheckI64ImmPredicate:
26873471bf0Spatrick     case GIM_CheckImmOperandPredicate: {
26909467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
27073471bf0Spatrick       int64_t OpIdx = MatcherOpcode == GIM_CheckImmOperandPredicate
27173471bf0Spatrick                           ? MatchTable[CurrentIdx++]
27273471bf0Spatrick                           : 1;
27309467b48Spatrick       int64_t Predicate = MatchTable[CurrentIdx++];
27409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
27573471bf0Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckImmPredicate(MIs["
27673471bf0Spatrick                              << InsnID << "]->getOperand(" << OpIdx
27773471bf0Spatrick                              << "), Predicate=" << Predicate << ")\n");
27809467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
27973471bf0Spatrick       assert((State.MIs[InsnID]->getOperand(OpIdx).isImm() ||
28073471bf0Spatrick               State.MIs[InsnID]->getOperand(OpIdx).isCImm()) &&
28173471bf0Spatrick              "Expected immediate operand");
28209467b48Spatrick       assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
28309467b48Spatrick       int64_t Value = 0;
28473471bf0Spatrick       if (State.MIs[InsnID]->getOperand(OpIdx).isCImm())
28573471bf0Spatrick         Value = State.MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue();
28673471bf0Spatrick       else if (State.MIs[InsnID]->getOperand(OpIdx).isImm())
28773471bf0Spatrick         Value = State.MIs[InsnID]->getOperand(OpIdx).getImm();
28809467b48Spatrick       else
28909467b48Spatrick         llvm_unreachable("Expected Imm or CImm operand");
29009467b48Spatrick 
29109467b48Spatrick       if (!testImmPredicate_I64(Predicate, Value))
29209467b48Spatrick         if (handleReject() == RejectAndGiveUp)
29309467b48Spatrick           return false;
29409467b48Spatrick       break;
29509467b48Spatrick     }
29609467b48Spatrick     case GIM_CheckAPIntImmPredicate: {
29709467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
29809467b48Spatrick       int64_t Predicate = MatchTable[CurrentIdx++];
29909467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
30009467b48Spatrick                       dbgs()
30109467b48Spatrick                           << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
30209467b48Spatrick                           << InsnID << "], Predicate=" << Predicate << ")\n");
30309467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
30409467b48Spatrick       assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
30509467b48Spatrick              "Expected G_CONSTANT");
30609467b48Spatrick       assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate");
30709467b48Spatrick       APInt Value;
30809467b48Spatrick       if (State.MIs[InsnID]->getOperand(1).isCImm())
30909467b48Spatrick         Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
31009467b48Spatrick       else
31109467b48Spatrick         llvm_unreachable("Expected Imm or CImm operand");
31209467b48Spatrick 
31309467b48Spatrick       if (!testImmPredicate_APInt(Predicate, Value))
31409467b48Spatrick         if (handleReject() == RejectAndGiveUp)
31509467b48Spatrick           return false;
31609467b48Spatrick       break;
31709467b48Spatrick     }
31809467b48Spatrick     case GIM_CheckAPFloatImmPredicate: {
31909467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
32009467b48Spatrick       int64_t Predicate = MatchTable[CurrentIdx++];
32109467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
32209467b48Spatrick                       dbgs()
32309467b48Spatrick                           << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs["
32409467b48Spatrick                           << InsnID << "], Predicate=" << Predicate << ")\n");
32509467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
32609467b48Spatrick       assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
32709467b48Spatrick              "Expected G_FCONSTANT");
32809467b48Spatrick       assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand");
32909467b48Spatrick       assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
33009467b48Spatrick       APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
33109467b48Spatrick 
33209467b48Spatrick       if (!testImmPredicate_APFloat(Predicate, Value))
33309467b48Spatrick         if (handleReject() == RejectAndGiveUp)
33409467b48Spatrick           return false;
33509467b48Spatrick       break;
33609467b48Spatrick     }
33773471bf0Spatrick     case GIM_CheckIsBuildVectorAllOnes:
33873471bf0Spatrick     case GIM_CheckIsBuildVectorAllZeros: {
33973471bf0Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
34073471bf0Spatrick 
34173471bf0Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
34273471bf0Spatrick                       dbgs() << CurrentIdx
34373471bf0Spatrick                              << ": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
34473471bf0Spatrick                              << InsnID << "])\n");
34573471bf0Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
34673471bf0Spatrick 
34773471bf0Spatrick       const MachineInstr *MI = State.MIs[InsnID];
34873471bf0Spatrick       assert((MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
34973471bf0Spatrick               MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
35073471bf0Spatrick              "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
35173471bf0Spatrick 
35273471bf0Spatrick       if (MatcherOpcode == GIM_CheckIsBuildVectorAllOnes) {
35373471bf0Spatrick         if (!isBuildVectorAllOnes(*MI, MRI)) {
35473471bf0Spatrick           if (handleReject() == RejectAndGiveUp)
35573471bf0Spatrick             return false;
35673471bf0Spatrick         }
35773471bf0Spatrick       } else {
35873471bf0Spatrick         if (!isBuildVectorAllZeros(*MI, MRI)) {
35973471bf0Spatrick           if (handleReject() == RejectAndGiveUp)
36073471bf0Spatrick             return false;
36173471bf0Spatrick         }
36273471bf0Spatrick       }
36373471bf0Spatrick 
36473471bf0Spatrick       break;
36573471bf0Spatrick     }
36609467b48Spatrick     case GIM_CheckCxxInsnPredicate: {
36709467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
36809467b48Spatrick       int64_t Predicate = MatchTable[CurrentIdx++];
36909467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
37009467b48Spatrick                       dbgs()
37109467b48Spatrick                           << CurrentIdx << ": GIM_CheckCxxPredicate(MIs["
37209467b48Spatrick                           << InsnID << "], Predicate=" << Predicate << ")\n");
37309467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
37409467b48Spatrick       assert(Predicate > GIPFP_MI_Invalid && "Expected a valid predicate");
37509467b48Spatrick 
37673471bf0Spatrick       if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID],
37773471bf0Spatrick                               State.RecordedOperands))
37809467b48Spatrick         if (handleReject() == RejectAndGiveUp)
37909467b48Spatrick           return false;
38009467b48Spatrick       break;
38109467b48Spatrick     }
382*d415bd75Srobert     case GIM_CheckHasNoUse: {
383*d415bd75Srobert       int64_t InsnID = MatchTable[CurrentIdx++];
384*d415bd75Srobert 
385*d415bd75Srobert       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
386*d415bd75Srobert                       dbgs() << CurrentIdx << ": GIM_CheckHasNoUse(MIs["
387*d415bd75Srobert                              << InsnID << "]\n");
388*d415bd75Srobert 
389*d415bd75Srobert       const MachineInstr *MI = State.MIs[InsnID];
390*d415bd75Srobert       assert(MI && "Used insn before defined");
391*d415bd75Srobert       assert(MI->getNumDefs() > 0 && "No defs");
392*d415bd75Srobert       const Register Res = MI->getOperand(0).getReg();
393*d415bd75Srobert 
394*d415bd75Srobert       if (!MRI.use_nodbg_empty(Res)) {
395*d415bd75Srobert         if (handleReject() == RejectAndGiveUp)
396*d415bd75Srobert           return false;
397*d415bd75Srobert       }
398*d415bd75Srobert 
399*d415bd75Srobert       break;
400*d415bd75Srobert     }
40109467b48Spatrick     case GIM_CheckAtomicOrdering: {
40209467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
40309467b48Spatrick       AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
40409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
40509467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs["
40609467b48Spatrick                              << InsnID << "], " << (uint64_t)Ordering << ")\n");
40709467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
40809467b48Spatrick       if (!State.MIs[InsnID]->hasOneMemOperand())
40909467b48Spatrick         if (handleReject() == RejectAndGiveUp)
41009467b48Spatrick           return false;
41109467b48Spatrick 
41209467b48Spatrick       for (const auto &MMO : State.MIs[InsnID]->memoperands())
41373471bf0Spatrick         if (MMO->getMergedOrdering() != Ordering)
41409467b48Spatrick           if (handleReject() == RejectAndGiveUp)
41509467b48Spatrick             return false;
41609467b48Spatrick       break;
41709467b48Spatrick     }
41809467b48Spatrick     case GIM_CheckAtomicOrderingOrStrongerThan: {
41909467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
42009467b48Spatrick       AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
42109467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
42209467b48Spatrick                       dbgs() << CurrentIdx
42309467b48Spatrick                              << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
42409467b48Spatrick                              << InsnID << "], " << (uint64_t)Ordering << ")\n");
42509467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
42609467b48Spatrick       if (!State.MIs[InsnID]->hasOneMemOperand())
42709467b48Spatrick         if (handleReject() == RejectAndGiveUp)
42809467b48Spatrick           return false;
42909467b48Spatrick 
43009467b48Spatrick       for (const auto &MMO : State.MIs[InsnID]->memoperands())
43173471bf0Spatrick         if (!isAtLeastOrStrongerThan(MMO->getMergedOrdering(), Ordering))
43209467b48Spatrick           if (handleReject() == RejectAndGiveUp)
43309467b48Spatrick             return false;
43409467b48Spatrick       break;
43509467b48Spatrick     }
43609467b48Spatrick     case GIM_CheckAtomicOrderingWeakerThan: {
43709467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
43809467b48Spatrick       AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
43909467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
44009467b48Spatrick                       dbgs() << CurrentIdx
44109467b48Spatrick                              << ": GIM_CheckAtomicOrderingWeakerThan(MIs["
44209467b48Spatrick                              << InsnID << "], " << (uint64_t)Ordering << ")\n");
44309467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
44409467b48Spatrick       if (!State.MIs[InsnID]->hasOneMemOperand())
44509467b48Spatrick         if (handleReject() == RejectAndGiveUp)
44609467b48Spatrick           return false;
44709467b48Spatrick 
44809467b48Spatrick       for (const auto &MMO : State.MIs[InsnID]->memoperands())
44973471bf0Spatrick         if (!isStrongerThan(Ordering, MMO->getMergedOrdering()))
45009467b48Spatrick           if (handleReject() == RejectAndGiveUp)
45109467b48Spatrick             return false;
45209467b48Spatrick       break;
45309467b48Spatrick     }
45409467b48Spatrick     case GIM_CheckMemoryAddressSpace: {
45509467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
45609467b48Spatrick       int64_t MMOIdx = MatchTable[CurrentIdx++];
45709467b48Spatrick       // This accepts a list of possible address spaces.
45809467b48Spatrick       const int NumAddrSpace = MatchTable[CurrentIdx++];
45909467b48Spatrick 
46009467b48Spatrick       if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
46109467b48Spatrick         if (handleReject() == RejectAndGiveUp)
46209467b48Spatrick           return false;
46309467b48Spatrick         break;
46409467b48Spatrick       }
46509467b48Spatrick 
46609467b48Spatrick       // Need to still jump to the end of the list of address spaces if we find
46709467b48Spatrick       // a match earlier.
46809467b48Spatrick       const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
46909467b48Spatrick 
47009467b48Spatrick       const MachineMemOperand *MMO
47109467b48Spatrick         = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
47209467b48Spatrick       const unsigned MMOAddrSpace = MMO->getAddrSpace();
47309467b48Spatrick 
47409467b48Spatrick       bool Success = false;
47509467b48Spatrick       for (int I = 0; I != NumAddrSpace; ++I) {
47609467b48Spatrick         unsigned AddrSpace = MatchTable[CurrentIdx++];
47709467b48Spatrick         DEBUG_WITH_TYPE(
47809467b48Spatrick           TgtInstructionSelector::getName(),
47909467b48Spatrick           dbgs() << "addrspace(" << MMOAddrSpace << ") vs "
48009467b48Spatrick                  << AddrSpace << '\n');
48109467b48Spatrick 
48209467b48Spatrick         if (AddrSpace == MMOAddrSpace) {
48309467b48Spatrick           Success = true;
48409467b48Spatrick           break;
48509467b48Spatrick         }
48609467b48Spatrick       }
48709467b48Spatrick 
48809467b48Spatrick       CurrentIdx = LastIdx;
48909467b48Spatrick       if (!Success && handleReject() == RejectAndGiveUp)
49009467b48Spatrick         return false;
49109467b48Spatrick       break;
49209467b48Spatrick     }
49309467b48Spatrick     case GIM_CheckMemoryAlignment: {
49409467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
49509467b48Spatrick       int64_t MMOIdx = MatchTable[CurrentIdx++];
49609467b48Spatrick       unsigned MinAlign = MatchTable[CurrentIdx++];
49709467b48Spatrick 
49809467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
49909467b48Spatrick 
50009467b48Spatrick       if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
50109467b48Spatrick         if (handleReject() == RejectAndGiveUp)
50209467b48Spatrick           return false;
50309467b48Spatrick         break;
50409467b48Spatrick       }
50509467b48Spatrick 
50609467b48Spatrick       MachineMemOperand *MMO
50709467b48Spatrick         = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
50809467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
50909467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment"
51009467b48Spatrick                       << "(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
51109467b48Spatrick                       << ")->getAlignment() >= " << MinAlign << ")\n");
512097a140dSpatrick       if (MMO->getAlign() < MinAlign && handleReject() == RejectAndGiveUp)
51309467b48Spatrick         return false;
51409467b48Spatrick 
51509467b48Spatrick       break;
51609467b48Spatrick     }
51709467b48Spatrick     case GIM_CheckMemorySizeEqualTo: {
51809467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
51909467b48Spatrick       int64_t MMOIdx = MatchTable[CurrentIdx++];
52009467b48Spatrick       uint64_t Size = MatchTable[CurrentIdx++];
52109467b48Spatrick 
52209467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
52309467b48Spatrick                       dbgs() << CurrentIdx
52409467b48Spatrick                              << ": GIM_CheckMemorySizeEqual(MIs[" << InsnID
52509467b48Spatrick                              << "]->memoperands() + " << MMOIdx
52609467b48Spatrick                              << ", Size=" << Size << ")\n");
52709467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
52809467b48Spatrick 
52909467b48Spatrick       if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
53009467b48Spatrick         if (handleReject() == RejectAndGiveUp)
53109467b48Spatrick           return false;
53209467b48Spatrick         break;
53309467b48Spatrick       }
53409467b48Spatrick 
53509467b48Spatrick       MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
53609467b48Spatrick 
53709467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
53809467b48Spatrick                       dbgs() << MMO->getSize() << " bytes vs " << Size
53909467b48Spatrick                              << " bytes\n");
54009467b48Spatrick       if (MMO->getSize() != Size)
54109467b48Spatrick         if (handleReject() == RejectAndGiveUp)
54209467b48Spatrick           return false;
54309467b48Spatrick 
54409467b48Spatrick       break;
54509467b48Spatrick     }
54609467b48Spatrick     case GIM_CheckMemorySizeEqualToLLT:
54709467b48Spatrick     case GIM_CheckMemorySizeLessThanLLT:
54809467b48Spatrick     case GIM_CheckMemorySizeGreaterThanLLT: {
54909467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
55009467b48Spatrick       int64_t MMOIdx = MatchTable[CurrentIdx++];
55109467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
55209467b48Spatrick 
55309467b48Spatrick       DEBUG_WITH_TYPE(
55409467b48Spatrick           TgtInstructionSelector::getName(),
55509467b48Spatrick           dbgs() << CurrentIdx << ": GIM_CheckMemorySize"
55609467b48Spatrick                  << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT
55709467b48Spatrick                          ? "EqualTo"
55809467b48Spatrick                          : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT
55909467b48Spatrick                                ? "GreaterThan"
56009467b48Spatrick                                : "LessThan")
56109467b48Spatrick                  << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
56209467b48Spatrick                  << ", OpIdx=" << OpIdx << ")\n");
56309467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
56409467b48Spatrick 
56509467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
56609467b48Spatrick       if (!MO.isReg()) {
56709467b48Spatrick         DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
56809467b48Spatrick                         dbgs() << CurrentIdx << ": Not a register\n");
56909467b48Spatrick         if (handleReject() == RejectAndGiveUp)
57009467b48Spatrick           return false;
57109467b48Spatrick         break;
57209467b48Spatrick       }
57309467b48Spatrick 
57409467b48Spatrick       if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
57509467b48Spatrick         if (handleReject() == RejectAndGiveUp)
57609467b48Spatrick           return false;
57709467b48Spatrick         break;
57809467b48Spatrick       }
57909467b48Spatrick 
58009467b48Spatrick       MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
58109467b48Spatrick 
58209467b48Spatrick       unsigned Size = MRI.getType(MO.getReg()).getSizeInBits();
58309467b48Spatrick       if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT &&
58409467b48Spatrick           MMO->getSizeInBits() != Size) {
58509467b48Spatrick         if (handleReject() == RejectAndGiveUp)
58609467b48Spatrick           return false;
58709467b48Spatrick       } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT &&
58809467b48Spatrick                  MMO->getSizeInBits() >= Size) {
58909467b48Spatrick         if (handleReject() == RejectAndGiveUp)
59009467b48Spatrick           return false;
59109467b48Spatrick       } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT &&
59209467b48Spatrick                  MMO->getSizeInBits() <= Size)
59309467b48Spatrick         if (handleReject() == RejectAndGiveUp)
59409467b48Spatrick           return false;
59509467b48Spatrick 
59609467b48Spatrick       break;
59709467b48Spatrick     }
59809467b48Spatrick     case GIM_CheckType: {
59909467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
60009467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
60109467b48Spatrick       int64_t TypeID = MatchTable[CurrentIdx++];
60209467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
60309467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
60409467b48Spatrick                              << "]->getOperand(" << OpIdx
60509467b48Spatrick                              << "), TypeID=" << TypeID << ")\n");
60609467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
60709467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
60809467b48Spatrick       if (!MO.isReg() ||
60909467b48Spatrick           MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) {
61009467b48Spatrick         if (handleReject() == RejectAndGiveUp)
61109467b48Spatrick           return false;
61209467b48Spatrick       }
61309467b48Spatrick       break;
61409467b48Spatrick     }
61509467b48Spatrick     case GIM_CheckPointerToAny: {
61609467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
61709467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
61873471bf0Spatrick       uint64_t SizeInBits = MatchTable[CurrentIdx++];
61909467b48Spatrick 
62009467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
62109467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
62209467b48Spatrick                              << InsnID << "]->getOperand(" << OpIdx
62309467b48Spatrick                              << "), SizeInBits=" << SizeInBits << ")\n");
62409467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
62509467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
62609467b48Spatrick       const LLT Ty = MRI.getType(MO.getReg());
62709467b48Spatrick 
62809467b48Spatrick       // iPTR must be looked up in the target.
62909467b48Spatrick       if (SizeInBits == 0) {
63009467b48Spatrick         MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
63109467b48Spatrick         const unsigned AddrSpace = Ty.getAddressSpace();
63209467b48Spatrick         SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace);
63309467b48Spatrick       }
63409467b48Spatrick 
63509467b48Spatrick       assert(SizeInBits != 0 && "Pointer size must be known");
63609467b48Spatrick 
63709467b48Spatrick       if (MO.isReg()) {
63809467b48Spatrick         if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
63909467b48Spatrick           if (handleReject() == RejectAndGiveUp)
64009467b48Spatrick             return false;
64109467b48Spatrick       } else if (handleReject() == RejectAndGiveUp)
64209467b48Spatrick         return false;
64309467b48Spatrick 
64409467b48Spatrick       break;
64509467b48Spatrick     }
64673471bf0Spatrick     case GIM_RecordNamedOperand: {
64773471bf0Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
64873471bf0Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
64973471bf0Spatrick       uint64_t StoreIdx = MatchTable[CurrentIdx++];
65073471bf0Spatrick 
65173471bf0Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
65273471bf0Spatrick                       dbgs() << CurrentIdx << ": GIM_RecordNamedOperand(MIs["
65373471bf0Spatrick                              << InsnID << "]->getOperand(" << OpIdx
65473471bf0Spatrick                              << "), StoreIdx=" << StoreIdx << ")\n");
65573471bf0Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
65673471bf0Spatrick       assert(StoreIdx < State.RecordedOperands.size() && "Index out of range");
65773471bf0Spatrick       State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx);
65873471bf0Spatrick       break;
65973471bf0Spatrick     }
66009467b48Spatrick     case GIM_CheckRegBankForClass: {
66109467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
66209467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
66309467b48Spatrick       int64_t RCEnum = MatchTable[CurrentIdx++];
66409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
66509467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
66609467b48Spatrick                              << InsnID << "]->getOperand(" << OpIdx
66709467b48Spatrick                              << "), RCEnum=" << RCEnum << ")\n");
66809467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
66909467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
67009467b48Spatrick       if (!MO.isReg() ||
67109467b48Spatrick           &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum),
67209467b48Spatrick                                       MRI.getType(MO.getReg())) !=
67309467b48Spatrick               RBI.getRegBank(MO.getReg(), MRI, TRI)) {
67409467b48Spatrick         if (handleReject() == RejectAndGiveUp)
67509467b48Spatrick           return false;
67609467b48Spatrick       }
67709467b48Spatrick       break;
67809467b48Spatrick     }
67909467b48Spatrick 
68009467b48Spatrick     case GIM_CheckComplexPattern: {
68109467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
68209467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
68309467b48Spatrick       int64_t RendererID = MatchTable[CurrentIdx++];
68409467b48Spatrick       int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
68509467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
68609467b48Spatrick                       dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
68709467b48Spatrick                              << "] = GIM_CheckComplexPattern(MIs[" << InsnID
68809467b48Spatrick                              << "]->getOperand(" << OpIdx
68909467b48Spatrick                              << "), ComplexPredicateID=" << ComplexPredicateID
69009467b48Spatrick                              << ")\n");
69109467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
69209467b48Spatrick       // FIXME: Use std::invoke() when it's available.
69309467b48Spatrick       ComplexRendererFns Renderer =
69409467b48Spatrick           (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])(
69509467b48Spatrick               State.MIs[InsnID]->getOperand(OpIdx));
696*d415bd75Srobert       if (Renderer)
697*d415bd75Srobert         State.Renderers[RendererID] = *Renderer;
69809467b48Spatrick       else
69909467b48Spatrick         if (handleReject() == RejectAndGiveUp)
70009467b48Spatrick           return false;
70109467b48Spatrick       break;
70209467b48Spatrick     }
70309467b48Spatrick 
70409467b48Spatrick     case GIM_CheckConstantInt: {
70509467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
70609467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
70709467b48Spatrick       int64_t Value = MatchTable[CurrentIdx++];
70809467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
70909467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
71009467b48Spatrick                              << InsnID << "]->getOperand(" << OpIdx
71109467b48Spatrick                              << "), Value=" << Value << ")\n");
71209467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
71309467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
71409467b48Spatrick       if (MO.isReg()) {
71509467b48Spatrick         // isOperandImmEqual() will sign-extend to 64-bits, so should we.
71609467b48Spatrick         LLT Ty = MRI.getType(MO.getReg());
71709467b48Spatrick         Value = SignExtend64(Value, Ty.getSizeInBits());
71809467b48Spatrick 
71909467b48Spatrick         if (!isOperandImmEqual(MO, Value, MRI)) {
72009467b48Spatrick           if (handleReject() == RejectAndGiveUp)
72109467b48Spatrick             return false;
72209467b48Spatrick         }
72309467b48Spatrick       } else if (handleReject() == RejectAndGiveUp)
72409467b48Spatrick         return false;
72509467b48Spatrick 
72609467b48Spatrick       break;
72709467b48Spatrick     }
72809467b48Spatrick 
72909467b48Spatrick     case GIM_CheckLiteralInt: {
73009467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
73109467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
73209467b48Spatrick       int64_t Value = MatchTable[CurrentIdx++];
73309467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
73409467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
73509467b48Spatrick                              << InsnID << "]->getOperand(" << OpIdx
73609467b48Spatrick                              << "), Value=" << Value << ")\n");
73709467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
73809467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
73909467b48Spatrick       if (MO.isImm() && MO.getImm() == Value)
74009467b48Spatrick         break;
74109467b48Spatrick 
74209467b48Spatrick       if (MO.isCImm() && MO.getCImm()->equalsInt(Value))
74309467b48Spatrick         break;
74409467b48Spatrick 
74509467b48Spatrick       if (handleReject() == RejectAndGiveUp)
74609467b48Spatrick         return false;
74709467b48Spatrick 
74809467b48Spatrick       break;
74909467b48Spatrick     }
75009467b48Spatrick 
75109467b48Spatrick     case GIM_CheckIntrinsicID: {
75209467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
75309467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
75409467b48Spatrick       int64_t Value = MatchTable[CurrentIdx++];
75509467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
75609467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
75709467b48Spatrick                              << InsnID << "]->getOperand(" << OpIdx
75809467b48Spatrick                              << "), Value=" << Value << ")\n");
75909467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
76009467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
76109467b48Spatrick       if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
76209467b48Spatrick         if (handleReject() == RejectAndGiveUp)
76309467b48Spatrick           return false;
76409467b48Spatrick       break;
76509467b48Spatrick     }
76609467b48Spatrick     case GIM_CheckCmpPredicate: {
76709467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
76809467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
76909467b48Spatrick       int64_t Value = MatchTable[CurrentIdx++];
77009467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
77109467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs["
77209467b48Spatrick                              << InsnID << "]->getOperand(" << OpIdx
77309467b48Spatrick                              << "), Value=" << Value << ")\n");
77409467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
77509467b48Spatrick       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
77609467b48Spatrick       if (!MO.isPredicate() || MO.getPredicate() != Value)
77709467b48Spatrick         if (handleReject() == RejectAndGiveUp)
77809467b48Spatrick           return false;
77909467b48Spatrick       break;
78009467b48Spatrick     }
78109467b48Spatrick     case GIM_CheckIsMBB: {
78209467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
78309467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
78409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
78509467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
78609467b48Spatrick                              << "]->getOperand(" << OpIdx << "))\n");
78709467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
78809467b48Spatrick       if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
78909467b48Spatrick         if (handleReject() == RejectAndGiveUp)
79009467b48Spatrick           return false;
79109467b48Spatrick       }
79209467b48Spatrick       break;
79309467b48Spatrick     }
79409467b48Spatrick     case GIM_CheckIsImm: {
79509467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
79609467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
79709467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
79809467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckIsImm(MIs[" << InsnID
79909467b48Spatrick                              << "]->getOperand(" << OpIdx << "))\n");
80009467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
80109467b48Spatrick       if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) {
80209467b48Spatrick         if (handleReject() == RejectAndGiveUp)
80309467b48Spatrick           return false;
80409467b48Spatrick       }
80509467b48Spatrick       break;
80609467b48Spatrick     }
80709467b48Spatrick     case GIM_CheckIsSafeToFold: {
80809467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
80909467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
81009467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs["
81109467b48Spatrick                              << InsnID << "])\n");
81209467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
81309467b48Spatrick       if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) {
81409467b48Spatrick         if (handleReject() == RejectAndGiveUp)
81509467b48Spatrick           return false;
81609467b48Spatrick       }
81709467b48Spatrick       break;
81809467b48Spatrick     }
81909467b48Spatrick     case GIM_CheckIsSameOperand: {
82009467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
82109467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
82209467b48Spatrick       int64_t OtherInsnID = MatchTable[CurrentIdx++];
82309467b48Spatrick       int64_t OtherOpIdx = MatchTable[CurrentIdx++];
82409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
82509467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
82609467b48Spatrick                              << InsnID << "][" << OpIdx << "], MIs["
82709467b48Spatrick                              << OtherInsnID << "][" << OtherOpIdx << "])\n");
82809467b48Spatrick       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
82909467b48Spatrick       assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
83009467b48Spatrick       if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
83109467b48Spatrick               State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
83209467b48Spatrick         if (handleReject() == RejectAndGiveUp)
83309467b48Spatrick           return false;
83409467b48Spatrick       }
83509467b48Spatrick       break;
83609467b48Spatrick     }
83709467b48Spatrick     case GIM_Reject:
83809467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
83909467b48Spatrick                       dbgs() << CurrentIdx << ": GIM_Reject\n");
84009467b48Spatrick       if (handleReject() == RejectAndGiveUp)
84109467b48Spatrick         return false;
84209467b48Spatrick       break;
84309467b48Spatrick 
84409467b48Spatrick     case GIR_MutateOpcode: {
84509467b48Spatrick       int64_t OldInsnID = MatchTable[CurrentIdx++];
84609467b48Spatrick       uint64_t NewInsnID = MatchTable[CurrentIdx++];
84709467b48Spatrick       int64_t NewOpcode = MatchTable[CurrentIdx++];
84809467b48Spatrick       if (NewInsnID >= OutMIs.size())
84909467b48Spatrick         OutMIs.resize(NewInsnID + 1);
85009467b48Spatrick 
85109467b48Spatrick       OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
85209467b48Spatrick                                               State.MIs[OldInsnID]);
85309467b48Spatrick       OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
85409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
85509467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
85609467b48Spatrick                              << NewInsnID << "], MIs[" << OldInsnID << "], "
85709467b48Spatrick                              << NewOpcode << ")\n");
85809467b48Spatrick       break;
85909467b48Spatrick     }
86009467b48Spatrick 
86109467b48Spatrick     case GIR_BuildMI: {
86209467b48Spatrick       uint64_t NewInsnID = MatchTable[CurrentIdx++];
86309467b48Spatrick       int64_t Opcode = MatchTable[CurrentIdx++];
86409467b48Spatrick       if (NewInsnID >= OutMIs.size())
86509467b48Spatrick         OutMIs.resize(NewInsnID + 1);
86609467b48Spatrick 
86709467b48Spatrick       OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
868*d415bd75Srobert                                   MIMetadata(*State.MIs[0]), TII.get(Opcode));
86909467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
87009467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
87109467b48Spatrick                              << NewInsnID << "], " << Opcode << ")\n");
87209467b48Spatrick       break;
87309467b48Spatrick     }
87409467b48Spatrick 
87509467b48Spatrick     case GIR_Copy: {
87609467b48Spatrick       int64_t NewInsnID = MatchTable[CurrentIdx++];
87709467b48Spatrick       int64_t OldInsnID = MatchTable[CurrentIdx++];
87809467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
87909467b48Spatrick       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
88009467b48Spatrick       OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
88109467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
88209467b48Spatrick                       dbgs()
88309467b48Spatrick                           << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
88409467b48Spatrick                           << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
88509467b48Spatrick       break;
88609467b48Spatrick     }
88709467b48Spatrick 
88809467b48Spatrick     case GIR_CopyOrAddZeroReg: {
88909467b48Spatrick       int64_t NewInsnID = MatchTable[CurrentIdx++];
89009467b48Spatrick       int64_t OldInsnID = MatchTable[CurrentIdx++];
89109467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
89209467b48Spatrick       int64_t ZeroReg = MatchTable[CurrentIdx++];
89309467b48Spatrick       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
89409467b48Spatrick       MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
89509467b48Spatrick       if (isOperandImmEqual(MO, 0, MRI))
89609467b48Spatrick         OutMIs[NewInsnID].addReg(ZeroReg);
89709467b48Spatrick       else
89809467b48Spatrick         OutMIs[NewInsnID].add(MO);
89909467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
90009467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
90109467b48Spatrick                              << NewInsnID << "], MIs[" << OldInsnID << "], "
90209467b48Spatrick                              << OpIdx << ", " << ZeroReg << ")\n");
90309467b48Spatrick       break;
90409467b48Spatrick     }
90509467b48Spatrick 
90609467b48Spatrick     case GIR_CopySubReg: {
90709467b48Spatrick       int64_t NewInsnID = MatchTable[CurrentIdx++];
90809467b48Spatrick       int64_t OldInsnID = MatchTable[CurrentIdx++];
90909467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
91009467b48Spatrick       int64_t SubRegIdx = MatchTable[CurrentIdx++];
91109467b48Spatrick       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
91209467b48Spatrick       OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
91309467b48Spatrick                                0, SubRegIdx);
91409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
91509467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
91609467b48Spatrick                              << NewInsnID << "], MIs[" << OldInsnID << "], "
91709467b48Spatrick                              << OpIdx << ", " << SubRegIdx << ")\n");
91809467b48Spatrick       break;
91909467b48Spatrick     }
92009467b48Spatrick 
92109467b48Spatrick     case GIR_AddImplicitDef: {
92209467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
92309467b48Spatrick       int64_t RegNum = MatchTable[CurrentIdx++];
92409467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
92509467b48Spatrick       OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
92609467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
92709467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
92809467b48Spatrick                              << InsnID << "], " << RegNum << ")\n");
92909467b48Spatrick       break;
93009467b48Spatrick     }
93109467b48Spatrick 
93209467b48Spatrick     case GIR_AddImplicitUse: {
93309467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
93409467b48Spatrick       int64_t RegNum = MatchTable[CurrentIdx++];
93509467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
93609467b48Spatrick       OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
93709467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
93809467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
93909467b48Spatrick                              << InsnID << "], " << RegNum << ")\n");
94009467b48Spatrick       break;
94109467b48Spatrick     }
94209467b48Spatrick 
94309467b48Spatrick     case GIR_AddRegister: {
94409467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
94509467b48Spatrick       int64_t RegNum = MatchTable[CurrentIdx++];
94609467b48Spatrick       uint64_t RegFlags = MatchTable[CurrentIdx++];
94709467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
94809467b48Spatrick       OutMIs[InsnID].addReg(RegNum, RegFlags);
94909467b48Spatrick       DEBUG_WITH_TYPE(
95009467b48Spatrick         TgtInstructionSelector::getName(),
95109467b48Spatrick         dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
95209467b48Spatrick         << InsnID << "], " << RegNum << ", " << RegFlags << ")\n");
95309467b48Spatrick       break;
95409467b48Spatrick     }
95509467b48Spatrick 
956097a140dSpatrick     case GIR_AddTempRegister:
957097a140dSpatrick     case GIR_AddTempSubRegister: {
95809467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
95909467b48Spatrick       int64_t TempRegID = MatchTable[CurrentIdx++];
96009467b48Spatrick       uint64_t TempRegFlags = MatchTable[CurrentIdx++];
961097a140dSpatrick       unsigned SubReg = 0;
962097a140dSpatrick       if (MatcherOpcode == GIR_AddTempSubRegister)
963097a140dSpatrick         SubReg = MatchTable[CurrentIdx++];
964097a140dSpatrick 
96509467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
966097a140dSpatrick 
967097a140dSpatrick       OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags, SubReg);
96809467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
96909467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
97009467b48Spatrick                              << InsnID << "], TempRegisters[" << TempRegID
971097a140dSpatrick                              << "]";
972097a140dSpatrick                       if (SubReg)
973097a140dSpatrick                         dbgs() << '.' << TRI.getSubRegIndexName(SubReg);
974097a140dSpatrick                       dbgs() << ", " << TempRegFlags << ")\n");
97509467b48Spatrick       break;
97609467b48Spatrick     }
97709467b48Spatrick 
97809467b48Spatrick     case GIR_AddImm: {
97909467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
98009467b48Spatrick       int64_t Imm = MatchTable[CurrentIdx++];
98109467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
98209467b48Spatrick       OutMIs[InsnID].addImm(Imm);
98309467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
98409467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
98509467b48Spatrick                              << "], " << Imm << ")\n");
98609467b48Spatrick       break;
98709467b48Spatrick     }
98809467b48Spatrick 
98909467b48Spatrick     case GIR_ComplexRenderer: {
99009467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
99109467b48Spatrick       int64_t RendererID = MatchTable[CurrentIdx++];
99209467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
99309467b48Spatrick       for (const auto &RenderOpFn : State.Renderers[RendererID])
99409467b48Spatrick         RenderOpFn(OutMIs[InsnID]);
99509467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
99609467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
99709467b48Spatrick                              << InsnID << "], " << RendererID << ")\n");
99809467b48Spatrick       break;
99909467b48Spatrick     }
100009467b48Spatrick     case GIR_ComplexSubOperandRenderer: {
100109467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
100209467b48Spatrick       int64_t RendererID = MatchTable[CurrentIdx++];
100309467b48Spatrick       int64_t RenderOpID = MatchTable[CurrentIdx++];
100409467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
100509467b48Spatrick       State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
100609467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
100709467b48Spatrick                       dbgs() << CurrentIdx
100809467b48Spatrick                              << ": GIR_ComplexSubOperandRenderer(OutMIs["
100909467b48Spatrick                              << InsnID << "], " << RendererID << ", "
101009467b48Spatrick                              << RenderOpID << ")\n");
101109467b48Spatrick       break;
101209467b48Spatrick     }
101309467b48Spatrick 
101409467b48Spatrick     case GIR_CopyConstantAsSImm: {
101509467b48Spatrick       int64_t NewInsnID = MatchTable[CurrentIdx++];
101609467b48Spatrick       int64_t OldInsnID = MatchTable[CurrentIdx++];
101709467b48Spatrick       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
101809467b48Spatrick       assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
101909467b48Spatrick       if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
102009467b48Spatrick         OutMIs[NewInsnID].addImm(
102109467b48Spatrick             State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
102209467b48Spatrick       } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
102309467b48Spatrick         OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
102409467b48Spatrick       else
102509467b48Spatrick         llvm_unreachable("Expected Imm or CImm operand");
102609467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
102709467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
102809467b48Spatrick                              << NewInsnID << "], MIs[" << OldInsnID << "])\n");
102909467b48Spatrick       break;
103009467b48Spatrick     }
103109467b48Spatrick 
103209467b48Spatrick     // TODO: Needs a test case once we have a pattern that uses this.
103309467b48Spatrick     case GIR_CopyFConstantAsFPImm: {
103409467b48Spatrick       int64_t NewInsnID = MatchTable[CurrentIdx++];
103509467b48Spatrick       int64_t OldInsnID = MatchTable[CurrentIdx++];
103609467b48Spatrick       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
103709467b48Spatrick       assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT");
103809467b48Spatrick       if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
103909467b48Spatrick         OutMIs[NewInsnID].addFPImm(
104009467b48Spatrick             State.MIs[OldInsnID]->getOperand(1).getFPImm());
104109467b48Spatrick       else
104209467b48Spatrick         llvm_unreachable("Expected FPImm operand");
104309467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
104409467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs["
104509467b48Spatrick                              << NewInsnID << "], MIs[" << OldInsnID << "])\n");
104609467b48Spatrick       break;
104709467b48Spatrick     }
104809467b48Spatrick 
104909467b48Spatrick     case GIR_CustomRenderer: {
105009467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
105109467b48Spatrick       int64_t OldInsnID = MatchTable[CurrentIdx++];
105209467b48Spatrick       int64_t RendererFnID = MatchTable[CurrentIdx++];
105309467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
105409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
105509467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
105609467b48Spatrick                              << InsnID << "], MIs[" << OldInsnID << "], "
105709467b48Spatrick                              << RendererFnID << ")\n");
105809467b48Spatrick       (ISel.*ISelInfo.CustomRenderers[RendererFnID])(
105909467b48Spatrick         OutMIs[InsnID], *State.MIs[OldInsnID],
106009467b48Spatrick         -1); // Not a source operand of the old instruction.
106109467b48Spatrick       break;
106209467b48Spatrick     }
106309467b48Spatrick     case GIR_CustomOperandRenderer: {
106409467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
106509467b48Spatrick       int64_t OldInsnID = MatchTable[CurrentIdx++];
106609467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
106709467b48Spatrick       int64_t RendererFnID = MatchTable[CurrentIdx++];
106809467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
106909467b48Spatrick 
107009467b48Spatrick       DEBUG_WITH_TYPE(
107109467b48Spatrick         TgtInstructionSelector::getName(),
107209467b48Spatrick         dbgs() << CurrentIdx << ": GIR_CustomOperandRenderer(OutMIs["
107309467b48Spatrick                << InsnID << "], MIs[" << OldInsnID << "]->getOperand("
107409467b48Spatrick                << OpIdx << "), "
107509467b48Spatrick         << RendererFnID << ")\n");
107609467b48Spatrick       (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID],
107709467b48Spatrick                                                      *State.MIs[OldInsnID],
107809467b48Spatrick                                                      OpIdx);
107909467b48Spatrick       break;
108009467b48Spatrick     }
108109467b48Spatrick     case GIR_ConstrainOperandRC: {
108209467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
108309467b48Spatrick       int64_t OpIdx = MatchTable[CurrentIdx++];
108409467b48Spatrick       int64_t RCEnum = MatchTable[CurrentIdx++];
108509467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
108673471bf0Spatrick       MachineInstr &I = *OutMIs[InsnID].getInstr();
108773471bf0Spatrick       MachineFunction &MF = *I.getParent()->getParent();
108873471bf0Spatrick       MachineRegisterInfo &MRI = MF.getRegInfo();
108973471bf0Spatrick       const TargetRegisterClass &RC = *TRI.getRegClass(RCEnum);
109073471bf0Spatrick       MachineOperand &MO = I.getOperand(OpIdx);
109173471bf0Spatrick       constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, RC, MO);
109209467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
109309467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
109409467b48Spatrick                              << InsnID << "], " << OpIdx << ", " << RCEnum
109509467b48Spatrick                              << ")\n");
109609467b48Spatrick       break;
109709467b48Spatrick     }
109809467b48Spatrick 
109909467b48Spatrick     case GIR_ConstrainSelectedInstOperands: {
110009467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
110109467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
110209467b48Spatrick       constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
110309467b48Spatrick                                        RBI);
110409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
110509467b48Spatrick                       dbgs() << CurrentIdx
110609467b48Spatrick                              << ": GIR_ConstrainSelectedInstOperands(OutMIs["
110709467b48Spatrick                              << InsnID << "])\n");
110809467b48Spatrick       break;
110909467b48Spatrick     }
111009467b48Spatrick 
111109467b48Spatrick     case GIR_MergeMemOperands: {
111209467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
111309467b48Spatrick       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
111409467b48Spatrick 
111509467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
111609467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
111709467b48Spatrick                              << InsnID << "]");
111809467b48Spatrick       int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
111909467b48Spatrick       while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
112009467b48Spatrick              GIU_MergeMemOperands_EndOfList) {
112109467b48Spatrick         DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
112209467b48Spatrick                         dbgs() << ", MIs[" << MergeInsnID << "]");
112309467b48Spatrick         for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
112409467b48Spatrick           OutMIs[InsnID].addMemOperand(MMO);
112509467b48Spatrick       }
112609467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), dbgs() << ")\n");
112709467b48Spatrick       break;
112809467b48Spatrick     }
112909467b48Spatrick 
113009467b48Spatrick     case GIR_EraseFromParent: {
113109467b48Spatrick       int64_t InsnID = MatchTable[CurrentIdx++];
113209467b48Spatrick       assert(State.MIs[InsnID] &&
113309467b48Spatrick              "Attempted to erase an undefined instruction");
113409467b48Spatrick       State.MIs[InsnID]->eraseFromParent();
113509467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
113609467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
113709467b48Spatrick                              << InsnID << "])\n");
113809467b48Spatrick       break;
113909467b48Spatrick     }
114009467b48Spatrick 
114109467b48Spatrick     case GIR_MakeTempReg: {
114209467b48Spatrick       int64_t TempRegID = MatchTable[CurrentIdx++];
114309467b48Spatrick       int64_t TypeID = MatchTable[CurrentIdx++];
114409467b48Spatrick 
114509467b48Spatrick       State.TempRegisters[TempRegID] =
114609467b48Spatrick           MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]);
114709467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
114809467b48Spatrick                       dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
114909467b48Spatrick                              << "] = GIR_MakeTempReg(" << TypeID << ")\n");
115009467b48Spatrick       break;
115109467b48Spatrick     }
115209467b48Spatrick 
115309467b48Spatrick     case GIR_Coverage: {
115409467b48Spatrick       int64_t RuleID = MatchTable[CurrentIdx++];
115509467b48Spatrick       CoverageInfo.setCovered(RuleID);
115609467b48Spatrick 
115709467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
115809467b48Spatrick                       dbgs()
115909467b48Spatrick                           << CurrentIdx << ": GIR_Coverage(" << RuleID << ")");
116009467b48Spatrick       break;
116109467b48Spatrick     }
116209467b48Spatrick 
116309467b48Spatrick     case GIR_Done:
116409467b48Spatrick       DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
116509467b48Spatrick                       dbgs() << CurrentIdx << ": GIR_Done\n");
1166097a140dSpatrick       propagateFlags(OutMIs);
116709467b48Spatrick       return true;
116809467b48Spatrick 
116909467b48Spatrick     default:
117009467b48Spatrick       llvm_unreachable("Unexpected command");
117109467b48Spatrick     }
117209467b48Spatrick   }
117309467b48Spatrick }
117409467b48Spatrick 
117509467b48Spatrick } // end namespace llvm
117609467b48Spatrick 
117709467b48Spatrick #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
1178