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;
145#define GET_GLOBALISEL_PREDICATES_DECL
146#include "X86GenGlobalISel.inc"
147#undef GET_GLOBALISEL_PREDICATES_DECL
149#define GET_GLOBALISEL_TEMPORARIES_DECL
150#include "X86GenGlobalISel.inc"
151#undef GET_GLOBALISEL_TEMPORARIES_DECL
156#define GET_GLOBALISEL_IMPL
157#include "X86GenGlobalISel.inc"
158#undef GET_GLOBALISEL_IMPL
163 : TM(TM), STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()),
166#include
"X86GenGlobalISel.inc"
169#include
"X86GenGlobalISel.inc"
177X86InstructionSelector::getRegClass(
LLT Ty,
const RegisterBank &RB)
const {
178 if (RB.
getID() == X86::GPRRegBankID) {
180 return &X86::GR8RegClass;
182 return &X86::GR16RegClass;
184 return &X86::GR32RegClass;
186 return &X86::GR64RegClass;
188 if (RB.
getID() == X86::VECRRegBankID) {
190 return STI.
hasAVX512() ? &X86::FR16XRegClass : &X86::FR16RegClass;
192 return STI.
hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
194 return STI.
hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
196 return STI.
hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
198 return STI.
hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
200 return &X86::VR512RegClass;
203 if (RB.
getID() == X86::PSRRegBankID) {
205 return &X86::RFP80RegClass;
207 return &X86::RFP64RegClass;
209 return &X86::RFP32RegClass;
216X86InstructionSelector::getRegClass(LLT Ty,
Register Reg,
217 MachineRegisterInfo &
MRI)
const {
223 unsigned SubIdx = X86::NoSubRegister;
224 if (RC == &X86::GR32RegClass) {
225 SubIdx = X86::sub_32bit;
226 }
else if (RC == &X86::GR16RegClass) {
227 SubIdx = X86::sub_16bit;
228 }
else if (RC == &X86::GR8RegClass) {
229 SubIdx = X86::sub_8bit;
238 return &X86::GR64RegClass;
240 return &X86::GR32RegClass;
242 return &X86::GR16RegClass;
244 return &X86::GR8RegClass;
250bool X86InstructionSelector::selectCopy(MachineInstr &
I,
251 MachineRegisterInfo &
MRI)
const {
252 Register DstReg =
I.getOperand(0).getReg();
256 Register SrcReg =
I.getOperand(1).getReg();
261 assert(
I.isCopy() &&
"Generic operators do not allow physical registers");
263 if (DstSize > SrcSize && SrcRegBank.
getID() == X86::GPRRegBankID &&
264 DstRegBank.
getID() == X86::GPRRegBankID) {
270 if (SrcRC != DstRC) {
274 TII.get(TargetOpcode::SUBREG_TO_REG))
277 .
addImm(getSubRegIndex(SrcRC));
279 I.getOperand(1).setReg(ExtSrc);
284 if (SrcSize == 16 && SrcRegBank.
getID() == X86::GPRRegBankID &&
285 (DstRegBank.
getID() == X86::VECRRegBankID)) {
291 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::SUBREG_TO_REG),
297 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), DstReg)
304 if (DstSize == 16 && DstRegBank.
getID() == X86::GPRRegBankID &&
305 (SrcRegBank.
getID() == X86::VECRRegBankID)) {
311 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), Temp32)
315 if (
Register Dst32 =
TRI.getMatchingSuperReg(DstReg, X86::sub_16bit,
316 &X86::GR32RegClass)) {
318 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), Dst32)
322 BuildMI(*
I.getParent(),
I,
DL,
TII.get(TargetOpcode::COPY), DstReg)
323 .
addReg(Temp32, {}, X86::sub_16bit);
333 "No phys reg on generic operators");
334 assert((DstSize == SrcSize ||
339 "Copy with different width?!");
344 if (SrcRegBank.
getID() == X86::GPRRegBankID &&
345 DstRegBank.
getID() == X86::GPRRegBankID && SrcSize > DstSize &&
351 if (DstRC != SrcRC) {
352 I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
353 I.getOperand(1).substPhysReg(SrcReg,
TRI);
368 I.setDesc(
TII.get(X86::COPY));
372bool X86InstructionSelector::select(MachineInstr &
I) {
373 assert(
I.getParent() &&
"Instruction should be in a basic block!");
374 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
380 unsigned Opcode =
I.getOpcode();
384 if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
393 assert(
I.getNumOperands() ==
I.getNumExplicitOperands() &&
394 "Generic instruction has unexpected implicit operands\n");
396 if (selectImpl(
I, *CoverageInfo))
402 switch (
I.getOpcode()) {
405 case TargetOpcode::G_STORE:
406 case TargetOpcode::G_LOAD:
408 case TargetOpcode::G_PTR_ADD:
409 case TargetOpcode::G_FRAME_INDEX:
410 return selectFrameIndexOrGep(
I,
MRI, MF);
411 case TargetOpcode::G_GLOBAL_VALUE:
412 return selectGlobalValue(
I,
MRI, MF);
413 case TargetOpcode::G_CONSTANT:
414 return selectConstant(
I,
MRI, MF);
415 case TargetOpcode::G_FCONSTANT:
416 return materializeFP(
I,
MRI, MF);
417 case TargetOpcode::G_PTRTOINT:
418 case TargetOpcode::G_TRUNC:
419 return selectTruncOrPtrToInt(
I,
MRI, MF);
420 case TargetOpcode::G_INTTOPTR:
421 case TargetOpcode::G_FREEZE:
423 case TargetOpcode::G_ZEXT:
424 return selectZext(
I,
MRI, MF);
425 case TargetOpcode::G_ANYEXT:
426 return selectAnyext(
I,
MRI, MF);
427 case TargetOpcode::G_ICMP:
428 return selectCmp(
I,
MRI, MF);
429 case TargetOpcode::G_FCMP:
430 return selectFCmp(
I,
MRI, MF);
431 case TargetOpcode::G_UADDE:
432 case TargetOpcode::G_UADDO:
433 case TargetOpcode::G_USUBE:
434 case TargetOpcode::G_USUBO:
435 return selectUAddSub(
I,
MRI, MF);
436 case TargetOpcode::G_UNMERGE_VALUES:
438 case TargetOpcode::G_MERGE_VALUES:
439 case TargetOpcode::G_CONCAT_VECTORS:
441 case TargetOpcode::G_EXTRACT:
442 return selectExtract(
I,
MRI, MF);
443 case TargetOpcode::G_INSERT:
444 return selectInsert(
I,
MRI, MF);
445 case TargetOpcode::G_BRCOND:
446 return selectCondBranch(
I,
MRI, MF);
447 case TargetOpcode::G_IMPLICIT_DEF:
448 case TargetOpcode::G_PHI:
449 return selectImplicitDefOrPHI(
I,
MRI);
450 case TargetOpcode::G_MUL:
451 case TargetOpcode::G_SMULH:
452 case TargetOpcode::G_UMULH:
453 case TargetOpcode::G_SDIV:
454 case TargetOpcode::G_UDIV:
455 case TargetOpcode::G_SREM:
456 case TargetOpcode::G_UREM:
457 return selectMulDivRem(
I,
MRI, MF);
458 case TargetOpcode::G_SELECT:
459 return selectSelect(
I,
MRI, MF);
465unsigned X86InstructionSelector::getPtrLoadStoreOp(
const LLT &Ty,
466 const RegisterBank &RB,
467 unsigned Opc)
const {
468 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
469 "Only G_STORE and G_LOAD are expected for selection");
471 bool IsLoad = (
Opc == TargetOpcode::G_LOAD);
476 return IsLoad ? X86::MOV32rm : X86::MOV32mr;
478 return IsLoad ? X86::MOV64rm : X86::MOV64mr;
484unsigned X86InstructionSelector::getLoadStoreOp(
const LLT &Ty,
485 const RegisterBank &RB,
487 Align Alignment)
const {
488 bool Isload = (
Opc == TargetOpcode::G_LOAD);
489 bool HasAVX = STI.
hasAVX();
491 bool HasVLX = STI.hasVLX();
494 if (X86::GPRRegBankID == RB.
getID())
495 return Isload ? X86::MOV8rm : X86::MOV8mr;
497 if (X86::GPRRegBankID == RB.
getID())
498 return Isload ? X86::MOV16rm : X86::MOV16mr;
500 if (X86::GPRRegBankID == RB.
getID())
501 return Isload ? X86::MOV32rm : X86::MOV32mr;
502 if (X86::VECRRegBankID == RB.
getID())
503 return Isload ? (HasAVX512 ? X86::VMOVSSZrm_alt :
504 HasAVX ? X86::VMOVSSrm_alt :
506 : (HasAVX512 ?
X86::VMOVSSZmr :
507 HasAVX ?
X86::VMOVSSmr :
509 if (X86::PSRRegBankID == RB.
getID())
510 return Isload ? X86::LD_Fp32m : X86::ST_Fp32m;
512 if (X86::GPRRegBankID == RB.
getID())
513 return Isload ? X86::MOV64rm : X86::MOV64mr;
514 if (X86::VECRRegBankID == RB.
getID())
515 return Isload ? (HasAVX512 ? X86::VMOVSDZrm_alt :
516 HasAVX ? X86::VMOVSDrm_alt :
518 : (HasAVX512 ?
X86::VMOVSDZmr :
519 HasAVX ?
X86::VMOVSDmr :
521 if (X86::PSRRegBankID == RB.
getID())
522 return Isload ? X86::LD_Fp64m : X86::ST_Fp64m;
524 return Isload ? X86::LD_Fp80m : X86::ST_FpP80m;
526 if (Alignment >=
Align(16))
527 return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
529 ? X86::VMOVAPSZ128rm_NOVLX
530 : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
531 : (HasVLX ?
X86::VMOVAPSZ128mr
533 ?
X86::VMOVAPSZ128mr_NOVLX
534 : HasAVX ?
X86::VMOVAPSmr :
X86::MOVAPSmr);
536 return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
538 ? X86::VMOVUPSZ128rm_NOVLX
539 : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
540 : (HasVLX ? X86::VMOVUPSZ128mr
542 ? X86::VMOVUPSZ128mr_NOVLX
543 : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
545 if (Alignment >=
Align(32))
546 return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
547 : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
549 : (HasVLX ?
X86::VMOVAPSZ256mr
550 : HasAVX512 ?
X86::VMOVAPSZ256mr_NOVLX
553 return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
554 : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
556 : (HasVLX ? X86::VMOVUPSZ256mr
557 : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
560 if (Alignment >=
Align(64))
561 return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
563 return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
572 assert(
I.getOperand(0).isReg() &&
"unsupported operand.");
573 assert(
MRI.getType(
I.getOperand(0).getReg()).isPointer() &&
574 "unsupported type.");
576 switch (
I.getOpcode()) {
579 case TargetOpcode::G_FRAME_INDEX:
583 case TargetOpcode::G_PTR_ADD: {
587 AM.
Disp =
static_cast<int32_t
>(
Imm);
588 AM.
Base.
Reg =
I.getOperand(1).getReg();
594 case TargetOpcode::G_GLOBAL_VALUE:
595 case X86::G_WRAPPER_RIP: {
596 auto GV =
I.getOperand(1).getGlobal();
597 if (GV->isThreadLocal()) {
614 "RIP-relative addresses can't have additional register operands");
619 case TargetOpcode::G_CONSTANT_POOL: {
627 else if (STI.is64Bit())
630 AM.
Disp =
I.getOperand(1).getIndex();
635 AM.
Base.
Reg =
I.getOperand(0).getReg();
639bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &
I,
640 MachineRegisterInfo &
MRI,
642 unsigned Opc =
I.getOpcode();
644 assert((
Opc == TargetOpcode::G_STORE ||
Opc == TargetOpcode::G_LOAD) &&
645 "Only G_STORE and G_LOAD are expected for selection");
647 const Register DefReg =
I.getOperand(0).getReg();
652 auto &MemOp = **
I.memoperands_begin();
653 if (MemOp.isAtomic()) {
659 if (!MemOp.isUnordered()) {
669 unsigned NewOpc = getPtrLoadStoreOp(Ty, RB,
Opc);
673 I.setDesc(
TII.get(NewOpc));
674 MachineInstrBuilder MIB(MF,
I);
681 if (
Opc == TargetOpcode::G_LOAD) {
691 I.addImplicitDefUseOperands(MF);
704bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &
I,
705 MachineRegisterInfo &
MRI,
707 unsigned Opc =
I.getOpcode();
709 assert((
Opc == TargetOpcode::G_FRAME_INDEX ||
Opc == TargetOpcode::G_PTR_ADD) &&
710 "unexpected instruction");
712 const Register DefReg =
I.getOperand(0).getReg();
716 unsigned NewOpc =
getLeaOP(Ty, STI);
717 I.setDesc(
TII.get(NewOpc));
718 MachineInstrBuilder MIB(MF,
I);
720 if (
Opc == TargetOpcode::G_FRAME_INDEX) {
723 MachineOperand &InxOp =
I.getOperand(2);
726 MIB.addImm(0).addReg(0);
733bool X86InstructionSelector::selectGlobalValue(MachineInstr &
I,
734 MachineRegisterInfo &
MRI,
736 assert((
I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
737 "unexpected instruction");
743 const Register DefReg =
I.getOperand(0).getReg();
745 unsigned NewOpc =
getLeaOP(Ty, STI);
747 I.setDesc(
TII.get(NewOpc));
748 MachineInstrBuilder MIB(MF,
I);
757bool X86InstructionSelector::selectConstant(MachineInstr &
I,
758 MachineRegisterInfo &
MRI,
760 assert((
I.getOpcode() == TargetOpcode::G_CONSTANT) &&
761 "unexpected instruction");
763 const Register DefReg =
I.getOperand(0).getReg();
770 if (
I.getOperand(1).isCImm()) {
771 Val =
I.getOperand(1).getCImm()->getZExtValue();
772 I.getOperand(1).ChangeToImmediate(Val);
773 }
else if (
I.getOperand(1).isImm()) {
774 Val =
I.getOperand(1).getImm();
781 NewOpc = X86::MOV8ri;
784 NewOpc = X86::MOV16ri;
787 NewOpc = X86::MOV32ri;
796 I.setDesc(
TII.get(NewOpc));
806 return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
807 DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
808 (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
811bool X86InstructionSelector::selectTurnIntoCOPY(
812 MachineInstr &
I, MachineRegisterInfo &
MRI,
const Register DstReg,
822 I.setDesc(
TII.get(X86::COPY));
826bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &
I,
827 MachineRegisterInfo &
MRI,
829 assert((
I.getOpcode() == TargetOpcode::G_TRUNC ||
830 I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
831 "unexpected instruction");
833 const Register DstReg =
I.getOperand(0).getReg();
834 const Register SrcReg =
I.getOperand(1).getReg();
844 <<
" input/output on different banks\n");
851 if (!DstRC || !SrcRC)
858 return selectTurnIntoCOPY(
I,
MRI, DstReg, DstRC, SrcReg, SrcRC);
860 if (DstRB.
getID() != X86::GPRRegBankID)
864 if (DstRC == SrcRC) {
866 SubIdx = X86::NoSubRegister;
867 }
else if (DstRC == &X86::GR32RegClass) {
868 SubIdx = X86::sub_32bit;
869 }
else if (DstRC == &X86::GR16RegClass) {
870 SubIdx = X86::sub_16bit;
871 }
else if (DstRC == &X86::GR8RegClass) {
872 SubIdx = X86::sub_8bit;
877 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
886 I.getOperand(1).setSubReg(SubIdx);
888 I.setDesc(
TII.get(X86::COPY));
892bool X86InstructionSelector::selectZext(MachineInstr &
I,
893 MachineRegisterInfo &
MRI,
895 assert((
I.getOpcode() == TargetOpcode::G_ZEXT) &&
"unexpected instruction");
897 const Register DstReg =
I.getOperand(0).getReg();
898 const Register SrcReg =
I.getOperand(1).getReg();
904 "8=>16 Zext is handled by tablegen");
906 "8=>32 Zext is handled by tablegen");
908 "16=>32 Zext is handled by tablegen");
910 "8=>64 Zext is handled by tablegen");
912 "16=>64 Zext is handled by tablegen");
914 "32=>64 Zext is handled by tablegen");
921 AndOpc = X86::AND8ri;
923 AndOpc = X86::AND16ri;
925 AndOpc = X86::AND32ri;
927 AndOpc = X86::AND64ri32;
936 TII.get(TargetOpcode::IMPLICIT_DEF), ImpDefReg);
940 TII.get(TargetOpcode::INSERT_SUBREG), DefReg)
946 MachineInstr &AndInst =
947 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(AndOpc), DstReg)
957bool X86InstructionSelector::selectAnyext(MachineInstr &
I,
958 MachineRegisterInfo &
MRI,
960 assert((
I.getOpcode() == TargetOpcode::G_ANYEXT) &&
"unexpected instruction");
962 const Register DstReg =
I.getOperand(0).getReg();
963 const Register SrcReg =
I.getOperand(1).getReg();
972 "G_ANYEXT input/output on different banks\n");
975 "G_ANYEXT incorrect operand size");
984 return selectTurnIntoCOPY(
I,
MRI, SrcReg, SrcRC, DstReg, DstRC);
986 if (DstRB.
getID() != X86::GPRRegBankID)
996 if (SrcRC == DstRC) {
997 I.setDesc(
TII.get(X86::COPY));
1002 TII.get(TargetOpcode::SUBREG_TO_REG))
1005 .
addImm(getSubRegIndex(SrcRC));
1007 I.eraseFromParent();
1011bool X86InstructionSelector::selectCmp(MachineInstr &
I,
1012 MachineRegisterInfo &
MRI,
1014 assert((
I.getOpcode() == TargetOpcode::G_ICMP) &&
"unexpected instruction");
1034 OpCmp = X86::CMP8rr;
1037 OpCmp = X86::CMP16rr;
1040 OpCmp = X86::CMP32rr;
1043 OpCmp = X86::CMP64rr;
1047 MachineInstr &CmpInst =
1048 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1052 MachineInstr &SetInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1053 TII.get(X86::SETCCr),
I.getOperand(0).getReg()).
addImm(
CC);
1058 I.eraseFromParent();
1062bool X86InstructionSelector::selectFCmp(MachineInstr &
I,
1063 MachineRegisterInfo &
MRI,
1065 assert((
I.getOpcode() == TargetOpcode::G_FCMP) &&
"unexpected instruction");
1067 Register LhsReg =
I.getOperand(2).getReg();
1068 Register RhsReg =
I.getOperand(3).getReg();
1073 static const uint16_t SETFOpcTable[2][3] = {
1076 const uint16_t *SETFOpc =
nullptr;
1077 switch (Predicate) {
1081 SETFOpc = &SETFOpcTable[0][0];
1084 SETFOpc = &SETFOpcTable[1][0];
1089 "Both arguments of FCMP need to be virtual!");
1092 assert((LhsBank == RhsBank) &&
1093 "Both banks assigned to FCMP arguments need to be same!");
1095 bool IsX87 = LhsBank->getID() == X86::PSRRegBankID;
1104 OpCmp = IsX87 ? X86::UCOM_FpIr32 : X86::UCOMISSrr;
1107 OpCmp = IsX87 ? X86::UCOM_FpIr64 : X86::UCOMISDrr;
1110 OpCmp = X86::UCOM_FpIr80;
1114 Register ResultReg =
I.getOperand(0).getReg();
1119 MachineInstr &CmpInst =
1120 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1128 MachineInstr &Set1 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1129 TII.get(X86::SETCCr), FlagReg1).
addImm(SETFOpc[0]);
1130 MachineInstr &Set2 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1131 TII.get(X86::SETCCr), FlagReg2).
addImm(SETFOpc[1]);
1132 MachineInstr &Set3 = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1133 TII.get(SETFOpc[2]), ResultReg)
1142 I.eraseFromParent();
1155 MachineInstr &CmpInst =
1156 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpCmp))
1166 I.eraseFromParent();
1170bool X86InstructionSelector::selectUAddSub(MachineInstr &
I,
1171 MachineRegisterInfo &
MRI,
1173 assert((
I.getOpcode() == TargetOpcode::G_UADDE ||
1174 I.getOpcode() == TargetOpcode::G_UADDO ||
1175 I.getOpcode() == TargetOpcode::G_USUBE ||
1176 I.getOpcode() == TargetOpcode::G_USUBO) &&
1177 "unexpected instruction");
1181 const Register DstReg = CarryMI.getDstReg();
1182 const Register CarryOutReg = CarryMI.getCarryOutReg();
1183 const Register Op0Reg = CarryMI.getLHSReg();
1184 const Register Op1Reg = CarryMI.getRHSReg();
1185 bool IsSub = CarryMI.isSub();
1188 assert(DstTy.
isScalar() &&
"selectUAddSub only supported for scalar types");
1191 unsigned OpADC, OpADD, OpSBB, OpSUB;
1194 OpADC = X86::ADC8rr;
1195 OpADD = X86::ADD8rr;
1196 OpSBB = X86::SBB8rr;
1197 OpSUB = X86::SUB8rr;
1200 OpADC = X86::ADC16rr;
1201 OpADD = X86::ADD16rr;
1202 OpSBB = X86::SBB16rr;
1203 OpSUB = X86::SUB16rr;
1206 OpADC = X86::ADC32rr;
1207 OpADD = X86::ADD32rr;
1208 OpSBB = X86::SBB32rr;
1209 OpSUB = X86::SUB32rr;
1212 OpADC = X86::ADC64rr;
1213 OpADD = X86::ADD64rr;
1214 OpSBB = X86::SBB64rr;
1215 OpSUB = X86::SUB64rr;
1225 unsigned Opcode = IsSub ? OpSUB : OpADD;
1229 Register CarryInReg = CarryInMI->getCarryInReg();
1231 while (
Def->getOpcode() == TargetOpcode::G_TRUNC) {
1232 CarryInReg =
Def->getOperand(1).getReg();
1237 if (
Def->getOpcode() == TargetOpcode::G_UADDE ||
1238 Def->getOpcode() == TargetOpcode::G_UADDO ||
1239 Def->getOpcode() == TargetOpcode::G_USUBE ||
1240 Def->getOpcode() == TargetOpcode::G_USUBO) {
1248 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::NEG8r), NegDef)
1251 Opcode = IsSub ? OpSBB : OpADC;
1257 Opcode = IsSub ? OpSUB : OpADD;
1262 MachineInstr &Inst =
1263 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcode), DstReg)
1267 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SETCCr), CarryOutReg)
1274 I.eraseFromParent();
1278bool X86InstructionSelector::selectExtract(MachineInstr &
I,
1279 MachineRegisterInfo &
MRI,
1281 assert((
I.getOpcode() == TargetOpcode::G_EXTRACT) &&
1282 "unexpected instruction");
1284 const Register DstReg =
I.getOperand(0).getReg();
1285 const Register SrcReg =
I.getOperand(1).getReg();
1286 int64_t
Index =
I.getOperand(2).getImm();
1300 if (!emitExtractSubreg(DstReg, SrcReg,
I,
MRI, MF))
1303 I.eraseFromParent();
1307 bool HasAVX = STI.
hasAVX();
1309 bool HasVLX = STI.hasVLX();
1313 I.setDesc(
TII.get(X86::VEXTRACTF32X4Z256rri));
1315 I.setDesc(
TII.get(X86::VEXTRACTF128rri));
1320 I.setDesc(
TII.get(X86::VEXTRACTF32X4Zrri));
1322 I.setDesc(
TII.get(X86::VEXTRACTF64X4Zrri));
1330 I.getOperand(2).setImm(Index);
1336bool X86InstructionSelector::emitExtractSubreg(
Register DstReg,
Register SrcReg,
1338 MachineRegisterInfo &
MRI,
1342 unsigned SubIdx = X86::NoSubRegister;
1348 "Incorrect Src/Dst register size");
1351 SubIdx = X86::sub_xmm;
1353 SubIdx = X86::sub_ymm;
1360 SrcRC =
TRI.getSubClassWithSubReg(SrcRC, SubIdx);
1368 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::COPY), DstReg)
1369 .
addReg(SrcReg, {}, SubIdx);
1374bool X86InstructionSelector::emitInsertSubreg(
Register DstReg,
Register SrcReg,
1376 MachineRegisterInfo &
MRI,
1380 unsigned SubIdx = X86::NoSubRegister;
1387 "Incorrect Src/Dst register size");
1390 SubIdx = X86::sub_xmm;
1392 SubIdx = X86::sub_ymm;
1406 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::IMPLICIT_DEF),
1409 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::INSERT_SUBREG),
1418bool X86InstructionSelector::selectInsert(MachineInstr &
I,
1419 MachineRegisterInfo &
MRI,
1421 assert((
I.getOpcode() == TargetOpcode::G_INSERT) &&
"unexpected instruction");
1423 const Register DstReg =
I.getOperand(0).getReg();
1424 const Register SrcReg =
I.getOperand(1).getReg();
1425 const Register InsertReg =
I.getOperand(2).getReg();
1426 int64_t
Index =
I.getOperand(3).getImm();
1429 const LLT InsertRegTy =
MRI.
getType(InsertReg);
1440 if (!emitInsertSubreg(DstReg, InsertReg,
I,
MRI, MF))
1443 I.eraseFromParent();
1447 bool HasAVX = STI.
hasAVX();
1449 bool HasVLX = STI.hasVLX();
1453 I.setDesc(
TII.get(X86::VINSERTF32X4Z256rri));
1455 I.setDesc(
TII.get(X86::VINSERTF128rri));
1460 I.setDesc(
TII.get(X86::VINSERTF32X4Zrri));
1462 I.setDesc(
TII.get(X86::VINSERTF64X4Zrri));
1471 I.getOperand(3).setImm(Index);
1477bool X86InstructionSelector::selectUnmergeValues(
1479 assert((
I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1480 "unexpected instruction");
1483 unsigned NumDefs =
I.getNumOperands() - 1;
1484 Register SrcReg =
I.getOperand(NumDefs).getReg();
1487 for (
unsigned Idx = 0;
Idx < NumDefs; ++
Idx) {
1488 MachineInstr &ExtrInst =
1490 TII.get(TargetOpcode::G_EXTRACT),
I.getOperand(Idx).getReg())
1494 if (!select(ExtrInst))
1498 I.eraseFromParent();
1502bool X86InstructionSelector::selectMergeValues(
1504 assert((
I.getOpcode() == TargetOpcode::G_MERGE_VALUES ||
1505 I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS) &&
1506 "unexpected instruction");
1509 Register DstReg =
I.getOperand(0).getReg();
1510 Register SrcReg0 =
I.getOperand(1).getReg();
1521 if (!emitInsertSubreg(DefReg,
I.getOperand(1).getReg(),
I,
MRI, MF))
1524 for (
unsigned Idx = 2;
Idx <
I.getNumOperands(); ++
Idx) {
1528 MachineInstr &InsertInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1529 TII.get(TargetOpcode::G_INSERT), Tmp)
1531 .
addReg(
I.getOperand(Idx).getReg())
1532 .
addImm((Idx - 1) * SrcSize);
1536 if (!select(InsertInst))
1540 MachineInstr &CopyInst = *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
1541 TII.get(TargetOpcode::COPY), DstReg)
1544 if (!select(CopyInst))
1547 I.eraseFromParent();
1551bool X86InstructionSelector::selectCondBranch(MachineInstr &
I,
1552 MachineRegisterInfo &
MRI,
1554 assert((
I.getOpcode() == TargetOpcode::G_BRCOND) &&
"unexpected instruction");
1556 const Register CondReg =
I.getOperand(0).getReg();
1557 MachineBasicBlock *DestMBB =
I.getOperand(1).getMBB();
1559 MachineInstr &TestInst =
1560 *
BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::TEST8ri))
1563 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::JCC_1))
1568 I.eraseFromParent();
1572bool X86InstructionSelector::materializeFP(MachineInstr &
I,
1573 MachineRegisterInfo &
MRI,
1575 assert((
I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1576 "unexpected instruction");
1583 const Register DstReg =
I.getOperand(0).getReg();
1587 const ConstantFP *CFP =
I.getOperand(1).getFPImm();
1590 const DebugLoc &DbgLoc =
I.getDebugLoc();
1593 getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Alignment);
1596 MachineInstr *LoadInst =
nullptr;
1604 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(X86::MOV64ri), AddrReg)
1621 unsigned PICBase = 0;
1630 BuildMI(*
I.getParent(),
I, DbgLoc,
TII.get(
Opc), DstReg), CPI, PICBase,
1636 I.eraseFromParent();
1640bool X86InstructionSelector::selectImplicitDefOrPHI(
1641 MachineInstr &
I, MachineRegisterInfo &
MRI)
const {
1642 assert((
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1643 I.getOpcode() == TargetOpcode::G_PHI) &&
1644 "unexpected instruction");
1646 Register DstReg =
I.getOperand(0).getReg();
1659 if (
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1660 I.setDesc(
TII.get(X86::IMPLICIT_DEF));
1662 I.setDesc(
TII.get(X86::PHI));
1667bool X86InstructionSelector::selectMulDivRem(MachineInstr &
I,
1668 MachineRegisterInfo &
MRI,
1671 assert((
I.getOpcode() == TargetOpcode::G_MUL ||
1672 I.getOpcode() == TargetOpcode::G_SMULH ||
1673 I.getOpcode() == TargetOpcode::G_UMULH ||
1674 I.getOpcode() == TargetOpcode::G_SDIV ||
1675 I.getOpcode() == TargetOpcode::G_SREM ||
1676 I.getOpcode() == TargetOpcode::G_UDIV ||
1677 I.getOpcode() == TargetOpcode::G_UREM) &&
1678 "unexpected instruction");
1680 const Register DstReg =
I.getOperand(0).getReg();
1681 const Register Op1Reg =
I.getOperand(1).getReg();
1682 const Register Op2Reg =
I.getOperand(2).getReg();
1686 "Arguments and return value types must match");
1689 if (!RegRB || RegRB->
getID() != X86::GPRRegBankID)
1692 const static unsigned NumTypes = 4;
1693 const static unsigned NumOps = 7;
1694 const static bool S =
true;
1695 const static bool U =
false;
1696 const static unsigned Copy = TargetOpcode::COPY;
1706 const static struct MulDivRemEntry {
1708 unsigned SizeInBits;
1712 struct MulDivRemResult {
1713 unsigned OpMulDivRem;
1714 unsigned OpSignExtend;
1721 } OpTable[NumTypes] = {
1726 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S},
1727 {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S},
1728 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U},
1729 {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1730 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AL, S},
1731 {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AH, S},
1732 {X86::MUL8r, 0, X86::MOVZX16rr8, X86::AH,
U},
1738 {X86::IDIV16r, X86::CWD,
Copy, X86::AX, S},
1739 {X86::IDIV16r, X86::CWD,
Copy, X86::DX, S},
1740 {X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U},
1741 {X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U},
1742 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::AX, S},
1743 {X86::IMUL16r, X86::MOV32r0,
Copy, X86::DX, S},
1744 {X86::MUL16r, X86::MOV32r0,
Copy, X86::DX,
U},
1750 {X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S},
1751 {X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S},
1752 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U},
1753 {X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1754 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EAX, S},
1755 {X86::IMUL32r, X86::MOV32r0,
Copy, X86::EDX, S},
1756 {X86::MUL32r, X86::MOV32r0,
Copy, X86::EDX,
U},
1762 {X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S},
1763 {X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S},
1764 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U},
1765 {X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1766 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RAX, S},
1767 {X86::IMUL64r, X86::MOV32r0,
Copy, X86::RDX, S},
1768 {X86::MUL64r, X86::MOV32r0,
Copy, X86::RDX,
U},
1772 auto OpEntryIt =
llvm::find_if(OpTable, [RegTy](
const MulDivRemEntry &El) {
1775 if (OpEntryIt == std::end(OpTable))
1779 switch (
I.getOpcode()) {
1782 case TargetOpcode::G_SDIV:
1785 case TargetOpcode::G_SREM:
1788 case TargetOpcode::G_UDIV:
1791 case TargetOpcode::G_UREM:
1794 case TargetOpcode::G_MUL:
1797 case TargetOpcode::G_SMULH:
1800 case TargetOpcode::G_UMULH:
1805 const MulDivRemEntry &
TypeEntry = *OpEntryIt;
1806 const MulDivRemEntry::MulDivRemResult &OpEntry =
1819 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpCopy),
1824 if (OpEntry.OpSignExtend) {
1825 if (OpEntry.IsOpSigned)
1827 TII.get(OpEntry.OpSignExtend));
1830 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::MOV32r0), Zero32)
1839 .
addReg(Zero32, {}, X86::sub_16bit);
1846 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
1854 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(OpEntry.OpMulDivRem))
1865 if (OpEntry.ResultReg == X86::AH && STI.is64Bit()) {
1868 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Copy), SourceSuperReg)
1872 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(X86::SHR16ri),
1878 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1880 .
addReg(ResultSuperReg, {}, X86::sub_8bit);
1882 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(TargetOpcode::COPY),
1884 .
addReg(OpEntry.ResultReg);
1886 I.eraseFromParent();
1891bool X86InstructionSelector::selectSelect(MachineInstr &
I,
1892 MachineRegisterInfo &
MRI,
1912 OpCmp = X86::CMOV_GR8;
1915 OpCmp = STI.
canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
1918 OpCmp = STI.
canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
1922 OpCmp = X86::CMOV64rr;
1940InstructionSelector::ComplexRendererFns
1941X86InstructionSelector::selectAddr(MachineOperand &Root)
const {
1943 MachineIRBuilder MIRBuilder(*
MI);
1949 return std::nullopt;
1952 return std::nullopt;
1955 {[=](MachineInstrBuilder &MIB) {
1960 "Unknown type of address base");
1965 [=](MachineInstrBuilder &MIB) { MIB.addImm(AM.
Scale); },
1967 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); },
1969 [=](MachineInstrBuilder &MIB) {
1975 MIB.addImm(AM.
Disp);
1978 [=](MachineInstrBuilder &MIB) { MIB.addUse(0); }}};
1981InstructionSelector *
1985 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)
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)
MachineRegisterInfo & MRI
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 ...
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...
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...
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