37#include "llvm/IR/IntrinsicsX86.h"
48class X86FastISel final :
public FastISel {
51 const X86Subtarget *Subtarget;
54 explicit X86FastISel(FunctionLoweringInfo &funcInfo,
55 const TargetLibraryInfo *libInfo,
56 const LibcallLoweringInfo *libcallLowering)
57 : FastISel(funcInfo, libInfo, libcallLowering) {
61 bool fastSelectInstruction(
const Instruction *
I)
override;
67 bool tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
68 const LoadInst *LI)
override;
70 bool fastLowerArguments()
override;
71 bool fastLowerCall(CallLoweringInfo &CLI)
override;
72 bool fastLowerIntrinsicCall(
const IntrinsicInst *
II)
override;
74#include "X86GenFastISel.inc"
80 bool X86FastEmitLoad(MVT VT, X86AddressMode &AM, MachineMemOperand *MMO,
81 Register &ResultReg,
unsigned Alignment = 1);
83 bool X86FastEmitStore(EVT VT,
const Value *Val, X86AddressMode &AM,
84 MachineMemOperand *MMO =
nullptr,
bool Aligned =
false);
85 bool X86FastEmitStore(EVT VT,
Register ValReg, X86AddressMode &AM,
86 MachineMemOperand *MMO =
nullptr,
bool Aligned =
false);
107 Register X86FastEmitMul(
unsigned Opc, MVT VT, MCRegister AccReg,
109 bool LiveEFLAGS =
false);
120 const ConstantInt *CI,
unsigned CondCode);
123 bool X86SelectCallAddress(
const Value *V, X86AddressMode &AM);
125 bool X86SelectLoad(
const Instruction *
I);
127 bool X86SelectStore(
const Instruction *
I);
129 bool X86SelectRet(
const Instruction *
I);
131 bool X86SelectCmp(
const Instruction *
I);
133 bool X86SelectZExt(
const Instruction *
I);
135 bool X86SelectSExt(
const Instruction *
I);
137 bool X86SelectBranch(
const Instruction *
I);
139 bool X86SelectShift(
const Instruction *
I);
141 bool X86SelectMul(
const Instruction *
I);
143 bool X86SelectDivRem(
const Instruction *
I);
145 bool X86FastEmitCMoveSelect(MVT RetVT,
const Instruction *
I);
147 bool X86FastEmitSSESelect(MVT RetVT,
const Instruction *
I);
149 bool X86FastEmitPseudoSelect(MVT RetVT,
const Instruction *
I);
151 bool X86SelectSelect(
const Instruction *
I);
153 bool X86SelectTrunc(
const Instruction *
I);
155 bool X86SelectFPExtOrFPTrunc(
const Instruction *
I,
unsigned Opc,
158 bool X86SelectFPExt(
const Instruction *
I);
159 bool X86SelectFPTrunc(
const Instruction *
I);
160 bool X86SelectSIToFP(
const Instruction *
I);
161 bool X86SelectUIToFP(
const Instruction *
I);
162 bool X86SelectIntToFP(
const Instruction *
I,
bool IsSigned);
163 bool X86SelectBitCast(
const Instruction *
I);
165 const X86InstrInfo *getInstrInfo()
const {
166 return Subtarget->getInstrInfo();
168 const X86TargetMachine *getTargetMachine()
const {
169 return static_cast<const X86TargetMachine *
>(&TM);
172 bool handleConstantAddresses(
const Value *V, X86AddressMode &AM);
176 Register X86MaterializeInt(
const ConstantInt *CI, MVT VT);
177 Register X86MaterializeFP(
const ConstantFP *CFP, MVT VT);
178 Register X86MaterializeGV(
const GlobalValue *GV, MVT VT);
179 Register fastMaterializeConstant(
const Constant *
C)
override;
181 Register fastMaterializeAlloca(
const AllocaInst *
C)
override;
183 Register fastMaterializeFloatZero(
const ConstantFP *CF)
override;
187 bool isScalarFPTypeInSSEReg(EVT VT)
const {
188 return (VT == MVT::f64 && Subtarget->hasSSE2()) ||
189 (VT == MVT::f32 && Subtarget->hasSSE1()) || VT == MVT::f16;
192 bool isTypeLegal(
Type *Ty, MVT &VT,
bool AllowI1 =
false);
196 bool TryEmitSmallMemcpy(X86AddressMode DestAM,
197 X86AddressMode SrcAM,
uint64_t Len);
199 bool foldX86XALUIntrinsic(
X86::CondCode &CC,
const Instruction *
I,
202 const MachineInstrBuilder &
addFullAddress(
const MachineInstrBuilder &MIB,
205 Register fastEmitInst_rrrr(
unsigned MachineInstOpcode,
212static std::pair<unsigned, bool>
215 bool NeedSwap =
false;
244 return std::make_pair(CC, NeedSwap);
258 return ::addFullAddress(MIB, AM);
263bool X86FastISel::foldX86XALUIntrinsic(
X86::CondCode &CC,
const Instruction *
I,
277 if (!isTypeLegal(RetTy, RetVT))
280 if (RetVT != MVT::i32 && RetVT != MVT::i64)
284 switch (
II->getIntrinsicID()) {
285 default:
return false;
286 case Intrinsic::sadd_with_overflow:
287 case Intrinsic::ssub_with_overflow: TmpCC =
X86::COND_O;
break;
288 case Intrinsic::smul_with_overflow:
289 case Intrinsic::umul_with_overflow:
290 case Intrinsic::uadd_with_overflow:
291 case Intrinsic::usub_with_overflow: TmpCC =
X86::COND_B;
break;
295 if (
II->getParent() !=
I->getParent())
301 for (
auto Itr = std::prev(Start); Itr != End; --Itr) {
309 if (EVI->getAggregateOperand() !=
II)
315 auto HasPhis = [](
const BasicBlock *Succ) {
return !Succ->phis().empty(); };
328bool X86FastISel::isTypeLegal(
Type *Ty, MVT &VT,
bool AllowI1) {
329 EVT evt = TLI.getValueType(
DL, Ty,
true);
330 if (evt == MVT::Other || !evt.
isSimple())
337 if (VT == MVT::f64 && !Subtarget->hasSSE2())
339 if (VT == MVT::f32 && !Subtarget->hasSSE1())
348 return (AllowI1 && VT == MVT::i1) || TLI.isTypeLegal(VT);
354bool X86FastISel::X86FastEmitLoad(MVT VT, X86AddressMode &AM,
355 MachineMemOperand *MMO,
Register &ResultReg,
356 unsigned Alignment) {
357 bool HasSSE1 = Subtarget->hasSSE1();
358 bool HasSSE2 = Subtarget->hasSSE2();
359 bool HasSSE41 = Subtarget->hasSSE41();
360 bool HasAVX = Subtarget->hasAVX();
361 bool HasAVX2 = Subtarget->hasAVX2();
362 bool HasAVX512 = Subtarget->hasAVX512();
363 bool HasVLX = Subtarget->hasVLX();
373 default:
return false;
388 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
389 : HasAVX ? X86::VMOVSSrm_alt
390 : HasSSE1 ? X86::MOVSSrm_alt
394 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
395 : HasAVX ? X86::VMOVSDrm_alt
396 : HasSSE2 ? X86::MOVSDrm_alt
403 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
404 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
405 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
406 else if (Alignment >= 16)
407 Opc = HasVLX ? X86::VMOVAPSZ128rm :
408 HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm;
410 Opc = HasVLX ? X86::VMOVUPSZ128rm :
411 HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm;
414 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
415 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
416 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
417 else if (Alignment >= 16)
418 Opc = HasVLX ? X86::VMOVAPDZ128rm :
419 HasAVX ? X86::VMOVAPDrm : X86::MOVAPDrm;
421 Opc = HasVLX ? X86::VMOVUPDZ128rm :
422 HasAVX ? X86::VMOVUPDrm : X86::MOVUPDrm;
428 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
429 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
430 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
431 else if (Alignment >= 16)
432 Opc = HasVLX ? X86::VMOVDQA64Z128rm :
433 HasAVX ? X86::VMOVDQArm : X86::MOVDQArm;
435 Opc = HasVLX ? X86::VMOVDQU64Z128rm :
436 HasAVX ? X86::VMOVDQUrm : X86::MOVDQUrm;
440 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
441 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
442 else if (IsNonTemporal && Alignment >= 16)
444 else if (Alignment >= 32)
445 Opc = HasVLX ? X86::VMOVAPSZ256rm : X86::VMOVAPSYrm;
447 Opc = HasVLX ? X86::VMOVUPSZ256rm : X86::VMOVUPSYrm;
451 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
452 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
453 else if (IsNonTemporal && Alignment >= 16)
455 else if (Alignment >= 32)
456 Opc = HasVLX ? X86::VMOVAPDZ256rm : X86::VMOVAPDYrm;
458 Opc = HasVLX ? X86::VMOVUPDZ256rm : X86::VMOVUPDYrm;
465 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
466 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
467 else if (IsNonTemporal && Alignment >= 16)
469 else if (Alignment >= 32)
470 Opc = HasVLX ? X86::VMOVDQA64Z256rm : X86::VMOVDQAYrm;
472 Opc = HasVLX ? X86::VMOVDQU64Z256rm : X86::VMOVDQUYrm;
476 if (IsNonTemporal && Alignment >= 64)
477 Opc = X86::VMOVNTDQAZrm;
483 if (IsNonTemporal && Alignment >= 64)
484 Opc = X86::VMOVNTDQAZrm;
495 if (IsNonTemporal && Alignment >= 64)
496 Opc = X86::VMOVNTDQAZrm;
504 ResultReg = createResultReg(RC);
505 MachineInstrBuilder MIB =
506 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
517bool X86FastISel::X86FastEmitStore(EVT VT,
Register ValReg, X86AddressMode &AM,
518 MachineMemOperand *MMO,
bool Aligned) {
519 bool HasSSE1 = Subtarget->hasSSE1();
520 bool HasSSE2 = Subtarget->hasSSE2();
521 bool HasSSE4A = Subtarget->hasSSE4A();
522 bool HasAVX = Subtarget->hasAVX();
523 bool HasAVX512 = Subtarget->hasAVX512();
524 bool HasVLX = Subtarget->hasVLX();
531 default:
return false;
534 Register AndResult = createResultReg(&X86::GR8RegClass);
535 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::AND8ri),
543 case MVT::i8:
Opc = X86::MOV8mr;
break;
544 case MVT::i16:
Opc = X86::MOV16mr;
break;
546 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTImr :
X86::MOV32mr;
550 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTI_64mr :
X86::MOV64mr;
554 if (IsNonTemporal && HasSSE4A)
557 Opc = HasAVX512 ? X86::VMOVSSZmr :
558 HasAVX ? X86::VMOVSSmr : X86::MOVSSmr;
564 if (IsNonTemporal && HasSSE4A)
567 Opc = HasAVX512 ? X86::VMOVSDZmr :
568 HasAVX ? X86::VMOVSDmr : X86::MOVSDmr;
573 Opc = (IsNonTemporal && HasSSE1) ? X86::MMX_MOVNTQmr :
X86::MMX_MOVQ64mr;
578 Opc = HasVLX ? X86::VMOVNTPSZ128mr :
579 HasAVX ? X86::VMOVNTPSmr : X86::MOVNTPSmr;
581 Opc = HasVLX ? X86::VMOVAPSZ128mr :
582 HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr;
584 Opc = HasVLX ? X86::VMOVUPSZ128mr :
585 HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr;
590 Opc = HasVLX ? X86::VMOVNTPDZ128mr :
591 HasAVX ? X86::VMOVNTPDmr : X86::MOVNTPDmr;
593 Opc = HasVLX ? X86::VMOVAPDZ128mr :
594 HasAVX ? X86::VMOVAPDmr : X86::MOVAPDmr;
596 Opc = HasVLX ? X86::VMOVUPDZ128mr :
597 HasAVX ? X86::VMOVUPDmr : X86::MOVUPDmr;
605 Opc = HasVLX ? X86::VMOVNTDQZ128mr :
606 HasAVX ? X86::VMOVNTDQmr : X86::MOVNTDQmr;
608 Opc = HasVLX ? X86::VMOVDQA64Z128mr :
609 HasAVX ? X86::VMOVDQAmr : X86::MOVDQAmr;
611 Opc = HasVLX ? X86::VMOVDQU64Z128mr :
612 HasAVX ? X86::VMOVDQUmr : X86::MOVDQUmr;
618 Opc = HasVLX ? X86::VMOVNTPSZ256mr : X86::VMOVNTPSYmr;
620 Opc = HasVLX ? X86::VMOVAPSZ256mr : X86::VMOVAPSYmr;
622 Opc = HasVLX ? X86::VMOVUPSZ256mr : X86::VMOVUPSYmr;
628 Opc = HasVLX ? X86::VMOVNTPDZ256mr : X86::VMOVNTPDYmr;
630 Opc = HasVLX ? X86::VMOVAPDZ256mr : X86::VMOVAPDYmr;
632 Opc = HasVLX ? X86::VMOVUPDZ256mr : X86::VMOVUPDYmr;
641 Opc = HasVLX ? X86::VMOVNTDQZ256mr : X86::VMOVNTDQYmr;
643 Opc = HasVLX ? X86::VMOVDQA64Z256mr : X86::VMOVDQAYmr;
645 Opc = HasVLX ? X86::VMOVDQU64Z256mr : X86::VMOVDQUYmr;
650 Opc = IsNonTemporal ? X86::VMOVNTPSZmr : X86::VMOVAPSZmr;
652 Opc = X86::VMOVUPSZmr;
657 Opc = IsNonTemporal ? X86::VMOVNTPDZmr : X86::VMOVAPDZmr;
659 Opc = X86::VMOVUPDZmr;
669 Opc = IsNonTemporal ? X86::VMOVNTDQZmr : X86::VMOVDQA64Zmr;
671 Opc = X86::VMOVDQU64Zmr;
683 MachineInstrBuilder MIB =
684 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
Desc);
692bool X86FastISel::X86FastEmitStore(EVT VT,
const Value *Val,
694 MachineMemOperand *MMO,
bool Aligned) {
708 case MVT::i8:
Opc = X86::MOV8mi;
break;
709 case MVT::i16:
Opc = X86::MOV16mi;
break;
710 case MVT::i32:
Opc = X86::MOV32mi;
break;
714 Opc = X86::MOV64mi32;
719 MachineInstrBuilder MIB =
720 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc));
722 : CI->getZExtValue());
729 Register ValReg = getRegForValue(Val);
733 return X86FastEmitStore(VT, ValReg, AM, MMO,
Aligned);
749Register X86FastISel::X86FastEmitLiveEFLAGS_rr(
unsigned Opc,
752 const MCInstrDesc &
II =
TII.get(
Opc);
753 assert(
II.getNumDefs() >= 1 &&
"instruction must define the result");
754 assert(
II.implicit_defs().size() == 1 &&
755 II.implicit_defs()[0] == X86::EFLAGS &&
"unexpected implicit def");
757 Register ResultReg = createResultReg(RC);
761 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
767Register X86FastISel::X86FastEmitLiveEFLAGS_ri(
unsigned Opc,
770 const MCInstrDesc &
II =
TII.get(
Opc);
771 assert(
II.getNumDefs() >= 1 &&
"instruction must define the result");
772 assert(
II.implicit_defs().size() == 1 &&
773 II.implicit_defs()[0] == X86::EFLAGS &&
"unexpected implicit def");
775 Register ResultReg = createResultReg(RC);
778 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
784Register X86FastISel::X86FastEmitMul(
unsigned Opc, MVT VT, MCRegister AccReg,
787 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
791 const MCInstrDesc &
II =
TII.get(
Opc);
792 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
795 MachineInstrBuilder MIB =
804 "unexpected operand order");
809 "unexpected operand order");
814 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
820bool X86FastISel::handleConstantAddresses(
const Value *V, X86AddressMode &AM) {
829 if (TM.isLargeGlobalValue(GV))
833 if (GV->isThreadLocal())
837 if (GV->isAbsoluteSymbolRef())
843 if (!Subtarget->isPICStyleRIPRel() ||
849 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
854 AM.
Base.
Reg = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
860 if (Subtarget->isPICStyleRIPRel()) {
872 auto I = LocalValueMap.find(V);
874 if (
I != LocalValueMap.end() &&
I->second) {
880 X86AddressMode StubAM;
886 SavePoint SaveInsertPt = enterLocalValueArea();
888 if (TLI.getPointerTy(
DL) == MVT::i64) {
890 RC = &X86::GR64RegClass;
893 RC = &X86::GR32RegClass;
900 LoadReg = createResultReg(RC);
901 MachineInstrBuilder LoadMI =
902 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), LoadReg);
906 leaveLocalValueArea(SaveInsertPt);
909 LocalValueMap[
V] = LoadReg;
921 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
923 AM.
Base.
Reg = getRegForValue(V);
938bool X86FastISel::X86SelectAddress(
const Value *V, X86AddressMode &AM) {
941 const User *
U =
nullptr;
942 unsigned Opcode = Instruction::UserOp1;
947 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(V)) ||
948 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
949 Opcode =
I->getOpcode();
953 Opcode =
C->getOpcode();
958 if (Ty->getAddressSpace() > 255)
965 case Instruction::BitCast:
969 case Instruction::IntToPtr:
971 if (TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
972 TLI.getPointerTy(
DL))
976 case Instruction::PtrToInt:
978 if (TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
982 case Instruction::Alloca: {
985 auto SI = FuncInfo.StaticAllocaMap.find(
A);
986 if (SI != FuncInfo.StaticAllocaMap.end()) {
994 case Instruction::Add: {
1000 AM.
Disp = (uint32_t)Disp;
1007 case Instruction::GetElementPtr: {
1008 X86AddressMode SavedAM = AM;
1013 unsigned Scale = AM.
Scale;
1014 MVT PtrVT = TLI.getValueType(
DL,
U->getType()).getSimpleVT();
1020 i != e; ++i, ++GTI) {
1023 const StructLayout *SL =
DL.getStructLayout(STy);
1035 Disp += CI->getValue().sextOrTrunc(64).getSExtValue() * S;
1038 if (canFoldAddIntoGEP(U,
Op)) {
1047 if (!IndexReg && (!AM.
GV || !Subtarget->isPICStyleRIPRel()) &&
1048 (S == 1 || S == 2 || S == 4 || S == 8)) {
1051 IndexReg = getRegForGEPIndex(PtrVT,
Op);
1057 goto unsupported_gep;
1067 AM.
Disp = (uint32_t)Disp;
1070 if (
const GetElementPtrInst *
GEP =
1085 if (handleConstantAddresses(
I, AM))
1095 return handleConstantAddresses(V, AM);
1100bool X86FastISel::X86SelectCallAddress(
const Value *V, X86AddressMode &AM) {
1101 const User *
U =
nullptr;
1102 unsigned Opcode = Instruction::UserOp1;
1129 Opcode =
I->getOpcode();
1131 InMBB =
I->getParent() == FuncInfo.MBB->getBasicBlock();
1133 Opcode =
C->getOpcode();
1139 case Instruction::BitCast:
1142 return X86SelectCallAddress(
U->getOperand(0), AM);
1145 case Instruction::IntToPtr:
1148 TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
1149 TLI.getPointerTy(
DL))
1150 return X86SelectCallAddress(
U->getOperand(0), AM);
1153 case Instruction::PtrToInt:
1155 if (InMBB && TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
1156 return X86SelectCallAddress(
U->getOperand(0), AM);
1168 if (Subtarget->isPICStyleRIPRel() &&
1174 if (GVar->isThreadLocal())
1183 if (Subtarget->isPICStyleRIPRel()) {
1189 AM.
GVOpFlags = Subtarget->classifyLocalReference(
nullptr);
1196 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
1197 auto GetCallRegForValue = [
this](
const Value *
V) {
1201 if (
Reg && Subtarget->isTarget64BitILP32()) {
1202 Register CopyReg = createResultReg(&X86::GR32RegClass);
1203 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32rr),
1207 Register ExtReg = createResultReg(&X86::GR64RegClass);
1208 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1209 TII.get(TargetOpcode::SUBREG_TO_REG), ExtReg)
1219 AM.
Base.
Reg = GetCallRegForValue(V);
1224 AM.
IndexReg = GetCallRegForValue(V);
1234bool X86FastISel::X86SelectStore(
const Instruction *
I) {
1241 const Value *PtrV =
I->getOperand(1);
1242 if (TLI.supportSwiftError()) {
1246 if (Arg->hasSwiftErrorAttr())
1251 if (Alloca->isSwiftError())
1260 if (!isTypeLegal(Val->
getType(), VT,
true))
1271 return X86FastEmitStore(VT, Val, AM, createMachineMemOperandFor(
I),
Aligned);
1275bool X86FastISel::X86SelectRet(
const Instruction *
I) {
1277 const Function &
F = *
I->getParent()->getParent();
1278 const X86MachineFunctionInfo *X86MFInfo =
1279 FuncInfo.MF->getInfo<X86MachineFunctionInfo>();
1281 if (!FuncInfo.CanLowerReturn)
1284 if (TLI.supportSwiftError() &&
1285 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
1288 if (TLI.supportSplitCSR(FuncInfo.MF))
1291 CallingConv::ID CC =
F.getCallingConv();
1292 if (CC != CallingConv::C &&
1293 CC != CallingConv::Fast &&
1294 CC != CallingConv::Tail &&
1295 CC != CallingConv::SwiftTail &&
1296 CC != CallingConv::X86_FastCall &&
1297 CC != CallingConv::X86_StdCall &&
1298 CC != CallingConv::X86_ThisCall &&
1299 CC != CallingConv::X86_64_SysV &&
1300 CC != CallingConv::Win64)
1309 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
1310 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
1326 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
I->getContext());
1335 if (ValLocs.
size() != 1)
1338 CCValAssign &VA = ValLocs[0];
1353 EVT SrcVT = TLI.getValueType(
DL, RV->
getType());
1356 if (SrcVT != DstVT) {
1357 if (SrcVT != MVT::i1 && SrcVT != MVT::i8 && SrcVT != MVT::i16)
1360 if (!Outs[0].
Flags.isZExt() && !Outs[0].Flags.isSExt())
1363 if (SrcVT == MVT::i1) {
1364 if (Outs[0].
Flags.isSExt())
1366 SrcReg = fastEmitZExtFromI1(MVT::i8, SrcReg);
1369 if (SrcVT != DstVT) {
1383 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1384 TII.get(TargetOpcode::COPY), DstReg).
addReg(SrcReg);
1397 if (
F.hasStructRetAttr() && CC != CallingConv::Swift &&
1398 CC != CallingConv::SwiftTail) {
1401 "SRetReturnReg should have been set in LowerFormalArguments()!");
1402 Register RetReg = Subtarget->isTarget64BitLP64() ? X86::RAX : X86::EAX;
1403 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1409 MachineInstrBuilder MIB;
1411 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1412 TII.get(Subtarget->is64Bit() ? X86::RETI64 : X86::RETI32))
1415 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1416 TII.get(Subtarget->is64Bit() ? X86::RET64 : X86::RET32));
1425bool X86FastISel::X86SelectLoad(
const Instruction *
I) {
1432 const Value *
SV =
I->getOperand(0);
1433 if (TLI.supportSwiftError()) {
1437 if (Arg->hasSwiftErrorAttr())
1442 if (Alloca->isSwiftError())
1448 if (!isTypeLegal(LI->
getType(), VT,
true))
1458 if (!X86FastEmitLoad(VT, AM, createMachineMemOperandFor(LI), ResultReg,
1462 updateValueMap(
I, ResultReg);
1467 bool HasAVX512 = Subtarget->
hasAVX512();
1468 bool HasAVX = Subtarget->
hasAVX();
1469 bool HasSSE1 = Subtarget->
hasSSE1();
1470 bool HasSSE2 = Subtarget->
hasSSE2();
1474 case MVT::i8:
return X86::CMP8rr;
1475 case MVT::i16:
return X86::CMP16rr;
1476 case MVT::i32:
return X86::CMP32rr;
1477 case MVT::i64:
return X86::CMP64rr;
1479 return HasAVX512 ? X86::VUCOMISSZrr
1480 : HasAVX ? X86::VUCOMISSrr
1481 : HasSSE1 ? X86::UCOMISSrr
1484 return HasAVX512 ? X86::VUCOMISDZrr
1485 : HasAVX ? X86::VUCOMISDrr
1486 : HasSSE2 ? X86::UCOMISDrr
1501 return X86::CMP16ri;
1503 return X86::CMP32ri;
1511bool X86FastISel::X86FastEmitCompare(
const Value *Op0,
const Value *Op1, EVT VT,
1513 Register Op0Reg = getRegForValue(Op0);
1526 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareImmOpc))
1528 .
addImm(Op1C->getSExtValue());
1534 if (CompareOpc == 0)
return false;
1536 Register Op1Reg = getRegForValue(Op1);
1539 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareOpc))
1547 ((!Subtarget->hasZU() || Subtarget->preferLegacySetCC()) ? X86::SETCCr \
1554 if (!isTypeLegal(
I->getOperand(0)->getType(), VT))
1567 ResultReg = emitMOV32r0();
1568 ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultReg, X86::sub_8bit);
1574 ResultReg = createResultReg(&X86::GR8RegClass);
1575 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
1582 updateValueMap(
I, ResultReg);
1594 if (RHSC && RHSC->isNullValue())
1599 static const uint16_t SETFOpcTable[2][3] = {
1610 ResultReg = createResultReg(&X86::GR8RegClass);
1612 if (!X86FastEmitCompare(
LHS,
RHS, VT,
I->getDebugLoc()))
1615 Register FlagReg1 = createResultReg(&X86::GR8RegClass);
1616 Register FlagReg2 = createResultReg(&X86::GR8RegClass);
1623 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(SETFOpc[2]),
1628 updateValueMap(
I, ResultReg);
1641 if (!X86FastEmitCompare(
LHS,
RHS, VT,
I->getDebugLoc()))
1646 updateValueMap(
I, ResultReg);
1650bool X86FastISel::X86SelectZExt(
const Instruction *
I) {
1651 EVT DstVT = TLI.getValueType(
DL,
I->getType());
1652 if (!TLI.isTypeLegal(DstVT))
1655 Register ResultReg = getRegForValue(
I->getOperand(0));
1660 MVT SrcVT = TLI.getSimpleValueType(
DL,
I->getOperand(0)->getType());
1661 if (SrcVT == MVT::i1) {
1663 ResultReg = fastEmitZExtFromI1(MVT::i8, ResultReg);
1670 if (DstVT == MVT::i64) {
1675 case MVT::i8: MovInst = X86::MOVZX32rr8;
break;
1676 case MVT::i16: MovInst = X86::MOVZX32rr16;
break;
1677 case MVT::i32: MovInst = X86::MOV32rr;
break;
1681 Register Result32 = createResultReg(&X86::GR32RegClass);
1682 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(MovInst), Result32)
1685 ResultReg = createResultReg(&X86::GR64RegClass);
1686 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1687 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
1690 }
else if (DstVT == MVT::i16) {
1693 Register Result32 = createResultReg(&X86::GR32RegClass);
1694 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVZX32rr8),
1695 Result32).
addReg(ResultReg);
1697 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1698 }
else if (DstVT != MVT::i8) {
1705 updateValueMap(
I, ResultReg);
1709bool X86FastISel::X86SelectSExt(
const Instruction *
I) {
1710 EVT DstVT = TLI.getValueType(
DL,
I->getType());
1711 if (!TLI.isTypeLegal(DstVT))
1714 Register ResultReg = getRegForValue(
I->getOperand(0));
1719 MVT SrcVT = TLI.getSimpleValueType(
DL,
I->getOperand(0)->getType());
1720 if (SrcVT == MVT::i1) {
1722 Register ZExtReg = fastEmitZExtFromI1(MVT::i8, ResultReg);
1727 ResultReg = createResultReg(&X86::GR8RegClass);
1728 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::NEG8r),
1736 if (DstVT == MVT::i16) {
1739 Register Result32 = createResultReg(&X86::GR32RegClass);
1740 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVSX32rr8),
1741 Result32).
addReg(ResultReg);
1743 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1744 }
else if (DstVT != MVT::i8) {
1751 updateValueMap(
I, ResultReg);
1755bool X86FastISel::X86SelectBranch(
const Instruction *
I) {
1759 MachineBasicBlock *TrueMBB = FuncInfo.getMBB(BI->
getSuccessor(0));
1760 MachineBasicBlock *FalseMBB = FuncInfo.getMBB(BI->
getSuccessor(1));
1767 if (CI->
hasOneUse() && CI->getParent() ==
I->getParent()) {
1772 switch (Predicate) {
1787 if (CmpRHSC && CmpRHSC->isNullValue())
1792 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1802 bool NeedExtraBranch =
false;
1803 switch (Predicate) {
1809 NeedExtraBranch =
true;
1822 if (!X86FastEmitCompare(CmpLHS, CmpRHS, VT, CI->getDebugLoc()))
1825 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1830 if (NeedExtraBranch) {
1831 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1835 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1842 if (TI->hasOneUse() && TI->getParent() ==
I->getParent() &&
1843 isTypeLegal(TI->getOperand(0)->getType(), SourceVT)) {
1844 unsigned TestOpc = 0;
1847 case MVT::i8: TestOpc = X86::TEST8ri;
break;
1848 case MVT::i16: TestOpc = X86::TEST16ri;
break;
1849 case MVT::i32: TestOpc = X86::TEST32ri;
break;
1850 case MVT::i64: TestOpc = X86::TEST64ri32;
break;
1853 Register OpReg = getRegForValue(TI->getOperand(0));
1857 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TestOpc))
1861 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1866 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1869 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1873 }
else if (foldX86XALUIntrinsic(CC, BI, BI->
getCondition())) {
1880 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1882 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1894 if (MRI.getRegClass(OpReg) == &X86::VK1RegClass) {
1896 OpReg = createResultReg(&X86::GR32RegClass);
1897 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1898 TII.get(TargetOpcode::COPY), OpReg)
1900 OpReg = fastEmitInst_extractsubreg(MVT::i8, OpReg, X86::sub_8bit);
1902 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
1905 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1907 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1911bool X86FastISel::X86SelectShift(
const Instruction *
I) {
1915 if (
I->getType()->isIntegerTy(8)) {
1917 RC = &X86::GR8RegClass;
1918 switch (
I->getOpcode()) {
1919 case Instruction::LShr: OpReg = X86::SHR8rCL;
break;
1920 case Instruction::AShr: OpReg = X86::SAR8rCL;
break;
1921 case Instruction::Shl: OpReg = X86::SHL8rCL;
break;
1922 default:
return false;
1924 }
else if (
I->getType()->isIntegerTy(16)) {
1926 RC = &X86::GR16RegClass;
1927 switch (
I->getOpcode()) {
1929 case Instruction::LShr: OpReg = X86::SHR16rCL;
break;
1930 case Instruction::AShr: OpReg = X86::SAR16rCL;
break;
1931 case Instruction::Shl: OpReg = X86::SHL16rCL;
break;
1933 }
else if (
I->getType()->isIntegerTy(32)) {
1935 RC = &X86::GR32RegClass;
1936 switch (
I->getOpcode()) {
1938 case Instruction::LShr: OpReg = X86::SHR32rCL;
break;
1939 case Instruction::AShr: OpReg = X86::SAR32rCL;
break;
1940 case Instruction::Shl: OpReg = X86::SHL32rCL;
break;
1942 }
else if (
I->getType()->isIntegerTy(64)) {
1944 RC = &X86::GR64RegClass;
1945 switch (
I->getOpcode()) {
1947 case Instruction::LShr: OpReg = X86::SHR64rCL;
break;
1948 case Instruction::AShr: OpReg = X86::SAR64rCL;
break;
1949 case Instruction::Shl: OpReg = X86::SHL64rCL;
break;
1956 if (!isTypeLegal(
I->getType(), VT))
1959 Register Op0Reg = getRegForValue(
I->getOperand(0));
1963 Register Op1Reg = getRegForValue(
I->getOperand(1));
1966 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
1971 if (CReg != X86::CL)
1972 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1973 TII.get(TargetOpcode::KILL), X86::CL)
1974 .
addReg(CReg, RegState::Kill);
1976 Register ResultReg = createResultReg(RC);
1977 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(OpReg), ResultReg)
1980 updateValueMap(
I, ResultReg);
1984bool X86FastISel::X86SelectMul(
const Instruction *
I) {
1985 if (!
I->getType()->isIntegerTy(8))
1988 Register LHSReg = getRegForValue(
I->getOperand(0));
1992 Register RHSReg = getRegForValue(
I->getOperand(1));
1997 X86FastEmitMul(X86::MUL8r, MVT::i8, X86::AL, LHSReg, RHSReg);
1998 updateValueMap(
I, ResultReg);
2002bool X86FastISel::X86SelectDivRem(
const Instruction *
I) {
2003 const static unsigned NumTypes = 4;
2004 const static unsigned NumOps = 4;
2005 const static bool S =
true;
2006 const static bool U =
false;
2007 const static unsigned Copy = TargetOpcode::COPY;
2017 const static struct DivRemEntry {
2023 struct DivRemResult {
2025 unsigned OpSignExtend;
2029 unsigned DivRemResultReg;
2032 } OpTable[NumTypes] = {
2033 { &X86::GR8RegClass, X86::AX, 0, {
2034 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S },
2035 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S },
2036 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U },
2037 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U },
2040 { &X86::GR16RegClass, X86::AX, X86::DX, {
2041 { X86::IDIV16r, X86::CWD,
Copy, X86::AX, S },
2042 { X86::IDIV16r, X86::CWD,
Copy, X86::DX, S },
2043 { X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U },
2044 { X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U },
2047 { &X86::GR32RegClass, X86::EAX, X86::EDX, {
2048 { X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S },
2049 { X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S },
2050 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U },
2051 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U },
2054 { &X86::GR64RegClass, X86::RAX, X86::RDX, {
2055 { X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S },
2056 { X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S },
2057 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U },
2058 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U },
2064 if (!isTypeLegal(
I->getType(), VT))
2067 unsigned TypeIndex, OpIndex;
2069 default:
return false;
2070 case MVT::i8: TypeIndex = 0;
break;
2071 case MVT::i16: TypeIndex = 1;
break;
2072 case MVT::i32: TypeIndex = 2;
break;
2073 case MVT::i64: TypeIndex = 3;
2074 if (!Subtarget->is64Bit())
2079 switch (
I->getOpcode()) {
2081 case Instruction::SDiv: OpIndex = 0;
break;
2082 case Instruction::SRem: OpIndex = 1;
break;
2083 case Instruction::UDiv: OpIndex = 2;
break;
2084 case Instruction::URem: OpIndex = 3;
break;
2087 const DivRemEntry &
TypeEntry = OpTable[TypeIndex];
2088 const DivRemEntry::DivRemResult &OpEntry =
TypeEntry.ResultTable[OpIndex];
2089 Register Op0Reg = getRegForValue(
I->getOperand(0));
2092 Register Op1Reg = getRegForValue(
I->getOperand(1));
2097 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2100 if (OpEntry.OpSignExtend) {
2101 if (OpEntry.IsOpSigned)
2102 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2103 TII.get(OpEntry.OpSignExtend));
2110 if (VT == MVT::i16) {
2111 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Copy),
2113 .
addReg(Zero32, {}, X86::sub_16bit);
2114 }
else if (VT == MVT::i32) {
2115 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2118 }
else if (VT == MVT::i64) {
2119 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2120 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
2134 bool UseAXForRem = (
I->getOpcode() == Instruction::SRem ||
2135 I->getOpcode() == Instruction::URem) &&
2136 OpEntry.DivRemResultReg == X86::AH && Subtarget->is64Bit();
2141 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(OpEntry.OpDivRem))
2147 Register SourceSuperReg = createResultReg(&X86::GR16RegClass);
2148 Register ResultSuperReg = createResultReg(&X86::GR16RegClass);
2149 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2150 TII.get(Copy), SourceSuperReg).
addReg(X86::AX);
2153 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SHR16ri),
2160 ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultSuperReg,
2165 ResultReg = createResultReg(
TypeEntry.RC);
2166 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Copy), ResultReg)
2167 .
addReg(OpEntry.DivRemResultReg);
2169 updateValueMap(
I, ResultReg);
2176bool X86FastISel::X86FastEmitCMoveSelect(MVT RetVT,
const Instruction *
I) {
2178 if (!Subtarget->canUseCMOV())
2182 if (RetVT < MVT::i16 || RetVT > MVT::i64)
2187 bool NeedTest =
true;
2194 if (CI && (CI->getParent() ==
I->getParent())) {
2198 static const uint16_t SETFOpcTable[2][3] = {
2202 const uint16_t *SETFOpc =
nullptr;
2203 switch (Predicate) {
2206 SETFOpc = &SETFOpcTable[0][0];
2210 SETFOpc = &SETFOpcTable[1][0];
2224 EVT CmpVT = TLI.getValueType(
DL, CmpLHS->
getType());
2226 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
2230 Register FlagReg1 = createResultReg(&X86::GR8RegClass);
2231 Register FlagReg2 = createResultReg(&X86::GR8RegClass);
2238 auto const &
II =
TII.get(SETFOpc[2]);
2239 if (
II.getNumDefs()) {
2240 Register TmpReg = createResultReg(&X86::GR8RegClass);
2241 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, TmpReg)
2244 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
2249 }
else if (foldX86XALUIntrinsic(CC,
I,
Cond)) {
2270 if (MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2272 CondReg = createResultReg(&X86::GR32RegClass);
2273 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2274 TII.get(TargetOpcode::COPY), CondReg)
2276 CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, X86::sub_8bit);
2278 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
2288 if (!LHSReg || !RHSReg)
2291 const TargetRegisterInfo &
TRI = *Subtarget->getRegisterInfo();
2293 Subtarget->hasNDD());
2294 Register ResultReg = fastEmitInst_rri(
Opc, RC, RHSReg, LHSReg, CC);
2295 updateValueMap(
I, ResultReg);
2304bool X86FastISel::X86FastEmitSSESelect(MVT RetVT,
const Instruction *
I) {
2309 if (!CI || (CI->getParent() !=
I->getParent()))
2313 !((Subtarget->hasSSE1() && RetVT == MVT::f32) ||
2314 (Subtarget->hasSSE2() && RetVT == MVT::f64)))
2326 if (CmpRHSC && CmpRHSC->isNullValue())
2333 if (CC > 7 && !Subtarget->hasAVX())
2344 Register CmpLHSReg = getRegForValue(CmpLHS);
2345 Register CmpRHSReg = getRegForValue(CmpRHS);
2346 if (!LHSReg || !RHSReg || !CmpLHSReg || !CmpRHSReg)
2352 if (Subtarget->hasAVX512()) {
2357 unsigned CmpOpcode =
2358 (RetVT == MVT::f32) ? X86::VCMPSSZrri :
X86::VCMPSDZrri;
2359 Register CmpReg = fastEmitInst_rri(CmpOpcode, VK1, CmpLHSReg, CmpRHSReg,
2364 Register ImplicitDefReg = createResultReg(VR128X);
2365 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2366 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2370 unsigned MovOpcode =
2371 (RetVT == MVT::f32) ? X86::VMOVSSZrrk :
X86::VMOVSDZrrk;
2372 Register MovReg = fastEmitInst_rrrr(MovOpcode, VR128X, RHSReg, CmpReg,
2373 ImplicitDefReg, LHSReg);
2375 ResultReg = createResultReg(RC);
2376 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2377 TII.get(TargetOpcode::COPY), ResultReg).
addReg(MovReg);
2379 }
else if (Subtarget->hasAVX()) {
2387 unsigned CmpOpcode =
2388 (RetVT == MVT::f32) ? X86::VCMPSSrri :
X86::VCMPSDrri;
2389 unsigned BlendOpcode =
2390 (RetVT == MVT::f32) ? X86::VBLENDVPSrrr :
X86::VBLENDVPDrrr;
2392 Register CmpReg = fastEmitInst_rri(CmpOpcode, RC, CmpLHSReg, CmpRHSReg,
2394 Register VBlendReg = fastEmitInst_rrr(BlendOpcode, VR128, RHSReg, LHSReg,
2396 ResultReg = createResultReg(RC);
2397 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2398 TII.get(TargetOpcode::COPY), ResultReg).
addReg(VBlendReg);
2401 static const uint16_t OpcTable[2][4] = {
2402 { X86::CMPSSrri, X86::ANDPSrr, X86::ANDNPSrr, X86::ORPSrr },
2403 { X86::CMPSDrri, X86::ANDPDrr, X86::ANDNPDrr, X86::ORPDrr }
2406 const uint16_t *
Opc =
nullptr;
2408 default:
return false;
2409 case MVT::f32:
Opc = &OpcTable[0][0];
break;
2410 case MVT::f64:
Opc = &OpcTable[1][0];
break;
2414 Register CmpReg = fastEmitInst_rri(
Opc[0], RC, CmpLHSReg, CmpRHSReg, CC);
2415 Register AndReg = fastEmitInst_rr(
Opc[1], VR128, CmpReg, LHSReg);
2416 Register AndNReg = fastEmitInst_rr(
Opc[2], VR128, CmpReg, RHSReg);
2417 Register OrReg = fastEmitInst_rr(
Opc[3], VR128, AndNReg, AndReg);
2418 ResultReg = createResultReg(RC);
2419 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2420 TII.get(TargetOpcode::COPY), ResultReg).
addReg(OrReg);
2422 updateValueMap(
I, ResultReg);
2426bool X86FastISel::X86FastEmitPseudoSelect(MVT RetVT,
const Instruction *
I) {
2431 default:
return false;
2432 case MVT::i8:
Opc = X86::CMOV_GR8;
break;
2433 case MVT::i16:
Opc = X86::CMOV_GR16;
break;
2434 case MVT::i32:
Opc = X86::CMOV_GR32;
break;
2436 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR16X : X86::CMOV_FR16;
break;
2438 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR32X : X86::CMOV_FR32;
break;
2440 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR64X : X86::CMOV_FR64;
break;
2450 if (CI && (CI->getParent() ==
I->getParent())) {
2462 EVT CmpVT = TLI.getValueType(
DL, CmpLHS->
getType());
2463 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
2471 if (MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2473 CondReg = createResultReg(&X86::GR32RegClass);
2474 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2475 TII.get(TargetOpcode::COPY), CondReg)
2477 CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, X86::sub_8bit);
2479 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
2489 if (!LHSReg || !RHSReg)
2495 fastEmitInst_rri(
Opc, RC, RHSReg, LHSReg, CC);
2496 updateValueMap(
I, ResultReg);
2500bool X86FastISel::X86SelectSelect(
const Instruction *
I) {
2502 if (!isTypeLegal(
I->getType(), RetVT))
2508 const Value *Opnd =
nullptr;
2509 switch (Predicate) {
2516 Register OpReg = getRegForValue(Opnd);
2520 Register ResultReg = createResultReg(RC);
2521 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2522 TII.get(TargetOpcode::COPY), ResultReg)
2524 updateValueMap(
I, ResultReg);
2530 if (X86FastEmitCMoveSelect(RetVT,
I))
2534 if (X86FastEmitSSESelect(RetVT,
I))
2539 if (X86FastEmitPseudoSelect(RetVT,
I))
2546bool X86FastISel::X86SelectIntToFP(
const Instruction *
I,
bool IsSigned) {
2551 bool HasAVX512 = Subtarget->hasAVX512();
2552 if (!Subtarget->hasAVX() || (!IsSigned && !HasAVX512))
2556 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
2557 if (SrcVT != MVT::i32 && SrcVT != MVT::i64)
2561 Register OpReg = getRegForValue(
I->getOperand(0));
2567 static const uint16_t SCvtOpc[2][2][2] = {
2568 { { X86::VCVTSI2SSrr, X86::VCVTSI642SSrr },
2569 { X86::VCVTSI2SDrr, X86::VCVTSI642SDrr } },
2570 { { X86::VCVTSI2SSZrr, X86::VCVTSI642SSZrr },
2571 { X86::VCVTSI2SDZrr, X86::VCVTSI642SDZrr } },
2573 static const uint16_t UCvtOpc[2][2] = {
2574 { X86::VCVTUSI2SSZrr, X86::VCVTUSI642SSZrr },
2575 { X86::VCVTUSI2SDZrr, X86::VCVTUSI642SDZrr },
2577 bool Is64Bit = SrcVT == MVT::i64;
2579 if (
I->getType()->isDoubleTy()) {
2581 Opcode = IsSigned ? SCvtOpc[HasAVX512][1][Is64Bit] : UCvtOpc[1][Is64Bit];
2582 }
else if (
I->getType()->isFloatTy()) {
2584 Opcode = IsSigned ? SCvtOpc[HasAVX512][0][Is64Bit] : UCvtOpc[0][Is64Bit];
2590 Register ImplicitDefReg = createResultReg(RC);
2591 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2592 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2593 Register ResultReg = fastEmitInst_rr(Opcode, RC, ImplicitDefReg, OpReg);
2594 updateValueMap(
I, ResultReg);
2598bool X86FastISel::X86SelectSIToFP(
const Instruction *
I) {
2599 return X86SelectIntToFP(
I,
true);
2602bool X86FastISel::X86SelectUIToFP(
const Instruction *
I) {
2603 return X86SelectIntToFP(
I,
false);
2607bool X86FastISel::X86SelectFPExtOrFPTrunc(
const Instruction *
I,
2610 assert((
I->getOpcode() == Instruction::FPExt ||
2611 I->getOpcode() == Instruction::FPTrunc) &&
2612 "Instruction must be an FPExt or FPTrunc!");
2613 bool HasAVX = Subtarget->hasAVX();
2615 Register OpReg = getRegForValue(
I->getOperand(0));
2621 ImplicitDefReg = createResultReg(RC);
2622 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2623 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2627 Register ResultReg = createResultReg(RC);
2628 MachineInstrBuilder MIB;
2629 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpc),
2633 MIB.
addReg(ImplicitDefReg);
2636 updateValueMap(
I, ResultReg);
2640bool X86FastISel::X86SelectFPExt(
const Instruction *
I) {
2641 if (Subtarget->hasSSE2() &&
I->getType()->isDoubleTy() &&
2642 I->getOperand(0)->getType()->isFloatTy()) {
2643 bool HasAVX512 = Subtarget->hasAVX512();
2646 HasAVX512 ? X86::VCVTSS2SDZrr
2647 : Subtarget->hasAVX() ? X86::VCVTSS2SDrr : X86::CVTSS2SDrr;
2648 return X86SelectFPExtOrFPTrunc(
I,
Opc, TLI.getRegClassFor(MVT::f64));
2654bool X86FastISel::X86SelectFPTrunc(
const Instruction *
I) {
2655 if (Subtarget->hasSSE2() &&
I->getType()->isFloatTy() &&
2656 I->getOperand(0)->getType()->isDoubleTy()) {
2657 bool HasAVX512 = Subtarget->hasAVX512();
2660 HasAVX512 ? X86::VCVTSD2SSZrr
2661 : Subtarget->hasAVX() ? X86::VCVTSD2SSrr : X86::CVTSD2SSrr;
2662 return X86SelectFPExtOrFPTrunc(
I,
Opc, TLI.getRegClassFor(MVT::f32));
2668bool X86FastISel::X86SelectTrunc(
const Instruction *
I) {
2669 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
2670 EVT DstVT = TLI.getValueType(
DL,
I->getType());
2673 if (DstVT != MVT::i8 && DstVT != MVT::i1)
2675 if (!TLI.isTypeLegal(SrcVT))
2678 Register InputReg = getRegForValue(
I->getOperand(0));
2683 if (SrcVT == MVT::i8) {
2685 updateValueMap(
I, InputReg);
2690 Register ResultReg = fastEmitInst_extractsubreg(MVT::i8, InputReg,
2695 updateValueMap(
I, ResultReg);
2699bool X86FastISel::X86SelectBitCast(
const Instruction *
I) {
2702 if (!Subtarget->hasSSE2() ||
2703 !isTypeLegal(
I->getOperand(0)->getType(), SrcVT) ||
2704 !isTypeLegal(
I->getType(), DstVT))
2720 Register ResultReg = createResultReg(DstClass);
2721 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
2725 updateValueMap(
I, ResultReg);
2729bool X86FastISel::IsMemcpySmall(
uint64_t Len) {
2730 return Len <= (Subtarget->is64Bit() ? 32 : 16);
2733bool X86FastISel::TryEmitSmallMemcpy(X86AddressMode DestAM,
2734 X86AddressMode SrcAM,
uint64_t Len) {
2737 if (!IsMemcpySmall(Len))
2740 bool i64Legal = Subtarget->is64Bit();
2745 if (Len >= 8 && i64Legal)
2755 bool RV = X86FastEmitLoad(VT, SrcAM,
nullptr,
Reg);
2756 RV &= X86FastEmitStore(VT,
Reg, DestAM);
2757 assert(RV &&
"Failed to emit load or store??");
2769Register X86FastISel::X86FastEmitAddSub_rr(
unsigned BaseOpc, MVT VT,
2771 static const uint16_t
Opc[2][2][4] = {
2772 {{X86::ADD8rr, X86::ADD16rr, X86::ADD32rr, X86::ADD64rr},
2773 {X86::ADD8rr_ND, X86::ADD16rr_ND, X86::ADD32rr_ND, X86::ADD64rr_ND}},
2774 {{X86::SUB8rr, X86::SUB16rr, X86::SUB32rr, X86::SUB64rr},
2775 {X86::SUB8rr_ND, X86::SUB16rr_ND, X86::SUB32rr_ND, X86::SUB64rr_ND}}};
2778 unsigned TypeIdx = VT.
SimpleTy - MVT::i8;
2779 return X86FastEmitLiveEFLAGS_rr(
Opc[IsSub][Subtarget->hasNDD()][TypeIdx],
2780 TLI.getRegClassFor(VT), LHSReg, RHSReg);
2783Register X86FastISel::X86FastEmitAddSub_ri(
unsigned BaseOpc, MVT VT,
2785 const ConstantInt *CI,
2786 unsigned CondCode) {
2788 unsigned TypeIdx = VT.
SimpleTy - MVT::i8;
2792 static const uint16_t IncDecOpc[2][4] = {
2793 {X86::INC8r, X86::INC16r, X86::INC32r, X86::INC64r},
2794 {X86::DEC8r, X86::DEC16r, X86::DEC32r, X86::DEC64r}};
2796 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
2797 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2798 TII.get(IncDecOpc[IsSub][TypeIdx]), ResultReg)
2806 static const uint16_t
Opc[2][2][4] = {
2807 {{X86::ADD8ri, X86::ADD16ri, X86::ADD32ri, X86::ADD64ri32},
2808 {X86::ADD8ri_ND, X86::ADD16ri_ND, X86::ADD32ri_ND, X86::ADD64ri32_ND}},
2809 {{X86::SUB8ri, X86::SUB16ri, X86::SUB32ri, X86::SUB64ri32},
2810 {X86::SUB8ri_ND, X86::SUB16ri_ND, X86::SUB32ri_ND, X86::SUB64ri32_ND}}};
2812 return X86FastEmitLiveEFLAGS_ri(
Opc[IsSub][Subtarget->hasNDD()][TypeIdx],
2813 TLI.getRegClassFor(VT), LHSReg,
2817bool X86FastISel::fastLowerIntrinsicCall(
const IntrinsicInst *
II) {
2819 switch (
II->getIntrinsicID()) {
2822 case Intrinsic::frameaddress: {
2827 Type *RetTy =
II->getCalledFunction()->getReturnType();
2830 if (!isTypeLegal(RetTy, VT))
2838 case MVT::i32:
Opc = X86::MOV32rm; RC = &X86::GR32RegClass;
break;
2839 case MVT::i64:
Opc = X86::MOV64rm; RC = &X86::GR64RegClass;
break;
2847 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2849 assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
2850 (FrameReg == X86::EBP && VT == MVT::i32)) &&
2851 "Invalid Frame Register!");
2856 Register SrcReg = createResultReg(RC);
2857 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2858 TII.get(TargetOpcode::COPY), SrcReg).
addReg(FrameReg);
2867 Register DestReg = createResultReg(RC);
2869 TII.get(
Opc), DestReg), SrcReg);
2873 updateValueMap(
II, SrcReg);
2876 case Intrinsic::memcpy: {
2886 if (IsMemcpySmall(Len)) {
2887 X86AddressMode DestAM, SrcAM;
2891 TryEmitSmallMemcpy(DestAM, SrcAM, Len);
2896 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2903 return lowerCallTo(
II,
"memcpy",
II->arg_size() - 1);
2905 case Intrinsic::memset: {
2911 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2918 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
2920 case Intrinsic::stackprotector: {
2922 EVT PtrTy = TLI.getPointerTy(
DL);
2924 const Value *Op1 =
II->getArgOperand(0);
2932 if (!X86FastEmitStore(PtrTy, Op1, AM))
return false;
2935 case Intrinsic::dbg_declare: {
2941 const MCInstrDesc &
II =
TII.get(TargetOpcode::DBG_VALUE);
2943 "Expected inlined-at fields to agree");
2950 case Intrinsic::trap: {
2951 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TRAP));
2954 case Intrinsic::sqrt: {
2955 if (!Subtarget->hasSSE1())
2958 Type *RetTy =
II->getCalledFunction()->getReturnType();
2961 if (!isTypeLegal(RetTy, VT))
2967 static const uint16_t SqrtOpc[3][2] = {
2968 { X86::SQRTSSr, X86::SQRTSDr },
2969 { X86::VSQRTSSr, X86::VSQRTSDr },
2970 { X86::VSQRTSSZr, X86::VSQRTSDZr },
2972 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
2973 Subtarget->hasAVX() ? 1 :
2977 default:
return false;
2978 case MVT::f32:
Opc = SqrtOpc[AVXLevel][0];
break;
2979 case MVT::f64:
Opc = SqrtOpc[AVXLevel][1];
break;
2982 const Value *SrcVal =
II->getArgOperand(0);
2983 Register SrcReg = getRegForValue(SrcVal);
2991 ImplicitDefReg = createResultReg(RC);
2992 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2993 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2996 Register ResultReg = createResultReg(RC);
2997 MachineInstrBuilder MIB;
2998 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
3002 MIB.
addReg(ImplicitDefReg);
3006 updateValueMap(
II, ResultReg);
3009 case Intrinsic::sadd_with_overflow:
3010 case Intrinsic::uadd_with_overflow:
3011 case Intrinsic::ssub_with_overflow:
3012 case Intrinsic::usub_with_overflow:
3013 case Intrinsic::smul_with_overflow:
3014 case Intrinsic::umul_with_overflow: {
3019 Type *RetTy = Ty->getTypeAtIndex(0U);
3022 "Overflow value expected to be an i1");
3025 if (!isTypeLegal(RetTy, VT))
3028 if (VT < MVT::i8 || VT > MVT::i64)
3039 switch (
II->getIntrinsicID()) {
3041 case Intrinsic::sadd_with_overflow:
3043 case Intrinsic::uadd_with_overflow:
3045 case Intrinsic::ssub_with_overflow:
3047 case Intrinsic::usub_with_overflow:
3049 case Intrinsic::smul_with_overflow:
3051 case Intrinsic::umul_with_overflow:
3064 ResultReg = X86FastEmitAddSub_ri(BaseOpc, VT, LHSReg, CI, CondCode);
3068 RHSReg = getRegForValue(
RHS);
3073 ResultReg = X86FastEmitAddSub_rr(BaseOpc, VT, LHSReg, RHSReg);
3076 if (BaseOpc == X86ISD::UMUL) {
3077 static const uint16_t MULOpc[] =
3078 { X86::MUL8r, X86::MUL16r, X86::MUL32r, X86::MUL64r };
3079 static const MCPhysReg Reg[] = { X86::AL, X86::AX, X86::EAX, X86::RAX };
3082 ResultReg = X86FastEmitMul(MULOpc[VT.
SimpleTy - MVT::i8], VT,
3085 }
else if (BaseOpc == X86ISD::SMUL) {
3086 static const uint16_t MULOpc[] =
3087 { X86::IMUL8r, X86::IMUL16rr, X86::IMUL32rr, X86::IMUL64rr };
3088 if (VT == MVT::i8) {
3091 ResultReg = X86FastEmitMul(MULOpc[0], VT, X86::AL, LHSReg, RHSReg,
3095 X86FastEmitLiveEFLAGS_rr(MULOpc[VT.
SimpleTy - MVT::i8],
3096 TLI.getRegClassFor(VT), LHSReg, RHSReg);
3104 Register ResultReg2 = createResultReg(&X86::GR8RegClass);
3105 assert((ResultReg+1) == ResultReg2 &&
"Nonconsecutive result registers.");
3110 updateValueMap(
II, ResultReg, 2);
3113 case Intrinsic::x86_sse_cvttss2si:
3114 case Intrinsic::x86_sse_cvttss2si64:
3115 case Intrinsic::x86_sse2_cvttsd2si:
3116 case Intrinsic::x86_sse2_cvttsd2si64: {
3118 switch (
II->getIntrinsicID()) {
3120 case Intrinsic::x86_sse_cvttss2si:
3121 case Intrinsic::x86_sse_cvttss2si64:
3122 if (!Subtarget->hasSSE1())
3124 IsInputDouble =
false;
3126 case Intrinsic::x86_sse2_cvttsd2si:
3127 case Intrinsic::x86_sse2_cvttsd2si64:
3128 if (!Subtarget->hasSSE2())
3130 IsInputDouble =
true;
3134 Type *RetTy =
II->getCalledFunction()->getReturnType();
3136 if (!isTypeLegal(RetTy, VT))
3139 static const uint16_t CvtOpc[3][2][2] = {
3140 { { X86::CVTTSS2SIrr, X86::CVTTSS2SI64rr },
3141 { X86::CVTTSD2SIrr, X86::CVTTSD2SI64rr } },
3142 { { X86::VCVTTSS2SIrr, X86::VCVTTSS2SI64rr },
3143 { X86::VCVTTSD2SIrr, X86::VCVTTSD2SI64rr } },
3144 { { X86::VCVTTSS2SIZrr, X86::VCVTTSS2SI64Zrr },
3145 { X86::VCVTTSD2SIZrr, X86::VCVTTSD2SI64Zrr } },
3147 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
3148 Subtarget->hasAVX() ? 1 :
3153 case MVT::i32:
Opc = CvtOpc[AVXLevel][IsInputDouble][0];
break;
3154 case MVT::i64:
Opc = CvtOpc[AVXLevel][IsInputDouble][1];
break;
3166 Op =
IE->getOperand(1);
3169 Op =
IE->getOperand(0);
3176 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3177 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
3180 updateValueMap(
II, ResultReg);
3183 case Intrinsic::x86_sse42_crc32_32_8:
3184 case Intrinsic::x86_sse42_crc32_32_16:
3185 case Intrinsic::x86_sse42_crc32_32_32:
3186 case Intrinsic::x86_sse42_crc32_64_64: {
3187 if (!Subtarget->hasCRC32())
3190 Type *RetTy =
II->getCalledFunction()->getReturnType();
3193 if (!isTypeLegal(RetTy, VT))
3199 switch (
II->getIntrinsicID()) {
3202#define GET_EGPR_IF_ENABLED(OPC) Subtarget->hasEGPR() ? OPC##_EVEX : OPC
3203 case Intrinsic::x86_sse42_crc32_32_8:
3205 RC = &X86::GR32RegClass;
3207 case Intrinsic::x86_sse42_crc32_32_16:
3209 RC = &X86::GR32RegClass;
3211 case Intrinsic::x86_sse42_crc32_32_32:
3213 RC = &X86::GR32RegClass;
3215 case Intrinsic::x86_sse42_crc32_64_64:
3217 RC = &X86::GR64RegClass;
3219#undef GET_EGPR_IF_ENABLED
3227 if (!LHSReg || !RHSReg)
3230 Register ResultReg = fastEmitInst_rr(
Opc, RC, LHSReg, RHSReg);
3234 updateValueMap(
II, ResultReg);
3240bool X86FastISel::fastLowerArguments() {
3241 if (!FuncInfo.CanLowerReturn)
3248 CallingConv::ID CC =
F->getCallingConv();
3249 if (CC != CallingConv::C)
3252 if (Subtarget->isCallingConvWin64(CC))
3255 if (!Subtarget->is64Bit())
3258 if (Subtarget->useSoftFloat())
3262 unsigned GPRCnt = 0;
3263 unsigned FPRCnt = 0;
3264 for (
auto const &Arg :
F->args()) {
3265 if (Arg.hasAttribute(Attribute::ByVal) ||
3266 Arg.hasAttribute(Attribute::InReg) ||
3267 Arg.hasAttribute(Attribute::StructRet) ||
3268 Arg.hasAttribute(Attribute::SwiftSelf) ||
3269 Arg.hasAttribute(Attribute::SwiftAsync) ||
3270 Arg.hasAttribute(Attribute::SwiftError) ||
3271 Arg.hasAttribute(Attribute::Nest))
3274 Type *ArgTy = Arg.getType();
3278 EVT ArgVT = TLI.getValueType(
DL, ArgTy);
3279 if (!ArgVT.
isSimple())
return false;
3281 default:
return false;
3288 if (!Subtarget->hasSSE1())
3301 static const MCPhysReg GPR32ArgRegs[] = {
3302 X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
3304 static const MCPhysReg GPR64ArgRegs[] = {
3305 X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8 , X86::R9
3308 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3309 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3312 unsigned GPRIdx = 0;
3313 unsigned FPRIdx = 0;
3314 for (
auto const &Arg :
F->args()) {
3315 MVT VT = TLI.getSimpleValueType(
DL, Arg.getType());
3320 case MVT::i32: SrcReg = GPR32ArgRegs[GPRIdx++];
break;
3321 case MVT::i64: SrcReg = GPR64ArgRegs[GPRIdx++];
break;
3322 case MVT::f32: [[fallthrough]];
3323 case MVT::f64: SrcReg = XMMArgRegs[FPRIdx++];
break;
3325 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
3329 Register ResultReg = createResultReg(RC);
3330 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3331 TII.get(TargetOpcode::COPY), ResultReg)
3333 updateValueMap(&Arg, ResultReg);
3341 if (Subtarget->is64Bit())
3358bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
3359 auto &OutVals = CLI.OutVals;
3360 auto &OutFlags = CLI.OutFlags;
3361 auto &OutRegs = CLI.OutRegs;
3362 auto &Ins = CLI.Ins;
3363 auto &InRegs = CLI.InRegs;
3364 CallingConv::ID CC = CLI.CallConv;
3365 bool &IsTailCall = CLI.IsTailCall;
3366 bool IsVarArg = CLI.IsVarArg;
3369 const auto *CB = CLI.CB;
3371 bool Is64Bit = Subtarget->is64Bit();
3372 bool IsWin64 = Subtarget->isCallingConvWin64(CC);
3384 for (
Type *RetTy : RetTys) {
3385 MVT RetVT = MVT::Other;
3386 if (!isTypeLegal(RetTy, RetVT)) {
3387 if (RetVT == MVT::Other)
3392 MVT ABIVT = TLI.getRegisterTypeForCallingConv(CLI.RetTy->getContext(),
3393 CLI.CallConv, RetVT);
3394 MVT RegVT = TLI.getRegisterType(CLI.RetTy->getContext(), RetVT);
3402 if (CB && CB->doesNoCfCheck())
3406 if ((CB &&
isa<CallInst>(CB) && CB->hasFnAttr(
"no_caller_saved_registers")))
3410 if ((CB && CB->hasFnAttr(
"no_callee_saved_registers")))
3418 if (Subtarget->useIndirectThunkCalls())
3423 default:
return false;
3424 case CallingConv::C:
3425 case CallingConv::Fast:
3426 case CallingConv::Tail:
3427 case CallingConv::Swift:
3428 case CallingConv::SwiftTail:
3429 case CallingConv::X86_FastCall:
3430 case CallingConv::X86_StdCall:
3431 case CallingConv::X86_ThisCall:
3432 case CallingConv::Win64:
3433 case CallingConv::X86_64_SysV:
3434 case CallingConv::CFGuard_Check:
3444 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
3445 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
3450 if (IsVarArg && IsWin64)
3454 if (CLI.CB && CLI.CB->hasInAllocaArgument())
3457 for (
auto Flag : CLI.OutFlags)
3458 if (
Flag.isSwiftError() ||
Flag.isPreallocated())
3468 SmallVector<Register, 16> ArgRegs;
3473 for (
int i = 0, e = OutVals.size(); i != e; ++i) {
3474 Value *&Val = OutVals[i];
3475 ISD::ArgFlagsTy
Flags = OutFlags[i];
3490 if (TI && TI->getType()->isIntegerTy(1) && CLI.CB &&
3491 (TI->getParent() == CLI.CB->getParent()) && TI->hasOneUse()) {
3492 Value *PrevVal = TI->getOperand(0);
3493 ResultReg = getRegForValue(PrevVal);
3498 if (!isTypeLegal(PrevVal->
getType(), VT))
3501 ResultReg = fastEmit_ri(VT, VT,
ISD::AND, ResultReg, 1);
3505 ResultReg = getRegForValue(Val);
3518 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, CLI.RetTy->getContext());
3522 CCInfo.AllocateStack(32,
Align(8));
3524 CCInfo.AnalyzeCallOperands(OutVTs, OutFlags, ArgTys,
CC_X86);
3527 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
3530 unsigned AdjStackDown =
TII.getCallFrameSetupOpcode();
3531 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackDown))
3538 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3539 for (
const CCValAssign &VA : ArgLocs) {
3543 if (ArgVT == MVT::x86mmx)
3553 "Unexpected extend");
3555 if (ArgVT == MVT::i1)
3560 assert(Emitted &&
"Failed to emit a sext!"); (void)Emitted;
3566 "Unexpected extend");
3569 if (ArgVT == MVT::i1) {
3571 ArgReg = fastEmitZExtFromI1(MVT::i8, ArgReg);
3580 assert(Emitted &&
"Failed to emit a zext!"); (void)Emitted;
3586 "Unexpected extend");
3596 assert(Emitted &&
"Failed to emit a aext!"); (void)Emitted;
3602 assert(ArgReg &&
"Failed to emit a bitcast!");
3623 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3636 AM.
Disp = LocMemOffset;
3639 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3642 if (
Flags.isByVal()) {
3643 X86AddressMode SrcAM;
3645 if (!TryEmitSmallMemcpy(AM, SrcAM,
Flags.getByValSize()))
3651 if (!X86FastEmitStore(ArgVT, ArgVal, AM, MMO))
3654 if (!X86FastEmitStore(ArgVT, ArgReg, AM, MMO))
3662 if (Subtarget->isPICStyleGOT()) {
3663 Register Base = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3664 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3668 if (Is64Bit && IsVarArg && !IsWin64) {
3679 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3680 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3682 unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs);
3683 assert((Subtarget->hasSSE1() || !NumXMMRegs)
3684 &&
"SSE registers cannot be used when SSE is disabled");
3685 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
3686 X86::AL).
addImm(NumXMMRegs);
3691 X86AddressMode CalleeAM;
3692 if (!X86SelectCallAddress(Callee, CalleeAM))
3696 const GlobalValue *GV =
nullptr;
3697 if (CalleeAM.
GV !=
nullptr) {
3699 }
else if (CalleeAM.
Base.
Reg) {
3705 MachineInstrBuilder MIB;
3708 unsigned CallOpc = Is64Bit ? X86::CALL64r : X86::CALL32r;
3709 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc))
3713 assert(GV &&
"Not a direct call");
3715 unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV);
3727 unsigned CallOpc = NeedLoad
3728 ? (Is64Bit ? X86::CALL64m : X86::CALL32m)
3729 : (Is64Bit ?
X86::CALL64pcrel32 :
X86::CALLpcrel32);
3731 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc));
3735 MIB.
addSym(Symbol, OpFlags);
3747 if (Subtarget->isPICStyleGOT())
3748 MIB.
addReg(X86::EBX, RegState::Implicit);
3750 if (Is64Bit && IsVarArg && !IsWin64)
3751 MIB.
addReg(X86::AL, RegState::Implicit);
3754 for (
auto Reg : OutRegs)
3758 unsigned NumBytesForCalleeToPop =
3760 TM.Options.GuaranteedTailCallOpt)
3763 unsigned AdjStackUp =
TII.getCallFrameDestroyOpcode();
3764 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackUp))
3766 .
addImm(NumBytesForCalleeToPop)
3771 CCState CCRetInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs,
3772 CLI.RetTy->getContext());
3773 CCRetInfo.AnalyzeCallResult(Ins,
RetCC_X86);
3776 Register ResultReg = FuncInfo.CreateRegs(CLI.RetTy);
3777 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
3778 CCValAssign &VA = RVLocs[i];
3784 if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) &&
3785 ((Is64Bit || Ins[i].
Flags.isInReg()) && !Subtarget->hasSSE1())) {
3791 if ((SrcReg == X86::FP0 || SrcReg == X86::FP1) &&
3792 isScalarFPTypeInSSEReg(VA.
getValVT())) {
3794 CopyReg = createResultReg(&X86::RFP80RegClass);
3798 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3799 TII.get(TargetOpcode::COPY), CopyReg).
addReg(SrcReg);
3807 unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
3813 Opc = ResVT == MVT::f32 ? X86::MOVSSrm_alt : X86::MOVSDrm_alt;
3815 TII.get(
Opc), ResultReg + i), FI);
3819 CLI.ResultReg = ResultReg;
3820 CLI.NumResultRegs = RVLocs.
size();
3824 if (TM.Options.EmitCallGraphSection && CB && CB->isIndirectCall()) {
3825 MachineFunction::CallSiteInfo CSInfo(*CB);
3833X86FastISel::fastSelectInstruction(
const Instruction *
I) {
3834 switch (
I->getOpcode()) {
3836 case Instruction::Load:
3837 return X86SelectLoad(
I);
3838 case Instruction::Store:
3839 return X86SelectStore(
I);
3840 case Instruction::Ret:
3841 return X86SelectRet(
I);
3842 case Instruction::ICmp:
3843 case Instruction::FCmp:
3844 return X86SelectCmp(
I);
3845 case Instruction::ZExt:
3846 return X86SelectZExt(
I);
3847 case Instruction::SExt:
3848 return X86SelectSExt(
I);
3849 case Instruction::CondBr:
3850 return X86SelectBranch(
I);
3851 case Instruction::LShr:
3852 case Instruction::AShr:
3853 case Instruction::Shl:
3854 return X86SelectShift(
I);
3855 case Instruction::Mul:
3856 return X86SelectMul(
I);
3857 case Instruction::SDiv:
3858 case Instruction::UDiv:
3859 case Instruction::SRem:
3860 case Instruction::URem:
3861 return X86SelectDivRem(
I);
3862 case Instruction::Select:
3863 return X86SelectSelect(
I);
3864 case Instruction::Trunc:
3865 return X86SelectTrunc(
I);
3866 case Instruction::FPExt:
3867 return X86SelectFPExt(
I);
3868 case Instruction::FPTrunc:
3869 return X86SelectFPTrunc(
I);
3870 case Instruction::SIToFP:
3871 return X86SelectSIToFP(
I);
3872 case Instruction::UIToFP:
3873 return X86SelectUIToFP(
I);
3874 case Instruction::IntToPtr:
3875 case Instruction::PtrToInt: {
3876 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
3877 EVT DstVT = TLI.getValueType(
DL,
I->getType());
3879 return X86SelectZExt(
I);
3881 return X86SelectTrunc(
I);
3885 updateValueMap(
I,
Reg);
3888 case Instruction::BitCast:
3889 return X86SelectBitCast(
I);
3895Register X86FastISel::emitMOV32r0() {
3896 Register ResultReg = createResultReg(&X86::GR32RegClass);
3897 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32r0),
3903Register X86FastISel::X86MaterializeInt(
const ConstantInt *CI, MVT VT) {
3914 return fastEmitInst_extractsubreg(MVT::i8, SrcReg, X86::sub_8bit);
3916 return fastEmitInst_extractsubreg(MVT::i16, SrcReg, X86::sub_16bit);
3920 Register ResultReg = createResultReg(&X86::GR64RegClass);
3921 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3922 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3936 case MVT::i8:
Opc = X86::MOV8ri;
break;
3937 case MVT::i16:
Opc = X86::MOV16ri;
break;
3938 case MVT::i32:
Opc = X86::MOV32ri;
break;
3943 return fastEmitInst_i(
Opc, TLI.getRegClassFor(VT),
Imm);
3946Register X86FastISel::X86MaterializeFP(
const ConstantFP *CFP, MVT VT) {
3948 return fastMaterializeFloatZero(CFP);
3958 bool HasSSE1 = Subtarget->hasSSE1();
3959 bool HasSSE2 = Subtarget->hasSSE2();
3960 bool HasAVX = Subtarget->hasAVX();
3961 bool HasAVX512 = Subtarget->hasAVX512();
3966 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
3967 : HasAVX ? X86::VMOVSSrm_alt
3968 : HasSSE1 ? X86::MOVSSrm_alt
3972 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
3973 : HasAVX ? X86::VMOVSDrm_alt
3974 : HasSSE2 ? X86::MOVSDrm_alt
3987 unsigned char OpFlag = Subtarget->classifyLocalReference(
nullptr);
3989 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3991 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3996 unsigned CPI = MCP.getConstantPoolIndex(CFP, Alignment);
4001 Register AddrReg = createResultReg(&X86::GR64RegClass);
4002 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
4005 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
4006 TII.get(
Opc), ResultReg);
4007 addRegReg(MIB, AddrReg,
false, X86::NoSubRegister, PICBase,
false,
4008 X86::NoSubRegister);
4009 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
4017 TII.get(
Opc), ResultReg),
4018 CPI, PICBase, OpFlag);
4022Register X86FastISel::X86MaterializeGV(
const GlobalValue *GV, MVT VT) {
4027 if (TM.isLargeGlobalValue(GV))
4039 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
4041 TLI.getPointerTy(
DL) == MVT::i64) {
4044 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
4049 TLI.getPointerTy(
DL) == MVT::i32
4050 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
4053 TII.get(
Opc), ResultReg), AM);
4060Register X86FastISel::fastMaterializeConstant(
const Constant *
C) {
4061 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
4069 return X86MaterializeInt(CI, VT);
4071 return X86MaterializeFP(CFP, VT);
4073 return X86MaterializeGV(GV, VT);
4080 if (!Subtarget->hasSSE1())
4081 Opc = X86::LD_Fp032;
4084 if (!Subtarget->hasSSE2())
4085 Opc = X86::LD_Fp064;
4088 Opc = X86::LD_Fp080;
4093 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
4094 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
4103Register X86FastISel::fastMaterializeAlloca(
const AllocaInst *
C) {
4111 if (!FuncInfo.StaticAllocaMap.count(
C))
4113 assert(
C->isStaticAlloca() &&
"dynamic alloca in the static alloca map?");
4119 TLI.getPointerTy(
DL) == MVT::i32
4120 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
4123 Register ResultReg = createResultReg(RC);
4125 TII.get(
Opc), ResultReg), AM);
4129Register X86FastISel::fastMaterializeFloatZero(
const ConstantFP *CF) {
4131 if (!isTypeLegal(CF->
getType(), VT))
4135 bool HasSSE1 = Subtarget->hasSSE1();
4136 bool HasSSE2 = Subtarget->hasSSE2();
4137 bool HasAVX512 = Subtarget->hasAVX512();
4142 Opc = HasAVX512 ? X86::AVX512_FsFLD0SH : X86::FsFLD0SH;
4145 Opc = HasAVX512 ? X86::AVX512_FsFLD0SS
4146 : HasSSE1 ? X86::FsFLD0SS
4150 Opc = HasAVX512 ? X86::AVX512_FsFLD0SD
4151 : HasSSE2 ? X86::FsFLD0SD
4159 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
4160 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
4164bool X86FastISel::tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
4165 const LoadInst *LI) {
4171 const X86InstrInfo &XII = (
const X86InstrInfo &)
TII;
4178 MachineInstr *CopyMI =
nullptr;
4180 *FuncInfo.MF, *
MI, OpNo, AddrOps, FuncInfo.InsertPt,
Size, LI->
getAlign(),
4190 unsigned OperandNo = 0;
4192 E =
Result->operands_end();
I !=
E; ++
I, ++OperandNo) {
4193 MachineOperand &MO = *
I;
4199 if (IndexReg == MO.
getReg())
4205 FuncInfo.MF->moveAdditionalCallInfo(
MI, Result);
4206 Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
4207 Result->cloneInstrSymbols(*FuncInfo.MF, *
MI);
4209 removeDeadCode(
I, std::next(
I));
4213Register X86FastISel::fastEmitInst_rrrr(
unsigned MachineInstOpcode,
4217 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
4219 Register ResultReg = createResultReg(RC);
4225 assert(
II.getNumDefs() >= 1 &&
"instruction must define the result");
4226 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
4238 return new X86FastISel(funcInfo, libInfo, libcallLowering);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the FastISel class.
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
#define GET_EGPR_IF_ENABLED(OPC)
static unsigned X86ChooseCmpImmediateOpcode(EVT VT, const ConstantInt *RHSC)
If we have a comparison with RHS as the RHS of the comparison, return an opcode that works for the co...
static std::pair< unsigned, bool > getX86SSEConditionCode(CmpInst::Predicate Predicate)
static unsigned computeBytesPoppedByCalleeForSRet(const X86Subtarget *Subtarget, CallingConv::ID CC, const CallBase *CB)
static unsigned X86ChooseCmpOpcode(EVT VT, const X86Subtarget *Subtarget)
static bool X86SelectAddress(MachineInstr &I, const X86TargetMachine &TM, const MachineRegisterInfo &MRI, const X86Subtarget &STI, X86AddressMode &AM)
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
InstListType::const_iterator const_iterator
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
unsigned getValNo() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
This is the shared class of boolean and integer constants.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this variable.
Value * getAddress() const
DILocalVariable * getVariable() const
DIExpression * getExpression() const
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
Tracks which library functions to use for a particular subtarget or function.
Value * getPointerOperand()
Align getAlign() const
Return the alignment of the access that is being performed.
bool usesWindowsCFI() const
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
bool isVectorOf(MVT EltVT) const
Return true if this is a vector with matching element type.
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
MVT getVectorElementType() const
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setStackProtectorIndex(int I)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
void addCallSiteInfo(const MachineInstr *CallI, CallSiteInfo &&CallInfo)
Start tracking the arguments passed to the call CallI.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
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 & addMetadata(const MDNode *MD) const
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
unsigned getNumOperands() const
Retuns the total number of operands.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
LLVM_ABI void setPhysRegsDeadExcept(ArrayRef< Register > UsedRegs, const TargetRegisterInfo &TRI)
Mark every physreg used by this instruction as dead except those in the UsedRegs list.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
bool isNonTemporal() const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
Value * getLength() const
Value * getRawDest() const
unsigned getDestAddressSpace() const
Value * getRawSource() const
Return the arguments to the instruction.
unsigned getSourceAddressSpace() const
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Wrapper class representing virtual and physical registers.
void push_back(const T &Elt)
Value * getValueOperand()
Value * getPointerOperand()
TypeSize getElementOffset(unsigned Idx) const
Provides information about what library functions are available for the current target.
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
bool isOSMSVCRT() const
Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isArrayTy() const
True if this is an instance of ArrayType.
bool isStructTy() const
True if this is an instance of StructType.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
const Use * const_op_iterator
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
Fold a load or store of the specified stack slot into the specified machine instruction for the speci...
Register getSRetReturnReg() const
unsigned getBytesToPopOnReturn() const
Register getPtrSizedFrameRegister(const MachineFunction &MF) const
Register getStackRegister() const
const Triple & getTargetTriple() const
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ HiPE
Used by the High-Performance Erlang Compiler (HiPE).
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ Fast
Attempts to make calls as fast as possible (e.g.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ BasicBlock
Various leaf nodes.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ AND
Bitwise operators - logical and, logical or, logical xor.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
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_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
@ MO_PLT
MO_PLT - On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol n...
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...
@ 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...
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo, const LibcallLoweringInfo *libcallLowering)
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...
bool isCalleePop(CallingConv::ID CallingConv, bool is64Bit, bool IsVarArg, bool GuaranteeTCO)
Determines whether the callee is required to pop its own arguments.
unsigned getMOVriOpcode(bool Use64BitReg, int64_t Imm)
Return a MOVri opcode for materializing Imm into a 32- or 64-bit GPR.
unsigned getCMovOpcode(unsigned RegBytes, bool HasMemoryOperand=false, bool HasNDD=false)
Return a cmov opcode for the given register size in bytes, and operand type.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
@ User
could "use" a pointer
@ Emitted
Assigned address, still materializing.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
static bool isGlobalStubReference(unsigned char TargetFlag)
isGlobalStubReference - Return true if the specified TargetFlag operand is a reference to a stub for ...
static bool isGlobalRelativeToPICBase(unsigned char TargetFlag)
isGlobalRelativeToPICBase - Return true if the specified global value reference is relative to a 32-b...
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
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 & addRegReg(const MachineInstrBuilder &MIB, Register Reg1, bool isKill1, unsigned SubReg1, Register Reg2, bool isKill2, unsigned SubReg2)
addRegReg - This function is used to add a memory reference of the form: [Reg + Reg].
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
static const MachineInstrBuilder & addFullAddress(const MachineInstrBuilder &MIB, const X86AddressMode &AM)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI void ComputeValueTypes(const DataLayout &DL, Type *Ty, SmallVectorImpl< Type * > &Types, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
Given an LLVM IR type, compute non-aggregate subtypes.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
bool CC_X86(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool RetCC_X86(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
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...
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
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.
void getFullAddress(SmallVectorImpl< MachineOperand > &MO)
union llvm::X86AddressMode::BaseUnion Base
enum llvm::X86AddressMode::@202116273335065351270200035056227005202106004277 BaseType