1 //===- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h --------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 /// \file This file declares the API for the instruction selector.
10 /// This class is responsible for selecting machine instructions.
11 /// It's implemented by the target. It's used by the InstructionSelect pass.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
16 #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
20 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
21 #include "llvm/CodeGen/GlobalISel/Utils.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineOperand.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 #include "llvm/CodeGen/TargetInstrInfo.h"
26 #include "llvm/CodeGen/TargetOpcodes.h"
27 #include "llvm/CodeGen/TargetRegisterInfo.h"
28 #include "llvm/IR/Constants.h"
29 #include "llvm/IR/DataLayout.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/raw_ostream.h"
39 /// GlobalISel PatFrag Predicates
41 GIPFP_I64_Invalid = 0,
42 GIPFP_APInt_Invalid = 0,
43 GIPFP_APFloat_Invalid = 0,
47 template <class TgtInstructionSelector, class PredicateBitset,
48 class ComplexMatcherMemFn, class CustomRendererFn>
49 bool InstructionSelector::executeMatchTable(
50 TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
51 const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn>
53 const int64_t *MatchTable, const TargetInstrInfo &TII,
54 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
55 const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures,
56 CodeGenCoverage &CoverageInfo) const {
58 uint64_t CurrentIdx = 0;
59 SmallVector<uint64_t, 4> OnFailResumeAt;
61 // Bypass the flag check on the instruction, and only look at the MCInstrDesc.
62 bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
64 const uint16_t Flags = State.MIs[0]->getFlags();
66 enum RejectAction { RejectAndGiveUp, RejectAndResume };
67 auto handleReject = [&]() -> RejectAction {
68 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
69 dbgs() << CurrentIdx << ": Rejected\n");
70 if (OnFailResumeAt.empty())
71 return RejectAndGiveUp;
72 CurrentIdx = OnFailResumeAt.pop_back_val();
73 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
74 dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " ("
75 << OnFailResumeAt.size() << " try-blocks remain)\n");
76 return RejectAndResume;
79 auto propagateFlags = [=](NewMIVector &OutMIs) {
80 for (auto MIB : OutMIs) {
81 // Set the NoFPExcept flag when no original matched instruction could
82 // raise an FP exception, but the new instruction potentially might.
83 uint16_t MIBFlags = Flags;
84 if (NoFPException && MIB->mayRaiseFPException())
85 MIBFlags |= MachineInstr::NoFPExcept;
86 MIB.setMIFlags(MIBFlags);
93 assert(CurrentIdx != ~0u && "Invalid MatchTable index");
94 int64_t MatcherOpcode = MatchTable[CurrentIdx++];
95 switch (MatcherOpcode) {
97 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
98 dbgs() << CurrentIdx << ": Begin try-block\n");
99 OnFailResumeAt.push_back(MatchTable[CurrentIdx++]);
103 case GIM_RecordInsn: {
104 int64_t NewInsnID = MatchTable[CurrentIdx++];
105 int64_t InsnID = MatchTable[CurrentIdx++];
106 int64_t OpIdx = MatchTable[CurrentIdx++];
108 // As an optimisation we require that MIs[0] is always the root. Refuse
109 // any attempt to modify it.
110 assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
112 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
114 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
115 dbgs() << CurrentIdx << ": Not a register\n");
116 if (handleReject() == RejectAndGiveUp)
120 if (Register::isPhysicalRegister(MO.getReg())) {
121 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
122 dbgs() << CurrentIdx << ": Is a physical register\n");
123 if (handleReject() == RejectAndGiveUp)
128 MachineInstr *NewMI = MRI.getVRegDef(MO.getReg());
129 if ((size_t)NewInsnID < State.MIs.size())
130 State.MIs[NewInsnID] = NewMI;
132 assert((size_t)NewInsnID == State.MIs.size() &&
133 "Expected to store MIs in order");
134 State.MIs.push_back(NewMI);
136 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
137 dbgs() << CurrentIdx << ": MIs[" << NewInsnID
138 << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
143 case GIM_CheckFeatures: {
144 int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
145 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
147 << ": GIM_CheckFeatures(ExpectedBitsetID="
148 << ExpectedBitsetID << ")\n");
149 if ((AvailableFeatures & ISelInfo.FeatureBitsets[ExpectedBitsetID]) !=
150 ISelInfo.FeatureBitsets[ExpectedBitsetID]) {
151 if (handleReject() == RejectAndGiveUp)
157 case GIM_CheckOpcode: {
158 int64_t InsnID = MatchTable[CurrentIdx++];
159 int64_t Expected = MatchTable[CurrentIdx++];
161 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
162 unsigned Opcode = State.MIs[InsnID]->getOpcode();
164 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
165 dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
166 << "], ExpectedOpcode=" << Expected
167 << ") // Got=" << Opcode << "\n");
168 if (Opcode != Expected) {
169 if (handleReject() == RejectAndGiveUp)
175 case GIM_SwitchOpcode: {
176 int64_t InsnID = MatchTable[CurrentIdx++];
177 int64_t LowerBound = MatchTable[CurrentIdx++];
178 int64_t UpperBound = MatchTable[CurrentIdx++];
179 int64_t Default = MatchTable[CurrentIdx++];
181 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
182 const int64_t Opcode = State.MIs[InsnID]->getOpcode();
184 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), {
185 dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], ["
186 << LowerBound << ", " << UpperBound << "), Default=" << Default
187 << ", JumpTable...) // Got=" << Opcode << "\n";
189 if (Opcode < LowerBound || UpperBound <= Opcode) {
190 CurrentIdx = Default;
193 CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)];
195 CurrentIdx = Default;
198 OnFailResumeAt.push_back(Default);
202 case GIM_SwitchType: {
203 int64_t InsnID = MatchTable[CurrentIdx++];
204 int64_t OpIdx = MatchTable[CurrentIdx++];
205 int64_t LowerBound = MatchTable[CurrentIdx++];
206 int64_t UpperBound = MatchTable[CurrentIdx++];
207 int64_t Default = MatchTable[CurrentIdx++];
209 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
210 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
212 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), {
213 dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID
214 << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", "
215 << UpperBound << "), Default=" << Default
216 << ", JumpTable...) // Got=";
218 dbgs() << "Not a VReg\n";
220 dbgs() << MRI.getType(MO.getReg()) << "\n";
223 CurrentIdx = Default;
226 const LLT Ty = MRI.getType(MO.getReg());
227 const auto TyI = ISelInfo.TypeIDMap.find(Ty);
228 if (TyI == ISelInfo.TypeIDMap.end()) {
229 CurrentIdx = Default;
232 const int64_t TypeID = TyI->second;
233 if (TypeID < LowerBound || UpperBound <= TypeID) {
234 CurrentIdx = Default;
237 CurrentIdx = MatchTable[CurrentIdx + (TypeID - LowerBound)];
239 CurrentIdx = Default;
242 OnFailResumeAt.push_back(Default);
246 case GIM_CheckNumOperands: {
247 int64_t InsnID = MatchTable[CurrentIdx++];
248 int64_t Expected = MatchTable[CurrentIdx++];
249 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
250 dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs["
251 << InsnID << "], Expected=" << Expected << ")\n");
252 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
253 if (State.MIs[InsnID]->getNumOperands() != Expected) {
254 if (handleReject() == RejectAndGiveUp)
259 case GIM_CheckI64ImmPredicate: {
260 int64_t InsnID = MatchTable[CurrentIdx++];
261 int64_t Predicate = MatchTable[CurrentIdx++];
262 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
264 << CurrentIdx << ": GIM_CheckI64ImmPredicate(MIs["
265 << InsnID << "], Predicate=" << Predicate << ")\n");
266 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
267 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
268 "Expected G_CONSTANT");
269 assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
271 if (State.MIs[InsnID]->getOperand(1).isCImm())
272 Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue();
273 else if (State.MIs[InsnID]->getOperand(1).isImm())
274 Value = State.MIs[InsnID]->getOperand(1).getImm();
276 llvm_unreachable("Expected Imm or CImm operand");
278 if (!testImmPredicate_I64(Predicate, Value))
279 if (handleReject() == RejectAndGiveUp)
283 case GIM_CheckAPIntImmPredicate: {
284 int64_t InsnID = MatchTable[CurrentIdx++];
285 int64_t Predicate = MatchTable[CurrentIdx++];
286 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
288 << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
289 << InsnID << "], Predicate=" << Predicate << ")\n");
290 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
291 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
292 "Expected G_CONSTANT");
293 assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate");
295 if (State.MIs[InsnID]->getOperand(1).isCImm())
296 Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
298 llvm_unreachable("Expected Imm or CImm operand");
300 if (!testImmPredicate_APInt(Predicate, Value))
301 if (handleReject() == RejectAndGiveUp)
305 case GIM_CheckAPFloatImmPredicate: {
306 int64_t InsnID = MatchTable[CurrentIdx++];
307 int64_t Predicate = MatchTable[CurrentIdx++];
308 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
310 << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs["
311 << InsnID << "], Predicate=" << Predicate << ")\n");
312 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
313 assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
314 "Expected G_FCONSTANT");
315 assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand");
316 assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
317 APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
319 if (!testImmPredicate_APFloat(Predicate, Value))
320 if (handleReject() == RejectAndGiveUp)
324 case GIM_CheckCxxInsnPredicate: {
325 int64_t InsnID = MatchTable[CurrentIdx++];
326 int64_t Predicate = MatchTable[CurrentIdx++];
327 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
329 << CurrentIdx << ": GIM_CheckCxxPredicate(MIs["
330 << InsnID << "], Predicate=" << Predicate << ")\n");
331 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
332 assert(Predicate > GIPFP_MI_Invalid && "Expected a valid predicate");
334 if (!testMIPredicate_MI(Predicate, *State.MIs[InsnID]))
335 if (handleReject() == RejectAndGiveUp)
339 case GIM_CheckAtomicOrdering: {
340 int64_t InsnID = MatchTable[CurrentIdx++];
341 AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
342 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
343 dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs["
344 << InsnID << "], " << (uint64_t)Ordering << ")\n");
345 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
346 if (!State.MIs[InsnID]->hasOneMemOperand())
347 if (handleReject() == RejectAndGiveUp)
350 for (const auto &MMO : State.MIs[InsnID]->memoperands())
351 if (MMO->getOrdering() != Ordering)
352 if (handleReject() == RejectAndGiveUp)
356 case GIM_CheckAtomicOrderingOrStrongerThan: {
357 int64_t InsnID = MatchTable[CurrentIdx++];
358 AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
359 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
361 << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
362 << InsnID << "], " << (uint64_t)Ordering << ")\n");
363 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
364 if (!State.MIs[InsnID]->hasOneMemOperand())
365 if (handleReject() == RejectAndGiveUp)
368 for (const auto &MMO : State.MIs[InsnID]->memoperands())
369 if (!isAtLeastOrStrongerThan(MMO->getOrdering(), Ordering))
370 if (handleReject() == RejectAndGiveUp)
374 case GIM_CheckAtomicOrderingWeakerThan: {
375 int64_t InsnID = MatchTable[CurrentIdx++];
376 AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
377 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
379 << ": GIM_CheckAtomicOrderingWeakerThan(MIs["
380 << InsnID << "], " << (uint64_t)Ordering << ")\n");
381 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
382 if (!State.MIs[InsnID]->hasOneMemOperand())
383 if (handleReject() == RejectAndGiveUp)
386 for (const auto &MMO : State.MIs[InsnID]->memoperands())
387 if (!isStrongerThan(Ordering, MMO->getOrdering()))
388 if (handleReject() == RejectAndGiveUp)
392 case GIM_CheckMemoryAddressSpace: {
393 int64_t InsnID = MatchTable[CurrentIdx++];
394 int64_t MMOIdx = MatchTable[CurrentIdx++];
395 // This accepts a list of possible address spaces.
396 const int NumAddrSpace = MatchTable[CurrentIdx++];
398 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
399 if (handleReject() == RejectAndGiveUp)
404 // Need to still jump to the end of the list of address spaces if we find
406 const uint64_t LastIdx = CurrentIdx + NumAddrSpace;
408 const MachineMemOperand *MMO
409 = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
410 const unsigned MMOAddrSpace = MMO->getAddrSpace();
412 bool Success = false;
413 for (int I = 0; I != NumAddrSpace; ++I) {
414 unsigned AddrSpace = MatchTable[CurrentIdx++];
416 TgtInstructionSelector::getName(),
417 dbgs() << "addrspace(" << MMOAddrSpace << ") vs "
418 << AddrSpace << '\n');
420 if (AddrSpace == MMOAddrSpace) {
426 CurrentIdx = LastIdx;
427 if (!Success && handleReject() == RejectAndGiveUp)
431 case GIM_CheckMemoryAlignment: {
432 int64_t InsnID = MatchTable[CurrentIdx++];
433 int64_t MMOIdx = MatchTable[CurrentIdx++];
434 unsigned MinAlign = MatchTable[CurrentIdx++];
436 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
438 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
439 if (handleReject() == RejectAndGiveUp)
444 MachineMemOperand *MMO
445 = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
446 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
447 dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment"
448 << "(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
449 << ")->getAlignment() >= " << MinAlign << ")\n");
450 if (MMO->getAlign() < MinAlign && handleReject() == RejectAndGiveUp)
455 case GIM_CheckMemorySizeEqualTo: {
456 int64_t InsnID = MatchTable[CurrentIdx++];
457 int64_t MMOIdx = MatchTable[CurrentIdx++];
458 uint64_t Size = MatchTable[CurrentIdx++];
460 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
462 << ": GIM_CheckMemorySizeEqual(MIs[" << InsnID
463 << "]->memoperands() + " << MMOIdx
464 << ", Size=" << Size << ")\n");
465 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
467 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
468 if (handleReject() == RejectAndGiveUp)
473 MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
475 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
476 dbgs() << MMO->getSize() << " bytes vs " << Size
478 if (MMO->getSize() != Size)
479 if (handleReject() == RejectAndGiveUp)
484 case GIM_CheckMemorySizeEqualToLLT:
485 case GIM_CheckMemorySizeLessThanLLT:
486 case GIM_CheckMemorySizeGreaterThanLLT: {
487 int64_t InsnID = MatchTable[CurrentIdx++];
488 int64_t MMOIdx = MatchTable[CurrentIdx++];
489 int64_t OpIdx = MatchTable[CurrentIdx++];
492 TgtInstructionSelector::getName(),
493 dbgs() << CurrentIdx << ": GIM_CheckMemorySize"
494 << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT
496 : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT
499 << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
500 << ", OpIdx=" << OpIdx << ")\n");
501 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
503 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
505 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
506 dbgs() << CurrentIdx << ": Not a register\n");
507 if (handleReject() == RejectAndGiveUp)
512 if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) {
513 if (handleReject() == RejectAndGiveUp)
518 MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx);
520 unsigned Size = MRI.getType(MO.getReg()).getSizeInBits();
521 if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT &&
522 MMO->getSizeInBits() != Size) {
523 if (handleReject() == RejectAndGiveUp)
525 } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT &&
526 MMO->getSizeInBits() >= Size) {
527 if (handleReject() == RejectAndGiveUp)
529 } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT &&
530 MMO->getSizeInBits() <= Size)
531 if (handleReject() == RejectAndGiveUp)
536 case GIM_CheckType: {
537 int64_t InsnID = MatchTable[CurrentIdx++];
538 int64_t OpIdx = MatchTable[CurrentIdx++];
539 int64_t TypeID = MatchTable[CurrentIdx++];
540 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
541 dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
542 << "]->getOperand(" << OpIdx
543 << "), TypeID=" << TypeID << ")\n");
544 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
545 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
547 MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) {
548 if (handleReject() == RejectAndGiveUp)
553 case GIM_CheckPointerToAny: {
554 int64_t InsnID = MatchTable[CurrentIdx++];
555 int64_t OpIdx = MatchTable[CurrentIdx++];
556 int64_t SizeInBits = MatchTable[CurrentIdx++];
558 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
559 dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs["
560 << InsnID << "]->getOperand(" << OpIdx
561 << "), SizeInBits=" << SizeInBits << ")\n");
562 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
563 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
564 const LLT Ty = MRI.getType(MO.getReg());
566 // iPTR must be looked up in the target.
567 if (SizeInBits == 0) {
568 MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
569 const unsigned AddrSpace = Ty.getAddressSpace();
570 SizeInBits = MF->getDataLayout().getPointerSizeInBits(AddrSpace);
573 assert(SizeInBits != 0 && "Pointer size must be known");
576 if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits)
577 if (handleReject() == RejectAndGiveUp)
579 } else if (handleReject() == RejectAndGiveUp)
584 case GIM_CheckRegBankForClass: {
585 int64_t InsnID = MatchTable[CurrentIdx++];
586 int64_t OpIdx = MatchTable[CurrentIdx++];
587 int64_t RCEnum = MatchTable[CurrentIdx++];
588 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
589 dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs["
590 << InsnID << "]->getOperand(" << OpIdx
591 << "), RCEnum=" << RCEnum << ")\n");
592 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
593 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
595 &RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum),
596 MRI.getType(MO.getReg())) !=
597 RBI.getRegBank(MO.getReg(), MRI, TRI)) {
598 if (handleReject() == RejectAndGiveUp)
604 case GIM_CheckComplexPattern: {
605 int64_t InsnID = MatchTable[CurrentIdx++];
606 int64_t OpIdx = MatchTable[CurrentIdx++];
607 int64_t RendererID = MatchTable[CurrentIdx++];
608 int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
609 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
610 dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
611 << "] = GIM_CheckComplexPattern(MIs[" << InsnID
612 << "]->getOperand(" << OpIdx
613 << "), ComplexPredicateID=" << ComplexPredicateID
615 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
616 // FIXME: Use std::invoke() when it's available.
617 ComplexRendererFns Renderer =
618 (ISel.*ISelInfo.ComplexPredicates[ComplexPredicateID])(
619 State.MIs[InsnID]->getOperand(OpIdx));
620 if (Renderer.hasValue())
621 State.Renderers[RendererID] = Renderer.getValue();
623 if (handleReject() == RejectAndGiveUp)
628 case GIM_CheckConstantInt: {
629 int64_t InsnID = MatchTable[CurrentIdx++];
630 int64_t OpIdx = MatchTable[CurrentIdx++];
631 int64_t Value = MatchTable[CurrentIdx++];
632 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
633 dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs["
634 << InsnID << "]->getOperand(" << OpIdx
635 << "), Value=" << Value << ")\n");
636 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
637 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
639 // isOperandImmEqual() will sign-extend to 64-bits, so should we.
640 LLT Ty = MRI.getType(MO.getReg());
641 Value = SignExtend64(Value, Ty.getSizeInBits());
643 if (!isOperandImmEqual(MO, Value, MRI)) {
644 if (handleReject() == RejectAndGiveUp)
647 } else if (handleReject() == RejectAndGiveUp)
653 case GIM_CheckLiteralInt: {
654 int64_t InsnID = MatchTable[CurrentIdx++];
655 int64_t OpIdx = MatchTable[CurrentIdx++];
656 int64_t Value = MatchTable[CurrentIdx++];
657 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
658 dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs["
659 << InsnID << "]->getOperand(" << OpIdx
660 << "), Value=" << Value << ")\n");
661 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
662 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
663 if (MO.isImm() && MO.getImm() == Value)
666 if (MO.isCImm() && MO.getCImm()->equalsInt(Value))
669 if (handleReject() == RejectAndGiveUp)
675 case GIM_CheckIntrinsicID: {
676 int64_t InsnID = MatchTable[CurrentIdx++];
677 int64_t OpIdx = MatchTable[CurrentIdx++];
678 int64_t Value = MatchTable[CurrentIdx++];
679 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
680 dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
681 << InsnID << "]->getOperand(" << OpIdx
682 << "), Value=" << Value << ")\n");
683 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
684 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
685 if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
686 if (handleReject() == RejectAndGiveUp)
690 case GIM_CheckCmpPredicate: {
691 int64_t InsnID = MatchTable[CurrentIdx++];
692 int64_t OpIdx = MatchTable[CurrentIdx++];
693 int64_t Value = MatchTable[CurrentIdx++];
694 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
695 dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs["
696 << InsnID << "]->getOperand(" << OpIdx
697 << "), Value=" << Value << ")\n");
698 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
699 MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
700 if (!MO.isPredicate() || MO.getPredicate() != Value)
701 if (handleReject() == RejectAndGiveUp)
705 case GIM_CheckIsMBB: {
706 int64_t InsnID = MatchTable[CurrentIdx++];
707 int64_t OpIdx = MatchTable[CurrentIdx++];
708 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
709 dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
710 << "]->getOperand(" << OpIdx << "))\n");
711 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
712 if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
713 if (handleReject() == RejectAndGiveUp)
718 case GIM_CheckIsImm: {
719 int64_t InsnID = MatchTable[CurrentIdx++];
720 int64_t OpIdx = MatchTable[CurrentIdx++];
721 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
722 dbgs() << CurrentIdx << ": GIM_CheckIsImm(MIs[" << InsnID
723 << "]->getOperand(" << OpIdx << "))\n");
724 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
725 if (!State.MIs[InsnID]->getOperand(OpIdx).isImm()) {
726 if (handleReject() == RejectAndGiveUp)
731 case GIM_CheckIsSafeToFold: {
732 int64_t InsnID = MatchTable[CurrentIdx++];
733 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
734 dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs["
735 << InsnID << "])\n");
736 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
737 if (!isObviouslySafeToFold(*State.MIs[InsnID], *State.MIs[0])) {
738 if (handleReject() == RejectAndGiveUp)
743 case GIM_CheckIsSameOperand: {
744 int64_t InsnID = MatchTable[CurrentIdx++];
745 int64_t OpIdx = MatchTable[CurrentIdx++];
746 int64_t OtherInsnID = MatchTable[CurrentIdx++];
747 int64_t OtherOpIdx = MatchTable[CurrentIdx++];
748 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
749 dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs["
750 << InsnID << "][" << OpIdx << "], MIs["
751 << OtherInsnID << "][" << OtherOpIdx << "])\n");
752 assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
753 assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
754 if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
755 State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
756 if (handleReject() == RejectAndGiveUp)
762 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
763 dbgs() << CurrentIdx << ": GIM_Reject\n");
764 if (handleReject() == RejectAndGiveUp)
768 case GIR_MutateOpcode: {
769 int64_t OldInsnID = MatchTable[CurrentIdx++];
770 uint64_t NewInsnID = MatchTable[CurrentIdx++];
771 int64_t NewOpcode = MatchTable[CurrentIdx++];
772 if (NewInsnID >= OutMIs.size())
773 OutMIs.resize(NewInsnID + 1);
775 OutMIs[NewInsnID] = MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
776 State.MIs[OldInsnID]);
777 OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
778 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
779 dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs["
780 << NewInsnID << "], MIs[" << OldInsnID << "], "
781 << NewOpcode << ")\n");
786 uint64_t NewInsnID = MatchTable[CurrentIdx++];
787 int64_t Opcode = MatchTable[CurrentIdx++];
788 if (NewInsnID >= OutMIs.size())
789 OutMIs.resize(NewInsnID + 1);
791 OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
792 State.MIs[0]->getDebugLoc(), TII.get(Opcode));
793 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
794 dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
795 << NewInsnID << "], " << Opcode << ")\n");
800 int64_t NewInsnID = MatchTable[CurrentIdx++];
801 int64_t OldInsnID = MatchTable[CurrentIdx++];
802 int64_t OpIdx = MatchTable[CurrentIdx++];
803 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
804 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
805 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
807 << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
808 << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
812 case GIR_CopyOrAddZeroReg: {
813 int64_t NewInsnID = MatchTable[CurrentIdx++];
814 int64_t OldInsnID = MatchTable[CurrentIdx++];
815 int64_t OpIdx = MatchTable[CurrentIdx++];
816 int64_t ZeroReg = MatchTable[CurrentIdx++];
817 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
818 MachineOperand &MO = State.MIs[OldInsnID]->getOperand(OpIdx);
819 if (isOperandImmEqual(MO, 0, MRI))
820 OutMIs[NewInsnID].addReg(ZeroReg);
822 OutMIs[NewInsnID].add(MO);
823 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
824 dbgs() << CurrentIdx << ": GIR_CopyOrAddZeroReg(OutMIs["
825 << NewInsnID << "], MIs[" << OldInsnID << "], "
826 << OpIdx << ", " << ZeroReg << ")\n");
830 case GIR_CopySubReg: {
831 int64_t NewInsnID = MatchTable[CurrentIdx++];
832 int64_t OldInsnID = MatchTable[CurrentIdx++];
833 int64_t OpIdx = MatchTable[CurrentIdx++];
834 int64_t SubRegIdx = MatchTable[CurrentIdx++];
835 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
836 OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
838 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
839 dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs["
840 << NewInsnID << "], MIs[" << OldInsnID << "], "
841 << OpIdx << ", " << SubRegIdx << ")\n");
845 case GIR_AddImplicitDef: {
846 int64_t InsnID = MatchTable[CurrentIdx++];
847 int64_t RegNum = MatchTable[CurrentIdx++];
848 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
849 OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
850 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
851 dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs["
852 << InsnID << "], " << RegNum << ")\n");
856 case GIR_AddImplicitUse: {
857 int64_t InsnID = MatchTable[CurrentIdx++];
858 int64_t RegNum = MatchTable[CurrentIdx++];
859 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
860 OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
861 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
862 dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs["
863 << InsnID << "], " << RegNum << ")\n");
867 case GIR_AddRegister: {
868 int64_t InsnID = MatchTable[CurrentIdx++];
869 int64_t RegNum = MatchTable[CurrentIdx++];
870 uint64_t RegFlags = MatchTable[CurrentIdx++];
871 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
872 OutMIs[InsnID].addReg(RegNum, RegFlags);
874 TgtInstructionSelector::getName(),
875 dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs["
876 << InsnID << "], " << RegNum << ", " << RegFlags << ")\n");
880 case GIR_AddTempRegister:
881 case GIR_AddTempSubRegister: {
882 int64_t InsnID = MatchTable[CurrentIdx++];
883 int64_t TempRegID = MatchTable[CurrentIdx++];
884 uint64_t TempRegFlags = MatchTable[CurrentIdx++];
886 if (MatcherOpcode == GIR_AddTempSubRegister)
887 SubReg = MatchTable[CurrentIdx++];
889 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
891 OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags, SubReg);
892 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
893 dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
894 << InsnID << "], TempRegisters[" << TempRegID
897 dbgs() << '.' << TRI.getSubRegIndexName(SubReg);
898 dbgs() << ", " << TempRegFlags << ")\n");
903 int64_t InsnID = MatchTable[CurrentIdx++];
904 int64_t Imm = MatchTable[CurrentIdx++];
905 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
906 OutMIs[InsnID].addImm(Imm);
907 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
908 dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID
909 << "], " << Imm << ")\n");
913 case GIR_ComplexRenderer: {
914 int64_t InsnID = MatchTable[CurrentIdx++];
915 int64_t RendererID = MatchTable[CurrentIdx++];
916 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
917 for (const auto &RenderOpFn : State.Renderers[RendererID])
918 RenderOpFn(OutMIs[InsnID]);
919 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
920 dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs["
921 << InsnID << "], " << RendererID << ")\n");
924 case GIR_ComplexSubOperandRenderer: {
925 int64_t InsnID = MatchTable[CurrentIdx++];
926 int64_t RendererID = MatchTable[CurrentIdx++];
927 int64_t RenderOpID = MatchTable[CurrentIdx++];
928 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
929 State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
930 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
932 << ": GIR_ComplexSubOperandRenderer(OutMIs["
933 << InsnID << "], " << RendererID << ", "
934 << RenderOpID << ")\n");
938 case GIR_CopyConstantAsSImm: {
939 int64_t NewInsnID = MatchTable[CurrentIdx++];
940 int64_t OldInsnID = MatchTable[CurrentIdx++];
941 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
942 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
943 if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
944 OutMIs[NewInsnID].addImm(
945 State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
946 } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
947 OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
949 llvm_unreachable("Expected Imm or CImm operand");
950 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
951 dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs["
952 << NewInsnID << "], MIs[" << OldInsnID << "])\n");
956 // TODO: Needs a test case once we have a pattern that uses this.
957 case GIR_CopyFConstantAsFPImm: {
958 int64_t NewInsnID = MatchTable[CurrentIdx++];
959 int64_t OldInsnID = MatchTable[CurrentIdx++];
960 assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
961 assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT");
962 if (State.MIs[OldInsnID]->getOperand(1).isFPImm())
963 OutMIs[NewInsnID].addFPImm(
964 State.MIs[OldInsnID]->getOperand(1).getFPImm());
966 llvm_unreachable("Expected FPImm operand");
967 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
968 dbgs() << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs["
969 << NewInsnID << "], MIs[" << OldInsnID << "])\n");
973 case GIR_CustomRenderer: {
974 int64_t InsnID = MatchTable[CurrentIdx++];
975 int64_t OldInsnID = MatchTable[CurrentIdx++];
976 int64_t RendererFnID = MatchTable[CurrentIdx++];
977 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
978 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
979 dbgs() << CurrentIdx << ": GIR_CustomRenderer(OutMIs["
980 << InsnID << "], MIs[" << OldInsnID << "], "
981 << RendererFnID << ")\n");
982 (ISel.*ISelInfo.CustomRenderers[RendererFnID])(
983 OutMIs[InsnID], *State.MIs[OldInsnID],
984 -1); // Not a source operand of the old instruction.
987 case GIR_CustomOperandRenderer: {
988 int64_t InsnID = MatchTable[CurrentIdx++];
989 int64_t OldInsnID = MatchTable[CurrentIdx++];
990 int64_t OpIdx = MatchTable[CurrentIdx++];
991 int64_t RendererFnID = MatchTable[CurrentIdx++];
992 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
995 TgtInstructionSelector::getName(),
996 dbgs() << CurrentIdx << ": GIR_CustomOperandRenderer(OutMIs["
997 << InsnID << "], MIs[" << OldInsnID << "]->getOperand("
999 << RendererFnID << ")\n");
1000 (ISel.*ISelInfo.CustomRenderers[RendererFnID])(OutMIs[InsnID],
1001 *State.MIs[OldInsnID],
1005 case GIR_ConstrainOperandRC: {
1006 int64_t InsnID = MatchTable[CurrentIdx++];
1007 int64_t OpIdx = MatchTable[CurrentIdx++];
1008 int64_t RCEnum = MatchTable[CurrentIdx++];
1009 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1010 constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
1011 *TRI.getRegClass(RCEnum), TII, TRI, RBI);
1012 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1013 dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs["
1014 << InsnID << "], " << OpIdx << ", " << RCEnum
1019 case GIR_ConstrainSelectedInstOperands: {
1020 int64_t InsnID = MatchTable[CurrentIdx++];
1021 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1022 constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
1024 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1025 dbgs() << CurrentIdx
1026 << ": GIR_ConstrainSelectedInstOperands(OutMIs["
1027 << InsnID << "])\n");
1031 case GIR_MergeMemOperands: {
1032 int64_t InsnID = MatchTable[CurrentIdx++];
1033 assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
1035 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1036 dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs["
1038 int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
1039 while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
1040 GIU_MergeMemOperands_EndOfList) {
1041 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1042 dbgs() << ", MIs[" << MergeInsnID << "]");
1043 for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
1044 OutMIs[InsnID].addMemOperand(MMO);
1046 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), dbgs() << ")\n");
1050 case GIR_EraseFromParent: {
1051 int64_t InsnID = MatchTable[CurrentIdx++];
1052 assert(State.MIs[InsnID] &&
1053 "Attempted to erase an undefined instruction");
1054 State.MIs[InsnID]->eraseFromParent();
1055 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1056 dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs["
1057 << InsnID << "])\n");
1061 case GIR_MakeTempReg: {
1062 int64_t TempRegID = MatchTable[CurrentIdx++];
1063 int64_t TypeID = MatchTable[CurrentIdx++];
1065 State.TempRegisters[TempRegID] =
1066 MRI.createGenericVirtualRegister(ISelInfo.TypeObjects[TypeID]);
1067 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1068 dbgs() << CurrentIdx << ": TempRegs[" << TempRegID
1069 << "] = GIR_MakeTempReg(" << TypeID << ")\n");
1073 case GIR_Coverage: {
1074 int64_t RuleID = MatchTable[CurrentIdx++];
1075 CoverageInfo.setCovered(RuleID);
1077 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1079 << CurrentIdx << ": GIR_Coverage(" << RuleID << ")");
1084 DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
1085 dbgs() << CurrentIdx << ": GIR_Done\n");
1086 propagateFlags(OutMIs);
1090 llvm_unreachable("Unexpected command");
1095 } // end namespace llvm
1097 #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H