40#include "llvm/IR/IntrinsicsX86.h"
50#define DEBUG_TYPE "X86-isel"
56#define GET_GLOBALISEL_PREDICATE_BITSET
57#include "X86GenGlobalISel.inc"
58#undef GET_GLOBALISEL_PREDICATE_BITSET
75 Align Alignment)
const;
144#define GET_GLOBALISEL_PREDICATES_DECL
145#include "X86GenGlobalISel.inc"
146#undef GET_GLOBALISEL_PREDICATES_DECL
148#define GET_GLOBALISEL_TEMPORARIES_DECL
149#include "X86GenGlobalISel.inc"
150#undef GET_GLOBALISEL_TEMPORARIES_DECL
155#define GET_GLOBALISEL_IMPL
156#include "X86GenGlobalISel.inc"
157#undef GET_GLOBALISEL_IMPL
162 : TM(TM), STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()),
165#include
"X86GenGlobalISel.inc"
168#include
"X86GenGlobalISel.inc"
176X86InstructionSelector::getRegClass(
LLT Ty,
const RegisterBank &RB)
const {
177 if (RB.
getID() == X86::GPRRegBankID) {
179 return &X86::GR8RegClass;
181 return &X86::GR16RegClass;
183 return &X86::GR32RegClass;
185 return &X86::GR64RegClass;
187 if (RB.
getID() == X86::VECRRegBankID) {
189 return STI.
hasAVX512() ? &X86::FR16XRegClass : &X86::FR16RegClass;
191 return STI.
hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
193 return STI.
hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
195 return STI.
hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
197 return STI.
hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
199 return &X86::VR512RegClass;
202 if (RB.
getID() == X86::PSRRegBankID) {
204 return &X86::RFP80RegClass;
206 return &X86::RFP64RegClass;
208 return &X86::RFP32RegClass;
214const TargetRegisterClass *
215X86InstructionSelector::getRegClass(LLT Ty,
Register Reg,
216 MachineRegisterInfo &
MRI)
const {
221static unsigned getSubRegIndex(
const TargetRegisterClass *RC) {
222 unsigned SubIdx = X86::NoSubRegister;
223 if (RC == &X86::GR32RegClass) {
224 SubIdx = X86::sub_32bit;
225 }
else if (RC == &X86::GR16RegClass) {
226 SubIdx = X86::sub_16bit;
227 }
else if (RC == &X86::GR8RegClass) {
228 SubIdx = X86::sub_8bit;
237 return &X86::GR64RegClass;
239 return &X86::GR32RegClass;
241 return &X86::GR16RegClass;
243 return &X86::GR8RegClass;
251bool X86InstructionSelector::selectDebugInstr(MachineInstr &
I,
252 MachineRegisterInfo &
MRI)
const {
253 for (MachineOperand &MO :
I.operands()) {
261 LLT Ty =
MRI.getType(
Reg);
263 const TargetRegisterClass *RC =
270 dbgs() <<
"Warning: DBG_VALUE operand has unexpected size/bank\n");
281bool X86InstructionSelector::selectCopy(MachineInstr &
I,
282 MachineRegisterInfo &
MRI)
const {
283 Register DstReg =
I.getOperand(0).getReg();
287 Register SrcReg =
I.getOperand(1).getReg();
292 assert(
I.isCopy() &&
"Generic operators do not allow physical registers");
294 if (DstSize > SrcSize && SrcRegBank.
getID() == X86::GPRRegBankID &&
295 DstRegBank.
getID() == X86::GPRRegBankID) {
297 const TargetRegisterClass *SrcRC =
301 if (SrcRC != DstRC) {
303 Register ExtSrc =
MRI.createVirtualRegister(DstRC);
305 TII.get(TargetOpcode::SUBREG_TO_REG))
309 .
addImm(getSubRegIndex(SrcRC));
311 I.getOperand(1).setReg(ExtSrc);
319 "No phys reg on generic operators");
320 assert((DstSize == SrcSize ||
325 "Copy with different width?!");
327 const TargetRegisterClass *DstRC =
330 if (SrcRegBank.
getID() == X86::GPRRegBankID &&
331 DstRegBank.
getID() == X86::GPRRegBankID && SrcSize > DstSize &&
337 if (DstRC != SrcRC) {
338 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
339 I.getOperand(1).substPhysReg(SrcReg,
TRI);
346 const TargetRegisterClass *OldRC =
MRI.getRegClassOrNull(DstReg);
354 I.setDesc(
TII.get(X86::COPY));
358bool X86InstructionSelector::select(MachineInstr &
I) {
359 assert(
I.getParent() &&
"Instruction should be in a basic block!");
360 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
366 unsigned Opcode =
I.getOpcode();
370 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
376 if (
I.isDebugInstr())
382 assert(
I.getNumOperands() ==
I.getNumExplicitOperands() &&
383 "Generic instruction has unexpected implicit operands\n");
385 if (selectImpl(
I, *CoverageInfo))
391 switch (
I.getOpcode()) {
394 case TargetOpcode::G_STORE:
395 case TargetOpcode::G_LOAD:
397 case TargetOpcode::G_PTR_ADD:
398 case TargetOpcode::G_FRAME_INDEX:
399 return selectFrameIndexOrGep(
I,
MRI, MF);
400 case TargetOpcode::G_GLOBAL_VALUE:
401 return selectGlobalValue(
I,
MRI, MF);
402 case TargetOpcode::G_CONSTANT:
403 return selectConstant(
I,
MRI, MF);
404 case TargetOpcode::G_FCONSTANT:
405 return materializeFP(
I,
MRI, MF);
406 case TargetOpcode::G_PTRTOINT:
407 case TargetOpcode::G_TRUNC:
408 return selectTruncOrPtrToInt(
I,
MRI, MF);
409 case TargetOpcode::G_INTTOPTR:
410 case TargetOpcode::G_FREEZE:
412 case TargetOpcode::G_ZEXT:
413 return selectZext(
I,
MRI, MF);
414 case TargetOpcode::G_ANYEXT:
415 return selectAnyext(
I,
MRI, MF);
416 case TargetOpcode::G_ICMP:
417 return selectCmp(
I,
MRI, MF);
418 case TargetOpcode::G_FCMP:
419 return selectFCmp(
I,
MRI, MF);
420 case TargetOpcode::G_UADDE:
421 case TargetOpcode::G_UADDO:
422 case TargetOpcode::G_USUBE:
423 case TargetOpcode::G_USUBO:
424 return selectUAddSub(
I,
MRI, MF);
425 case TargetOpcode::G_UNMERGE_VALUES:
427 case TargetOpcode::G_MERGE_VALUES:
428 case TargetOpcode::G_CONCAT_VECTORS:
430 case TargetOpcode::G_EXTRACT:
431 return selectExtract(
I,
MRI, MF);
432 case TargetOpcode::G_INSERT:
433 return selectInsert(
I,
MRI, MF);
434 case TargetOpcode::G_BRCOND:
435 return selectCondBranch(
I,
MRI, MF);
436 case TargetOpcode::G_IMPLICIT_DEF:
437 case TargetOpcode::G_PHI:
438 return selectImplicitDefOrPHI(
I,
MRI);
439 case TargetOpcode::G_MUL:
440 case TargetOpcode::G_SMULH:
441 case TargetOpcode::G_UMULH:
442 case TargetOpcode::G_SDIV:
443 case TargetOpcode::G_UDIV:
444 case TargetOpcode::G_SREM:
445 case TargetOpcode::G_UREM:
446 return selectMulDivRem(
I,
MRI, MF);
447 case TargetOpcode::G_SELECT:
448 return selectSelect(
I,
MRI, MF);
454unsigned X86InstructionSelector::getPtrLoadStoreOp(
const LLT &Ty,
455 const RegisterBank &RB,
456 unsigned Opc)
const {
457 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
458 "Only G_STORE and G_LOAD are expected for selection");
460 bool IsLoad = (
Opc == TargetOpcode::G_LOAD);
465 return IsLoad ? X86::MOV32rm : X86::MOV32mr;
467 return IsLoad ? X86::MOV64rm : X86::MOV64mr;
473unsigned X86InstructionSelector::getLoadStoreOp(
const LLT &Ty,
474 const RegisterBank &RB,
476 Align Alignment)
const {
477 bool Isload = (
Opc == TargetOpcode::G_LOAD);
478 bool HasAVX = STI.
hasAVX();
480 bool HasVLX = STI.hasVLX();
483 if (X86::GPRRegBankID == RB.
getID())
484 return Isload ? X86::MOV8rm : X86::MOV8mr;
486 if (X86::GPRRegBankID == RB.
getID())
487 return Isload ? X86::MOV16rm : X86::MOV16mr;
489 if (X86::GPRRegBankID == RB.
getID())
490 return Isload ? X86::MOV32rm : X86::MOV32mr;
491 if (X86::VECRRegBankID == RB.
getID())
492 return Isload ? (HasAVX512 ? X86::VMOVSSZrm_alt :
493 HasAVX ? X86::VMOVSSrm_alt :
495 : (HasAVX512 ?
X86::VMOVSSZmr :
496 HasAVX ?
X86::VMOVSSmr :
498 if (X86::PSRRegBankID == RB.
getID())
499 return Isload ? X86::LD_Fp32m : X86::ST_Fp32m;
501 if (X86::GPRRegBankID == RB.
getID())
502 return Isload ? X86::MOV64rm : X86::MOV64mr;
503 if (X86::VECRRegBankID == RB.
getID())
504 return Isload ? (HasAVX512 ? X86::VMOVSDZrm_alt :
505 HasAVX ? X86::VMOVSDrm_alt :
507 : (HasAVX512 ?
X86::VMOVSDZmr :
508 HasAVX ?
X86::VMOVSDmr :
510 if (X86::PSRRegBankID == RB.
getID())
511 return Isload ? X86::LD_Fp64m : X86::ST_Fp64m;
513 return Isload ? X86::LD_Fp80m : X86::ST_FpP80m;
515 if (Alignment >=
Align(16))
516 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
518 ? X86::VMOVAPSZ128rm_NOVLX
519 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
520 : (HasVLX ?
X86::VMOVAPSZ128mr
522 ?
X86::VMOVAPSZ128mr_NOVLX
523 : HasAVX ?
X86::VMOVAPSmr :
X86::MOVAPSmr);
525 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
527 ? X86::VMOVUPSZ128rm_NOVLX
528 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
529 : (HasVLX ? X86::VMOVUPSZ128mr
531 ? X86::VMOVUPSZ128mr_NOVLX
532 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
534 if (Alignment >=
Align(32))
535 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
536 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
538 : (HasVLX ?
X86::VMOVAPSZ256mr
539 : HasAVX512 ?
X86::VMOVAPSZ256mr_NOVLX
542 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
543 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
545 : (HasVLX ? X86::VMOVUPSZ256mr
546 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
549 if (Alignment >=
Align(64))
550 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
552 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
561 assert(
I.getOperand(0).isReg() &&
"unsupported operand.");
562 assert(
MRI.getType(
I.getOperand(0).getReg()).isPointer() &&
563 "unsupported type.");
565 switch (
I.getOpcode()) {
568 case TargetOpcode::G_FRAME_INDEX:
572 case TargetOpcode::G_PTR_ADD: {
576 AM.
Disp =
static_cast<int32_t
>(Imm);
577 AM.
Base.
Reg =
I.getOperand(1).getReg();
583 case TargetOpcode::G_GLOBAL_VALUE: {
584 auto GV =
I.getOperand(1).getGlobal();
585 if (GV->isThreadLocal()) {
605 "RIP-relative addresses can't have additional register operands");
610 case TargetOpcode::G_CONSTANT_POOL: {
618 else if (STI.is64Bit())
621 AM.
Disp =
I.getOperand(1).getIndex();
626 AM.
Base.
Reg =
I.getOperand(0).getReg();
630bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &
I,
631 MachineRegisterInfo &
MRI,
632 MachineFunction &MF)
const {
633 unsigned Opc =
I.getOpcode();
635 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
636 "Only G_STORE and G_LOAD are expected for selection");
638 const Register DefReg =
I.getOperand(0).getReg();
639 LLT Ty =
MRI.getType(DefReg);
643 auto &MemOp = **
I.memoperands_begin();
644 if (MemOp.isAtomic()) {
650 if (!MemOp.isUnordered()) {
660 unsigned NewOpc = getPtrLoadStoreOp(Ty, RB,
Opc);
664 I.setDesc(
TII.get(NewOpc));
665 MachineInstrBuilder MIB(MF,
I);
666 MachineInstr *
Ptr =
MRI.getVRegDef(
I.getOperand(1).getReg());
672 if (
Opc == TargetOpcode::G_LOAD) {
682 I.addImplicitDefUseOperands(MF);
695bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &
I,
696 MachineRegisterInfo &
MRI,
697 MachineFunction &MF)
const {
698 unsigned Opc =
I.getOpcode();
700 assert((
Opc == TargetOpcode::G_FRAME_INDEX ||
Opc == TargetOpcode::G_PTR_ADD) &&
701 "unexpected instruction");
703 const Register DefReg =
I.getOperand(0).getReg();
704 LLT Ty =
MRI.getType(DefReg);
707 unsigned NewOpc =
getLeaOP(Ty, STI);
708 I.setDesc(
TII.get(NewOpc));
709 MachineInstrBuilder MIB(MF,
I);
711 if (
Opc == TargetOpcode::G_FRAME_INDEX) {
714 MachineOperand &InxOp =
I.getOperand(2);
717 MIB.addImm(0).addReg(0);
723bool X86InstructionSelector::selectGlobalValue(MachineInstr &
I,
724 MachineRegisterInfo &
MRI,
725 MachineFunction &MF)
const {
726 assert((
I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
727 "unexpected instruction");
733 const Register DefReg =
I.getOperand(0).getReg();
734 LLT Ty =
MRI.getType(DefReg);
735 unsigned NewOpc =
getLeaOP(Ty, STI);
737 I.setDesc(
TII.get(NewOpc));
738 MachineInstrBuilder MIB(MF,
I);
746bool X86InstructionSelector::selectConstant(MachineInstr &
I,
747 MachineRegisterInfo &
MRI,
748 MachineFunction &MF)
const {
749 assert((
I.getOpcode() == TargetOpcode::G_CONSTANT) &&
750 "unexpected instruction");
752 const Register DefReg =
I.getOperand(0).getReg();
753 LLT Ty =
MRI.getType(DefReg);
759 if (
I.getOperand(1).isCImm()) {
760 Val =
I.getOperand(1).getCImm()->getZExtValue();
761 I.getOperand(1).ChangeToImmediate(Val);
762 }
else if (
I.getOperand(1).isImm()) {
763 Val =
I.getOperand(1).getImm();
770 NewOpc = X86::MOV8ri;
773 NewOpc = X86::MOV16ri;
776 NewOpc = X86::MOV32ri;
781 NewOpc = X86::MOV64ri32;
783 NewOpc = X86::MOV64ri;
789 I.setDesc(
TII.get(NewOpc));
798 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
799 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
800 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
803bool X86InstructionSelector::selectTurnIntoCOPY(
804 MachineInstr &
I, MachineRegisterInfo &
MRI,
const Register DstReg,
805 const TargetRegisterClass *DstRC,
const Register SrcReg,
806 const TargetRegisterClass *SrcRC)
const {
814 I.setDesc(
TII.get(X86::COPY));
818bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &
I,
819 MachineRegisterInfo &
MRI,
820 MachineFunction &MF)
const {
821 assert((
I.getOpcode() == TargetOpcode::G_TRUNC ||
822 I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
823 "unexpected instruction");
825 const Register DstReg =
I.getOperand(0).getReg();
826 const Register SrcReg =
I.getOperand(1).getReg();
828 const LLT DstTy =
MRI.getType(DstReg);
829 const LLT SrcTy =
MRI.getType(SrcReg);
836 <<
" input/output on different banks\n");
840 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstRB);
841 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcRB);
843 if (!DstRC || !SrcRC)
850 return selectTurnIntoCOPY(
I,
MRI, DstReg, DstRC, SrcReg, SrcRC);
852 if (DstRB.
getID() != X86::GPRRegBankID)
856 if (DstRC == SrcRC) {
858 SubIdx = X86::NoSubRegister;
859 }
else if (DstRC == &X86::GR32RegClass) {
860 SubIdx = X86::sub_32bit;
861 }
else if (DstRC == &X86::GR16RegClass) {
862 SubIdx = X86::sub_16bit;
863 }
else if (DstRC == &X86::GR8RegClass) {
864 SubIdx = X86::sub_8bit;
869 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
878 I.getOperand(1).setSubReg(SubIdx);
880 I.setDesc(
TII.get(X86::COPY));
884bool X86InstructionSelector::selectZext(MachineInstr &
I,
885 MachineRegisterInfo &
MRI,
886 MachineFunction &MF)
const {
887 assert((
I.getOpcode() == TargetOpcode::G_ZEXT) &&
"unexpected instruction");
889 const Register DstReg =
I.getOperand(0).getReg();
890 const Register SrcReg =
I.getOperand(1).getReg();
892 const LLT DstTy =
MRI.getType(DstReg);
893 const LLT SrcTy =
MRI.getType(SrcReg);
896 "8=>16 Zext is handled by tablegen");
898 "8=>32 Zext is handled by tablegen");
900 "16=>32 Zext is handled by tablegen");
902 "8=>64 Zext is handled by tablegen");
904 "16=>64 Zext is handled by tablegen");
906 "32=>64 Zext is handled by tablegen");
913 AndOpc = X86::AND8ri;
915 AndOpc = X86::AND16ri;
917 AndOpc = X86::AND32ri;
919 AndOpc = X86::AND64ri32;
928 TII.get(TargetOpcode::IMPLICIT_DEF), ImpDefReg);
932 TII.get(TargetOpcode::INSERT_SUBREG), DefReg)
938 MachineInstr &AndInst =
939 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(AndOpc), DstReg)
949bool X86InstructionSelector::selectAnyext(MachineInstr &
I,
950 MachineRegisterInfo &
MRI,
951 MachineFunction &MF)
const {
952 assert((
I.getOpcode() == TargetOpcode::G_ANYEXT) &&
"unexpected instruction");
954 const Register DstReg =
I.getOperand(0).getReg();
955 const Register SrcReg =
I.getOperand(1).getReg();
957 const LLT DstTy =
MRI.getType(DstReg);
958 const LLT SrcTy =
MRI.getType(SrcReg);
964 "G_ANYEXT input/output on different banks\n");
967 "G_ANYEXT incorrect operand size");
969 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstRB);
970 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcRB);
976 return selectTurnIntoCOPY(
I,
MRI, SrcReg, SrcRC, DstReg, DstRC);
978 if (DstRB.
getID() != X86::GPRRegBankID)
988 if (SrcRC == DstRC) {
989 I.setDesc(
TII.get(X86::COPY));
994 TII.get(TargetOpcode::SUBREG_TO_REG))
998 .
addImm(getSubRegIndex(SrcRC));
1000 I.eraseFromParent();
1004bool X86InstructionSelector::selectCmp(MachineInstr &
I,
1005 MachineRegisterInfo &
MRI,
1006 MachineFunction &MF)
const {
1007 assert((
I.getOpcode() == TargetOpcode::G_ICMP) &&
"unexpected instruction");
1021 LLT Ty =
MRI.getType(
LHS);
1027 OpCmp = X86::CMP8rr;
1030 OpCmp = X86::CMP16rr;
1033 OpCmp = X86::CMP32rr;
1036 OpCmp = X86::CMP64rr;
1040 MachineInstr &CmpInst =
1041 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1045 MachineInstr &SetInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1046 TII.get(X86::SETCCr),
I.getOperand(0).getReg()).
addImm(CC);
1051 I.eraseFromParent();
1055bool X86InstructionSelector::selectFCmp(MachineInstr &
I,
1056 MachineRegisterInfo &
MRI,
1057 MachineFunction &MF)
const {
1058 assert((
I.getOpcode() == TargetOpcode::G_FCMP) &&
"unexpected instruction");
1060 Register LhsReg =
I.getOperand(2).getReg();
1061 Register RhsReg =
I.getOperand(3).getReg();
1066 static const uint16_t SETFOpcTable[2][3] = {
1069 const uint16_t *SETFOpc =
nullptr;
1070 switch (Predicate) {
1074 SETFOpc = &SETFOpcTable[0][0];
1077 SETFOpc = &SETFOpcTable[1][0];
1082 "Both arguments of FCMP need to be virtual!");
1085 assert((LhsBank == RhsBank) &&
1086 "Both banks assigned to FCMP arguments need to be same!");
1090 LLT Ty =
MRI.getType(LhsReg);
1095 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr32
1099 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr64
1103 OpCmp = X86::UCOM_FpIr80;
1107 Register ResultReg =
I.getOperand(0).getReg();
1112 MachineInstr &CmpInst =
1113 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1117 Register FlagReg1 =
MRI.createVirtualRegister(&X86::GR8RegClass);
1118 Register FlagReg2 =
MRI.createVirtualRegister(&X86::GR8RegClass);
1119 MachineInstr &Set1 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1120 TII.get(X86::SETCCr), FlagReg1).
addImm(SETFOpc[0]);
1121 MachineInstr &Set2 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1122 TII.get(X86::SETCCr), FlagReg2).
addImm(SETFOpc[1]);
1123 MachineInstr &Set3 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1124 TII.get(SETFOpc[2]), ResultReg)
1132 I.eraseFromParent();
1145 MachineInstr &CmpInst =
1146 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1154 I.eraseFromParent();
1158bool X86InstructionSelector::selectUAddSub(MachineInstr &
I,
1159 MachineRegisterInfo &
MRI,
1160 MachineFunction &MF)
const {
1161 assert((
I.getOpcode() == TargetOpcode::G_UADDE ||
1162 I.getOpcode() == TargetOpcode::G_UADDO ||
1163 I.getOpcode() == TargetOpcode::G_USUBE ||
1164 I.getOpcode() == TargetOpcode::G_USUBO) &&
1165 "unexpected instruction");
1169 const Register DstReg = CarryMI.getDstReg();
1170 const Register CarryOutReg = CarryMI.getCarryOutReg();
1171 const Register Op0Reg = CarryMI.getLHSReg();
1172 const Register Op1Reg = CarryMI.getRHSReg();
1173 bool IsSub = CarryMI.isSub();
1175 const LLT DstTy =
MRI.getType(DstReg);
1176 assert(DstTy.
isScalar() &&
"selectUAddSub only supported for scalar types");
1179 unsigned OpADC, OpADD, OpSBB, OpSUB;
1182 OpADC = X86::ADC8rr;
1183 OpADD = X86::ADD8rr;
1184 OpSBB = X86::SBB8rr;
1185 OpSUB = X86::SUB8rr;
1188 OpADC = X86::ADC16rr;
1189 OpADD = X86::ADD16rr;
1190 OpSBB = X86::SBB16rr;
1191 OpSUB = X86::SUB16rr;
1194 OpADC = X86::ADC32rr;
1195 OpADD = X86::ADD32rr;
1196 OpSBB = X86::SBB32rr;
1197 OpSUB = X86::SUB32rr;
1200 OpADC = X86::ADC64rr;
1201 OpADD = X86::ADD64rr;
1202 OpSBB = X86::SBB64rr;
1203 OpSUB = X86::SUB64rr;
1210 const TargetRegisterClass *CarryRC =
1213 unsigned Opcode = IsSub ? OpSUB : OpADD;
1217 Register CarryInReg = CarryInMI->getCarryInReg();
1218 MachineInstr *
Def =
MRI.getVRegDef(CarryInReg);
1219 while (
Def->getOpcode() == TargetOpcode::G_TRUNC) {
1220 CarryInReg =
Def->getOperand(1).getReg();
1221 Def =
MRI.getVRegDef(CarryInReg);
1225 if (
Def->getOpcode() == TargetOpcode::G_UADDE ||
1226 Def->getOpcode() == TargetOpcode::G_UADDO ||
1227 Def->getOpcode() == TargetOpcode::G_USUBE ||
1228 Def->getOpcode() == TargetOpcode::G_USUBO) {
1231 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::CMP8ri))
1238 Opcode = IsSub ? OpSBB : OpADC;
1244 Opcode = IsSub ? OpSUB : OpADD;
1249 MachineInstr &Inst =
1250 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1254 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SETCCr), CarryOutReg)
1261 I.eraseFromParent();
1265bool X86InstructionSelector::selectExtract(MachineInstr &
I,
1266 MachineRegisterInfo &
MRI,
1267 MachineFunction &MF)
const {
1268 assert((
I.getOpcode() == TargetOpcode::G_EXTRACT) &&
1269 "unexpected instruction");
1271 const Register DstReg =
I.getOperand(0).getReg();
1272 const Register SrcReg =
I.getOperand(1).getReg();
1273 int64_t
Index =
I.getOperand(2).getImm();
1275 const LLT DstTy =
MRI.getType(DstReg);
1276 const LLT SrcTy =
MRI.getType(SrcReg);
1287 if (!emitExtractSubreg(DstReg, SrcReg,
I,
MRI, MF))
1290 I.eraseFromParent();
1294 bool HasAVX = STI.
hasAVX();
1296 bool HasVLX = STI.hasVLX();
1300 I.setDesc(
TII.get(X86::VEXTRACTF32X4Z256rri));
1302 I.setDesc(
TII.get(X86::VEXTRACTF128rri));
1307 I.setDesc(
TII.get(X86::VEXTRACTF32X4Zrri));
1309 I.setDesc(
TII.get(X86::VEXTRACTF64X4Zrri));
1317 I.getOperand(2).setImm(Index);
1322bool X86InstructionSelector::emitExtractSubreg(
Register DstReg,
Register SrcReg,
1324 MachineRegisterInfo &
MRI,
1325 MachineFunction &MF)
const {
1326 const LLT DstTy =
MRI.getType(DstReg);
1327 const LLT SrcTy =
MRI.getType(SrcReg);
1328 unsigned SubIdx = X86::NoSubRegister;
1334 "Incorrect Src/Dst register size");
1337 SubIdx = X86::sub_xmm;
1339 SubIdx = X86::sub_ymm;
1343 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstReg,
MRI);
1344 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcReg,
MRI);
1346 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1354 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::COPY), DstReg)
1355 .
addReg(SrcReg, 0, SubIdx);
1360bool X86InstructionSelector::emitInsertSubreg(
Register DstReg,
Register SrcReg,
1362 MachineRegisterInfo &
MRI,
1363 MachineFunction &MF)
const {
1364 const LLT DstTy =
MRI.getType(DstReg);
1365 const LLT SrcTy =
MRI.getType(SrcReg);
1366 unsigned SubIdx = X86::NoSubRegister;
1373 "Incorrect Src/Dst register size");
1376 SubIdx = X86::sub_xmm;
1378 SubIdx = X86::sub_ymm;
1382 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcReg,
MRI);
1383 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstReg,
MRI);
1391 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::COPY))
1398bool X86InstructionSelector::selectInsert(MachineInstr &
I,
1399 MachineRegisterInfo &
MRI,
1400 MachineFunction &MF)
const {
1401 assert((
I.getOpcode() == TargetOpcode::G_INSERT) &&
"unexpected instruction");
1403 const Register DstReg =
I.getOperand(0).getReg();
1404 const Register SrcReg =
I.getOperand(1).getReg();
1405 const Register InsertReg =
I.getOperand(2).getReg();
1406 int64_t
Index =
I.getOperand(3).getImm();
1408 const LLT DstTy =
MRI.getType(DstReg);
1409 const LLT InsertRegTy =
MRI.getType(InsertReg);
1418 if (Index == 0 &&
MRI.getVRegDef(SrcReg)->isImplicitDef()) {
1420 if (!emitInsertSubreg(DstReg, InsertReg,
I,
MRI, MF))
1423 I.eraseFromParent();
1427 bool HasAVX = STI.
hasAVX();
1429 bool HasVLX = STI.hasVLX();
1433 I.setDesc(
TII.get(X86::VINSERTF32X4Z256rri));
1435 I.setDesc(
TII.get(X86::VINSERTF128rri));
1440 I.setDesc(
TII.get(X86::VINSERTF32X4Zrri));
1442 I.setDesc(
TII.get(X86::VINSERTF64X4Zrri));
1451 I.getOperand(3).setImm(Index);
1456bool X86InstructionSelector::selectUnmergeValues(
1457 MachineInstr &
I, MachineRegisterInfo &
MRI, MachineFunction &MF) {
1458 assert((
I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1459 "unexpected instruction");
1462 unsigned NumDefs =
I.getNumOperands() - 1;
1463 Register SrcReg =
I.getOperand(NumDefs).getReg();
1464 unsigned DefSize =
MRI.getType(
I.getOperand(0).getReg()).getSizeInBits();
1466 for (
unsigned Idx = 0; Idx < NumDefs; ++Idx) {
1467 MachineInstr &ExtrInst =
1469 TII.get(TargetOpcode::G_EXTRACT),
I.getOperand(Idx).getReg())
1473 if (!select(ExtrInst))
1477 I.eraseFromParent();
1481bool X86InstructionSelector::selectMergeValues(
1482 MachineInstr &
I, MachineRegisterInfo &
MRI, MachineFunction &MF) {
1483 assert((
I.getOpcode() == TargetOpcode::G_MERGE_VALUES ||
1484 I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS) &&
1485 "unexpected instruction");
1488 Register DstReg =
I.getOperand(0).getReg();
1489 Register SrcReg0 =
I.getOperand(1).getReg();
1491 const LLT DstTy =
MRI.getType(DstReg);
1492 const LLT SrcTy =
MRI.getType(SrcReg0);
1498 Register DefReg =
MRI.createGenericVirtualRegister(DstTy);
1499 MRI.setRegBank(DefReg, RegBank);
1500 if (!emitInsertSubreg(DefReg,
I.getOperand(1).getReg(),
I,
MRI, MF))
1503 for (
unsigned Idx = 2; Idx <
I.getNumOperands(); ++Idx) {
1504 Register Tmp =
MRI.createGenericVirtualRegister(DstTy);
1505 MRI.setRegBank(Tmp, RegBank);
1507 MachineInstr &InsertInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1508 TII.get(TargetOpcode::G_INSERT), Tmp)
1510 .
addReg(
I.getOperand(Idx).getReg())
1511 .
addImm((Idx - 1) * SrcSize);
1515 if (!select(InsertInst))
1519 MachineInstr &CopyInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1520 TII.get(TargetOpcode::COPY), DstReg)
1523 if (!select(CopyInst))
1526 I.eraseFromParent();
1530bool X86InstructionSelector::selectCondBranch(MachineInstr &
I,
1531 MachineRegisterInfo &
MRI,
1532 MachineFunction &MF)
const {
1533 assert((
I.getOpcode() == TargetOpcode::G_BRCOND) &&
"unexpected instruction");
1535 const Register CondReg =
I.getOperand(0).getReg();
1536 MachineBasicBlock *DestMBB =
I.getOperand(1).getMBB();
1538 MachineInstr &TestInst =
1539 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::TEST8ri))
1542 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::JCC_1))
1547 I.eraseFromParent();
1551bool X86InstructionSelector::materializeFP(MachineInstr &
I,
1552 MachineRegisterInfo &
MRI,
1553 MachineFunction &MF)
const {
1554 assert((
I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1555 "unexpected instruction");
1562 const Register DstReg =
I.getOperand(0).getReg();
1563 const LLT DstTy =
MRI.getType(DstReg);
1566 const ConstantFP *CFP =
I.getOperand(1).getFPImm();
1569 const DebugLoc &DbgLoc =
I.getDebugLoc();
1572 getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Alignment);
1575 MachineInstr *LoadInst =
nullptr;
1582 Register AddrReg =
MRI.createVirtualRegister(&X86::GR64RegClass);
1583 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(X86::MOV64ri), AddrReg)
1600 unsigned PICBase = 0;
1609 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(
Opc), DstReg), CPI, PICBase,
1615 I.eraseFromParent();
1619bool X86InstructionSelector::selectImplicitDefOrPHI(
1620 MachineInstr &
I, MachineRegisterInfo &
MRI)
const {
1621 assert((
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1622 I.getOpcode() == TargetOpcode::G_PHI) &&
1623 "unexpected instruction");
1625 Register DstReg =
I.getOperand(0).getReg();
1627 if (!
MRI.getRegClassOrNull(DstReg)) {
1628 const LLT DstTy =
MRI.getType(DstReg);
1638 if (
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1639 I.setDesc(
TII.get(X86::IMPLICIT_DEF));
1641 I.setDesc(
TII.get(X86::PHI));
1646bool X86InstructionSelector::selectMulDivRem(MachineInstr &
I,
1647 MachineRegisterInfo &
MRI,
1648 MachineFunction &MF)
const {
1650 assert((
I.getOpcode() == TargetOpcode::G_MUL ||
1651 I.getOpcode() == TargetOpcode::G_SMULH ||
1652 I.getOpcode() == TargetOpcode::G_UMULH ||
1653 I.getOpcode() == TargetOpcode::G_SDIV ||
1654 I.getOpcode() == TargetOpcode::G_SREM ||
1655 I.getOpcode() == TargetOpcode::G_UDIV ||
1656 I.getOpcode() == TargetOpcode::G_UREM) &&
1657 "unexpected instruction");
1659 const Register DstReg =
I.getOperand(0).getReg();
1660 const Register Op1Reg =
I.getOperand(1).getReg();
1661 const Register Op2Reg =
I.getOperand(2).getReg();
1663 const LLT RegTy =
MRI.getType(DstReg);
1664 assert(RegTy ==
MRI.getType(Op1Reg) && RegTy ==
MRI.getType(Op2Reg) &&
1665 "Arguments and return value types must match");
1668 if (!RegRB || RegRB->
getID() != X86::GPRRegBankID)
1671 const static unsigned NumTypes = 4;
1672 const static unsigned NumOps = 7;
1673 const static bool S =
true;
1674 const static bool U =
false;
1675 const static unsigned Copy = TargetOpcode::COPY;
1685 const static struct MulDivRemEntry {
1687 unsigned SizeInBits;
1691 struct MulDivRemResult {
1692 unsigned OpMulDivRem;
1693 unsigned OpSignExtend;
1700 } OpTable[NumTypes] = {
1705 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S},
1706 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S},
1707 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U},
1708 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1709 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AL, S},
1710 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AH, S},
1711 {X86::MUL8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1717 {X86::IDIV16r, X86::CWD,
Copy, X86::AX, S},
1718 {X86::IDIV16r, X86::CWD,
Copy, X86::DX, S},
1719 {X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U},
1720 {X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U},
1721 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::AX, S},
1722 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::DX, S},
1723 {X86::MUL16r, X86::MOV32r0,
Copy, X86::DX,
U},
1729 {X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S},
1730 {X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S},
1731 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U},
1732 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1733 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EAX, S},
1734 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EDX, S},
1735 {X86::MUL32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1741 {X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S},
1742 {X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S},
1743 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U},
1744 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1745 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RAX, S},
1746 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RDX, S},
1747 {X86::MUL64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1751 auto OpEntryIt =
llvm::find_if(OpTable, [RegTy](
const MulDivRemEntry &El) {
1754 if (OpEntryIt == std::end(OpTable))
1758 switch (
I.getOpcode()) {
1761 case TargetOpcode::G_SDIV:
1764 case TargetOpcode::G_SREM:
1767 case TargetOpcode::G_UDIV:
1770 case TargetOpcode::G_UREM:
1773 case TargetOpcode::G_MUL:
1776 case TargetOpcode::G_SMULH:
1779 case TargetOpcode::G_UMULH:
1784 const MulDivRemEntry &
TypeEntry = *OpEntryIt;
1785 const MulDivRemEntry::MulDivRemResult &OpEntry =
1788 const TargetRegisterClass *RegRC =
getRegClass(RegTy, *RegRB);
1798 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpCopy),
1803 if (OpEntry.OpSignExtend) {
1804 if (OpEntry.IsOpSigned)
1806 TII.get(OpEntry.OpSignExtend));
1808 Register Zero32 =
MRI.createVirtualRegister(&X86::GR32RegClass);
1809 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::MOV32r0),
1818 .
addReg(Zero32, 0, X86::sub_16bit);
1825 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
1834 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpMulDivRem))
1845 if (OpEntry.ResultReg == X86::AH && STI.is64Bit()) {
1846 Register SourceSuperReg =
MRI.createVirtualRegister(&X86::GR16RegClass);
1847 Register ResultSuperReg =
MRI.createVirtualRegister(&X86::GR16RegClass);
1848 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Copy), SourceSuperReg)
1852 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SHR16ri),
1858 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1860 .
addReg(ResultSuperReg, 0, X86::sub_8bit);
1862 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1864 .
addReg(OpEntry.ResultReg);
1866 I.eraseFromParent();
1871bool X86InstructionSelector::selectSelect(MachineInstr &
I,
1872 MachineRegisterInfo &
MRI,
1873 MachineFunction &MF)
const {
1881 LLT Ty =
MRI.getType(DstReg);
1892 OpCmp = X86::CMOV_GR8;
1895 OpCmp = STI.
canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
1898 OpCmp = STI.
canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
1902 OpCmp = X86::CMOV64rr;
1920InstructionSelector::ComplexRendererFns
1921X86InstructionSelector::selectAddr(MachineOperand &Root)
const {
1923 MachineIRBuilder MIRBuilder(*
MI);
1925 MachineRegisterInfo &
MRI =
MI->getMF()->getRegInfo();
1931 return std::nullopt;
1934 {[=](MachineInstrBuilder &MIB) {
1939 "Unknown type of address base");
1944 [=](MachineInstrBuilder &MIB) { MIB.addImm(AM.
Scale); },
1946 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); },
1948 [=](MachineInstrBuilder &MIB) {
1954 MIB.addImm(AM.
Disp);
1957 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); }}};
1960InstructionSelector *
1964 return new X86InstructionSelector(TM, Subtarget, RBI);
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectDebugInstr(MachineInstr &I, MachineRegisterInfo &MRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
static StringRef getName(Value *V)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool X86SelectAddress(MachineInstr &I, const X86TargetMachine &TM, const MachineRegisterInfo &MRI, const X86Subtarget &STI, X86AddressMode &AM)
static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC, const TargetRegisterClass *SrcRC)
static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI)
static const TargetRegisterClass * getRegClassFromGRPhysReg(Register Reg)
This file declares the targeting of the RegisterBankInfo class for X86.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
Register getCondReg() const
Register getFalseReg() const
Register getTrueReg() const
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
@ MOLoad
The memory access reads data.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
TypeSize getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
CodeModel::Model getCodeModel() const
Returns the code model.
bool hasSubClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Type * getType() const
All values are typed, get the type of this value.
Register getGlobalBaseReg(MachineFunction *MF) const
getGlobalBaseReg - Return a virtual register initialized with the the global base register value.
This class provides the information for the target register banks.
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
const X86InstrInfo * getInstrInfo() const override
unsigned char classifyGlobalReference(const GlobalValue *GV, const Module &M) const
bool isPICStyleRIPRel() const
unsigned char classifyLocalReference(const GlobalValue *GV) const
Classify a global variable reference for the current subtarget according to how we should reference i...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
@ X86
Windows x64, Windows Itanium (IA-64)
@ MO_GOTOFF
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
@ MO_PIC_BASE_OFFSET
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
std::pair< CondCode, bool > getX86ConditionCode(CmpInst::Predicate Predicate)
Return a pair of condition code for the given predicate and whether the instruction operands should b...
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
static bool isGlobalStubReference(unsigned char TargetFlag)
isGlobalStubReference - Return true if the specified TargetFlag operand is a reference to a stub for ...
static bool isGlobalRelativeToPICBase(unsigned char TargetFlag)
isGlobalRelativeToPICBase - Return true if the specified global value reference is relative to a 32-b...
PointerUnion< const TargetRegisterClass *, const RegisterBank * > RegClassOrRegBank
Convenient type to represent either a register class or a register bank.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI std::optional< APInt > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
static const MachineInstrBuilder & addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI, Register GlobalBaseReg, unsigned char OpFlags)
addConstantPoolReference - This function is used to add a reference to the base of a constant value s...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
static const MachineInstrBuilder & addFullAddress(const MachineInstrBuilder &MIB, const X86AddressMode &AM)
LLVM_ABI std::optional< int64_t > getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT fits in int64_t returns it.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static const MachineInstrBuilder & addOffset(const MachineInstrBuilder &MIB, int Offset)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
static const MachineInstrBuilder & addDirectMem(const MachineInstrBuilder &MIB, Register Reg)
addDirectMem - This function is used to add a direct memory reference to the current instruction – th...
InstructionSelector * createX86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &, const X86RegisterBankInfo &)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
X86AddressMode - This struct holds a generalized full x86 address mode.
union llvm::X86AddressMode::BaseUnion Base
enum llvm::X86AddressMode::@202116273335065351270200035056227005202106004277 BaseType