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()) {
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();
285 const RegisterBank &DstRegBank = *RBI.
getRegBank(DstReg, MRI,
TRI);
287 Register SrcReg =
I.getOperand(1).getReg();
289 const RegisterBank &SrcRegBank = *RBI.
getRegBank(SrcReg, MRI,
TRI);
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) {
305 TII.get(TargetOpcode::SUBREG_TO_REG))
308 .
addImm(getSubRegIndex(SrcRC));
310 I.getOperand(1).setReg(ExtSrc);
315 if (SrcSize == 16 && SrcRegBank.
getID() == X86::GPRRegBankID &&
316 (DstRegBank.
getID() == X86::VECRRegBankID)) {
322 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::SUBREG_TO_REG),
328 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), DstReg)
335 if (DstSize == 16 && DstRegBank.
getID() == X86::GPRRegBankID &&
336 (SrcRegBank.
getID() == X86::VECRRegBankID)) {
342 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), Temp32)
346 if (
Register Dst32 =
TRI.getMatchingSuperReg(DstReg, X86::sub_16bit,
347 &X86::GR32RegClass)) {
349 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), Dst32)
353 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), DstReg)
354 .
addReg(Temp32, {}, X86::sub_16bit);
364 "No phys reg on generic operators");
365 assert((DstSize == SrcSize ||
370 "Copy with different width?!");
372 const TargetRegisterClass *DstRC =
375 if (SrcRegBank.
getID() == X86::GPRRegBankID &&
376 DstRegBank.
getID() == X86::GPRRegBankID && SrcSize > DstSize &&
382 if (DstRC != SrcRC) {
383 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
384 I.getOperand(1).substPhysReg(SrcReg,
TRI);
399 I.setDesc(
TII.get(X86::COPY));
403bool X86InstructionSelector::select(MachineInstr &
I) {
404 assert(
I.getParent() &&
"Instruction should be in a basic block!");
405 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
411 unsigned Opcode =
I.getOpcode();
415 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
421 if (
I.isDebugInstr())
427 assert(
I.getNumOperands() ==
I.getNumExplicitOperands() &&
428 "Generic instruction has unexpected implicit operands\n");
430 if (selectImpl(
I, *CoverageInfo))
436 switch (
I.getOpcode()) {
439 case TargetOpcode::G_STORE:
440 case TargetOpcode::G_LOAD:
442 case TargetOpcode::G_PTR_ADD:
443 case TargetOpcode::G_FRAME_INDEX:
444 return selectFrameIndexOrGep(
I, MRI, MF);
445 case TargetOpcode::G_GLOBAL_VALUE:
446 return selectGlobalValue(
I, MRI, MF);
447 case TargetOpcode::G_CONSTANT:
448 return selectConstant(
I, MRI, MF);
449 case TargetOpcode::G_FCONSTANT:
450 return materializeFP(
I, MRI, MF);
451 case TargetOpcode::G_PTRTOINT:
452 case TargetOpcode::G_TRUNC:
453 return selectTruncOrPtrToInt(
I, MRI, MF);
454 case TargetOpcode::G_INTTOPTR:
455 case TargetOpcode::G_FREEZE:
457 case TargetOpcode::G_ZEXT:
458 return selectZext(
I, MRI, MF);
459 case TargetOpcode::G_ANYEXT:
460 return selectAnyext(
I, MRI, MF);
461 case TargetOpcode::G_ICMP:
462 return selectCmp(
I, MRI, MF);
463 case TargetOpcode::G_FCMP:
464 return selectFCmp(
I, MRI, MF);
465 case TargetOpcode::G_UADDE:
466 case TargetOpcode::G_UADDO:
467 case TargetOpcode::G_USUBE:
468 case TargetOpcode::G_USUBO:
469 return selectUAddSub(
I, MRI, MF);
470 case TargetOpcode::G_UNMERGE_VALUES:
472 case TargetOpcode::G_MERGE_VALUES:
473 case TargetOpcode::G_CONCAT_VECTORS:
475 case TargetOpcode::G_EXTRACT:
476 return selectExtract(
I, MRI, MF);
477 case TargetOpcode::G_INSERT:
478 return selectInsert(
I, MRI, MF);
479 case TargetOpcode::G_BRCOND:
480 return selectCondBranch(
I, MRI, MF);
481 case TargetOpcode::G_IMPLICIT_DEF:
482 case TargetOpcode::G_PHI:
483 return selectImplicitDefOrPHI(
I, MRI);
484 case TargetOpcode::G_MUL:
485 case TargetOpcode::G_SMULH:
486 case TargetOpcode::G_UMULH:
487 case TargetOpcode::G_SDIV:
488 case TargetOpcode::G_UDIV:
489 case TargetOpcode::G_SREM:
490 case TargetOpcode::G_UREM:
491 return selectMulDivRem(
I, MRI, MF);
492 case TargetOpcode::G_SELECT:
493 return selectSelect(
I, MRI, MF);
499unsigned X86InstructionSelector::getPtrLoadStoreOp(
const LLT &Ty,
500 const RegisterBank &RB,
501 unsigned Opc)
const {
502 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
503 "Only G_STORE and G_LOAD are expected for selection");
505 bool IsLoad = (
Opc == TargetOpcode::G_LOAD);
510 return IsLoad ? X86::MOV32rm : X86::MOV32mr;
512 return IsLoad ? X86::MOV64rm : X86::MOV64mr;
518unsigned X86InstructionSelector::getLoadStoreOp(
const LLT &Ty,
519 const RegisterBank &RB,
521 Align Alignment)
const {
522 bool Isload = (
Opc == TargetOpcode::G_LOAD);
523 bool HasAVX = STI.
hasAVX();
525 bool HasVLX = STI.hasVLX();
528 if (X86::GPRRegBankID == RB.
getID())
529 return Isload ? X86::MOV8rm : X86::MOV8mr;
531 if (X86::GPRRegBankID == RB.
getID())
532 return Isload ? X86::MOV16rm : X86::MOV16mr;
534 if (X86::GPRRegBankID == RB.
getID())
535 return Isload ? X86::MOV32rm : X86::MOV32mr;
536 if (X86::VECRRegBankID == RB.
getID())
537 return Isload ? (HasAVX512 ? X86::VMOVSSZrm_alt :
538 HasAVX ? X86::VMOVSSrm_alt :
540 : (HasAVX512 ?
X86::VMOVSSZmr :
541 HasAVX ?
X86::VMOVSSmr :
543 if (X86::PSRRegBankID == RB.
getID())
544 return Isload ? X86::LD_Fp32m : X86::ST_Fp32m;
546 if (X86::GPRRegBankID == RB.
getID())
547 return Isload ? X86::MOV64rm : X86::MOV64mr;
548 if (X86::VECRRegBankID == RB.
getID())
549 return Isload ? (HasAVX512 ? X86::VMOVSDZrm_alt :
550 HasAVX ? X86::VMOVSDrm_alt :
552 : (HasAVX512 ?
X86::VMOVSDZmr :
553 HasAVX ?
X86::VMOVSDmr :
555 if (X86::PSRRegBankID == RB.
getID())
556 return Isload ? X86::LD_Fp64m : X86::ST_Fp64m;
558 return Isload ? X86::LD_Fp80m : X86::ST_FpP80m;
560 if (Alignment >=
Align(16))
561 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
563 ? X86::VMOVAPSZ128rm_NOVLX
564 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
565 : (HasVLX ?
X86::VMOVAPSZ128mr
567 ?
X86::VMOVAPSZ128mr_NOVLX
568 : HasAVX ?
X86::VMOVAPSmr :
X86::MOVAPSmr);
570 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
572 ? X86::VMOVUPSZ128rm_NOVLX
573 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
574 : (HasVLX ? X86::VMOVUPSZ128mr
576 ? X86::VMOVUPSZ128mr_NOVLX
577 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
579 if (Alignment >=
Align(32))
580 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
581 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
583 : (HasVLX ?
X86::VMOVAPSZ256mr
584 : HasAVX512 ?
X86::VMOVAPSZ256mr_NOVLX
587 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
588 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
590 : (HasVLX ? X86::VMOVUPSZ256mr
591 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
594 if (Alignment >=
Align(64))
595 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
597 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
606 assert(
I.getOperand(0).isReg() &&
"unsupported operand.");
608 "unsupported type.");
610 switch (
I.getOpcode()) {
613 case TargetOpcode::G_FRAME_INDEX:
617 case TargetOpcode::G_PTR_ADD: {
621 AM.
Disp =
static_cast<int32_t
>(Imm);
622 AM.
Base.
Reg =
I.getOperand(1).getReg();
628 case TargetOpcode::G_GLOBAL_VALUE: {
629 auto GV =
I.getOperand(1).getGlobal();
630 if (GV->isThreadLocal()) {
656 "RIP-relative addresses can't have additional register operands");
661 case TargetOpcode::G_CONSTANT_POOL: {
669 else if (STI.is64Bit())
672 AM.
Disp =
I.getOperand(1).getIndex();
677 AM.
Base.
Reg =
I.getOperand(0).getReg();
681bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &
I,
682 MachineRegisterInfo &MRI,
683 MachineFunction &MF)
const {
684 unsigned Opc =
I.getOpcode();
686 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
687 "Only G_STORE and G_LOAD are expected for selection");
689 const Register DefReg =
I.getOperand(0).getReg();
694 auto &MemOp = **
I.memoperands_begin();
695 if (MemOp.isAtomic()) {
701 if (!MemOp.isUnordered()) {
711 unsigned NewOpc = getPtrLoadStoreOp(Ty, RB,
Opc);
715 I.setDesc(
TII.get(NewOpc));
716 MachineInstrBuilder MIB(MF,
I);
717 MachineInstr *Ptr = MRI.
getVRegDef(
I.getOperand(1).getReg());
723 if (
Opc == TargetOpcode::G_LOAD) {
733 I.addImplicitDefUseOperands(MF);
746bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &
I,
747 MachineRegisterInfo &MRI,
748 MachineFunction &MF)
const {
749 unsigned Opc =
I.getOpcode();
751 assert((
Opc == TargetOpcode::G_FRAME_INDEX ||
Opc == TargetOpcode::G_PTR_ADD) &&
752 "unexpected instruction");
754 const Register DefReg =
I.getOperand(0).getReg();
758 unsigned NewOpc =
getLeaOP(Ty, STI);
759 I.setDesc(
TII.get(NewOpc));
760 MachineInstrBuilder MIB(MF,
I);
762 if (
Opc == TargetOpcode::G_FRAME_INDEX) {
765 MachineOperand &InxOp =
I.getOperand(2);
768 MIB.addImm(0).addReg(0);
775bool X86InstructionSelector::selectGlobalValue(MachineInstr &
I,
776 MachineRegisterInfo &MRI,
777 MachineFunction &MF)
const {
778 assert((
I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
779 "unexpected instruction");
784 const GlobalValue *GV =
I.getOperand(1).getGlobal();
799 const Register DefReg =
I.getOperand(0).getReg();
804 I.setDesc(
TII.get(NewOpc));
805 MachineInstrBuilder MIB(MF,
I);
814bool X86InstructionSelector::selectConstant(MachineInstr &
I,
815 MachineRegisterInfo &MRI,
816 MachineFunction &MF)
const {
817 assert((
I.getOpcode() == TargetOpcode::G_CONSTANT) &&
818 "unexpected instruction");
820 const Register DefReg =
I.getOperand(0).getReg();
827 if (
I.getOperand(1).isCImm()) {
828 Val =
I.getOperand(1).getCImm()->getZExtValue();
829 I.getOperand(1).ChangeToImmediate(Val);
830 }
else if (
I.getOperand(1).isImm()) {
831 Val =
I.getOperand(1).getImm();
838 NewOpc = X86::MOV8ri;
841 NewOpc = X86::MOV16ri;
844 NewOpc = X86::MOV32ri;
848 NewOpc = X86::MOV32ri64;
850 NewOpc = X86::MOV64ri32;
852 NewOpc = X86::MOV64ri;
858 I.setDesc(
TII.get(NewOpc));
868 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
869 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
870 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
873bool X86InstructionSelector::selectTurnIntoCOPY(
874 MachineInstr &
I, MachineRegisterInfo &MRI,
const Register DstReg,
875 const TargetRegisterClass *DstRC,
const Register SrcReg,
876 const TargetRegisterClass *SrcRC)
const {
884 I.setDesc(
TII.get(X86::COPY));
888bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &
I,
889 MachineRegisterInfo &MRI,
890 MachineFunction &MF)
const {
891 assert((
I.getOpcode() == TargetOpcode::G_TRUNC ||
892 I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
893 "unexpected instruction");
895 const Register DstReg =
I.getOperand(0).getReg();
896 const Register SrcReg =
I.getOperand(1).getReg();
898 const LLT DstTy = MRI.
getType(DstReg);
899 const LLT SrcTy = MRI.
getType(SrcReg);
901 const RegisterBank &DstRB = *RBI.
getRegBank(DstReg, MRI,
TRI);
902 const RegisterBank &SrcRB = *RBI.
getRegBank(SrcReg, MRI,
TRI);
906 <<
" input/output on different banks\n");
910 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstRB);
911 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcRB);
913 if (!DstRC || !SrcRC)
920 return selectTurnIntoCOPY(
I, MRI, DstReg, DstRC, SrcReg, SrcRC);
922 if (DstRB.
getID() != X86::GPRRegBankID)
926 if (DstRC == SrcRC) {
928 SubIdx = X86::NoSubRegister;
929 }
else if (DstRC == &X86::GR32RegClass) {
930 SubIdx = X86::sub_32bit;
931 }
else if (DstRC == &X86::GR16RegClass) {
932 SubIdx = X86::sub_16bit;
933 }
else if (DstRC == &X86::GR8RegClass) {
934 SubIdx = X86::sub_8bit;
939 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
948 I.getOperand(1).setSubReg(SubIdx);
950 I.setDesc(
TII.get(X86::COPY));
954bool X86InstructionSelector::selectZext(MachineInstr &
I,
955 MachineRegisterInfo &MRI,
956 MachineFunction &MF)
const {
957 assert((
I.getOpcode() == TargetOpcode::G_ZEXT) &&
"unexpected instruction");
959 const Register DstReg =
I.getOperand(0).getReg();
960 const Register SrcReg =
I.getOperand(1).getReg();
962 const LLT DstTy = MRI.
getType(DstReg);
963 const LLT SrcTy = MRI.
getType(SrcReg);
966 "8=>16 Zext is handled by tablegen");
968 "8=>32 Zext is handled by tablegen");
970 "16=>32 Zext is handled by tablegen");
972 "8=>64 Zext is handled by tablegen");
974 "16=>64 Zext is handled by tablegen");
976 "32=>64 Zext is handled by tablegen");
983 AndOpc = X86::AND8ri;
985 AndOpc = X86::AND16ri;
987 AndOpc = X86::AND32ri;
989 AndOpc = X86::AND64ri32;
998 TII.get(TargetOpcode::IMPLICIT_DEF), ImpDefReg);
1002 TII.get(TargetOpcode::INSERT_SUBREG), DefReg)
1008 MachineInstr &AndInst =
1009 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(AndOpc), DstReg)
1015 I.eraseFromParent();
1019bool X86InstructionSelector::selectAnyext(MachineInstr &
I,
1020 MachineRegisterInfo &MRI,
1021 MachineFunction &MF)
const {
1022 assert((
I.getOpcode() == TargetOpcode::G_ANYEXT) &&
"unexpected instruction");
1024 const Register DstReg =
I.getOperand(0).getReg();
1025 const Register SrcReg =
I.getOperand(1).getReg();
1027 const LLT DstTy = MRI.
getType(DstReg);
1028 const LLT SrcTy = MRI.
getType(SrcReg);
1030 const RegisterBank &DstRB = *RBI.
getRegBank(DstReg, MRI,
TRI);
1031 const RegisterBank &SrcRB = *RBI.
getRegBank(SrcReg, MRI,
TRI);
1034 "G_ANYEXT input/output on different banks\n");
1037 "G_ANYEXT incorrect operand size");
1039 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstRB);
1040 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcRB);
1046 return selectTurnIntoCOPY(
I, MRI, SrcReg, SrcRC, DstReg, DstRC);
1048 if (DstRB.
getID() != X86::GPRRegBankID)
1058 if (SrcRC == DstRC) {
1059 I.setDesc(
TII.get(X86::COPY));
1064 TII.get(TargetOpcode::SUBREG_TO_REG))
1067 .
addImm(getSubRegIndex(SrcRC));
1069 I.eraseFromParent();
1073bool X86InstructionSelector::selectCmp(MachineInstr &
I,
1074 MachineRegisterInfo &MRI,
1075 MachineFunction &MF)
const {
1076 assert((
I.getOpcode() == TargetOpcode::G_ICMP) &&
"unexpected instruction");
1096 OpCmp = X86::CMP8rr;
1099 OpCmp = X86::CMP16rr;
1102 OpCmp = X86::CMP32rr;
1105 OpCmp = X86::CMP64rr;
1109 MachineInstr &CmpInst =
1110 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1114 MachineInstr &SetInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1115 TII.get(X86::SETCCr),
I.getOperand(0).getReg()).
addImm(CC);
1120 I.eraseFromParent();
1124bool X86InstructionSelector::selectFCmp(MachineInstr &
I,
1125 MachineRegisterInfo &MRI,
1126 MachineFunction &MF)
const {
1127 assert((
I.getOpcode() == TargetOpcode::G_FCMP) &&
"unexpected instruction");
1129 Register LhsReg =
I.getOperand(2).getReg();
1130 Register RhsReg =
I.getOperand(3).getReg();
1135 static const uint16_t SETFOpcTable[2][3] = {
1138 const uint16_t *SETFOpc =
nullptr;
1139 switch (Predicate) {
1143 SETFOpc = &SETFOpcTable[0][0];
1146 SETFOpc = &SETFOpcTable[1][0];
1151 "Both arguments of FCMP need to be virtual!");
1153 [[maybe_unused]]
auto *RhsBank = RBI.
getRegBank(RhsReg, MRI,
TRI);
1154 assert((LhsBank == RhsBank) &&
1155 "Both banks assigned to FCMP arguments need to be same!");
1164 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr32
1168 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr64
1172 OpCmp = X86::UCOM_FpIr80;
1176 Register ResultReg =
I.getOperand(0).getReg();
1181 MachineInstr &CmpInst =
1182 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1188 MachineInstr &Set1 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1189 TII.get(X86::SETCCr), FlagReg1).
addImm(SETFOpc[0]);
1190 MachineInstr &Set2 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1191 TII.get(X86::SETCCr), FlagReg2).
addImm(SETFOpc[1]);
1192 MachineInstr &Set3 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1193 TII.get(SETFOpc[2]), ResultReg)
1201 I.eraseFromParent();
1214 MachineInstr &CmpInst =
1215 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1223 I.eraseFromParent();
1227bool X86InstructionSelector::selectUAddSub(MachineInstr &
I,
1228 MachineRegisterInfo &MRI,
1229 MachineFunction &MF)
const {
1230 assert((
I.getOpcode() == TargetOpcode::G_UADDE ||
1231 I.getOpcode() == TargetOpcode::G_UADDO ||
1232 I.getOpcode() == TargetOpcode::G_USUBE ||
1233 I.getOpcode() == TargetOpcode::G_USUBO) &&
1234 "unexpected instruction");
1238 const Register DstReg = CarryMI.getDstReg();
1239 const Register CarryOutReg = CarryMI.getCarryOutReg();
1240 const Register Op0Reg = CarryMI.getLHSReg();
1241 const Register Op1Reg = CarryMI.getRHSReg();
1242 bool IsSub = CarryMI.isSub();
1244 const LLT DstTy = MRI.
getType(DstReg);
1245 assert(DstTy.
isScalar() &&
"selectUAddSub only supported for scalar types");
1248 unsigned OpADC, OpADD, OpSBB, OpSUB;
1251 OpADC = X86::ADC8rr;
1252 OpADD = X86::ADD8rr;
1253 OpSBB = X86::SBB8rr;
1254 OpSUB = X86::SUB8rr;
1257 OpADC = X86::ADC16rr;
1258 OpADD = X86::ADD16rr;
1259 OpSBB = X86::SBB16rr;
1260 OpSUB = X86::SUB16rr;
1263 OpADC = X86::ADC32rr;
1264 OpADD = X86::ADD32rr;
1265 OpSBB = X86::SBB32rr;
1266 OpSUB = X86::SUB32rr;
1269 OpADC = X86::ADC64rr;
1270 OpADD = X86::ADD64rr;
1271 OpSBB = X86::SBB64rr;
1272 OpSUB = X86::SUB64rr;
1278 const RegisterBank &CarryRB = *RBI.
getRegBank(CarryOutReg, MRI,
TRI);
1279 const TargetRegisterClass *CarryRC =
1282 unsigned Opcode = IsSub ? OpSUB : OpADD;
1286 Register CarryInReg = CarryInMI->getCarryInReg();
1288 while (
Def->getOpcode() == TargetOpcode::G_TRUNC) {
1289 CarryInReg =
Def->getOperand(1).getReg();
1294 if (
Def->getOpcode() == TargetOpcode::G_UADDE ||
1295 Def->getOpcode() == TargetOpcode::G_UADDO ||
1296 Def->getOpcode() == TargetOpcode::G_USUBE ||
1297 Def->getOpcode() == TargetOpcode::G_USUBO) {
1300 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::CMP8ri))
1307 Opcode = IsSub ? OpSBB : OpADC;
1313 Opcode = IsSub ? OpSUB : OpADD;
1318 MachineInstr &Inst =
1319 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1323 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SETCCr), CarryOutReg)
1330 I.eraseFromParent();
1334bool X86InstructionSelector::selectExtract(MachineInstr &
I,
1335 MachineRegisterInfo &MRI,
1336 MachineFunction &MF)
const {
1337 assert((
I.getOpcode() == TargetOpcode::G_EXTRACT) &&
1338 "unexpected instruction");
1340 const Register DstReg =
I.getOperand(0).getReg();
1341 const Register SrcReg =
I.getOperand(1).getReg();
1342 int64_t
Index =
I.getOperand(2).getImm();
1344 const LLT DstTy = MRI.
getType(DstReg);
1345 const LLT SrcTy = MRI.
getType(SrcReg);
1356 if (!emitExtractSubreg(DstReg, SrcReg,
I, MRI, MF))
1359 I.eraseFromParent();
1363 bool HasAVX = STI.
hasAVX();
1365 bool HasVLX = STI.hasVLX();
1369 I.setDesc(
TII.get(X86::VEXTRACTF32X4Z256rri));
1371 I.setDesc(
TII.get(X86::VEXTRACTF128rri));
1376 I.setDesc(
TII.get(X86::VEXTRACTF32X4Zrri));
1378 I.setDesc(
TII.get(X86::VEXTRACTF64X4Zrri));
1386 I.getOperand(2).setImm(Index);
1392bool X86InstructionSelector::emitExtractSubreg(
Register DstReg,
Register SrcReg,
1394 MachineRegisterInfo &MRI,
1395 MachineFunction &MF)
const {
1396 const LLT DstTy = MRI.
getType(DstReg);
1397 const LLT SrcTy = MRI.
getType(SrcReg);
1398 unsigned SubIdx = X86::NoSubRegister;
1404 "Incorrect Src/Dst register size");
1407 SubIdx = X86::sub_xmm;
1409 SubIdx = X86::sub_ymm;
1413 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstReg, MRI);
1414 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcReg, MRI);
1416 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1424 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::COPY), DstReg)
1425 .
addReg(SrcReg, {}, SubIdx);
1430bool X86InstructionSelector::emitInsertSubreg(
Register DstReg,
Register SrcReg,
1432 MachineRegisterInfo &MRI,
1433 MachineFunction &MF)
const {
1434 const LLT DstTy = MRI.
getType(DstReg);
1435 const LLT SrcTy = MRI.
getType(SrcReg);
1436 unsigned SubIdx = X86::NoSubRegister;
1443 "Incorrect Src/Dst register size");
1446 SubIdx = X86::sub_xmm;
1448 SubIdx = X86::sub_ymm;
1452 const TargetRegisterClass *SrcRC =
getRegClass(SrcTy, SrcReg, MRI);
1453 const TargetRegisterClass *DstRC =
getRegClass(DstTy, DstReg, MRI);
1462 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::IMPLICIT_DEF),
1465 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::INSERT_SUBREG),
1474bool X86InstructionSelector::selectInsert(MachineInstr &
I,
1475 MachineRegisterInfo &MRI,
1476 MachineFunction &MF)
const {
1477 assert((
I.getOpcode() == TargetOpcode::G_INSERT) &&
"unexpected instruction");
1479 const Register DstReg =
I.getOperand(0).getReg();
1480 const Register SrcReg =
I.getOperand(1).getReg();
1481 const Register InsertReg =
I.getOperand(2).getReg();
1482 int64_t
Index =
I.getOperand(3).getImm();
1484 const LLT DstTy = MRI.
getType(DstReg);
1485 const LLT InsertRegTy = MRI.
getType(InsertReg);
1496 if (!emitInsertSubreg(DstReg, InsertReg,
I, MRI, MF))
1499 I.eraseFromParent();
1503 bool HasAVX = STI.
hasAVX();
1505 bool HasVLX = STI.hasVLX();
1509 I.setDesc(
TII.get(X86::VINSERTF32X4Z256rri));
1511 I.setDesc(
TII.get(X86::VINSERTF128rri));
1516 I.setDesc(
TII.get(X86::VINSERTF32X4Zrri));
1518 I.setDesc(
TII.get(X86::VINSERTF64X4Zrri));
1527 I.getOperand(3).setImm(Index);
1533bool X86InstructionSelector::selectUnmergeValues(
1534 MachineInstr &
I, MachineRegisterInfo &MRI, MachineFunction &MF) {
1535 assert((
I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1536 "unexpected instruction");
1539 unsigned NumDefs =
I.getNumOperands() - 1;
1540 Register SrcReg =
I.getOperand(NumDefs).getReg();
1543 for (
unsigned Idx = 0; Idx < NumDefs; ++Idx) {
1544 MachineInstr &ExtrInst =
1546 TII.get(TargetOpcode::G_EXTRACT),
I.getOperand(Idx).getReg())
1550 if (!select(ExtrInst))
1554 I.eraseFromParent();
1558bool X86InstructionSelector::selectMergeValues(
1559 MachineInstr &
I, MachineRegisterInfo &MRI, MachineFunction &MF) {
1560 assert((
I.getOpcode() == TargetOpcode::G_MERGE_VALUES ||
1561 I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS) &&
1562 "unexpected instruction");
1565 Register DstReg =
I.getOperand(0).getReg();
1566 Register SrcReg0 =
I.getOperand(1).getReg();
1568 const LLT DstTy = MRI.
getType(DstReg);
1569 const LLT SrcTy = MRI.
getType(SrcReg0);
1572 const RegisterBank &RegBank = *RBI.
getRegBank(DstReg, MRI,
TRI);
1577 if (!emitInsertSubreg(DefReg,
I.getOperand(1).getReg(),
I, MRI, MF))
1580 for (
unsigned Idx = 2; Idx <
I.getNumOperands(); ++Idx) {
1584 MachineInstr &InsertInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1585 TII.get(TargetOpcode::G_INSERT), Tmp)
1587 .
addReg(
I.getOperand(Idx).getReg())
1588 .
addImm((Idx - 1) * SrcSize);
1592 if (!select(InsertInst))
1596 MachineInstr &CopyInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1597 TII.get(TargetOpcode::COPY), DstReg)
1600 if (!select(CopyInst))
1603 I.eraseFromParent();
1607bool X86InstructionSelector::selectCondBranch(MachineInstr &
I,
1608 MachineRegisterInfo &MRI,
1609 MachineFunction &MF)
const {
1610 assert((
I.getOpcode() == TargetOpcode::G_BRCOND) &&
"unexpected instruction");
1612 const Register CondReg =
I.getOperand(0).getReg();
1613 MachineBasicBlock *DestMBB =
I.getOperand(1).getMBB();
1615 MachineInstr &TestInst =
1616 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::TEST8ri))
1619 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::JCC_1))
1624 I.eraseFromParent();
1628bool X86InstructionSelector::materializeFP(MachineInstr &
I,
1629 MachineRegisterInfo &MRI,
1630 MachineFunction &MF)
const {
1631 assert((
I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1632 "unexpected instruction");
1639 const Register DstReg =
I.getOperand(0).getReg();
1640 const LLT DstTy = MRI.
getType(DstReg);
1641 const RegisterBank &RegBank = *RBI.
getRegBank(DstReg, MRI,
TRI);
1643 const ConstantFP *CFP =
I.getOperand(1).getFPImm();
1646 const DebugLoc &DbgLoc =
I.getDebugLoc();
1649 getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Alignment);
1652 MachineInstr *LoadInst =
nullptr;
1660 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(X86::MOV64ri), AddrReg)
1677 unsigned PICBase = 0;
1686 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(
Opc), DstReg), CPI, PICBase,
1692 I.eraseFromParent();
1696bool X86InstructionSelector::selectImplicitDefOrPHI(
1697 MachineInstr &
I, MachineRegisterInfo &MRI)
const {
1698 assert((
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1699 I.getOpcode() == TargetOpcode::G_PHI) &&
1700 "unexpected instruction");
1702 Register DstReg =
I.getOperand(0).getReg();
1705 const LLT DstTy = MRI.
getType(DstReg);
1706 const TargetRegisterClass *RC =
getRegClass(DstTy, DstReg, MRI);
1715 if (
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1716 I.setDesc(
TII.get(X86::IMPLICIT_DEF));
1718 I.setDesc(
TII.get(X86::PHI));
1723bool X86InstructionSelector::selectMulDivRem(MachineInstr &
I,
1724 MachineRegisterInfo &MRI,
1725 MachineFunction &MF)
const {
1727 assert((
I.getOpcode() == TargetOpcode::G_MUL ||
1728 I.getOpcode() == TargetOpcode::G_SMULH ||
1729 I.getOpcode() == TargetOpcode::G_UMULH ||
1730 I.getOpcode() == TargetOpcode::G_SDIV ||
1731 I.getOpcode() == TargetOpcode::G_SREM ||
1732 I.getOpcode() == TargetOpcode::G_UDIV ||
1733 I.getOpcode() == TargetOpcode::G_UREM) &&
1734 "unexpected instruction");
1736 const Register DstReg =
I.getOperand(0).getReg();
1737 const Register Op1Reg =
I.getOperand(1).getReg();
1738 const Register Op2Reg =
I.getOperand(2).getReg();
1740 const LLT RegTy = MRI.
getType(DstReg);
1742 "Arguments and return value types must match");
1744 const RegisterBank *RegRB = RBI.
getRegBank(DstReg, MRI,
TRI);
1745 if (!RegRB || RegRB->
getID() != X86::GPRRegBankID)
1748 const static unsigned NumTypes = 4;
1749 const static unsigned NumOps = 7;
1750 const static bool S =
true;
1751 const static bool U =
false;
1752 const static unsigned Copy = TargetOpcode::COPY;
1762 const static struct MulDivRemEntry {
1764 unsigned SizeInBits;
1768 struct MulDivRemResult {
1769 unsigned OpMulDivRem;
1770 unsigned OpSignExtend;
1777 } OpTable[NumTypes] = {
1782 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S},
1783 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S},
1784 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U},
1785 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1786 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AL, S},
1787 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AH, S},
1788 {X86::MUL8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1794 {X86::IDIV16r, X86::CWD,
Copy, X86::AX, S},
1795 {X86::IDIV16r, X86::CWD,
Copy, X86::DX, S},
1796 {X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U},
1797 {X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U},
1798 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::AX, S},
1799 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::DX, S},
1800 {X86::MUL16r, X86::MOV32r0,
Copy, X86::DX,
U},
1806 {X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S},
1807 {X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S},
1808 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U},
1809 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1810 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EAX, S},
1811 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EDX, S},
1812 {X86::MUL32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1818 {X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S},
1819 {X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S},
1820 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U},
1821 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1822 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RAX, S},
1823 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RDX, S},
1824 {X86::MUL64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1828 auto OpEntryIt =
llvm::find_if(OpTable, [RegTy](
const MulDivRemEntry &El) {
1831 if (OpEntryIt == std::end(OpTable))
1835 switch (
I.getOpcode()) {
1838 case TargetOpcode::G_SDIV:
1841 case TargetOpcode::G_SREM:
1844 case TargetOpcode::G_UDIV:
1847 case TargetOpcode::G_UREM:
1850 case TargetOpcode::G_MUL:
1853 case TargetOpcode::G_SMULH:
1856 case TargetOpcode::G_UMULH:
1861 const MulDivRemEntry &
TypeEntry = *OpEntryIt;
1862 const MulDivRemEntry::MulDivRemResult &OpEntry =
1865 const TargetRegisterClass *RegRC =
getRegClass(RegTy, *RegRB);
1875 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpCopy),
1880 if (OpEntry.OpSignExtend) {
1881 if (OpEntry.IsOpSigned)
1883 TII.get(OpEntry.OpSignExtend));
1886 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::MOV32r0),
1895 .
addReg(Zero32, {}, X86::sub_16bit);
1902 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
1910 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpMulDivRem))
1921 if (OpEntry.ResultReg == X86::AH && STI.is64Bit()) {
1924 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Copy), SourceSuperReg)
1928 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SHR16ri),
1934 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1936 .
addReg(ResultSuperReg, {}, X86::sub_8bit);
1938 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1940 .
addReg(OpEntry.ResultReg);
1942 I.eraseFromParent();
1947bool X86InstructionSelector::selectSelect(MachineInstr &
I,
1948 MachineRegisterInfo &MRI,
1949 MachineFunction &MF)
const {
1968 OpCmp = X86::CMOV_GR8;
1971 OpCmp = STI.
canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
1974 OpCmp = STI.
canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
1978 OpCmp = X86::CMOV64rr;
1986 const TargetRegisterClass *DstRC =
getRegClass(Ty, DstReg, MRI);
1996InstructionSelector::ComplexRendererFns
1997X86InstructionSelector::selectAddr(MachineOperand &Root)
const {
1999 MachineIRBuilder MIRBuilder(*
MI);
2001 MachineRegisterInfo &MRI =
MI->getMF()->getRegInfo();
2007 return std::nullopt;
2010 {[=](MachineInstrBuilder &MIB) {
2015 "Unknown type of address base");
2020 [=](MachineInstrBuilder &MIB) { MIB.addImm(AM.
Scale); },
2022 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); },
2024 [=](MachineInstrBuilder &MIB) {
2030 MIB.addImm(AM.
Disp);
2033 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); }}};
2036InstructionSelector *
2040 return new X86InstructionSelector(TM, Subtarget, RBI);
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 & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
bool isImplicitDef() const
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > 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,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const RegClassOrRegBank & getRegClassOrRegBank(Register Reg) const
Return the register bank or register class of Reg.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI void setRegBank(Register Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
const TargetRegisterClass * getRegClassOrNull(Register Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet.
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)?
bool isTarget64BitLP64() const
Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
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_GOTPCREL_NORELAX
MO_GOTPCREL_NORELAX - Same as MO_GOTPCREL except that R_X86_64_GOTPCREL relocations are guaranteed to...
@ 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...
@ MO_GOTPCREL
MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for 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 void 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.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
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