41#include "llvm/IR/IntrinsicsX86.h"
51#define DEBUG_TYPE "X86-isel"
58#define GET_GLOBALISEL_PREDICATE_BITSET
59#include "X86GenGlobalISel.inc"
60#undef GET_GLOBALISEL_PREDICATE_BITSET
77 Align Alignment)
const;
146#define GET_GLOBALISEL_PREDICATES_DECL
147#include "X86GenGlobalISel.inc"
148#undef GET_GLOBALISEL_PREDICATES_DECL
150#define GET_GLOBALISEL_TEMPORARIES_DECL
151#include "X86GenGlobalISel.inc"
152#undef GET_GLOBALISEL_TEMPORARIES_DECL
157#define GET_GLOBALISEL_IMPL
158#include "X86GenGlobalISel.inc"
159#undef GET_GLOBALISEL_IMPL
164 : TM(TM), STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()),
167#include
"X86GenGlobalISel.inc"
170#include
"X86GenGlobalISel.inc"
178X86InstructionSelector::getRegClass(
LLT Ty,
const RegisterBank &RB)
const {
179 if (RB.
getID() == X86::GPRRegBankID) {
181 return &X86::GR8RegClass;
183 return &X86::GR16RegClass;
185 return &X86::GR32RegClass;
187 return &X86::GR64RegClass;
189 if (RB.
getID() == X86::VECRRegBankID) {
191 return STI.
hasAVX512() ? &X86::FR16XRegClass : &X86::FR16RegClass;
193 return STI.
hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
195 return STI.
hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
197 return STI.
hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
199 return STI.
hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
201 return &X86::VR512RegClass;
204 if (RB.
getID() == X86::PSRRegBankID) {
206 return &X86::RFP80RegClass;
208 return &X86::RFP64RegClass;
210 return &X86::RFP32RegClass;
217X86InstructionSelector::getRegClass(LLT Ty,
Register Reg,
218 MachineRegisterInfo &MRI)
const {
224 unsigned SubIdx = X86::NoSubRegister;
225 if (RC == &X86::GR32RegClass) {
226 SubIdx = X86::sub_32bit;
227 }
else if (RC == &X86::GR16RegClass) {
228 SubIdx = X86::sub_16bit;
229 }
else if (RC == &X86::GR8RegClass) {
230 SubIdx = X86::sub_8bit;
239 return &X86::GR64RegClass;
241 return &X86::GR32RegClass;
243 return &X86::GR16RegClass;
245 return &X86::GR8RegClass;
253bool X86InstructionSelector::selectDebugInstr(MachineInstr &
I,
254 MachineRegisterInfo &MRI)
const {
255 for (MachineOperand &MO :
I.operands()) {
272 dbgs() <<
"Warning: DBG_VALUE operand has unexpected size/bank\n");
283bool X86InstructionSelector::selectCopy(MachineInstr &
I,
284 MachineRegisterInfo &MRI)
const {
285 Register DstReg =
I.getOperand(0).getReg();
287 const RegisterBank &DstRegBank = *RBI.
getRegBank(DstReg, MRI,
TRI);
289 Register SrcReg =
I.getOperand(1).getReg();
291 const RegisterBank &SrcRegBank = *RBI.
getRegBank(SrcReg, MRI,
TRI);
294 assert(
I.isCopy() &&
"Generic operators do not allow physical registers");
296 if (DstSize > SrcSize && SrcRegBank.
getID() == X86::GPRRegBankID &&
297 DstRegBank.
getID() == X86::GPRRegBankID) {
303 if (SrcRC != DstRC) {
307 TII.get(TargetOpcode::SUBREG_TO_REG))
310 .
addImm(getSubRegIndex(SrcRC));
312 I.getOperand(1).setReg(ExtSrc);
317 if (SrcSize == 16 && SrcRegBank.
getID() == X86::GPRRegBankID &&
318 (DstRegBank.
getID() == X86::VECRRegBankID)) {
324 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::SUBREG_TO_REG),
330 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), DstReg)
337 if (DstSize == 16 && DstRegBank.
getID() == X86::GPRRegBankID &&
338 (SrcRegBank.
getID() == X86::VECRRegBankID)) {
344 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), Temp32)
348 if (
Register Dst32 =
TRI.getMatchingSuperReg(DstReg, X86::sub_16bit,
349 &X86::GR32RegClass)) {
351 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), Dst32)
355 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), DstReg)
356 .
addReg(Temp32, {}, X86::sub_16bit);
366 "No phys reg on generic operators");
367 assert((DstSize == SrcSize ||
372 "Copy with different width?!");
377 if (SrcRegBank.
getID() == X86::GPRRegBankID &&
378 DstRegBank.
getID() == X86::GPRRegBankID && SrcSize > DstSize &&
384 if (DstRC != SrcRC) {
385 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
386 I.getOperand(1).substPhysReg(SrcReg,
TRI);
401 I.setDesc(
TII.get(X86::COPY));
405bool X86InstructionSelector::select(MachineInstr &
I) {
406 assert(
I.getParent() &&
"Instruction should be in a basic block!");
407 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
413 unsigned Opcode =
I.getOpcode();
417 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
423 if (
I.isDebugInstr())
429 assert(
I.getNumOperands() ==
I.getNumExplicitOperands() &&
430 "Generic instruction has unexpected implicit operands\n");
432 if (selectImpl(
I, *CoverageInfo))
438 switch (
I.getOpcode()) {
441 case TargetOpcode::G_STORE:
442 case TargetOpcode::G_LOAD:
444 case TargetOpcode::G_PTR_ADD:
445 case TargetOpcode::G_FRAME_INDEX:
446 return selectFrameIndexOrGep(
I, MRI, MF);
447 case TargetOpcode::G_GLOBAL_VALUE:
448 return selectGlobalValue(
I, MRI, MF);
449 case TargetOpcode::G_CONSTANT:
450 return selectConstant(
I, MRI, MF);
451 case TargetOpcode::G_FCONSTANT:
452 return materializeFP(
I, MRI, MF);
453 case TargetOpcode::G_PTRTOINT:
454 case TargetOpcode::G_TRUNC:
455 return selectTruncOrPtrToInt(
I, MRI, MF);
456 case TargetOpcode::G_INTTOPTR:
457 case TargetOpcode::G_FREEZE:
459 case TargetOpcode::G_ZEXT:
460 return selectZext(
I, MRI, MF);
461 case TargetOpcode::G_ANYEXT:
462 return selectAnyext(
I, MRI, MF);
463 case TargetOpcode::G_ICMP:
464 return selectCmp(
I, MRI, MF);
465 case TargetOpcode::G_FCMP:
466 return selectFCmp(
I, MRI, MF);
467 case TargetOpcode::G_UADDE:
468 case TargetOpcode::G_UADDO:
469 case TargetOpcode::G_USUBE:
470 case TargetOpcode::G_USUBO:
471 return selectUAddSub(
I, MRI, MF);
472 case TargetOpcode::G_UNMERGE_VALUES:
474 case TargetOpcode::G_MERGE_VALUES:
475 case TargetOpcode::G_CONCAT_VECTORS:
477 case TargetOpcode::G_EXTRACT:
478 return selectExtract(
I, MRI, MF);
479 case TargetOpcode::G_INSERT:
480 return selectInsert(
I, MRI, MF);
481 case TargetOpcode::G_BRCOND:
482 return selectCondBranch(
I, MRI, MF);
483 case TargetOpcode::G_IMPLICIT_DEF:
484 case TargetOpcode::G_PHI:
485 return selectImplicitDefOrPHI(
I, MRI);
486 case TargetOpcode::G_MUL:
487 case TargetOpcode::G_SMULH:
488 case TargetOpcode::G_UMULH:
489 case TargetOpcode::G_SDIV:
490 case TargetOpcode::G_UDIV:
491 case TargetOpcode::G_SREM:
492 case TargetOpcode::G_UREM:
493 return selectMulDivRem(
I, MRI, MF);
494 case TargetOpcode::G_SELECT:
495 return selectSelect(
I, MRI, MF);
501unsigned X86InstructionSelector::getPtrLoadStoreOp(
const LLT &Ty,
502 const RegisterBank &RB,
503 unsigned Opc)
const {
504 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
505 "Only G_STORE and G_LOAD are expected for selection");
507 bool IsLoad = (
Opc == TargetOpcode::G_LOAD);
512 return IsLoad ? X86::MOV32rm : X86::MOV32mr;
514 return IsLoad ? X86::MOV64rm : X86::MOV64mr;
520unsigned X86InstructionSelector::getLoadStoreOp(
const LLT &Ty,
521 const RegisterBank &RB,
523 Align Alignment)
const {
524 bool Isload = (
Opc == TargetOpcode::G_LOAD);
525 bool HasAVX = STI.
hasAVX();
527 bool HasVLX = STI.hasVLX();
530 if (X86::GPRRegBankID == RB.
getID())
531 return Isload ? X86::MOV8rm : X86::MOV8mr;
533 if (X86::GPRRegBankID == RB.
getID())
534 return Isload ? X86::MOV16rm : X86::MOV16mr;
536 if (X86::GPRRegBankID == RB.
getID())
537 return Isload ? X86::MOV32rm : X86::MOV32mr;
538 if (X86::VECRRegBankID == RB.
getID())
539 return Isload ? (HasAVX512 ? X86::VMOVSSZrm_alt :
540 HasAVX ? X86::VMOVSSrm_alt :
542 : (HasAVX512 ?
X86::VMOVSSZmr :
543 HasAVX ?
X86::VMOVSSmr :
545 if (X86::PSRRegBankID == RB.
getID())
546 return Isload ? X86::LD_Fp32m : X86::ST_Fp32m;
548 if (X86::GPRRegBankID == RB.
getID())
549 return Isload ? X86::MOV64rm : X86::MOV64mr;
550 if (X86::VECRRegBankID == RB.
getID())
551 return Isload ? (HasAVX512 ? X86::VMOVSDZrm_alt :
552 HasAVX ? X86::VMOVSDrm_alt :
554 : (HasAVX512 ?
X86::VMOVSDZmr :
555 HasAVX ?
X86::VMOVSDmr :
557 if (X86::PSRRegBankID == RB.
getID())
558 return Isload ? X86::LD_Fp64m : X86::ST_Fp64m;
560 return Isload ? X86::LD_Fp80m : X86::ST_FpP80m;
562 if (Alignment >=
Align(16))
563 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
565 ? X86::VMOVAPSZ128rm_NOVLX
566 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
567 : (HasVLX ?
X86::VMOVAPSZ128mr
569 ?
X86::VMOVAPSZ128mr_NOVLX
570 : HasAVX ?
X86::VMOVAPSmr :
X86::MOVAPSmr);
572 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
574 ? X86::VMOVUPSZ128rm_NOVLX
575 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
576 : (HasVLX ? X86::VMOVUPSZ128mr
578 ? X86::VMOVUPSZ128mr_NOVLX
579 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
581 if (Alignment >=
Align(32))
582 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
583 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
585 : (HasVLX ?
X86::VMOVAPSZ256mr
586 : HasAVX512 ?
X86::VMOVAPSZ256mr_NOVLX
589 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
590 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
592 : (HasVLX ? X86::VMOVUPSZ256mr
593 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
596 if (Alignment >=
Align(64))
597 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
599 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
608 assert(
I.getOperand(0).isReg() &&
"unsupported operand.");
610 "unsupported type.");
612 switch (
I.getOpcode()) {
615 case TargetOpcode::G_FRAME_INDEX:
619 case TargetOpcode::G_PTR_ADD: {
623 AM.
Disp =
static_cast<int32_t
>(
Imm);
624 AM.
Base.
Reg =
I.getOperand(1).getReg();
630 case TargetOpcode::G_GLOBAL_VALUE:
631 case X86::G_WRAPPER_RIP: {
632 auto GV =
I.getOperand(1).getGlobal();
633 if (GV->isThreadLocal()) {
650 "RIP-relative addresses can't have additional register operands");
655 case TargetOpcode::G_CONSTANT_POOL: {
663 else if (STI.is64Bit())
666 AM.
Disp =
I.getOperand(1).getIndex();
671 AM.
Base.
Reg =
I.getOperand(0).getReg();
675bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &
I,
676 MachineRegisterInfo &MRI,
678 unsigned Opc =
I.getOpcode();
680 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
681 "Only G_STORE and G_LOAD are expected for selection");
683 const Register DefReg =
I.getOperand(0).getReg();
688 auto &MemOp = **
I.memoperands_begin();
689 if (MemOp.isAtomic()) {
695 if (!MemOp.isUnordered()) {
705 unsigned NewOpc = getPtrLoadStoreOp(Ty, RB,
Opc);
709 I.setDesc(
TII.get(NewOpc));
710 MachineInstrBuilder MIB(MF,
I);
711 MachineInstr *Ptr = MRI.
getVRegDef(
I.getOperand(1).getReg());
717 if (
Opc == TargetOpcode::G_LOAD) {
727 I.addImplicitDefUseOperands(MF);
740bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &
I,
741 MachineRegisterInfo &MRI,
743 unsigned Opc =
I.getOpcode();
745 assert((
Opc == TargetOpcode::G_FRAME_INDEX ||
Opc == TargetOpcode::G_PTR_ADD) &&
746 "unexpected instruction");
748 const Register DefReg =
I.getOperand(0).getReg();
752 unsigned NewOpc =
getLeaOP(Ty, STI);
753 I.setDesc(
TII.get(NewOpc));
754 MachineInstrBuilder MIB(MF,
I);
756 if (
Opc == TargetOpcode::G_FRAME_INDEX) {
759 MachineOperand &InxOp =
I.getOperand(2);
762 MIB.addImm(0).addReg(0);
769bool X86InstructionSelector::selectGlobalValue(MachineInstr &
I,
770 MachineRegisterInfo &MRI,
772 assert((
I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
773 "unexpected instruction");
779 const Register DefReg =
I.getOperand(0).getReg();
781 unsigned NewOpc =
getLeaOP(Ty, STI);
783 I.setDesc(
TII.get(NewOpc));
784 MachineInstrBuilder MIB(MF,
I);
793bool X86InstructionSelector::selectConstant(MachineInstr &
I,
794 MachineRegisterInfo &MRI,
796 assert((
I.getOpcode() == TargetOpcode::G_CONSTANT) &&
797 "unexpected instruction");
799 const Register DefReg =
I.getOperand(0).getReg();
806 if (
I.getOperand(1).isCImm()) {
807 Val =
I.getOperand(1).getCImm()->getZExtValue();
808 I.getOperand(1).ChangeToImmediate(Val);
809 }
else if (
I.getOperand(1).isImm()) {
810 Val =
I.getOperand(1).getImm();
817 NewOpc = X86::MOV8ri;
820 NewOpc = X86::MOV16ri;
823 NewOpc = X86::MOV32ri;
832 I.setDesc(
TII.get(NewOpc));
842 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
843 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
844 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
847bool X86InstructionSelector::selectTurnIntoCOPY(
848 MachineInstr &
I, MachineRegisterInfo &MRI,
const Register DstReg,
858 I.setDesc(
TII.get(X86::COPY));
862bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &
I,
863 MachineRegisterInfo &MRI,
865 assert((
I.getOpcode() == TargetOpcode::G_TRUNC ||
866 I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
867 "unexpected instruction");
869 const Register DstReg =
I.getOperand(0).getReg();
870 const Register SrcReg =
I.getOperand(1).getReg();
872 const LLT DstTy = MRI.
getType(DstReg);
873 const LLT SrcTy = MRI.
getType(SrcReg);
875 const RegisterBank &DstRB = *RBI.
getRegBank(DstReg, MRI,
TRI);
876 const RegisterBank &SrcRB = *RBI.
getRegBank(SrcReg, MRI,
TRI);
880 <<
" input/output on different banks\n");
887 if (!DstRC || !SrcRC)
894 return selectTurnIntoCOPY(
I, MRI, DstReg, DstRC, SrcReg, SrcRC);
896 if (DstRB.
getID() != X86::GPRRegBankID)
900 if (DstRC == SrcRC) {
902 SubIdx = X86::NoSubRegister;
903 }
else if (DstRC == &X86::GR32RegClass) {
904 SubIdx = X86::sub_32bit;
905 }
else if (DstRC == &X86::GR16RegClass) {
906 SubIdx = X86::sub_16bit;
907 }
else if (DstRC == &X86::GR8RegClass) {
908 SubIdx = X86::sub_8bit;
913 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
922 I.getOperand(1).setSubReg(SubIdx);
924 I.setDesc(
TII.get(X86::COPY));
928bool X86InstructionSelector::selectZext(MachineInstr &
I,
929 MachineRegisterInfo &MRI,
931 assert((
I.getOpcode() == TargetOpcode::G_ZEXT) &&
"unexpected instruction");
933 const Register DstReg =
I.getOperand(0).getReg();
934 const Register SrcReg =
I.getOperand(1).getReg();
936 const LLT DstTy = MRI.
getType(DstReg);
937 const LLT SrcTy = MRI.
getType(SrcReg);
940 "8=>16 Zext is handled by tablegen");
942 "8=>32 Zext is handled by tablegen");
944 "16=>32 Zext is handled by tablegen");
946 "8=>64 Zext is handled by tablegen");
948 "16=>64 Zext is handled by tablegen");
950 "32=>64 Zext is handled by tablegen");
957 AndOpc = X86::AND8ri;
959 AndOpc = X86::AND16ri;
961 AndOpc = X86::AND32ri;
963 AndOpc = X86::AND64ri32;
972 TII.get(TargetOpcode::IMPLICIT_DEF), ImpDefReg);
976 TII.get(TargetOpcode::INSERT_SUBREG), DefReg)
982 MachineInstr &AndInst =
983 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(AndOpc), DstReg)
993bool X86InstructionSelector::selectAnyext(MachineInstr &
I,
994 MachineRegisterInfo &MRI,
996 assert((
I.getOpcode() == TargetOpcode::G_ANYEXT) &&
"unexpected instruction");
998 const Register DstReg =
I.getOperand(0).getReg();
999 const Register SrcReg =
I.getOperand(1).getReg();
1001 const LLT DstTy = MRI.
getType(DstReg);
1002 const LLT SrcTy = MRI.
getType(SrcReg);
1004 const RegisterBank &DstRB = *RBI.
getRegBank(DstReg, MRI,
TRI);
1005 const RegisterBank &SrcRB = *RBI.
getRegBank(SrcReg, MRI,
TRI);
1008 "G_ANYEXT input/output on different banks\n");
1011 "G_ANYEXT incorrect operand size");
1020 return selectTurnIntoCOPY(
I, MRI, SrcReg, SrcRC, DstReg, DstRC);
1022 if (DstRB.
getID() != X86::GPRRegBankID)
1032 if (SrcRC == DstRC) {
1033 I.setDesc(
TII.get(X86::COPY));
1038 TII.get(TargetOpcode::SUBREG_TO_REG))
1041 .
addImm(getSubRegIndex(SrcRC));
1043 I.eraseFromParent();
1047bool X86InstructionSelector::selectCmp(MachineInstr &
I,
1048 MachineRegisterInfo &MRI,
1050 assert((
I.getOpcode() == TargetOpcode::G_ICMP) &&
"unexpected instruction");
1070 OpCmp = X86::CMP8rr;
1073 OpCmp = X86::CMP16rr;
1076 OpCmp = X86::CMP32rr;
1079 OpCmp = X86::CMP64rr;
1083 MachineInstr &CmpInst =
1084 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1088 MachineInstr &SetInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1089 TII.get(X86::SETCCr),
I.getOperand(0).getReg()).
addImm(CC);
1094 I.eraseFromParent();
1098bool X86InstructionSelector::selectFCmp(MachineInstr &
I,
1099 MachineRegisterInfo &MRI,
1101 assert((
I.getOpcode() == TargetOpcode::G_FCMP) &&
"unexpected instruction");
1103 Register LhsReg =
I.getOperand(2).getReg();
1104 Register RhsReg =
I.getOperand(3).getReg();
1109 static const uint16_t SETFOpcTable[2][3] = {
1112 const uint16_t *SETFOpc =
nullptr;
1113 switch (Predicate) {
1117 SETFOpc = &SETFOpcTable[0][0];
1120 SETFOpc = &SETFOpcTable[1][0];
1125 "Both arguments of FCMP need to be virtual!");
1127 [[maybe_unused]]
auto *RhsBank = RBI.
getRegBank(RhsReg, MRI,
TRI);
1128 assert((LhsBank == RhsBank) &&
1129 "Both banks assigned to FCMP arguments need to be same!");
1138 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr32
1142 OpCmp = LhsBank->getID() == X86::PSRRegBankID ? X86::UCOM_FpIr64
1146 OpCmp = X86::UCOM_FpIr80;
1150 Register ResultReg =
I.getOperand(0).getReg();
1155 MachineInstr &CmpInst =
1156 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1162 MachineInstr &Set1 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1163 TII.get(X86::SETCCr), FlagReg1).
addImm(SETFOpc[0]);
1164 MachineInstr &Set2 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1165 TII.get(X86::SETCCr), FlagReg2).
addImm(SETFOpc[1]);
1166 MachineInstr &Set3 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1167 TII.get(SETFOpc[2]), ResultReg)
1175 I.eraseFromParent();
1188 MachineInstr &CmpInst =
1189 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1197 I.eraseFromParent();
1201bool X86InstructionSelector::selectUAddSub(MachineInstr &
I,
1202 MachineRegisterInfo &MRI,
1204 assert((
I.getOpcode() == TargetOpcode::G_UADDE ||
1205 I.getOpcode() == TargetOpcode::G_UADDO ||
1206 I.getOpcode() == TargetOpcode::G_USUBE ||
1207 I.getOpcode() == TargetOpcode::G_USUBO) &&
1208 "unexpected instruction");
1212 const Register DstReg = CarryMI.getDstReg();
1213 const Register CarryOutReg = CarryMI.getCarryOutReg();
1214 const Register Op0Reg = CarryMI.getLHSReg();
1215 const Register Op1Reg = CarryMI.getRHSReg();
1216 bool IsSub = CarryMI.isSub();
1218 const LLT DstTy = MRI.
getType(DstReg);
1219 assert(DstTy.
isScalar() &&
"selectUAddSub only supported for scalar types");
1222 unsigned OpADC, OpADD, OpSBB, OpSUB;
1225 OpADC = X86::ADC8rr;
1226 OpADD = X86::ADD8rr;
1227 OpSBB = X86::SBB8rr;
1228 OpSUB = X86::SUB8rr;
1231 OpADC = X86::ADC16rr;
1232 OpADD = X86::ADD16rr;
1233 OpSBB = X86::SBB16rr;
1234 OpSUB = X86::SUB16rr;
1237 OpADC = X86::ADC32rr;
1238 OpADD = X86::ADD32rr;
1239 OpSBB = X86::SBB32rr;
1240 OpSUB = X86::SUB32rr;
1243 OpADC = X86::ADC64rr;
1244 OpADD = X86::ADD64rr;
1245 OpSBB = X86::SBB64rr;
1246 OpSUB = X86::SUB64rr;
1252 const RegisterBank &CarryRB = *RBI.
getRegBank(CarryOutReg, MRI,
TRI);
1256 unsigned Opcode = IsSub ? OpSUB : OpADD;
1260 Register CarryInReg = CarryInMI->getCarryInReg();
1262 while (
Def->getOpcode() == TargetOpcode::G_TRUNC) {
1263 CarryInReg =
Def->getOperand(1).getReg();
1268 if (
Def->getOpcode() == TargetOpcode::G_UADDE ||
1269 Def->getOpcode() == TargetOpcode::G_UADDO ||
1270 Def->getOpcode() == TargetOpcode::G_USUBE ||
1271 Def->getOpcode() == TargetOpcode::G_USUBO) {
1279 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::NEG8r), NegDef)
1282 Opcode = IsSub ? OpSBB : OpADC;
1288 Opcode = IsSub ? OpSUB : OpADD;
1293 MachineInstr &Inst =
1294 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1298 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SETCCr), CarryOutReg)
1305 I.eraseFromParent();
1309bool X86InstructionSelector::selectExtract(MachineInstr &
I,
1310 MachineRegisterInfo &MRI,
1312 assert((
I.getOpcode() == TargetOpcode::G_EXTRACT) &&
1313 "unexpected instruction");
1315 const Register DstReg =
I.getOperand(0).getReg();
1316 const Register SrcReg =
I.getOperand(1).getReg();
1317 int64_t
Index =
I.getOperand(2).getImm();
1319 const LLT DstTy = MRI.
getType(DstReg);
1320 const LLT SrcTy = MRI.
getType(SrcReg);
1331 if (!emitExtractSubreg(DstReg, SrcReg,
I, MRI, MF))
1334 I.eraseFromParent();
1338 bool HasAVX = STI.
hasAVX();
1340 bool HasVLX = STI.hasVLX();
1344 I.setDesc(
TII.get(X86::VEXTRACTF32X4Z256rri));
1346 I.setDesc(
TII.get(X86::VEXTRACTF128rri));
1351 I.setDesc(
TII.get(X86::VEXTRACTF32X4Zrri));
1353 I.setDesc(
TII.get(X86::VEXTRACTF64X4Zrri));
1361 I.getOperand(2).setImm(Index);
1367bool X86InstructionSelector::emitExtractSubreg(
Register DstReg,
Register SrcReg,
1369 MachineRegisterInfo &MRI,
1371 const LLT DstTy = MRI.
getType(DstReg);
1372 const LLT SrcTy = MRI.
getType(SrcReg);
1373 unsigned SubIdx = X86::NoSubRegister;
1379 "Incorrect Src/Dst register size");
1382 SubIdx = X86::sub_xmm;
1384 SubIdx = X86::sub_ymm;
1391 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1399 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::COPY), DstReg)
1400 .
addReg(SrcReg, {}, SubIdx);
1405bool X86InstructionSelector::emitInsertSubreg(
Register DstReg,
Register SrcReg,
1407 MachineRegisterInfo &MRI,
1409 const LLT DstTy = MRI.
getType(DstReg);
1410 const LLT SrcTy = MRI.
getType(SrcReg);
1411 unsigned SubIdx = X86::NoSubRegister;
1418 "Incorrect Src/Dst register size");
1421 SubIdx = X86::sub_xmm;
1423 SubIdx = X86::sub_ymm;
1437 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::IMPLICIT_DEF),
1440 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::INSERT_SUBREG),
1449bool X86InstructionSelector::selectInsert(MachineInstr &
I,
1450 MachineRegisterInfo &MRI,
1452 assert((
I.getOpcode() == TargetOpcode::G_INSERT) &&
"unexpected instruction");
1454 const Register DstReg =
I.getOperand(0).getReg();
1455 const Register SrcReg =
I.getOperand(1).getReg();
1456 const Register InsertReg =
I.getOperand(2).getReg();
1457 int64_t
Index =
I.getOperand(3).getImm();
1459 const LLT DstTy = MRI.
getType(DstReg);
1460 const LLT InsertRegTy = MRI.
getType(InsertReg);
1471 if (!emitInsertSubreg(DstReg, InsertReg,
I, MRI, MF))
1474 I.eraseFromParent();
1478 bool HasAVX = STI.
hasAVX();
1480 bool HasVLX = STI.hasVLX();
1484 I.setDesc(
TII.get(X86::VINSERTF32X4Z256rri));
1486 I.setDesc(
TII.get(X86::VINSERTF128rri));
1491 I.setDesc(
TII.get(X86::VINSERTF32X4Zrri));
1493 I.setDesc(
TII.get(X86::VINSERTF64X4Zrri));
1502 I.getOperand(3).setImm(Index);
1508bool X86InstructionSelector::selectUnmergeValues(
1510 assert((
I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1511 "unexpected instruction");
1514 unsigned NumDefs =
I.getNumOperands() - 1;
1515 Register SrcReg =
I.getOperand(NumDefs).getReg();
1518 for (
unsigned Idx = 0; Idx < NumDefs; ++Idx) {
1519 MachineInstr &ExtrInst =
1521 TII.get(TargetOpcode::G_EXTRACT),
I.getOperand(Idx).getReg())
1525 if (!select(ExtrInst))
1529 I.eraseFromParent();
1533bool X86InstructionSelector::selectMergeValues(
1535 assert((
I.getOpcode() == TargetOpcode::G_MERGE_VALUES ||
1536 I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS) &&
1537 "unexpected instruction");
1540 Register DstReg =
I.getOperand(0).getReg();
1541 Register SrcReg0 =
I.getOperand(1).getReg();
1543 const LLT DstTy = MRI.
getType(DstReg);
1544 const LLT SrcTy = MRI.
getType(SrcReg0);
1547 const RegisterBank &RegBank = *RBI.
getRegBank(DstReg, MRI,
TRI);
1552 if (!emitInsertSubreg(DefReg,
I.getOperand(1).getReg(),
I, MRI, MF))
1555 for (
unsigned Idx = 2; Idx <
I.getNumOperands(); ++Idx) {
1559 MachineInstr &InsertInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1560 TII.get(TargetOpcode::G_INSERT), Tmp)
1562 .
addReg(
I.getOperand(Idx).getReg())
1563 .
addImm((Idx - 1) * SrcSize);
1567 if (!select(InsertInst))
1571 MachineInstr &CopyInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1572 TII.get(TargetOpcode::COPY), DstReg)
1575 if (!select(CopyInst))
1578 I.eraseFromParent();
1582bool X86InstructionSelector::selectCondBranch(MachineInstr &
I,
1583 MachineRegisterInfo &MRI,
1585 assert((
I.getOpcode() == TargetOpcode::G_BRCOND) &&
"unexpected instruction");
1587 const Register CondReg =
I.getOperand(0).getReg();
1588 MachineBasicBlock *DestMBB =
I.getOperand(1).getMBB();
1590 MachineInstr &TestInst =
1591 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::TEST8ri))
1594 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::JCC_1))
1599 I.eraseFromParent();
1603bool X86InstructionSelector::materializeFP(MachineInstr &
I,
1604 MachineRegisterInfo &MRI,
1606 assert((
I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1607 "unexpected instruction");
1614 const Register DstReg =
I.getOperand(0).getReg();
1615 const LLT DstTy = MRI.
getType(DstReg);
1616 const RegisterBank &RegBank = *RBI.
getRegBank(DstReg, MRI,
TRI);
1618 const ConstantFP *CFP =
I.getOperand(1).getFPImm();
1621 const DebugLoc &DbgLoc =
I.getDebugLoc();
1624 getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Alignment);
1627 MachineInstr *LoadInst =
nullptr;
1635 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(X86::MOV64ri), AddrReg)
1652 unsigned PICBase = 0;
1661 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(
Opc), DstReg), CPI, PICBase,
1667 I.eraseFromParent();
1671bool X86InstructionSelector::selectImplicitDefOrPHI(
1672 MachineInstr &
I, MachineRegisterInfo &MRI)
const {
1673 assert((
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1674 I.getOpcode() == TargetOpcode::G_PHI) &&
1675 "unexpected instruction");
1677 Register DstReg =
I.getOperand(0).getReg();
1680 const LLT DstTy = MRI.
getType(DstReg);
1690 if (
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1691 I.setDesc(
TII.get(X86::IMPLICIT_DEF));
1693 I.setDesc(
TII.get(X86::PHI));
1698bool X86InstructionSelector::selectMulDivRem(MachineInstr &
I,
1699 MachineRegisterInfo &MRI,
1702 assert((
I.getOpcode() == TargetOpcode::G_MUL ||
1703 I.getOpcode() == TargetOpcode::G_SMULH ||
1704 I.getOpcode() == TargetOpcode::G_UMULH ||
1705 I.getOpcode() == TargetOpcode::G_SDIV ||
1706 I.getOpcode() == TargetOpcode::G_SREM ||
1707 I.getOpcode() == TargetOpcode::G_UDIV ||
1708 I.getOpcode() == TargetOpcode::G_UREM) &&
1709 "unexpected instruction");
1711 const Register DstReg =
I.getOperand(0).getReg();
1712 const Register Op1Reg =
I.getOperand(1).getReg();
1713 const Register Op2Reg =
I.getOperand(2).getReg();
1715 const LLT RegTy = MRI.
getType(DstReg);
1717 "Arguments and return value types must match");
1719 const RegisterBank *RegRB = RBI.
getRegBank(DstReg, MRI,
TRI);
1720 if (!RegRB || RegRB->
getID() != X86::GPRRegBankID)
1723 const static unsigned NumTypes = 4;
1724 const static unsigned NumOps = 7;
1725 const static bool S =
true;
1726 const static bool U =
false;
1727 const static unsigned Copy = TargetOpcode::COPY;
1737 const static struct MulDivRemEntry {
1739 unsigned SizeInBits;
1743 struct MulDivRemResult {
1744 unsigned OpMulDivRem;
1745 unsigned OpSignExtend;
1752 } OpTable[NumTypes] = {
1757 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S},
1758 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S},
1759 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U},
1760 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1761 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AL, S},
1762 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AH, S},
1763 {X86::MUL8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1769 {X86::IDIV16r, X86::CWD,
Copy, X86::AX, S},
1770 {X86::IDIV16r, X86::CWD,
Copy, X86::DX, S},
1771 {X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U},
1772 {X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U},
1773 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::AX, S},
1774 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::DX, S},
1775 {X86::MUL16r, X86::MOV32r0,
Copy, X86::DX,
U},
1781 {X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S},
1782 {X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S},
1783 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U},
1784 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1785 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EAX, S},
1786 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EDX, S},
1787 {X86::MUL32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1793 {X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S},
1794 {X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S},
1795 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U},
1796 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1797 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RAX, S},
1798 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RDX, S},
1799 {X86::MUL64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1803 auto OpEntryIt =
llvm::find_if(OpTable, [RegTy](
const MulDivRemEntry &El) {
1806 if (OpEntryIt == std::end(OpTable))
1810 switch (
I.getOpcode()) {
1813 case TargetOpcode::G_SDIV:
1816 case TargetOpcode::G_SREM:
1819 case TargetOpcode::G_UDIV:
1822 case TargetOpcode::G_UREM:
1825 case TargetOpcode::G_MUL:
1828 case TargetOpcode::G_SMULH:
1831 case TargetOpcode::G_UMULH:
1836 const MulDivRemEntry &
TypeEntry = *OpEntryIt;
1837 const MulDivRemEntry::MulDivRemResult &OpEntry =
1850 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpCopy),
1855 if (OpEntry.OpSignExtend) {
1856 if (OpEntry.IsOpSigned)
1858 TII.get(OpEntry.OpSignExtend));
1861 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::MOV32r0),
1870 .
addReg(Zero32, {}, X86::sub_16bit);
1877 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
1885 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpMulDivRem))
1896 if (OpEntry.ResultReg == X86::AH && STI.is64Bit()) {
1899 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Copy), SourceSuperReg)
1903 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SHR16ri),
1909 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1911 .
addReg(ResultSuperReg, {}, X86::sub_8bit);
1913 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1915 .
addReg(OpEntry.ResultReg);
1917 I.eraseFromParent();
1922bool X86InstructionSelector::selectSelect(MachineInstr &
I,
1923 MachineRegisterInfo &MRI,
1943 OpCmp = X86::CMOV_GR8;
1946 OpCmp = STI.
canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
1949 OpCmp = STI.
canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
1953 OpCmp = X86::CMOV64rr;
1971InstructionSelector::ComplexRendererFns
1972X86InstructionSelector::selectAddr(MachineOperand &Root)
const {
1974 MachineIRBuilder MIRBuilder(*
MI);
1980 return std::nullopt;
1983 return std::nullopt;
1986 {[=](MachineInstrBuilder &MIB) {
1991 "Unknown type of address base");
1996 [=](MachineInstrBuilder &MIB) { MIB.addImm(AM.
Scale); },
1998 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); },
2000 [=](MachineInstrBuilder &MIB) {
2006 MIB.addImm(AM.
Disp);
2009 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); }}};
2012InstructionSelector *
2016 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.
Contains matchers for matching SSA Machine Instructions.
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
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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.
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 LLVM_READONLY 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.
const MachineFunction & getMF() const
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.
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.
ImplicitDefMatch m_GImplicitDef()
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
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...
unsigned getMOVriOpcode(bool Use64BitReg, int64_t Imm)
Return a MOVri opcode for materializing Imm into a 32- or 64-bit GPR.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
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.
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 &)
MCRegisterClass TargetRegisterClass
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