Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:24

0001 //===- llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h -------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 /// \file This file implements GIMatchTableExecutor's `executeMatchTable`
0010 /// function. This is implemented in a separate file because the function is
0011 /// quite large.
0012 //
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
0016 #define LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H
0017 
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
0020 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
0021 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
0022 #include "llvm/CodeGen/GlobalISel/Utils.h"
0023 #include "llvm/CodeGen/MachineInstrBuilder.h"
0024 #include "llvm/CodeGen/MachineOperand.h"
0025 #include "llvm/CodeGen/MachineRegisterInfo.h"
0026 #include "llvm/CodeGen/RegisterBankInfo.h"
0027 #include "llvm/CodeGen/TargetInstrInfo.h"
0028 #include "llvm/CodeGen/TargetOpcodes.h"
0029 #include "llvm/CodeGen/TargetRegisterInfo.h"
0030 #include "llvm/IR/Constants.h"
0031 #include "llvm/IR/DataLayout.h"
0032 #include "llvm/IR/Type.h"
0033 #include "llvm/Support/CodeGenCoverage.h"
0034 #include "llvm/Support/Debug.h"
0035 #include "llvm/Support/ErrorHandling.h"
0036 #include "llvm/Support/LEB128.h"
0037 #include "llvm/Support/raw_ostream.h"
0038 #include <cassert>
0039 #include <cstddef>
0040 #include <cstdint>
0041 
0042 namespace llvm {
0043 
0044 template <class TgtExecutor, class PredicateBitset, class ComplexMatcherMemFn,
0045           class CustomRendererFn>
0046 bool GIMatchTableExecutor::executeMatchTable(
0047     TgtExecutor &Exec, MatcherState &State,
0048     const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
0049         &ExecInfo,
0050     MachineIRBuilder &Builder, const uint8_t *MatchTable,
0051     const TargetInstrInfo &TII, MachineRegisterInfo &MRI,
0052     const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI,
0053     const PredicateBitset &AvailableFeatures,
0054     CodeGenCoverage *CoverageInfo) const {
0055 
0056   uint64_t CurrentIdx = 0;
0057   SmallVector<uint64_t, 4> OnFailResumeAt;
0058   NewMIVector OutMIs;
0059 
0060   GISelChangeObserver *Observer = Builder.getObserver();
0061   // Bypass the flag check on the instruction, and only look at the MCInstrDesc.
0062   bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
0063 
0064   const uint16_t Flags = State.MIs[0]->getFlags();
0065 
0066   enum RejectAction { RejectAndGiveUp, RejectAndResume };
0067   auto handleReject = [&]() -> RejectAction {
0068     DEBUG_WITH_TYPE(TgtExecutor::getName(),
0069                     dbgs() << CurrentIdx << ": Rejected\n");
0070     if (OnFailResumeAt.empty())
0071       return RejectAndGiveUp;
0072     CurrentIdx = OnFailResumeAt.pop_back_val();
0073     DEBUG_WITH_TYPE(TgtExecutor::getName(),
0074                     dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " ("
0075                            << OnFailResumeAt.size() << " try-blocks remain)\n");
0076     return RejectAndResume;
0077   };
0078 
0079   const auto propagateFlags = [&]() {
0080     for (auto MIB : OutMIs) {
0081       // Set the NoFPExcept flag when no original matched instruction could
0082       // raise an FP exception, but the new instruction potentially might.
0083       uint16_t MIBFlags = Flags;
0084       if (NoFPException && MIB->mayRaiseFPException())
0085         MIBFlags |= MachineInstr::NoFPExcept;
0086       if (Observer)
0087         Observer->changingInstr(*MIB);
0088       MIB.setMIFlags(MIBFlags);
0089       if (Observer)
0090         Observer->changedInstr(*MIB);
0091     }
0092   };
0093 
0094   // If the index is >= 0, it's an index in the type objects generated by
0095   // TableGen. If the index is <0, it's an index in the recorded types object.
0096   const auto getTypeFromIdx = [&](int64_t Idx) -> LLT {
0097     if (Idx >= 0)
0098       return ExecInfo.TypeObjects[Idx];
0099     return State.RecordedTypes[1 - Idx];
0100   };
0101 
0102   const auto readULEB = [&]() {
0103     return fastDecodeULEB128(MatchTable, CurrentIdx);
0104   };
0105 
0106   // Convenience function to return a signed value. This avoids
0107   // us forgetting to first cast to int8_t before casting to a
0108   // wider signed int type.
0109   // if we casted uint8 directly to a wider type we'd lose
0110   // negative values.
0111   const auto readS8 = [&]() { return (int8_t)MatchTable[CurrentIdx++]; };
0112 
0113   const auto readU16 = [&]() {
0114     auto V = readBytesAs<uint16_t>(MatchTable + CurrentIdx);
0115     CurrentIdx += 2;
0116     return V;
0117   };
0118 
0119   const auto readU32 = [&]() {
0120     auto V = readBytesAs<uint32_t>(MatchTable + CurrentIdx);
0121     CurrentIdx += 4;
0122     return V;
0123   };
0124 
0125   const auto readU64 = [&]() {
0126     auto V = readBytesAs<uint64_t>(MatchTable + CurrentIdx);
0127     CurrentIdx += 8;
0128     return V;
0129   };
0130 
0131   const auto eraseImpl = [&](MachineInstr *MI) {
0132     // If we're erasing the insertion point, ensure we don't leave a dangling
0133     // pointer in the builder.
0134     if (Builder.getInsertPt() == MI)
0135       Builder.setInsertPt(*MI->getParent(), ++MI->getIterator());
0136     if (Observer)
0137       Observer->erasingInstr(*MI);
0138     MI->eraseFromParent();
0139   };
0140 
0141   while (true) {
0142     assert(CurrentIdx != ~0u && "Invalid MatchTable index");
0143     uint8_t MatcherOpcode = MatchTable[CurrentIdx++];
0144     switch (MatcherOpcode) {
0145     case GIM_Try: {
0146       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0147                       dbgs() << CurrentIdx << ": Begin try-block\n");
0148       OnFailResumeAt.push_back(readU32());
0149       break;
0150     }
0151 
0152     case GIM_RecordInsn:
0153     case GIM_RecordInsnIgnoreCopies: {
0154       uint64_t NewInsnID = readULEB();
0155       uint64_t InsnID = readULEB();
0156       uint64_t OpIdx = readULEB();
0157 
0158       // As an optimisation we require that MIs[0] is always the root. Refuse
0159       // any attempt to modify it.
0160       assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
0161 
0162       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0163       if (!MO.isReg()) {
0164         DEBUG_WITH_TYPE(TgtExecutor::getName(),
0165                         dbgs() << CurrentIdx << ": Not a register\n");
0166         if (handleReject() == RejectAndGiveUp)
0167           return false;
0168         break;
0169       }
0170       if (MO.getReg().isPhysical()) {
0171         DEBUG_WITH_TYPE(TgtExecutor::getName(),
0172                         dbgs() << CurrentIdx << ": Is a physical register\n");
0173         if (handleReject() == RejectAndGiveUp)
0174           return false;
0175         break;
0176       }
0177 
0178       MachineInstr *NewMI;
0179       if (MatcherOpcode == GIM_RecordInsnIgnoreCopies)
0180         NewMI = getDefIgnoringCopies(MO.getReg(), MRI);
0181       else
0182         NewMI = MRI.getVRegDef(MO.getReg());
0183 
0184       if ((size_t)NewInsnID < State.MIs.size())
0185         State.MIs[NewInsnID] = NewMI;
0186       else {
0187         assert((size_t)NewInsnID == State.MIs.size() &&
0188                "Expected to store MIs in order");
0189         State.MIs.push_back(NewMI);
0190       }
0191       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0192                       dbgs() << CurrentIdx << ": MIs[" << NewInsnID
0193                              << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
0194                              << ")\n");
0195       break;
0196     }
0197 
0198     case GIM_CheckFeatures: {
0199       uint16_t ExpectedBitsetID = readU16();
0200       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0201                       dbgs() << CurrentIdx
0202                              << ": GIM_CheckFeatures(ExpectedBitsetID="
0203                              << ExpectedBitsetID << ")\n");
0204       if ((AvailableFeatures & ExecInfo.FeatureBitsets[ExpectedBitsetID]) !=
0205           ExecInfo.FeatureBitsets[ExpectedBitsetID]) {
0206         if (handleReject() == RejectAndGiveUp)
0207           return false;
0208       }
0209       break;
0210     }
0211     case GIM_CheckOpcode:
0212     case GIM_CheckOpcodeIsEither: {
0213       uint64_t InsnID = readULEB();
0214       uint16_t Expected0 = readU16();
0215       uint16_t Expected1 = -1;
0216       if (MatcherOpcode == GIM_CheckOpcodeIsEither)
0217         Expected1 = readU16();
0218 
0219       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0220       unsigned Opcode = State.MIs[InsnID]->getOpcode();
0221 
0222       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
0223         dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
0224                << "], ExpectedOpcode=" << Expected0;
0225         if (MatcherOpcode == GIM_CheckOpcodeIsEither)
0226           dbgs() << " || " << Expected1;
0227         dbgs() << ") // Got=" << Opcode << "\n";
0228       });
0229 
0230       if (Opcode != Expected0 && Opcode != Expected1) {
0231         if (handleReject() == RejectAndGiveUp)
0232           return false;
0233       }
0234       break;
0235     }
0236     case GIM_SwitchOpcode: {
0237       uint64_t InsnID = readULEB();
0238       uint16_t LowerBound = readU16();
0239       uint16_t UpperBound = readU16();
0240       uint32_t Default = readU32();
0241 
0242       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0243       const int64_t Opcode = State.MIs[InsnID]->getOpcode();
0244 
0245       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
0246         dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
0247                << LowerBound << ", " << UpperBound << "), Default=" << Default
0248                << ", JumpTable...) // Got=" << Opcode << "\n";
0249       });
0250       if (Opcode < LowerBound || UpperBound <= Opcode) {
0251         CurrentIdx = Default;
0252         break;
0253       }
0254       const auto EntryIdx = (Opcode - LowerBound);
0255       // Each entry is 4 bytes
0256       CurrentIdx =
0257           readBytesAs<uint32_t>(MatchTable + CurrentIdx + (EntryIdx * 4));
0258       if (!CurrentIdx) {
0259         CurrentIdx = Default;
0260         break;
0261       }
0262       OnFailResumeAt.push_back(Default);
0263       break;
0264     }
0265 
0266     case GIM_SwitchType: {
0267       uint64_t InsnID = readULEB();
0268       uint64_t OpIdx = readULEB();
0269       uint16_t LowerBound = readU16();
0270       uint16_t UpperBound = readU16();
0271       int64_t Default = readU32();
0272 
0273       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0274       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0275 
0276       DEBUG_WITH_TYPE(TgtExecutor::getName(), {
0277         dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID
0278                << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", "
0279                << UpperBound << "), Default=" << Default
0280                << ", JumpTable...) // Got=";
0281         if (!MO.isReg())
0282           dbgs() << "Not a VReg\n";
0283         else
0284           dbgs() << MRI.getType(MO.getReg()) << "\n";
0285       });
0286       if (!MO.isReg()) {
0287         CurrentIdx = Default;
0288         break;
0289       }
0290       const LLT Ty = MRI.getType(MO.getReg());
0291       const auto TyI = ExecInfo.TypeIDMap.find(Ty);
0292       if (TyI == ExecInfo.TypeIDMap.end()) {
0293         CurrentIdx = Default;
0294         break;
0295       }
0296       const int64_t TypeID = TyI->second;
0297       if (TypeID < LowerBound || UpperBound <= TypeID) {
0298         CurrentIdx = Default;
0299         break;
0300       }
0301       const auto NumEntry = (TypeID - LowerBound);
0302       // Each entry is 4 bytes
0303       CurrentIdx =
0304           readBytesAs<uint32_t>(MatchTable + CurrentIdx + (NumEntry * 4));
0305       if (!CurrentIdx) {
0306         CurrentIdx = Default;
0307         break;
0308       }
0309       OnFailResumeAt.push_back(Default);
0310       break;
0311     }
0312 
0313     case GIM_CheckNumOperandsGE:
0314     case GIM_CheckNumOperandsLE: {
0315       uint64_t InsnID = readULEB();
0316       uint64_t Expected = readULEB();
0317       const bool IsLE = (MatcherOpcode == GIM_CheckNumOperandsLE);
0318       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0319                       dbgs() << CurrentIdx << ": GIM_CheckNumOperands"
0320                              << (IsLE ? "LE" : "GE") << "(MIs[" << InsnID
0321                              << "], Expected=" << Expected << ")\n");
0322       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0323       const unsigned NumOps = State.MIs[InsnID]->getNumOperands();
0324       if (IsLE ? (NumOps > Expected) : (NumOps < Expected)) {
0325         if (handleReject() == RejectAndGiveUp)
0326           return false;
0327       }
0328       break;
0329     }
0330     case GIM_CheckNumOperands: {
0331       uint64_t InsnID = readULEB();
0332       uint64_t Expected = readULEB();
0333       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0334                       dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs["
0335                              << InsnID << "], Expected=" << Expected << ")\n");
0336       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0337       if (State.MIs[InsnID]->getNumOperands() != Expected) {
0338         if (handleReject() == RejectAndGiveUp)
0339           return false;
0340       }
0341       break;
0342     }
0343     case GIM_CheckI64ImmPredicate:
0344     case GIM_CheckImmOperandPredicate: {
0345       uint64_t InsnID = readULEB();
0346       unsigned OpIdx =
0347           MatcherOpcode == GIM_CheckImmOperandPredicate ? readULEB() : 1;
0348       uint16_t Predicate = readU16();
0349       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0350                       dbgs() << CurrentIdx << ": GIM_CheckImmPredicate(MIs["
0351                              << InsnID << "]->getOperand(" << OpIdx
0352                              << "), Predicate=" << Predicate << ")\n");
0353       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0354       assert((State.MIs[InsnID]->getOperand(OpIdx).isImm() ||
0355               State.MIs[InsnID]->getOperand(OpIdx).isCImm()) &&
0356              "Expected immediate operand");
0357       assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0358       int64_t Value = 0;
0359       if (State.MIs[InsnID]->getOperand(OpIdx).isCImm())
0360         Value = State.MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue();
0361       else if (State.MIs[InsnID]->getOperand(OpIdx).isImm())
0362         Value = State.MIs[InsnID]->getOperand(OpIdx).getImm();
0363       else
0364         llvm_unreachable("Expected Imm or CImm operand");
0365 
0366       if (!testImmPredicate_I64(Predicate, Value))
0367         if (handleReject() == RejectAndGiveUp)
0368           return false;
0369       break;
0370     }
0371     case GIM_CheckAPIntImmPredicate: {
0372       uint64_t InsnID = readULEB();
0373       uint16_t Predicate = readU16();
0374       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0375                       dbgs()
0376                           << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
0377                           << InsnID << "], Predicate=" << Predicate << ")\n");
0378       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0379       assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
0380              "Expected G_CONSTANT");
0381       assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0382       if (!State.MIs[InsnID]->getOperand(1).isCImm())
0383         llvm_unreachable("Expected Imm or CImm operand");
0384 
0385       const APInt &Value =
0386           State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
0387       if (!testImmPredicate_APInt(Predicate, Value))
0388         if (handleReject() == RejectAndGiveUp)
0389           return false;
0390       break;
0391     }
0392     case GIM_CheckAPFloatImmPredicate: {
0393       uint64_t InsnID = readULEB();
0394       uint16_t Predicate = readU16();
0395       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0396                       dbgs()
0397                           << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs["
0398                           << InsnID << "], Predicate=" << Predicate << ")\n");
0399       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0400       assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
0401              "Expected G_FCONSTANT");
0402       assert(State.MIs[InsnID]->getOperand(1).isFPImm() &&
0403              "Expected FPImm operand");
0404       assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0405       const APFloat &Value =
0406           State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
0407 
0408       if (!testImmPredicate_APFloat(Predicate, Value))
0409         if (handleReject() == RejectAndGiveUp)
0410           return false;
0411       break;
0412     }
0413     case GIM_CheckIsBuildVectorAllOnes:
0414     case GIM_CheckIsBuildVectorAllZeros: {
0415       uint64_t InsnID = readULEB();
0416 
0417       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0418                       dbgs() << CurrentIdx
0419                              << ": GIM_CheckBuildVectorAll{Zeros|Ones}(MIs["
0420                              << InsnID << "])\n");
0421       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0422 
0423       const MachineInstr *MI = State.MIs[InsnID];
0424       assert((MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
0425               MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC) &&
0426              "Expected G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC");
0427 
0428       if (MatcherOpcode == GIM_CheckIsBuildVectorAllOnes) {
0429         if (!isBuildVectorAllOnes(*MI, MRI)) {
0430           if (handleReject() == RejectAndGiveUp)
0431             return false;
0432         }
0433       } else {
0434         if (!isBuildVectorAllZeros(*MI, MRI)) {
0435           if (handleReject() == RejectAndGiveUp)
0436             return false;
0437         }
0438       }
0439 
0440       break;
0441     }
0442     case GIM_CheckSimplePredicate: {
0443       // Note: we don't check for invalid here because this is purely a hook to
0444       // allow some executors (such as the combiner) to check arbitrary,
0445       // contextless predicates, such as whether a rule is enabled or not.
0446       uint16_t Predicate = readU16();
0447       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0448                       dbgs() << CurrentIdx
0449                              << ": GIM_CheckSimplePredicate(Predicate="
0450                              << Predicate << ")\n");
0451       assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0452       if (!testSimplePredicate(Predicate)) {
0453         if (handleReject() == RejectAndGiveUp)
0454           return false;
0455       }
0456       break;
0457     }
0458     case GIM_CheckCxxInsnPredicate: {
0459       uint64_t InsnID = readULEB();
0460       uint16_t Predicate = readU16();
0461       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0462                       dbgs()
0463                           << CurrentIdx << ": GIM_CheckCxxPredicate(MIs["
0464                           << InsnID << "], Predicate=" << Predicate << ")\n");
0465       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0466       assert(Predicate > GICXXPred_Invalid && "Expected a valid predicate");
0467 
0468       if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID], State))
0469         if (handleReject() == RejectAndGiveUp)
0470           return false;
0471       break;
0472     }
0473     case GIM_CheckHasNoUse: {
0474       uint64_t InsnID = readULEB();
0475 
0476       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0477                       dbgs() << CurrentIdx << ": GIM_CheckHasNoUse(MIs["
0478                              << InsnID << "]\n");
0479 
0480       const MachineInstr *MI = State.MIs[InsnID];
0481       assert(MI && "Used insn before defined");
0482       assert(MI->getNumDefs() > 0 && "No defs");
0483       const Register Res = MI->getOperand(0).getReg();
0484 
0485       if (!MRI.use_nodbg_empty(Res)) {
0486         if (handleReject() == RejectAndGiveUp)
0487           return false;
0488       }
0489       break;
0490     }
0491     case GIM_CheckHasOneUse: {
0492       uint64_t InsnID = readULEB();
0493 
0494       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0495                       dbgs() << CurrentIdx << ": GIM_CheckHasOneUse(MIs["
0496                              << InsnID << "]\n");
0497 
0498       const MachineInstr *MI = State.MIs[InsnID];
0499       assert(MI && "Used insn before defined");
0500       assert(MI->getNumDefs() > 0 && "No defs");
0501       const Register Res = MI->getOperand(0).getReg();
0502 
0503       if (!MRI.hasOneNonDBGUse(Res)) {
0504         if (handleReject() == RejectAndGiveUp)
0505           return false;
0506       }
0507       break;
0508     }
0509     case GIM_CheckAtomicOrdering: {
0510       uint64_t InsnID = readULEB();
0511       auto Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
0512       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0513                       dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs["
0514                              << InsnID << "], " << (uint64_t)Ordering << ")\n");
0515       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0516       if (!State.MIs[InsnID]->hasOneMemOperand())
0517         if (handleReject() == RejectAndGiveUp)
0518           return false;
0519 
0520       for (const auto &MMO : State.MIs[InsnID]->memoperands())
0521         if (MMO->getMergedOrdering() != Ordering)
0522           if (handleReject() == RejectAndGiveUp)
0523             return false;
0524       break;
0525     }
0526     case GIM_CheckAtomicOrderingOrStrongerThan: {
0527       uint64_t InsnID = readULEB();
0528       auto Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
0529       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0530                       dbgs() << CurrentIdx
0531                              << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
0532                              << InsnID << "], " << (uint64_t)Ordering << ")\n");
0533       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0534       if (!State.MIs[InsnID]->hasOneMemOperand())
0535         if (handleReject() == RejectAndGiveUp)
0536           return false;
0537 
0538       for (const auto &MMO : State.MIs[InsnID]->memoperands())
0539         if (!isAtLeastOrStrongerThan(MMO->getMergedOrdering(), Ordering))
0540           if (handleReject() == RejectAndGiveUp)
0541             return false;
0542       break;
0543     }
0544     case GIM_CheckAtomicOrderingWeakerThan: {
0545       uint64_t InsnID = readULEB();
0546       auto Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
0547       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0548                       dbgs() << CurrentIdx
0549                              << ": GIM_CheckAtomicOrderingWeakerThan(MIs["
0550                              << InsnID << "], " << (uint64_t)Ordering << ")\n");
0551       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0552       if (!State.MIs[InsnID]->hasOneMemOperand())
0553         if (handleReject() == RejectAndGiveUp)
0554           return false;
0555 
0556       for (const auto &MMO : State.MIs[InsnID]->memoperands())
0557         if (!isStrongerThan(Ordering, MMO->getMergedOrdering()))
0558           if (handleReject() == RejectAndGiveUp)
0559             return false;
0560       break;
0561     }
0562     case GIM_CheckMemoryAddressSpace: {
0563       uint64_t InsnID = readULEB();
0564       uint64_t MMOIdx = readULEB();
0565       // This accepts a list of possible address spaces.
0566       const uint64_t NumAddrSpace = MatchTable[CurrentIdx++];
0567 
0568       if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
0569         if (handleReject() == RejectAndGiveUp)
0570           return false;
0571         break;
0572       }
0573 
0574       // Need to still jump to the end of the list of address spaces if we find
0575       // a match earlier.
0576       const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
0577 
0578       const MachineMemOperand *MMO =
0579           *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
0580       const unsigned MMOAddrSpace = MMO->getAddrSpace();
0581 
0582       bool Success = false;
0583       for (unsigned I = 0; I != NumAddrSpace; ++I) {
0584         uint64_t AddrSpace = readULEB();
0585         DEBUG_WITH_TYPE(TgtExecutor::getName(),
0586                         dbgs() << "addrspace(" << MMOAddrSpace << ") vs "
0587                                << AddrSpace << '\n');
0588 
0589         if (AddrSpace == MMOAddrSpace) {
0590           Success = true;
0591           break;
0592         }
0593       }
0594 
0595       CurrentIdx = LastIdx;
0596       if (!Success && handleReject() == RejectAndGiveUp)
0597         return false;
0598       break;
0599     }
0600     case GIM_CheckMemoryAlignment: {
0601       uint64_t InsnID = readULEB();
0602       uint64_t MMOIdx = readULEB();
0603       uint64_t MinAlign = MatchTable[CurrentIdx++];
0604 
0605       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0606 
0607       if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
0608         if (handleReject() == RejectAndGiveUp)
0609           return false;
0610         break;
0611       }
0612 
0613       MachineMemOperand *MMO =
0614           *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
0615       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0616                       dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment"
0617                              << "(MIs[" << InsnID << "]->memoperands() + "
0618                              << MMOIdx << ")->getAlignment() >= " << MinAlign
0619                              << ")\n");
0620       if (MMO->getAlign() < MinAlign && handleReject() == RejectAndGiveUp)
0621         return false;
0622 
0623       break;
0624     }
0625     case GIM_CheckMemorySizeEqualTo: {
0626       uint64_t InsnID = readULEB();
0627       uint64_t MMOIdx = readULEB();
0628       uint32_t Size = readU32();
0629 
0630       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0631                       dbgs() << CurrentIdx << ": GIM_CheckMemorySizeEqual(MIs["
0632                              << InsnID << "]->memoperands() + " << MMOIdx
0633                              << ", Size=" << Size << ")\n");
0634       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0635 
0636       if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
0637         if (handleReject() == RejectAndGiveUp)
0638           return false;
0639         break;
0640       }
0641 
0642       MachineMemOperand *MMO =
0643           *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
0644 
0645       DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << MMO->getSize()
0646                                                      << " bytes vs " << Size
0647                                                      << " bytes\n");
0648       if (MMO->getSize() != Size)
0649         if (handleReject() == RejectAndGiveUp)
0650           return false;
0651 
0652       break;
0653     }
0654     case GIM_CheckMemorySizeEqualToLLT:
0655     case GIM_CheckMemorySizeLessThanLLT:
0656     case GIM_CheckMemorySizeGreaterThanLLT: {
0657       uint64_t InsnID = readULEB();
0658       uint64_t MMOIdx = readULEB();
0659       uint64_t OpIdx = readULEB();
0660 
0661       DEBUG_WITH_TYPE(
0662           TgtExecutor::getName(),
0663           dbgs() << CurrentIdx << ": GIM_CheckMemorySize"
0664                  << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT ? "EqualTo"
0665                      : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT
0666                          ? "GreaterThan"
0667                          : "LessThan")
0668                  << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
0669                  << ", OpIdx=" << OpIdx << ")\n");
0670       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0671 
0672       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0673       if (!MO.isReg()) {
0674         DEBUG_WITH_TYPE(TgtExecutor::getName(),
0675                         dbgs() << CurrentIdx << ": Not a register\n");
0676         if (handleReject() == RejectAndGiveUp)
0677           return false;
0678         break;
0679       }
0680 
0681       if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
0682         if (handleReject() == RejectAndGiveUp)
0683           return false;
0684         break;
0685       }
0686 
0687       MachineMemOperand *MMO =
0688           *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
0689 
0690       const TypeSize Size = MRI.getType(MO.getReg()).getSizeInBits();
0691       if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT &&
0692           MMO->getSizeInBits() != Size) {
0693         if (handleReject() == RejectAndGiveUp)
0694           return false;
0695       } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT &&
0696                  TypeSize::isKnownGE(MMO->getSizeInBits().getValue(), Size)) {
0697         if (handleReject() == RejectAndGiveUp)
0698           return false;
0699       } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT &&
0700                  TypeSize::isKnownLE(MMO->getSizeInBits().getValue(), Size))
0701         if (handleReject() == RejectAndGiveUp)
0702           return false;
0703 
0704       break;
0705     }
0706     case GIM_RootCheckType:
0707     case GIM_CheckType: {
0708       uint64_t InsnID = (MatcherOpcode == GIM_RootCheckType) ? 0 : readULEB();
0709       uint64_t OpIdx = readULEB();
0710       int TypeID = readS8();
0711       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0712                       dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
0713                              << "]->getOperand(" << OpIdx
0714                              << "), TypeID=" << TypeID << ")\n");
0715       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0716       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0717       if (!MO.isReg() || MRI.getType(MO.getReg()) != getTypeFromIdx(TypeID)) {
0718         if (handleReject() == RejectAndGiveUp)
0719           return false;
0720       }
0721       break;
0722     }
0723     case GIM_CheckPointerToAny: {
0724       uint64_t InsnID = readULEB();
0725       uint64_t OpIdx = readULEB();
0726       uint64_t SizeInBits = readULEB();
0727 
0728       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0729                       dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
0730                              << InsnID << "]->getOperand(" << OpIdx
0731                              << "), SizeInBits=" << SizeInBits << ")\n");
0732       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0733       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0734       const LLT Ty = MRI.getType(MO.getReg());
0735 
0736       // iPTR must be looked up in the target.
0737       if (SizeInBits == 0) {
0738         MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
0739         const unsigned AddrSpace = Ty.getAddressSpace();
0740         SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace);
0741       }
0742 
0743       assert(SizeInBits != 0 && "Pointer size must be known");
0744 
0745       if (MO.isReg()) {
0746         if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
0747           if (handleReject() == RejectAndGiveUp)
0748             return false;
0749       } else if (handleReject() == RejectAndGiveUp)
0750         return false;
0751 
0752       break;
0753     }
0754     case GIM_RecordNamedOperand: {
0755       uint64_t InsnID = readULEB();
0756       uint64_t OpIdx = readULEB();
0757       uint64_t StoreIdx = readULEB();
0758 
0759       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0760                       dbgs() << CurrentIdx << ": GIM_RecordNamedOperand(MIs["
0761                              << InsnID << "]->getOperand(" << OpIdx
0762                              << "), StoreIdx=" << StoreIdx << ")\n");
0763       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0764       assert(StoreIdx < State.RecordedOperands.size() && "Index out of range");
0765       State.RecordedOperands[StoreIdx] = &State.MIs[InsnID]->getOperand(OpIdx);
0766       break;
0767     }
0768     case GIM_RecordRegType: {
0769       uint64_t InsnID = readULEB();
0770       uint64_t OpIdx = readULEB();
0771       int TypeIdx = readS8();
0772 
0773       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0774                       dbgs() << CurrentIdx << ": GIM_RecordRegType(MIs["
0775                              << InsnID << "]->getOperand(" << OpIdx
0776                              << "), TypeIdx=" << TypeIdx << ")\n");
0777       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0778       assert(TypeIdx < 0 && "Temp types always have negative indexes!");
0779       // Indexes start at -1.
0780       TypeIdx = 1 - TypeIdx;
0781       const auto &Op = State.MIs[InsnID]->getOperand(OpIdx);
0782       if (State.RecordedTypes.size() <= (uint64_t)TypeIdx)
0783         State.RecordedTypes.resize(TypeIdx + 1, LLT());
0784       State.RecordedTypes[TypeIdx] = MRI.getType(Op.getReg());
0785       break;
0786     }
0787 
0788     case GIM_RootCheckRegBankForClass:
0789     case GIM_CheckRegBankForClass: {
0790       uint64_t InsnID =
0791           (MatcherOpcode == GIM_RootCheckRegBankForClass) ? 0 : readULEB();
0792       uint64_t OpIdx = readULEB();
0793       uint16_t RCEnum = readU16();
0794       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0795                       dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
0796                              << InsnID << "]->getOperand(" << OpIdx
0797                              << "), RCEnum=" << RCEnum << ")\n");
0798       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0799       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0800       if (!MO.isReg() ||
0801           &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum),
0802                                       MRI.getType(MO.getReg())) !=
0803               RBI.getRegBank(MO.getReg(), MRI, TRI)) {
0804         if (handleReject() == RejectAndGiveUp)
0805           return false;
0806       }
0807       break;
0808     }
0809 
0810     case GIM_CheckComplexPattern: {
0811       uint64_t InsnID = readULEB();
0812       uint64_t OpIdx = readULEB();
0813       uint16_t RendererID = readU16();
0814       uint16_t ComplexPredicateID = readU16();
0815       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0816                       dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
0817                              << "] = GIM_CheckComplexPattern(MIs[" << InsnID
0818                              << "]->getOperand(" << OpIdx
0819                              << "), ComplexPredicateID=" << ComplexPredicateID
0820                              << ")\n");
0821       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0822       // FIXME: Use std::invoke() when it's available.
0823       ComplexRendererFns Renderer =
0824           (Exec.*ExecInfo.ComplexPredicates[ComplexPredicateID])(
0825               State.MIs[InsnID]->getOperand(OpIdx));
0826       if (Renderer)
0827         State.Renderers[RendererID] = *Renderer;
0828       else if (handleReject() == RejectAndGiveUp)
0829         return false;
0830       break;
0831     }
0832 
0833     case GIM_CheckConstantInt:
0834     case GIM_CheckConstantInt8: {
0835       const bool IsInt8 = (MatcherOpcode == GIM_CheckConstantInt8);
0836 
0837       uint64_t InsnID = readULEB();
0838       uint64_t OpIdx = readULEB();
0839       uint64_t Value = IsInt8 ? (int64_t)readS8() : readU64();
0840       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0841                       dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
0842                              << InsnID << "]->getOperand(" << OpIdx
0843                              << "), Value=" << Value << ")\n");
0844       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0845       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0846       if (MO.isReg()) {
0847         // isOperandImmEqual() will sign-extend to 64-bits, so should we.
0848         LLT Ty = MRI.getType(MO.getReg());
0849         // If the type is > 64 bits, it can't be a constant int, so we bail
0850         // early because SignExtend64 will assert otherwise.
0851         if (Ty.getScalarSizeInBits() > 64) {
0852           if (handleReject() == RejectAndGiveUp)
0853             return false;
0854           break;
0855         }
0856 
0857         Value = SignExtend64(Value, Ty.getScalarSizeInBits());
0858         if (!isOperandImmEqual(MO, Value, MRI, /*Splat=*/true)) {
0859           if (handleReject() == RejectAndGiveUp)
0860             return false;
0861         }
0862       } else if (handleReject() == RejectAndGiveUp)
0863         return false;
0864 
0865       break;
0866     }
0867 
0868     case GIM_CheckLiteralInt: {
0869       uint64_t InsnID = readULEB();
0870       uint64_t OpIdx = readULEB();
0871       int64_t Value = readU64();
0872       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0873                       dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
0874                              << InsnID << "]->getOperand(" << OpIdx
0875                              << "), Value=" << Value << ")\n");
0876       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0877       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0878       if (MO.isImm() && MO.getImm() == Value)
0879         break;
0880 
0881       if (MO.isCImm() && MO.getCImm()->equalsInt(Value))
0882         break;
0883 
0884       if (handleReject() == RejectAndGiveUp)
0885         return false;
0886 
0887       break;
0888     }
0889 
0890     case GIM_CheckIntrinsicID: {
0891       uint64_t InsnID = readULEB();
0892       uint64_t OpIdx = readULEB();
0893       uint16_t Value = readU16();
0894       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0895                       dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
0896                              << InsnID << "]->getOperand(" << OpIdx
0897                              << "), Value=" << Value << ")\n");
0898       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0899       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0900       if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
0901         if (handleReject() == RejectAndGiveUp)
0902           return false;
0903       break;
0904     }
0905     case GIM_CheckCmpPredicate: {
0906       uint64_t InsnID = readULEB();
0907       uint64_t OpIdx = readULEB();
0908       uint16_t Value = readU16();
0909       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0910                       dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs["
0911                              << InsnID << "]->getOperand(" << OpIdx
0912                              << "), Value=" << Value << ")\n");
0913       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0914       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
0915       if (!MO.isPredicate() || MO.getPredicate() != Value)
0916         if (handleReject() == RejectAndGiveUp)
0917           return false;
0918       break;
0919     }
0920     case GIM_CheckIsMBB: {
0921       uint64_t InsnID = readULEB();
0922       uint64_t OpIdx = readULEB();
0923       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0924                       dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
0925                              << "]->getOperand(" << OpIdx << "))\n");
0926       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0927       if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
0928         if (handleReject() == RejectAndGiveUp)
0929           return false;
0930       }
0931       break;
0932     }
0933     case GIM_CheckIsImm: {
0934       uint64_t InsnID = readULEB();
0935       uint64_t OpIdx = readULEB();
0936       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0937                       dbgs() << CurrentIdx << ": GIM_CheckIsImm(MIs[" << InsnID
0938                              << "]->getOperand(" << OpIdx << "))\n");
0939       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0940       if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) {
0941         if (handleReject() == RejectAndGiveUp)
0942           return false;
0943       }
0944       break;
0945     }
0946     case GIM_CheckIsSafeToFold: {
0947       uint64_t NumInsn = MatchTable[CurrentIdx++];
0948       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0949                       dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(N = "
0950                              << NumInsn << ")\n");
0951       MachineInstr &Root = *State.MIs[0];
0952       for (unsigned K = 1, E = NumInsn + 1; K < E; ++K) {
0953         if (!isObviouslySafeToFold(*State.MIs[K], Root)) {
0954           if (handleReject() == RejectAndGiveUp)
0955             return false;
0956         }
0957       }
0958       break;
0959     }
0960     case GIM_CheckIsSameOperand:
0961     case GIM_CheckIsSameOperandIgnoreCopies: {
0962       uint64_t InsnID = readULEB();
0963       uint64_t OpIdx = readULEB();
0964       uint64_t OtherInsnID = readULEB();
0965       uint64_t OtherOpIdx = readULEB();
0966       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0967                       dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
0968                              << InsnID << "][" << OpIdx << "], MIs["
0969                              << OtherInsnID << "][" << OtherOpIdx << "])\n");
0970       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
0971       assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
0972 
0973       MachineOperand &Op = State.MIs[InsnID]->getOperand(OpIdx);
0974       MachineOperand &OtherOp = State.MIs[OtherInsnID]->getOperand(OtherOpIdx);
0975 
0976       if (MatcherOpcode == GIM_CheckIsSameOperandIgnoreCopies) {
0977         if (Op.isReg() && OtherOp.isReg()) {
0978           if (getSrcRegIgnoringCopies(Op.getReg(), MRI) ==
0979               getSrcRegIgnoringCopies(OtherOp.getReg(), MRI))
0980             break;
0981         }
0982       }
0983 
0984       if (!Op.isIdenticalTo(OtherOp)) {
0985         if (handleReject() == RejectAndGiveUp)
0986           return false;
0987       }
0988       break;
0989     }
0990     case GIM_CheckCanReplaceReg: {
0991       uint64_t OldInsnID = readULEB();
0992       uint64_t OldOpIdx = readULEB();
0993       uint64_t NewInsnID = readULEB();
0994       uint64_t NewOpIdx = readULEB();
0995 
0996       DEBUG_WITH_TYPE(TgtExecutor::getName(),
0997                       dbgs() << CurrentIdx << ": GIM_CheckCanReplaceReg(MIs["
0998                              << OldInsnID << "][" << OldOpIdx << "] = MIs["
0999                              << NewInsnID << "][" << NewOpIdx << "])\n");
1000 
1001       Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1002       Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1003       if (!canReplaceReg(Old, New, MRI)) {
1004         if (handleReject() == RejectAndGiveUp)
1005           return false;
1006       }
1007       break;
1008     }
1009     case GIM_MIFlags: {
1010       uint64_t InsnID = readULEB();
1011       uint32_t Flags = readU32();
1012 
1013       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1014                       dbgs() << CurrentIdx << ": GIM_MIFlags(MIs[" << InsnID
1015                              << "], " << Flags << ")\n");
1016       if ((State.MIs[InsnID]->getFlags() & Flags) != Flags) {
1017         if (handleReject() == RejectAndGiveUp)
1018           return false;
1019       }
1020       break;
1021     }
1022     case GIM_MIFlagsNot: {
1023       uint64_t InsnID = readULEB();
1024       uint32_t Flags = readU32();
1025 
1026       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1027                       dbgs() << CurrentIdx << ": GIM_MIFlagsNot(MIs[" << InsnID
1028                              << "], " << Flags << ")\n");
1029       if ((State.MIs[InsnID]->getFlags() & Flags)) {
1030         if (handleReject() == RejectAndGiveUp)
1031           return false;
1032       }
1033       break;
1034     }
1035     case GIM_Reject:
1036       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1037                       dbgs() << CurrentIdx << ": GIM_Reject\n");
1038       if (handleReject() == RejectAndGiveUp)
1039         return false;
1040       break;
1041     case GIR_MutateOpcode: {
1042       uint64_t OldInsnID = readULEB();
1043       uint64_t NewInsnID = readULEB();
1044       uint16_t NewOpcode = readU16();
1045       if (NewInsnID >= OutMIs.size())
1046         OutMIs.resize(NewInsnID + 1);
1047 
1048       MachineInstr *OldMI = State.MIs[OldInsnID];
1049       if (Observer)
1050         Observer->changingInstr(*OldMI);
1051       OutMIs[NewInsnID] = MachineInstrBuilder(*OldMI->getMF(), OldMI);
1052       OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
1053       if (Observer)
1054         Observer->changedInstr(*OldMI);
1055       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1056                       dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
1057                              << NewInsnID << "], MIs[" << OldInsnID << "], "
1058                              << NewOpcode << ")\n");
1059       break;
1060     }
1061 
1062     case GIR_BuildRootMI:
1063     case GIR_BuildMI: {
1064       uint64_t NewInsnID = (MatcherOpcode == GIR_BuildRootMI) ? 0 : readULEB();
1065       uint16_t Opcode = readU16();
1066       if (NewInsnID >= OutMIs.size())
1067         OutMIs.resize(NewInsnID + 1);
1068 
1069       OutMIs[NewInsnID] = Builder.buildInstr(Opcode);
1070       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1071                       dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
1072                              << NewInsnID << "], " << Opcode << ")\n");
1073       break;
1074     }
1075 
1076     case GIR_BuildConstant: {
1077       uint64_t TempRegID = readULEB();
1078       uint64_t Imm = readU64();
1079       Builder.buildConstant(State.TempRegisters[TempRegID], Imm);
1080       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1081                       dbgs() << CurrentIdx << ": GIR_BuildConstant(TempReg["
1082                              << TempRegID << "], Imm=" << Imm << ")\n");
1083       break;
1084     }
1085 
1086     case GIR_RootToRootCopy:
1087     case GIR_Copy: {
1088       uint64_t NewInsnID =
1089           (MatcherOpcode == GIR_RootToRootCopy) ? 0 : readULEB();
1090       uint64_t OldInsnID =
1091           (MatcherOpcode == GIR_RootToRootCopy) ? 0 : readULEB();
1092       uint64_t OpIdx = readULEB();
1093       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1094       OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
1095       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1096                       dbgs()
1097                           << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
1098                           << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
1099       break;
1100     }
1101 
1102     case GIR_CopyRemaining: {
1103       uint64_t NewInsnID = readULEB();
1104       uint64_t OldInsnID = readULEB();
1105       uint64_t OpIdx = readULEB();
1106       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1107       MachineInstr &OldMI = *State.MIs[OldInsnID];
1108       MachineInstrBuilder &NewMI = OutMIs[NewInsnID];
1109       for (const auto &Op : drop_begin(OldMI.operands(), OpIdx))
1110         NewMI.add(Op);
1111       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1112                       dbgs() << CurrentIdx << ": GIR_CopyRemaining(OutMIs["
1113                              << NewInsnID << "], MIs[" << OldInsnID
1114                              << "], /*start=*/" << OpIdx << ")\n");
1115       break;
1116     }
1117 
1118     case GIR_CopyOrAddZeroReg: {
1119       uint64_t NewInsnID = readULEB();
1120       uint64_t OldInsnID = readULEB();
1121       uint64_t OpIdx = readULEB();
1122       uint16_t ZeroReg = readU16();
1123       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1124       MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
1125       if (isOperandImmEqual(MO, 0, MRI))
1126         OutMIs[NewInsnID].addReg(ZeroReg);
1127       else
1128         OutMIs[NewInsnID].add(MO);
1129       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1130                       dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
1131                              << NewInsnID << "], MIs[" << OldInsnID << "], "
1132                              << OpIdx << ", " << ZeroReg << ")\n");
1133       break;
1134     }
1135 
1136     case GIR_CopySubReg: {
1137       uint64_t NewInsnID = readULEB();
1138       uint64_t OldInsnID = readULEB();
1139       uint64_t OpIdx = readULEB();
1140       uint16_t SubRegIdx = readU16();
1141       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1142       OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
1143                                0, SubRegIdx);
1144       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1145                       dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
1146                              << NewInsnID << "], MIs[" << OldInsnID << "], "
1147                              << OpIdx << ", " << SubRegIdx << ")\n");
1148       break;
1149     }
1150 
1151     case GIR_AddImplicitDef: {
1152       uint64_t InsnID = readULEB();
1153       uint16_t RegNum = readU16();
1154       uint16_t Flags = readU16();
1155       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1156       Flags |= RegState::Implicit;
1157       OutMIs[InsnID].addDef(RegNum, Flags);
1158       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1159                       dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
1160                              << InsnID << "], " << RegNum << ")\n");
1161       break;
1162     }
1163 
1164     case GIR_AddImplicitUse: {
1165       uint64_t InsnID = readULEB();
1166       uint16_t RegNum = readU16();
1167       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1168       OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
1169       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1170                       dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
1171                              << InsnID << "], " << RegNum << ")\n");
1172       break;
1173     }
1174 
1175     case GIR_AddRegister: {
1176       uint64_t InsnID = readULEB();
1177       uint16_t RegNum = readU16();
1178       uint16_t RegFlags = readU16();
1179       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1180       OutMIs[InsnID].addReg(RegNum, RegFlags);
1181       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1182                       dbgs()
1183                           << CurrentIdx << ": GIR_AddRegister(OutMIs[" << InsnID
1184                           << "], " << RegNum << ", " << RegFlags << ")\n");
1185       break;
1186     }
1187     case GIR_AddIntrinsicID: {
1188       uint64_t InsnID = readULEB();
1189       uint16_t Value = readU16();
1190       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1191       OutMIs[InsnID].addIntrinsicID((Intrinsic::ID)Value);
1192       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1193                       dbgs() << CurrentIdx << ": GIR_AddIntrinsicID(OutMIs["
1194                              << InsnID << "], " << Value << ")\n");
1195       break;
1196     }
1197     case GIR_SetImplicitDefDead: {
1198       uint64_t InsnID = readULEB();
1199       uint64_t OpIdx = readULEB();
1200       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1201                       dbgs() << CurrentIdx << ": GIR_SetImplicitDefDead(OutMIs["
1202                              << InsnID << "], OpIdx=" << OpIdx << ")\n");
1203       MachineInstr *MI = OutMIs[InsnID];
1204       assert(MI && "Modifying undefined instruction");
1205       MI->getOperand(MI->getNumExplicitOperands() + OpIdx).setIsDead();
1206       break;
1207     }
1208     case GIR_SetMIFlags: {
1209       uint64_t InsnID = readULEB();
1210       uint32_t Flags = readU32();
1211 
1212       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1213                       dbgs() << CurrentIdx << ": GIR_SetMIFlags(OutMIs["
1214                              << InsnID << "], " << Flags << ")\n");
1215       MachineInstr *MI = OutMIs[InsnID];
1216       MI->setFlags(MI->getFlags() | Flags);
1217       break;
1218     }
1219     case GIR_UnsetMIFlags: {
1220       uint64_t InsnID = readULEB();
1221       uint32_t Flags = readU32();
1222 
1223       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1224                       dbgs() << CurrentIdx << ": GIR_UnsetMIFlags(OutMIs["
1225                              << InsnID << "], " << Flags << ")\n");
1226       MachineInstr *MI = OutMIs[InsnID];
1227       MI->setFlags(MI->getFlags() & ~Flags);
1228       break;
1229     }
1230     case GIR_CopyMIFlags: {
1231       uint64_t InsnID = readULEB();
1232       uint64_t OldInsnID = readULEB();
1233 
1234       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1235                       dbgs() << CurrentIdx << ": GIR_CopyMIFlags(OutMIs["
1236                              << InsnID << "], MIs[" << OldInsnID << "])\n");
1237       MachineInstr *MI = OutMIs[InsnID];
1238       MI->setFlags(MI->getFlags() | State.MIs[OldInsnID]->getFlags());
1239       break;
1240     }
1241     case GIR_AddSimpleTempRegister:
1242     case GIR_AddTempRegister:
1243     case GIR_AddTempSubRegister: {
1244       uint64_t InsnID = readULEB();
1245       uint64_t TempRegID = readULEB();
1246       uint16_t TempRegFlags = 0;
1247       if (MatcherOpcode != GIR_AddSimpleTempRegister)
1248         TempRegFlags = readU16();
1249       uint16_t SubReg = 0;
1250       if (MatcherOpcode == GIR_AddTempSubRegister)
1251         SubReg = readU16();
1252 
1253       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1254 
1255       OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags,
1256                             SubReg);
1257       DEBUG_WITH_TYPE(
1258           TgtExecutor::getName(),
1259           dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs[" << InsnID
1260                  << "], TempRegisters[" << TempRegID << "]";
1261           if (SubReg) dbgs() << '.' << TRI.getSubRegIndexName(SubReg);
1262           dbgs() << ", " << TempRegFlags << ")\n");
1263       break;
1264     }
1265 
1266     case GIR_AddImm8:
1267     case GIR_AddImm: {
1268       const bool IsAdd8 = (MatcherOpcode == GIR_AddImm8);
1269       uint64_t InsnID = readULEB();
1270       uint64_t Imm = IsAdd8 ? (int64_t)readS8() : readU64();
1271       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1272       OutMIs[InsnID].addImm(Imm);
1273       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1274                       dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
1275                              << "], " << Imm << ")\n");
1276       break;
1277     }
1278 
1279     case GIR_AddCImm: {
1280       uint64_t InsnID = readULEB();
1281       int TypeID = readS8();
1282       uint64_t Imm = readU64();
1283       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1284 
1285       unsigned Width = ExecInfo.TypeObjects[TypeID].getScalarSizeInBits();
1286       LLVMContext &Ctx = MF->getFunction().getContext();
1287       OutMIs[InsnID].addCImm(
1288           ConstantInt::get(IntegerType::get(Ctx, Width), Imm, /*signed*/ true));
1289       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1290                       dbgs() << CurrentIdx << ": GIR_AddCImm(OutMIs[" << InsnID
1291                              << "], TypeID=" << TypeID << ", Imm=" << Imm
1292                              << ")\n");
1293       break;
1294     }
1295 
1296     case GIR_ComplexRenderer: {
1297       uint64_t InsnID = readULEB();
1298       uint16_t RendererID = readU16();
1299       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1300       for (const auto &RenderOpFn : State.Renderers[RendererID])
1301         RenderOpFn(OutMIs[InsnID]);
1302       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1303                       dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
1304                              << InsnID << "], " << RendererID << ")\n");
1305       break;
1306     }
1307     case GIR_ComplexSubOperandRenderer: {
1308       uint64_t InsnID = readULEB();
1309       uint16_t RendererID = readU16();
1310       uint64_t RenderOpID = readULEB();
1311       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1312       State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
1313       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1314                       dbgs() << CurrentIdx
1315                              << ": GIR_ComplexSubOperandRenderer(OutMIs["
1316                              << InsnID << "], " << RendererID << ", "
1317                              << RenderOpID << ")\n");
1318       break;
1319     }
1320     case GIR_ComplexSubOperandSubRegRenderer: {
1321       uint64_t InsnID = readULEB();
1322       uint16_t RendererID = readU16();
1323       uint64_t RenderOpID = readULEB();
1324       uint16_t SubRegIdx = readU16();
1325       MachineInstrBuilder &MI = OutMIs[InsnID];
1326       assert(MI && "Attempted to add to undefined instruction");
1327       State.Renderers[RendererID][RenderOpID](MI);
1328       MI->getOperand(MI->getNumOperands() - 1).setSubReg(SubRegIdx);
1329       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1330                       dbgs() << CurrentIdx
1331                              << ": GIR_ComplexSubOperandSubRegRenderer(OutMIs["
1332                              << InsnID << "], " << RendererID << ", "
1333                              << RenderOpID << ", " << SubRegIdx << ")\n");
1334       break;
1335     }
1336 
1337     case GIR_CopyConstantAsSImm: {
1338       uint64_t NewInsnID = readULEB();
1339       uint64_t OldInsnID = readULEB();
1340       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1341       assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
1342              "Expected G_CONSTANT");
1343       if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
1344         OutMIs[NewInsnID].addImm(
1345             State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
1346       } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
1347         OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
1348       else
1349         llvm_unreachable("Expected Imm or CImm operand");
1350       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1351                       dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
1352                              << NewInsnID << "], MIs[" << OldInsnID << "])\n");
1353       break;
1354     }
1355 
1356     // TODO: Needs a test case once we have a pattern that uses this.
1357     case GIR_CopyFConstantAsFPImm: {
1358       uint64_t NewInsnID = readULEB();
1359       uint64_t OldInsnID = readULEB();
1360       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
1361       assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
1362              "Expected G_FCONSTANT");
1363       if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
1364         OutMIs[NewInsnID].addFPImm(
1365             State.MIs[OldInsnID]->getOperand(1).getFPImm());
1366       else
1367         llvm_unreachable("Expected FPImm operand");
1368       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1369                       dbgs()
1370                           << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs["
1371                           << NewInsnID << "], MIs[" << OldInsnID << "])\n");
1372       break;
1373     }
1374 
1375     case GIR_CustomRenderer: {
1376       uint64_t InsnID = readULEB();
1377       uint64_t OldInsnID = readULEB();
1378       uint16_t RendererFnID = readU16();
1379       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1380       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1381                       dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
1382                              << InsnID << "], MIs[" << OldInsnID << "], "
1383                              << RendererFnID << ")\n");
1384       (Exec.*ExecInfo.CustomRenderers[RendererFnID])(
1385           OutMIs[InsnID], *State.MIs[OldInsnID],
1386           -1); // Not a source operand of the old instruction.
1387       break;
1388     }
1389     case GIR_DoneWithCustomAction: {
1390       uint16_t FnID = readU16();
1391       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1392                       dbgs() << CurrentIdx << ": GIR_DoneWithCustomAction(FnID="
1393                              << FnID << ")\n");
1394       assert(FnID > GICXXCustomAction_Invalid && "Expected a valid FnID");
1395       if (runCustomAction(FnID, State, OutMIs)) {
1396         propagateFlags();
1397         return true;
1398       }
1399 
1400       if (handleReject() == RejectAndGiveUp)
1401         return false;
1402       break;
1403     }
1404     case GIR_CustomOperandRenderer: {
1405       uint64_t InsnID = readULEB();
1406       uint64_t OldInsnID = readULEB();
1407       uint64_t OpIdx = readULEB();
1408       uint16_t RendererFnID = readU16();
1409       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1410 
1411       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1412                       dbgs() << CurrentIdx
1413                              << ": GIR_CustomOperandRenderer(OutMIs[" << InsnID
1414                              << "], MIs[" << OldInsnID << "]->getOperand("
1415                              << OpIdx << "), " << RendererFnID << ")\n");
1416       (Exec.*ExecInfo.CustomRenderers[RendererFnID])(
1417           OutMIs[InsnID], *State.MIs[OldInsnID], OpIdx);
1418       break;
1419     }
1420     case GIR_ConstrainOperandRC: {
1421       uint64_t InsnID = readULEB();
1422       uint64_t OpIdx = readULEB();
1423       uint16_t RCEnum = readU16();
1424       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1425       MachineInstr &I = *OutMIs[InsnID].getInstr();
1426       MachineFunction &MF = *I.getParent()->getParent();
1427       MachineRegisterInfo &MRI = MF.getRegInfo();
1428       const TargetRegisterClass &RC = *TRI.getRegClass(RCEnum);
1429       MachineOperand &MO = I.getOperand(OpIdx);
1430       constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, RC, MO);
1431       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1432                       dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
1433                              << InsnID << "], " << OpIdx << ", " << RCEnum
1434                              << ")\n");
1435       break;
1436     }
1437 
1438     case GIR_RootConstrainSelectedInstOperands:
1439     case GIR_ConstrainSelectedInstOperands: {
1440       uint64_t InsnID = (MatcherOpcode == GIR_RootConstrainSelectedInstOperands)
1441                             ? 0
1442                             : readULEB();
1443       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1444       constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
1445                                        RBI);
1446       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1447                       dbgs() << CurrentIdx
1448                              << ": GIR_ConstrainSelectedInstOperands(OutMIs["
1449                              << InsnID << "])\n");
1450       break;
1451     }
1452     case GIR_MergeMemOperands: {
1453       uint64_t InsnID = readULEB();
1454       uint64_t NumInsn = MatchTable[CurrentIdx++];
1455       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1456 
1457       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1458                       dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
1459                              << InsnID << "]");
1460       for (unsigned K = 0; K < NumInsn; ++K) {
1461         uint64_t NextID = readULEB();
1462         DEBUG_WITH_TYPE(TgtExecutor::getName(),
1463                         dbgs() << ", MIs[" << NextID << "]");
1464         for (const auto &MMO : State.MIs[NextID]->memoperands())
1465           OutMIs[InsnID].addMemOperand(MMO);
1466       }
1467       DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << ")\n");
1468       break;
1469     }
1470     case GIR_EraseFromParent: {
1471       uint64_t InsnID = readULEB();
1472       MachineInstr *MI = State.MIs[InsnID];
1473       assert(MI && "Attempted to erase an undefined instruction");
1474       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1475                       dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
1476                              << InsnID << "])\n");
1477       eraseImpl(MI);
1478       break;
1479     }
1480     case GIR_EraseRootFromParent_Done: {
1481       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1482                       dbgs()
1483                           << CurrentIdx << ": GIR_EraseRootFromParent_Done\n");
1484       eraseImpl(State.MIs[0]);
1485       propagateFlags();
1486       return true;
1487     }
1488     case GIR_MakeTempReg: {
1489       uint64_t TempRegID = readULEB();
1490       int TypeID = readS8();
1491 
1492       State.TempRegisters[TempRegID] =
1493           MRI.createGenericVirtualRegister(getTypeFromIdx(TypeID));
1494       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1495                       dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
1496                              << "] = GIR_MakeTempReg(" << TypeID << ")\n");
1497       break;
1498     }
1499     case GIR_ReplaceReg: {
1500       uint64_t OldInsnID = readULEB();
1501       uint64_t OldOpIdx = readULEB();
1502       uint64_t NewInsnID = readULEB();
1503       uint64_t NewOpIdx = readULEB();
1504 
1505       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1506                       dbgs() << CurrentIdx << ": GIR_ReplaceReg(MIs["
1507                              << OldInsnID << "][" << OldOpIdx << "] = MIs["
1508                              << NewInsnID << "][" << NewOpIdx << "])\n");
1509 
1510       Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1511       Register New = State.MIs[NewInsnID]->getOperand(NewOpIdx).getReg();
1512       if (Observer)
1513         Observer->changingAllUsesOfReg(MRI, Old);
1514       MRI.replaceRegWith(Old, New);
1515       if (Observer)
1516         Observer->finishedChangingAllUsesOfReg();
1517       break;
1518     }
1519     case GIR_ReplaceRegWithTempReg: {
1520       uint64_t OldInsnID = readULEB();
1521       uint64_t OldOpIdx = readULEB();
1522       uint64_t TempRegID = readULEB();
1523 
1524       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1525                       dbgs() << CurrentIdx << ": GIR_ReplaceRegWithTempReg(MIs["
1526                              << OldInsnID << "][" << OldOpIdx << "] = TempRegs["
1527                              << TempRegID << "])\n");
1528 
1529       Register Old = State.MIs[OldInsnID]->getOperand(OldOpIdx).getReg();
1530       Register New = State.TempRegisters[TempRegID];
1531       if (Observer)
1532         Observer->changingAllUsesOfReg(MRI, Old);
1533       MRI.replaceRegWith(Old, New);
1534       if (Observer)
1535         Observer->finishedChangingAllUsesOfReg();
1536       break;
1537     }
1538     case GIR_Coverage: {
1539       uint32_t RuleID = readU32();
1540       assert(CoverageInfo);
1541       CoverageInfo->setCovered(RuleID);
1542 
1543       DEBUG_WITH_TYPE(TgtExecutor::getName(), dbgs() << CurrentIdx
1544                                                      << ": GIR_Coverage("
1545                                                      << RuleID << ")");
1546       break;
1547     }
1548 
1549     case GIR_Done:
1550       DEBUG_WITH_TYPE(TgtExecutor::getName(),
1551                       dbgs() << CurrentIdx << ": GIR_Done\n");
1552       propagateFlags();
1553       return true;
1554     default:
1555       llvm_unreachable("Unexpected command");
1556     }
1557   }
1558 }
1559 
1560 } // end namespace llvm
1561 
1562 #endif // LLVM_CODEGEN_GLOBALISEL_GIMATCHTABLEEXECUTORIMPL_H