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!");
1131 bool IsX87 = LhsBank->getID() == X86::PSRRegBankID;
1140 OpCmp = IsX87 ? X86::UCOM_FpIr32 : X86::UCOMISSrr;
1143 OpCmp = IsX87 ? X86::UCOM_FpIr64 : X86::UCOMISDrr;
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))
1164 MachineInstr &Set1 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1165 TII.get(X86::SETCCr), FlagReg1).
addImm(SETFOpc[0]);
1166 MachineInstr &Set2 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1167 TII.get(X86::SETCCr), FlagReg2).
addImm(SETFOpc[1]);
1168 MachineInstr &Set3 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1169 TII.get(SETFOpc[2]), ResultReg)
1178 I.eraseFromParent();
1191 MachineInstr &CmpInst =
1192 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1202 I.eraseFromParent();
1206bool X86InstructionSelector::selectUAddSub(MachineInstr &
I,
1207 MachineRegisterInfo &MRI,
1209 assert((
I.getOpcode() == TargetOpcode::G_UADDE ||
1210 I.getOpcode() == TargetOpcode::G_UADDO ||
1211 I.getOpcode() == TargetOpcode::G_USUBE ||
1212 I.getOpcode() == TargetOpcode::G_USUBO) &&
1213 "unexpected instruction");
1217 const Register DstReg = CarryMI.getDstReg();
1218 const Register CarryOutReg = CarryMI.getCarryOutReg();
1219 const Register Op0Reg = CarryMI.getLHSReg();
1220 const Register Op1Reg = CarryMI.getRHSReg();
1221 bool IsSub = CarryMI.isSub();
1223 const LLT DstTy = MRI.
getType(DstReg);
1224 assert(DstTy.
isScalar() &&
"selectUAddSub only supported for scalar types");
1227 unsigned OpADC, OpADD, OpSBB, OpSUB;
1230 OpADC = X86::ADC8rr;
1231 OpADD = X86::ADD8rr;
1232 OpSBB = X86::SBB8rr;
1233 OpSUB = X86::SUB8rr;
1236 OpADC = X86::ADC16rr;
1237 OpADD = X86::ADD16rr;
1238 OpSBB = X86::SBB16rr;
1239 OpSUB = X86::SUB16rr;
1242 OpADC = X86::ADC32rr;
1243 OpADD = X86::ADD32rr;
1244 OpSBB = X86::SBB32rr;
1245 OpSUB = X86::SUB32rr;
1248 OpADC = X86::ADC64rr;
1249 OpADD = X86::ADD64rr;
1250 OpSBB = X86::SBB64rr;
1251 OpSUB = X86::SUB64rr;
1257 const RegisterBank &CarryRB = *RBI.
getRegBank(CarryOutReg, MRI,
TRI);
1261 unsigned Opcode = IsSub ? OpSUB : OpADD;
1265 Register CarryInReg = CarryInMI->getCarryInReg();
1267 while (
Def->getOpcode() == TargetOpcode::G_TRUNC) {
1268 CarryInReg =
Def->getOperand(1).getReg();
1273 if (
Def->getOpcode() == TargetOpcode::G_UADDE ||
1274 Def->getOpcode() == TargetOpcode::G_UADDO ||
1275 Def->getOpcode() == TargetOpcode::G_USUBE ||
1276 Def->getOpcode() == TargetOpcode::G_USUBO) {
1284 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::NEG8r), NegDef)
1287 Opcode = IsSub ? OpSBB : OpADC;
1293 Opcode = IsSub ? OpSUB : OpADD;
1298 MachineInstr &Inst =
1299 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1303 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SETCCr), CarryOutReg)
1310 I.eraseFromParent();
1314bool X86InstructionSelector::selectExtract(MachineInstr &
I,
1315 MachineRegisterInfo &MRI,
1317 assert((
I.getOpcode() == TargetOpcode::G_EXTRACT) &&
1318 "unexpected instruction");
1320 const Register DstReg =
I.getOperand(0).getReg();
1321 const Register SrcReg =
I.getOperand(1).getReg();
1322 int64_t
Index =
I.getOperand(2).getImm();
1324 const LLT DstTy = MRI.
getType(DstReg);
1325 const LLT SrcTy = MRI.
getType(SrcReg);
1336 if (!emitExtractSubreg(DstReg, SrcReg,
I, MRI, MF))
1339 I.eraseFromParent();
1343 bool HasAVX = STI.
hasAVX();
1345 bool HasVLX = STI.hasVLX();
1349 I.setDesc(
TII.get(X86::VEXTRACTF32X4Z256rri));
1351 I.setDesc(
TII.get(X86::VEXTRACTF128rri));
1356 I.setDesc(
TII.get(X86::VEXTRACTF32X4Zrri));
1358 I.setDesc(
TII.get(X86::VEXTRACTF64X4Zrri));
1366 I.getOperand(2).setImm(Index);
1372bool X86InstructionSelector::emitExtractSubreg(
Register DstReg,
Register SrcReg,
1374 MachineRegisterInfo &MRI,
1376 const LLT DstTy = MRI.
getType(DstReg);
1377 const LLT SrcTy = MRI.
getType(SrcReg);
1378 unsigned SubIdx = X86::NoSubRegister;
1384 "Incorrect Src/Dst register size");
1387 SubIdx = X86::sub_xmm;
1389 SubIdx = X86::sub_ymm;
1396 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1404 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::COPY), DstReg)
1405 .
addReg(SrcReg, {}, SubIdx);
1410bool X86InstructionSelector::emitInsertSubreg(
Register DstReg,
Register SrcReg,
1412 MachineRegisterInfo &MRI,
1414 const LLT DstTy = MRI.
getType(DstReg);
1415 const LLT SrcTy = MRI.
getType(SrcReg);
1416 unsigned SubIdx = X86::NoSubRegister;
1423 "Incorrect Src/Dst register size");
1426 SubIdx = X86::sub_xmm;
1428 SubIdx = X86::sub_ymm;
1442 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::IMPLICIT_DEF),
1445 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::INSERT_SUBREG),
1454bool X86InstructionSelector::selectInsert(MachineInstr &
I,
1455 MachineRegisterInfo &MRI,
1457 assert((
I.getOpcode() == TargetOpcode::G_INSERT) &&
"unexpected instruction");
1459 const Register DstReg =
I.getOperand(0).getReg();
1460 const Register SrcReg =
I.getOperand(1).getReg();
1461 const Register InsertReg =
I.getOperand(2).getReg();
1462 int64_t
Index =
I.getOperand(3).getImm();
1464 const LLT DstTy = MRI.
getType(DstReg);
1465 const LLT InsertRegTy = MRI.
getType(InsertReg);
1476 if (!emitInsertSubreg(DstReg, InsertReg,
I, MRI, MF))
1479 I.eraseFromParent();
1483 bool HasAVX = STI.
hasAVX();
1485 bool HasVLX = STI.hasVLX();
1489 I.setDesc(
TII.get(X86::VINSERTF32X4Z256rri));
1491 I.setDesc(
TII.get(X86::VINSERTF128rri));
1496 I.setDesc(
TII.get(X86::VINSERTF32X4Zrri));
1498 I.setDesc(
TII.get(X86::VINSERTF64X4Zrri));
1507 I.getOperand(3).setImm(Index);
1513bool X86InstructionSelector::selectUnmergeValues(
1515 assert((
I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1516 "unexpected instruction");
1519 unsigned NumDefs =
I.getNumOperands() - 1;
1520 Register SrcReg =
I.getOperand(NumDefs).getReg();
1523 for (
unsigned Idx = 0;
Idx < NumDefs; ++
Idx) {
1524 MachineInstr &ExtrInst =
1526 TII.get(TargetOpcode::G_EXTRACT),
I.getOperand(Idx).getReg())
1530 if (!select(ExtrInst))
1534 I.eraseFromParent();
1538bool X86InstructionSelector::selectMergeValues(
1540 assert((
I.getOpcode() == TargetOpcode::G_MERGE_VALUES ||
1541 I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS) &&
1542 "unexpected instruction");
1545 Register DstReg =
I.getOperand(0).getReg();
1546 Register SrcReg0 =
I.getOperand(1).getReg();
1548 const LLT DstTy = MRI.
getType(DstReg);
1549 const LLT SrcTy = MRI.
getType(SrcReg0);
1552 const RegisterBank &RegBank = *RBI.
getRegBank(DstReg, MRI,
TRI);
1557 if (!emitInsertSubreg(DefReg,
I.getOperand(1).getReg(),
I, MRI, MF))
1560 for (
unsigned Idx = 2;
Idx <
I.getNumOperands(); ++
Idx) {
1564 MachineInstr &InsertInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1565 TII.get(TargetOpcode::G_INSERT), Tmp)
1567 .
addReg(
I.getOperand(Idx).getReg())
1568 .
addImm((Idx - 1) * SrcSize);
1572 if (!select(InsertInst))
1576 MachineInstr &CopyInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1577 TII.get(TargetOpcode::COPY), DstReg)
1580 if (!select(CopyInst))
1583 I.eraseFromParent();
1587bool X86InstructionSelector::selectCondBranch(MachineInstr &
I,
1588 MachineRegisterInfo &MRI,
1590 assert((
I.getOpcode() == TargetOpcode::G_BRCOND) &&
"unexpected instruction");
1592 const Register CondReg =
I.getOperand(0).getReg();
1593 MachineBasicBlock *DestMBB =
I.getOperand(1).getMBB();
1595 MachineInstr &TestInst =
1596 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::TEST8ri))
1599 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::JCC_1))
1604 I.eraseFromParent();
1608bool X86InstructionSelector::materializeFP(MachineInstr &
I,
1609 MachineRegisterInfo &MRI,
1611 assert((
I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1612 "unexpected instruction");
1619 const Register DstReg =
I.getOperand(0).getReg();
1620 const LLT DstTy = MRI.
getType(DstReg);
1621 const RegisterBank &RegBank = *RBI.
getRegBank(DstReg, MRI,
TRI);
1623 const ConstantFP *CFP =
I.getOperand(1).getFPImm();
1626 const DebugLoc &DbgLoc =
I.getDebugLoc();
1629 getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Alignment);
1632 MachineInstr *LoadInst =
nullptr;
1640 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(X86::MOV64ri), AddrReg)
1657 unsigned PICBase = 0;
1666 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(
Opc), DstReg), CPI, PICBase,
1672 I.eraseFromParent();
1676bool X86InstructionSelector::selectImplicitDefOrPHI(
1677 MachineInstr &
I, MachineRegisterInfo &MRI)
const {
1678 assert((
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1679 I.getOpcode() == TargetOpcode::G_PHI) &&
1680 "unexpected instruction");
1682 Register DstReg =
I.getOperand(0).getReg();
1685 const LLT DstTy = MRI.
getType(DstReg);
1695 if (
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1696 I.setDesc(
TII.get(X86::IMPLICIT_DEF));
1698 I.setDesc(
TII.get(X86::PHI));
1703bool X86InstructionSelector::selectMulDivRem(MachineInstr &
I,
1704 MachineRegisterInfo &MRI,
1707 assert((
I.getOpcode() == TargetOpcode::G_MUL ||
1708 I.getOpcode() == TargetOpcode::G_SMULH ||
1709 I.getOpcode() == TargetOpcode::G_UMULH ||
1710 I.getOpcode() == TargetOpcode::G_SDIV ||
1711 I.getOpcode() == TargetOpcode::G_SREM ||
1712 I.getOpcode() == TargetOpcode::G_UDIV ||
1713 I.getOpcode() == TargetOpcode::G_UREM) &&
1714 "unexpected instruction");
1716 const Register DstReg =
I.getOperand(0).getReg();
1717 const Register Op1Reg =
I.getOperand(1).getReg();
1718 const Register Op2Reg =
I.getOperand(2).getReg();
1720 const LLT RegTy = MRI.
getType(DstReg);
1722 "Arguments and return value types must match");
1724 const RegisterBank *RegRB = RBI.
getRegBank(DstReg, MRI,
TRI);
1725 if (!RegRB || RegRB->
getID() != X86::GPRRegBankID)
1728 const static unsigned NumTypes = 4;
1729 const static unsigned NumOps = 7;
1730 const static bool S =
true;
1731 const static bool U =
false;
1732 const static unsigned Copy = TargetOpcode::COPY;
1742 const static struct MulDivRemEntry {
1744 unsigned SizeInBits;
1748 struct MulDivRemResult {
1749 unsigned OpMulDivRem;
1750 unsigned OpSignExtend;
1757 } OpTable[NumTypes] = {
1762 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S},
1763 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S},
1764 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U},
1765 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1766 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AL, S},
1767 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AH, S},
1768 {X86::MUL8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1774 {X86::IDIV16r, X86::CWD,
Copy, X86::AX, S},
1775 {X86::IDIV16r, X86::CWD,
Copy, X86::DX, S},
1776 {X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U},
1777 {X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U},
1778 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::AX, S},
1779 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::DX, S},
1780 {X86::MUL16r, X86::MOV32r0,
Copy, X86::DX,
U},
1786 {X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S},
1787 {X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S},
1788 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U},
1789 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1790 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EAX, S},
1791 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EDX, S},
1792 {X86::MUL32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1798 {X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S},
1799 {X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S},
1800 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U},
1801 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1802 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RAX, S},
1803 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RDX, S},
1804 {X86::MUL64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1808 auto OpEntryIt =
llvm::find_if(OpTable, [RegTy](
const MulDivRemEntry &El) {
1811 if (OpEntryIt == std::end(OpTable))
1815 switch (
I.getOpcode()) {
1818 case TargetOpcode::G_SDIV:
1821 case TargetOpcode::G_SREM:
1824 case TargetOpcode::G_UDIV:
1827 case TargetOpcode::G_UREM:
1830 case TargetOpcode::G_MUL:
1833 case TargetOpcode::G_SMULH:
1836 case TargetOpcode::G_UMULH:
1841 const MulDivRemEntry &
TypeEntry = *OpEntryIt;
1842 const MulDivRemEntry::MulDivRemResult &OpEntry =
1855 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpCopy),
1860 if (OpEntry.OpSignExtend) {
1861 if (OpEntry.IsOpSigned)
1863 TII.get(OpEntry.OpSignExtend));
1866 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::MOV32r0), Zero32)
1875 .
addReg(Zero32, {}, X86::sub_16bit);
1882 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
1890 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpMulDivRem))
1901 if (OpEntry.ResultReg == X86::AH && STI.is64Bit()) {
1904 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Copy), SourceSuperReg)
1908 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SHR16ri),
1914 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1916 .
addReg(ResultSuperReg, {}, X86::sub_8bit);
1918 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1920 .
addReg(OpEntry.ResultReg);
1922 I.eraseFromParent();
1927bool X86InstructionSelector::selectSelect(MachineInstr &
I,
1928 MachineRegisterInfo &MRI,
1948 OpCmp = X86::CMOV_GR8;
1951 OpCmp = STI.
canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
1954 OpCmp = STI.
canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
1958 OpCmp = X86::CMOV64rr;
1976InstructionSelector::ComplexRendererFns
1977X86InstructionSelector::selectAddr(MachineOperand &Root)
const {
1979 MachineIRBuilder MIRBuilder(*
MI);
1985 return std::nullopt;
1988 return std::nullopt;
1991 {[=](MachineInstrBuilder &MIB) {
1996 "Unknown type of address base");
2001 [=](MachineInstrBuilder &MIB) { MIB.addImm(AM.
Scale); },
2003 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); },
2005 [=](MachineInstrBuilder &MIB) {
2011 MIB.addImm(AM.
Disp);
2014 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); }}};
2017InstructionSelector *
2021 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 & setOperandDead(unsigned OpIdx) const
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.
const MachineOperand & getOperand(unsigned i) const
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.
void setIsDead(bool Val=true)
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