36#include "llvm/IR/IntrinsicsX86.h"
47class X86FastISel final :
public FastISel {
50 const X86Subtarget *Subtarget;
53 explicit X86FastISel(FunctionLoweringInfo &funcInfo,
54 const TargetLibraryInfo *libInfo,
55 const LibcallLoweringInfo *libcallLowering)
56 : FastISel(funcInfo, libInfo, libcallLowering) {
60 bool fastSelectInstruction(
const Instruction *
I)
override;
66 bool tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
67 const LoadInst *LI)
override;
69 bool fastLowerArguments()
override;
70 bool fastLowerCall(CallLoweringInfo &CLI)
override;
71 bool fastLowerIntrinsicCall(
const IntrinsicInst *
II)
override;
73#include "X86GenFastISel.inc"
79 bool X86FastEmitLoad(MVT VT, X86AddressMode &AM, MachineMemOperand *MMO,
80 Register &ResultReg,
unsigned Alignment = 1);
82 bool X86FastEmitStore(EVT VT,
const Value *Val, X86AddressMode &AM,
83 MachineMemOperand *MMO =
nullptr,
bool Aligned =
false);
84 bool X86FastEmitStore(EVT VT,
Register ValReg, X86AddressMode &AM,
85 MachineMemOperand *MMO =
nullptr,
bool Aligned =
false);
91 bool X86SelectCallAddress(
const Value *V, X86AddressMode &AM);
93 bool X86SelectLoad(
const Instruction *
I);
95 bool X86SelectStore(
const Instruction *
I);
97 bool X86SelectRet(
const Instruction *
I);
99 bool X86SelectCmp(
const Instruction *
I);
101 bool X86SelectZExt(
const Instruction *
I);
103 bool X86SelectSExt(
const Instruction *
I);
105 bool X86SelectBranch(
const Instruction *
I);
107 bool X86SelectShift(
const Instruction *
I);
109 bool X86SelectDivRem(
const Instruction *
I);
111 bool X86FastEmitCMoveSelect(MVT RetVT,
const Instruction *
I);
113 bool X86FastEmitSSESelect(MVT RetVT,
const Instruction *
I);
115 bool X86FastEmitPseudoSelect(MVT RetVT,
const Instruction *
I);
117 bool X86SelectSelect(
const Instruction *
I);
119 bool X86SelectTrunc(
const Instruction *
I);
121 bool X86SelectFPExtOrFPTrunc(
const Instruction *
I,
unsigned Opc,
122 const TargetRegisterClass *RC);
124 bool X86SelectFPExt(
const Instruction *
I);
125 bool X86SelectFPTrunc(
const Instruction *
I);
126 bool X86SelectSIToFP(
const Instruction *
I);
127 bool X86SelectUIToFP(
const Instruction *
I);
128 bool X86SelectIntToFP(
const Instruction *
I,
bool IsSigned);
129 bool X86SelectBitCast(
const Instruction *
I);
131 const X86InstrInfo *getInstrInfo()
const {
132 return Subtarget->getInstrInfo();
134 const X86TargetMachine *getTargetMachine()
const {
135 return static_cast<const X86TargetMachine *
>(&TM);
138 bool handleConstantAddresses(
const Value *V, X86AddressMode &AM);
140 Register X86MaterializeInt(
const ConstantInt *CI, MVT VT);
141 Register X86MaterializeFP(
const ConstantFP *CFP, MVT VT);
142 Register X86MaterializeGV(
const GlobalValue *GV, MVT VT);
143 Register fastMaterializeConstant(
const Constant *
C)
override;
145 Register fastMaterializeAlloca(
const AllocaInst *
C)
override;
147 Register fastMaterializeFloatZero(
const ConstantFP *CF)
override;
151 bool isScalarFPTypeInSSEReg(EVT VT)
const {
152 return (VT == MVT::f64 && Subtarget->hasSSE2()) ||
153 (VT == MVT::f32 && Subtarget->hasSSE1()) || VT == MVT::f16;
156 bool isTypeLegal(
Type *Ty, MVT &VT,
bool AllowI1 =
false);
158 bool IsMemcpySmall(uint64_t Len);
160 bool TryEmitSmallMemcpy(X86AddressMode DestAM,
161 X86AddressMode SrcAM, uint64_t Len);
163 bool foldX86XALUIntrinsic(
X86::CondCode &CC,
const Instruction *
I,
166 const MachineInstrBuilder &
addFullAddress(
const MachineInstrBuilder &MIB,
169 Register fastEmitInst_rrrr(
unsigned MachineInstOpcode,
170 const TargetRegisterClass *RC,
Register Op0,
176static std::pair<unsigned, bool>
179 bool NeedSwap =
false;
208 return std::make_pair(CC, NeedSwap);
222 return ::addFullAddress(MIB, AM);
227bool X86FastISel::foldX86XALUIntrinsic(
X86::CondCode &CC,
const Instruction *
I,
241 if (!isTypeLegal(RetTy, RetVT))
244 if (RetVT != MVT::i32 && RetVT != MVT::i64)
248 switch (
II->getIntrinsicID()) {
249 default:
return false;
250 case Intrinsic::sadd_with_overflow:
251 case Intrinsic::ssub_with_overflow:
252 case Intrinsic::smul_with_overflow:
253 case Intrinsic::umul_with_overflow: TmpCC =
X86::COND_O;
break;
254 case Intrinsic::uadd_with_overflow:
255 case Intrinsic::usub_with_overflow: TmpCC =
X86::COND_B;
break;
259 if (
II->getParent() !=
I->getParent())
265 for (
auto Itr = std::prev(Start); Itr != End; --Itr) {
273 if (EVI->getAggregateOperand() !=
II)
279 auto HasPhis = [](
const BasicBlock *Succ) {
return !Succ->phis().empty(); };
292bool X86FastISel::isTypeLegal(
Type *Ty, MVT &VT,
bool AllowI1) {
293 EVT evt = TLI.getValueType(
DL, Ty,
true);
294 if (evt == MVT::Other || !evt.
isSimple())
301 if (VT == MVT::f64 && !Subtarget->hasSSE2())
303 if (VT == MVT::f32 && !Subtarget->hasSSE1())
312 return (AllowI1 && VT == MVT::i1) || TLI.isTypeLegal(VT);
318bool X86FastISel::X86FastEmitLoad(MVT VT, X86AddressMode &AM,
319 MachineMemOperand *MMO,
Register &ResultReg,
320 unsigned Alignment) {
321 bool HasSSE1 = Subtarget->hasSSE1();
322 bool HasSSE2 = Subtarget->hasSSE2();
323 bool HasSSE41 = Subtarget->hasSSE41();
324 bool HasAVX = Subtarget->hasAVX();
325 bool HasAVX2 = Subtarget->hasAVX2();
326 bool HasAVX512 = Subtarget->hasAVX512();
327 bool HasVLX = Subtarget->hasVLX();
337 default:
return false;
352 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
353 : HasAVX ? X86::VMOVSSrm_alt
354 : HasSSE1 ? X86::MOVSSrm_alt
358 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
359 : HasAVX ? X86::VMOVSDrm_alt
360 : HasSSE2 ? X86::MOVSDrm_alt
367 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
368 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
369 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
370 else if (Alignment >= 16)
371 Opc = HasVLX ? X86::VMOVAPSZ128rm :
372 HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm;
374 Opc = HasVLX ? X86::VMOVUPSZ128rm :
375 HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm;
378 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
379 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
380 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
381 else if (Alignment >= 16)
382 Opc = HasVLX ? X86::VMOVAPDZ128rm :
383 HasAVX ? X86::VMOVAPDrm : X86::MOVAPDrm;
385 Opc = HasVLX ? X86::VMOVUPDZ128rm :
386 HasAVX ? X86::VMOVUPDrm : X86::MOVUPDrm;
392 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
393 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
394 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
395 else if (Alignment >= 16)
396 Opc = HasVLX ? X86::VMOVDQA64Z128rm :
397 HasAVX ? X86::VMOVDQArm : X86::MOVDQArm;
399 Opc = HasVLX ? X86::VMOVDQU64Z128rm :
400 HasAVX ? X86::VMOVDQUrm : X86::MOVDQUrm;
404 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
405 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
406 else if (IsNonTemporal && Alignment >= 16)
408 else if (Alignment >= 32)
409 Opc = HasVLX ? X86::VMOVAPSZ256rm : X86::VMOVAPSYrm;
411 Opc = HasVLX ? X86::VMOVUPSZ256rm : X86::VMOVUPSYrm;
415 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
416 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
417 else if (IsNonTemporal && Alignment >= 16)
419 else if (Alignment >= 32)
420 Opc = HasVLX ? X86::VMOVAPDZ256rm : X86::VMOVAPDYrm;
422 Opc = HasVLX ? X86::VMOVUPDZ256rm : X86::VMOVUPDYrm;
429 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
430 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
431 else if (IsNonTemporal && Alignment >= 16)
433 else if (Alignment >= 32)
434 Opc = HasVLX ? X86::VMOVDQA64Z256rm : X86::VMOVDQAYrm;
436 Opc = HasVLX ? X86::VMOVDQU64Z256rm : X86::VMOVDQUYrm;
440 if (IsNonTemporal && Alignment >= 64)
441 Opc = X86::VMOVNTDQAZrm;
443 Opc = (Alignment >= 64) ? X86::VMOVAPSZrm :
X86::VMOVUPSZrm;
447 if (IsNonTemporal && Alignment >= 64)
448 Opc = X86::VMOVNTDQAZrm;
450 Opc = (Alignment >= 64) ? X86::VMOVAPDZrm :
X86::VMOVUPDZrm;
459 if (IsNonTemporal && Alignment >= 64)
460 Opc = X86::VMOVNTDQAZrm;
462 Opc = (Alignment >= 64) ? X86::VMOVDQA64Zrm :
X86::VMOVDQU64Zrm;
466 const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
468 ResultReg = createResultReg(RC);
469 MachineInstrBuilder MIB =
470 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
481bool X86FastISel::X86FastEmitStore(EVT VT,
Register ValReg, X86AddressMode &AM,
482 MachineMemOperand *MMO,
bool Aligned) {
483 bool HasSSE1 = Subtarget->hasSSE1();
484 bool HasSSE2 = Subtarget->hasSSE2();
485 bool HasSSE4A = Subtarget->hasSSE4A();
486 bool HasAVX = Subtarget->hasAVX();
487 bool HasAVX512 = Subtarget->hasAVX512();
488 bool HasVLX = Subtarget->hasVLX();
495 default:
return false;
498 Register AndResult = createResultReg(&X86::GR8RegClass);
499 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
500 TII.get(X86::AND8ri), AndResult)
505 case MVT::i8:
Opc = X86::MOV8mr;
break;
506 case MVT::i16:
Opc = X86::MOV16mr;
break;
508 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTImr :
X86::MOV32mr;
512 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTI_64mr :
X86::MOV64mr;
516 if (IsNonTemporal && HasSSE4A)
519 Opc = HasAVX512 ? X86::VMOVSSZmr :
520 HasAVX ? X86::VMOVSSmr : X86::MOVSSmr;
526 if (IsNonTemporal && HasSSE4A)
529 Opc = HasAVX512 ? X86::VMOVSDZmr :
530 HasAVX ? X86::VMOVSDmr : X86::MOVSDmr;
535 Opc = (IsNonTemporal && HasSSE1) ? X86::MMX_MOVNTQmr :
X86::MMX_MOVQ64mr;
540 Opc = HasVLX ? X86::VMOVNTPSZ128mr :
541 HasAVX ? X86::VMOVNTPSmr : X86::MOVNTPSmr;
543 Opc = HasVLX ? X86::VMOVAPSZ128mr :
544 HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr;
546 Opc = HasVLX ? X86::VMOVUPSZ128mr :
547 HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr;
552 Opc = HasVLX ? X86::VMOVNTPDZ128mr :
553 HasAVX ? X86::VMOVNTPDmr : X86::MOVNTPDmr;
555 Opc = HasVLX ? X86::VMOVAPDZ128mr :
556 HasAVX ? X86::VMOVAPDmr : X86::MOVAPDmr;
558 Opc = HasVLX ? X86::VMOVUPDZ128mr :
559 HasAVX ? X86::VMOVUPDmr : X86::MOVUPDmr;
567 Opc = HasVLX ? X86::VMOVNTDQZ128mr :
568 HasAVX ? X86::VMOVNTDQmr : X86::MOVNTDQmr;
570 Opc = HasVLX ? X86::VMOVDQA64Z128mr :
571 HasAVX ? X86::VMOVDQAmr : X86::MOVDQAmr;
573 Opc = HasVLX ? X86::VMOVDQU64Z128mr :
574 HasAVX ? X86::VMOVDQUmr : X86::MOVDQUmr;
580 Opc = HasVLX ? X86::VMOVNTPSZ256mr : X86::VMOVNTPSYmr;
582 Opc = HasVLX ? X86::VMOVAPSZ256mr : X86::VMOVAPSYmr;
584 Opc = HasVLX ? X86::VMOVUPSZ256mr : X86::VMOVUPSYmr;
590 Opc = HasVLX ? X86::VMOVNTPDZ256mr : X86::VMOVNTPDYmr;
592 Opc = HasVLX ? X86::VMOVAPDZ256mr : X86::VMOVAPDYmr;
594 Opc = HasVLX ? X86::VMOVUPDZ256mr : X86::VMOVUPDYmr;
603 Opc = HasVLX ? X86::VMOVNTDQZ256mr : X86::VMOVNTDQYmr;
605 Opc = HasVLX ? X86::VMOVDQA64Z256mr : X86::VMOVDQAYmr;
607 Opc = HasVLX ? X86::VMOVDQU64Z256mr : X86::VMOVDQUYmr;
612 Opc = IsNonTemporal ? X86::VMOVNTPSZmr : X86::VMOVAPSZmr;
614 Opc = X86::VMOVUPSZmr;
619 Opc = IsNonTemporal ? X86::VMOVNTPDZmr : X86::VMOVAPDZmr;
621 Opc = X86::VMOVUPDZmr;
631 Opc = IsNonTemporal ? X86::VMOVNTDQZmr : X86::VMOVDQA64Zmr;
633 Opc = X86::VMOVDQU64Zmr;
645 MachineInstrBuilder MIB =
646 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
Desc);
654bool X86FastISel::X86FastEmitStore(EVT VT,
const Value *Val,
656 MachineMemOperand *MMO,
bool Aligned) {
670 case MVT::i8:
Opc = X86::MOV8mi;
break;
671 case MVT::i16:
Opc = X86::MOV16mi;
break;
672 case MVT::i32:
Opc = X86::MOV32mi;
break;
676 Opc = X86::MOV64mi32;
681 MachineInstrBuilder MIB =
682 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc));
684 : CI->getZExtValue());
691 Register ValReg = getRegForValue(Val);
695 return X86FastEmitStore(VT, ValReg, AM, MMO,
Aligned);
711bool X86FastISel::handleConstantAddresses(
const Value *V, X86AddressMode &AM) {
720 if (TM.isLargeGlobalValue(GV))
724 if (GV->isThreadLocal())
728 if (GV->isAbsoluteSymbolRef())
734 if (!Subtarget->isPICStyleRIPRel() ||
740 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
745 AM.
Base.
Reg = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
751 if (Subtarget->isPICStyleRIPRel()) {
763 DenseMap<const Value *, Register>::iterator
I = LocalValueMap.find(V);
765 if (
I != LocalValueMap.end() &&
I->second) {
770 const TargetRegisterClass *RC =
nullptr;
771 X86AddressMode StubAM;
777 SavePoint SaveInsertPt = enterLocalValueArea();
779 if (TLI.getPointerTy(
DL) == MVT::i64) {
781 RC = &X86::GR64RegClass;
784 RC = &X86::GR32RegClass;
791 LoadReg = createResultReg(RC);
792 MachineInstrBuilder LoadMI =
793 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), LoadReg);
797 leaveLocalValueArea(SaveInsertPt);
800 LocalValueMap[
V] = LoadReg;
812 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
814 AM.
Base.
Reg = getRegForValue(V);
829bool X86FastISel::X86SelectAddress(
const Value *V, X86AddressMode &AM) {
832 const User *
U =
nullptr;
833 unsigned Opcode = Instruction::UserOp1;
838 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(V)) ||
839 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
840 Opcode =
I->getOpcode();
844 Opcode =
C->getOpcode();
849 if (Ty->getAddressSpace() > 255)
856 case Instruction::BitCast:
860 case Instruction::IntToPtr:
862 if (TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
863 TLI.getPointerTy(
DL))
867 case Instruction::PtrToInt:
869 if (TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
873 case Instruction::Alloca: {
876 DenseMap<const AllocaInst *, int>::iterator
SI =
877 FuncInfo.StaticAllocaMap.find(
A);
878 if (SI != FuncInfo.StaticAllocaMap.end()) {
886 case Instruction::Add: {
889 uint64_t Disp = (int32_t)AM.
Disp + (uint64_t)CI->getSExtValue();
892 AM.
Disp = (uint32_t)Disp;
899 case Instruction::GetElementPtr: {
900 X86AddressMode SavedAM = AM;
903 uint64_t Disp = (int32_t)AM.
Disp;
905 unsigned Scale = AM.
Scale;
906 MVT PtrVT = TLI.getValueType(
DL,
U->getType()).getSimpleVT();
912 i != e; ++i, ++GTI) {
915 const StructLayout *SL =
DL.getStructLayout(STy);
926 Disp += CI->getSExtValue() * S;
929 if (canFoldAddIntoGEP(U,
Op)) {
938 if (!IndexReg && (!AM.
GV || !Subtarget->isPICStyleRIPRel()) &&
939 (S == 1 || S == 2 || S == 4 || S == 8)) {
942 IndexReg = getRegForGEPIndex(PtrVT,
Op);
948 goto unsupported_gep;
958 AM.
Disp = (uint32_t)Disp;
961 if (
const GetElementPtrInst *
GEP =
976 if (handleConstantAddresses(
I, AM))
986 return handleConstantAddresses(V, AM);
991bool X86FastISel::X86SelectCallAddress(
const Value *V, X86AddressMode &AM) {
992 const User *
U =
nullptr;
993 unsigned Opcode = Instruction::UserOp1;
1020 Opcode =
I->getOpcode();
1022 InMBB =
I->getParent() == FuncInfo.MBB->getBasicBlock();
1024 Opcode =
C->getOpcode();
1030 case Instruction::BitCast:
1033 return X86SelectCallAddress(
U->getOperand(0), AM);
1036 case Instruction::IntToPtr:
1039 TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
1040 TLI.getPointerTy(
DL))
1041 return X86SelectCallAddress(
U->getOperand(0), AM);
1044 case Instruction::PtrToInt:
1046 if (InMBB && TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
1047 return X86SelectCallAddress(
U->getOperand(0), AM);
1059 if (Subtarget->isPICStyleRIPRel() &&
1065 if (GVar->isThreadLocal())
1074 if (Subtarget->isPICStyleRIPRel()) {
1080 AM.
GVOpFlags = Subtarget->classifyLocalReference(
nullptr);
1087 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
1088 auto GetCallRegForValue = [
this](
const Value *
V) {
1092 if (
Reg && Subtarget->isTarget64BitILP32()) {
1093 Register CopyReg = createResultReg(&X86::GR32RegClass);
1094 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32rr),
1098 Register ExtReg = createResultReg(&X86::GR64RegClass);
1099 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1100 TII.get(TargetOpcode::SUBREG_TO_REG), ExtReg)
1111 AM.
Base.
Reg = GetCallRegForValue(V);
1116 AM.
IndexReg = GetCallRegForValue(V);
1126bool X86FastISel::X86SelectStore(
const Instruction *
I) {
1133 const Value *PtrV =
I->getOperand(1);
1134 if (TLI.supportSwiftError()) {
1138 if (Arg->hasSwiftErrorAttr())
1143 if (Alloca->isSwiftError())
1152 if (!isTypeLegal(Val->
getType(), VT,
true))
1157 bool Aligned = Alignment >= ABIAlignment;
1163 return X86FastEmitStore(VT, Val, AM, createMachineMemOperandFor(
I),
Aligned);
1167bool X86FastISel::X86SelectRet(
const Instruction *
I) {
1169 const Function &
F = *
I->getParent()->getParent();
1170 const X86MachineFunctionInfo *X86MFInfo =
1171 FuncInfo.MF->getInfo<X86MachineFunctionInfo>();
1173 if (!FuncInfo.CanLowerReturn)
1176 if (TLI.supportSwiftError() &&
1177 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
1180 if (TLI.supportSplitCSR(FuncInfo.MF))
1183 CallingConv::ID CC =
F.getCallingConv();
1184 if (CC != CallingConv::C &&
1185 CC != CallingConv::Fast &&
1186 CC != CallingConv::Tail &&
1187 CC != CallingConv::SwiftTail &&
1188 CC != CallingConv::X86_FastCall &&
1189 CC != CallingConv::X86_StdCall &&
1190 CC != CallingConv::X86_ThisCall &&
1191 CC != CallingConv::X86_64_SysV &&
1192 CC != CallingConv::Win64)
1201 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
1202 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
1218 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
I->getContext());
1227 if (ValLocs.
size() != 1)
1230 CCValAssign &VA = ValLocs[0];
1245 EVT SrcVT = TLI.getValueType(
DL, RV->
getType());
1248 if (SrcVT != DstVT) {
1249 if (SrcVT != MVT::i1 && SrcVT != MVT::i8 && SrcVT != MVT::i16)
1252 if (!Outs[0].
Flags.isZExt() && !Outs[0].Flags.isSExt())
1255 if (SrcVT == MVT::i1) {
1256 if (Outs[0].
Flags.isSExt())
1258 SrcReg = fastEmitZExtFromI1(MVT::i8, SrcReg);
1261 if (SrcVT != DstVT) {
1271 const TargetRegisterClass *SrcRC =
MRI.getRegClass(SrcReg);
1275 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1276 TII.get(TargetOpcode::COPY), DstReg).
addReg(SrcReg);
1289 if (
F.hasStructRetAttr() && CC != CallingConv::Swift &&
1290 CC != CallingConv::SwiftTail) {
1293 "SRetReturnReg should have been set in LowerFormalArguments()!");
1294 Register RetReg = Subtarget->isTarget64BitLP64() ? X86::RAX : X86::EAX;
1295 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1301 MachineInstrBuilder MIB;
1303 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1304 TII.get(Subtarget->is64Bit() ? X86::RETI64 : X86::RETI32))
1307 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1308 TII.get(Subtarget->is64Bit() ? X86::RET64 : X86::RET32));
1317bool X86FastISel::X86SelectLoad(
const Instruction *
I) {
1324 const Value *SV =
I->getOperand(0);
1325 if (TLI.supportSwiftError()) {
1329 if (Arg->hasSwiftErrorAttr())
1334 if (Alloca->isSwiftError())
1340 if (!isTypeLegal(LI->
getType(), VT,
true))
1350 if (!X86FastEmitLoad(VT, AM, createMachineMemOperandFor(LI), ResultReg,
1354 updateValueMap(
I, ResultReg);
1359 bool HasAVX512 = Subtarget->
hasAVX512();
1360 bool HasAVX = Subtarget->
hasAVX();
1361 bool HasSSE1 = Subtarget->
hasSSE1();
1362 bool HasSSE2 = Subtarget->
hasSSE2();
1366 case MVT::i8:
return X86::CMP8rr;
1367 case MVT::i16:
return X86::CMP16rr;
1368 case MVT::i32:
return X86::CMP32rr;
1369 case MVT::i64:
return X86::CMP64rr;
1371 return HasAVX512 ? X86::VUCOMISSZrr
1372 : HasAVX ? X86::VUCOMISSrr
1373 : HasSSE1 ? X86::UCOMISSrr
1376 return HasAVX512 ? X86::VUCOMISDZrr
1377 : HasAVX ? X86::VUCOMISDrr
1378 : HasSSE2 ? X86::UCOMISDrr
1393 return X86::CMP16ri;
1395 return X86::CMP32ri;
1403bool X86FastISel::X86FastEmitCompare(
const Value *Op0,
const Value *Op1, EVT VT,
1405 Register Op0Reg = getRegForValue(Op0);
1418 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareImmOpc))
1420 .
addImm(Op1C->getSExtValue());
1426 if (CompareOpc == 0)
return false;
1428 Register Op1Reg = getRegForValue(Op1);
1431 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareOpc))
1439 ((!Subtarget->hasZU() || Subtarget->preferLegacySetCC()) ? X86::SETCCr \
1446 if (!isTypeLegal(
I->getOperand(0)->getType(), VT))
1459 ResultReg = createResultReg(&X86::GR32RegClass);
1460 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32r0),
1462 ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultReg, X86::sub_8bit);
1468 ResultReg = createResultReg(&X86::GR8RegClass);
1469 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
1476 updateValueMap(
I, ResultReg);
1488 if (RHSC && RHSC->isNullValue())
1493 static const uint16_t SETFOpcTable[2][3] = {
1504 ResultReg = createResultReg(&X86::GR8RegClass);
1506 if (!X86FastEmitCompare(
LHS,
RHS, VT,
I->getDebugLoc()))
1509 Register FlagReg1 = createResultReg(&X86::GR8RegClass);
1510 Register FlagReg2 = createResultReg(&X86::GR8RegClass);
1517 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(SETFOpc[2]),
1519 updateValueMap(
I, ResultReg);
1532 if (!X86FastEmitCompare(
LHS,
RHS, VT,
I->getDebugLoc()))
1537 updateValueMap(
I, ResultReg);
1541bool X86FastISel::X86SelectZExt(
const Instruction *
I) {
1542 EVT DstVT = TLI.getValueType(
DL,
I->getType());
1543 if (!TLI.isTypeLegal(DstVT))
1546 Register ResultReg = getRegForValue(
I->getOperand(0));
1551 MVT SrcVT = TLI.getSimpleValueType(
DL,
I->getOperand(0)->getType());
1552 if (SrcVT == MVT::i1) {
1554 ResultReg = fastEmitZExtFromI1(MVT::i8, ResultReg);
1561 if (DstVT == MVT::i64) {
1566 case MVT::i8: MovInst = X86::MOVZX32rr8;
break;
1567 case MVT::i16: MovInst = X86::MOVZX32rr16;
break;
1568 case MVT::i32: MovInst = X86::MOV32rr;
break;
1572 Register Result32 = createResultReg(&X86::GR32RegClass);
1573 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(MovInst), Result32)
1576 ResultReg = createResultReg(&X86::GR64RegClass);
1577 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::SUBREG_TO_REG),
1580 }
else if (DstVT == MVT::i16) {
1583 Register Result32 = createResultReg(&X86::GR32RegClass);
1584 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVZX32rr8),
1585 Result32).
addReg(ResultReg);
1587 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1588 }
else if (DstVT != MVT::i8) {
1595 updateValueMap(
I, ResultReg);
1599bool X86FastISel::X86SelectSExt(
const Instruction *
I) {
1600 EVT DstVT = TLI.getValueType(
DL,
I->getType());
1601 if (!TLI.isTypeLegal(DstVT))
1604 Register ResultReg = getRegForValue(
I->getOperand(0));
1609 MVT SrcVT = TLI.getSimpleValueType(
DL,
I->getOperand(0)->getType());
1610 if (SrcVT == MVT::i1) {
1612 Register ZExtReg = fastEmitZExtFromI1(MVT::i8, ResultReg);
1617 ResultReg = createResultReg(&X86::GR8RegClass);
1618 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::NEG8r),
1619 ResultReg).
addReg(ZExtReg);
1624 if (DstVT == MVT::i16) {
1627 Register Result32 = createResultReg(&X86::GR32RegClass);
1628 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVSX32rr8),
1629 Result32).
addReg(ResultReg);
1631 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1632 }
else if (DstVT != MVT::i8) {
1639 updateValueMap(
I, ResultReg);
1643bool X86FastISel::X86SelectBranch(
const Instruction *
I) {
1647 MachineBasicBlock *TrueMBB = FuncInfo.getMBB(BI->
getSuccessor(0));
1648 MachineBasicBlock *FalseMBB = FuncInfo.getMBB(BI->
getSuccessor(1));
1655 if (CI->
hasOneUse() && CI->getParent() ==
I->getParent()) {
1660 switch (Predicate) {
1675 if (CmpRHSC && CmpRHSC->isNullValue())
1680 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1690 bool NeedExtraBranch =
false;
1691 switch (Predicate) {
1697 NeedExtraBranch =
true;
1710 if (!X86FastEmitCompare(CmpLHS, CmpRHS, VT, CI->getDebugLoc()))
1713 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1718 if (NeedExtraBranch) {
1719 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1723 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1730 if (TI->hasOneUse() && TI->getParent() ==
I->getParent() &&
1731 isTypeLegal(TI->getOperand(0)->getType(), SourceVT)) {
1732 unsigned TestOpc = 0;
1735 case MVT::i8: TestOpc = X86::TEST8ri;
break;
1736 case MVT::i16: TestOpc = X86::TEST16ri;
break;
1737 case MVT::i32: TestOpc = X86::TEST32ri;
break;
1738 case MVT::i64: TestOpc = X86::TEST64ri32;
break;
1741 Register OpReg = getRegForValue(TI->getOperand(0));
1745 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TestOpc))
1749 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1754 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1757 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1761 }
else if (foldX86XALUIntrinsic(CC, BI, BI->
getCondition())) {
1768 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1770 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1782 if (
MRI.getRegClass(OpReg) == &X86::VK1RegClass) {
1784 OpReg = createResultReg(&X86::GR32RegClass);
1785 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1786 TII.get(TargetOpcode::COPY), OpReg)
1788 OpReg = fastEmitInst_extractsubreg(MVT::i8, OpReg, X86::sub_8bit);
1790 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
1793 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1795 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1799bool X86FastISel::X86SelectShift(
const Instruction *
I) {
1802 const TargetRegisterClass *RC =
nullptr;
1803 if (
I->getType()->isIntegerTy(8)) {
1805 RC = &X86::GR8RegClass;
1806 switch (
I->getOpcode()) {
1807 case Instruction::LShr: OpReg = X86::SHR8rCL;
break;
1808 case Instruction::AShr: OpReg = X86::SAR8rCL;
break;
1809 case Instruction::Shl: OpReg = X86::SHL8rCL;
break;
1810 default:
return false;
1812 }
else if (
I->getType()->isIntegerTy(16)) {
1814 RC = &X86::GR16RegClass;
1815 switch (
I->getOpcode()) {
1817 case Instruction::LShr: OpReg = X86::SHR16rCL;
break;
1818 case Instruction::AShr: OpReg = X86::SAR16rCL;
break;
1819 case Instruction::Shl: OpReg = X86::SHL16rCL;
break;
1821 }
else if (
I->getType()->isIntegerTy(32)) {
1823 RC = &X86::GR32RegClass;
1824 switch (
I->getOpcode()) {
1826 case Instruction::LShr: OpReg = X86::SHR32rCL;
break;
1827 case Instruction::AShr: OpReg = X86::SAR32rCL;
break;
1828 case Instruction::Shl: OpReg = X86::SHL32rCL;
break;
1830 }
else if (
I->getType()->isIntegerTy(64)) {
1832 RC = &X86::GR64RegClass;
1833 switch (
I->getOpcode()) {
1835 case Instruction::LShr: OpReg = X86::SHR64rCL;
break;
1836 case Instruction::AShr: OpReg = X86::SAR64rCL;
break;
1837 case Instruction::Shl: OpReg = X86::SHL64rCL;
break;
1844 if (!isTypeLegal(
I->getType(), VT))
1847 Register Op0Reg = getRegForValue(
I->getOperand(0));
1851 Register Op1Reg = getRegForValue(
I->getOperand(1));
1854 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
1859 if (CReg != X86::CL)
1860 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1861 TII.get(TargetOpcode::KILL), X86::CL)
1864 Register ResultReg = createResultReg(RC);
1865 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(OpReg), ResultReg)
1867 updateValueMap(
I, ResultReg);
1871bool X86FastISel::X86SelectDivRem(
const Instruction *
I) {
1872 const static unsigned NumTypes = 4;
1873 const static unsigned NumOps = 4;
1874 const static bool S =
true;
1875 const static bool U =
false;
1876 const static unsigned Copy = TargetOpcode::COPY;
1886 const static struct DivRemEntry {
1888 const TargetRegisterClass *RC;
1892 struct DivRemResult {
1894 unsigned OpSignExtend;
1898 unsigned DivRemResultReg;
1901 } OpTable[NumTypes] = {
1902 { &X86::GR8RegClass, X86::AX, 0, {
1903 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S },
1904 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S },
1905 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U },
1906 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U },
1909 { &X86::GR16RegClass, X86::AX, X86::DX, {
1910 { X86::IDIV16r, X86::CWD,
Copy, X86::AX, S },
1911 { X86::IDIV16r, X86::CWD,
Copy, X86::DX, S },
1912 { X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U },
1913 { X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U },
1916 { &X86::GR32RegClass, X86::EAX, X86::EDX, {
1917 { X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S },
1918 { X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S },
1919 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U },
1920 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U },
1923 { &X86::GR64RegClass, X86::RAX, X86::RDX, {
1924 { X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S },
1925 { X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S },
1926 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U },
1927 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U },
1933 if (!isTypeLegal(
I->getType(), VT))
1938 default:
return false;
1939 case MVT::i8: TypeIndex = 0;
break;
1940 case MVT::i16: TypeIndex = 1;
break;
1941 case MVT::i32: TypeIndex = 2;
break;
1942 case MVT::i64: TypeIndex = 3;
1943 if (!Subtarget->is64Bit())
1948 switch (
I->getOpcode()) {
1950 case Instruction::SDiv:
OpIndex = 0;
break;
1951 case Instruction::SRem:
OpIndex = 1;
break;
1952 case Instruction::UDiv:
OpIndex = 2;
break;
1953 case Instruction::URem:
OpIndex = 3;
break;
1956 const DivRemEntry &
TypeEntry = OpTable[TypeIndex];
1958 Register Op0Reg = getRegForValue(
I->getOperand(0));
1961 Register Op1Reg = getRegForValue(
I->getOperand(1));
1966 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1969 if (OpEntry.OpSignExtend) {
1970 if (OpEntry.IsOpSigned)
1971 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1972 TII.get(OpEntry.OpSignExtend));
1974 Register Zero32 = createResultReg(&X86::GR32RegClass);
1975 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1976 TII.get(X86::MOV32r0), Zero32);
1981 if (VT == MVT::i16) {
1982 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1984 .
addReg(Zero32, 0, X86::sub_16bit);
1985 }
else if (VT == MVT::i32) {
1986 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1989 }
else if (VT == MVT::i64) {
1990 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1991 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
1997 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1998 TII.get(OpEntry.OpDivRem)).
addReg(Op1Reg);
2008 if ((
I->getOpcode() == Instruction::SRem ||
2009 I->getOpcode() == Instruction::URem) &&
2010 OpEntry.DivRemResultReg == X86::AH && Subtarget->is64Bit()) {
2011 Register SourceSuperReg = createResultReg(&X86::GR16RegClass);
2012 Register ResultSuperReg = createResultReg(&X86::GR16RegClass);
2013 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2014 TII.get(Copy), SourceSuperReg).
addReg(X86::AX);
2017 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SHR16ri),
2021 ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultSuperReg,
2026 ResultReg = createResultReg(
TypeEntry.RC);
2027 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Copy), ResultReg)
2028 .
addReg(OpEntry.DivRemResultReg);
2030 updateValueMap(
I, ResultReg);
2037bool X86FastISel::X86FastEmitCMoveSelect(MVT RetVT,
const Instruction *
I) {
2039 if (!Subtarget->canUseCMOV())
2043 if (RetVT < MVT::i16 || RetVT > MVT::i64)
2047 const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
2048 bool NeedTest =
true;
2055 if (CI && (CI->getParent() ==
I->getParent())) {
2059 static const uint16_t SETFOpcTable[2][3] = {
2063 const uint16_t *SETFOpc =
nullptr;
2064 switch (Predicate) {
2067 SETFOpc = &SETFOpcTable[0][0];
2071 SETFOpc = &SETFOpcTable[1][0];
2085 EVT CmpVT = TLI.getValueType(
DL, CmpLHS->
getType());
2087 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
2091 Register FlagReg1 = createResultReg(&X86::GR8RegClass);
2092 Register FlagReg2 = createResultReg(&X86::GR8RegClass);
2099 auto const &
II =
TII.get(SETFOpc[2]);
2100 if (
II.getNumDefs()) {
2101 Register TmpReg = createResultReg(&X86::GR8RegClass);
2102 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, TmpReg)
2105 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
2110 }
else if (foldX86XALUIntrinsic(CC,
I,
Cond)) {
2131 if (
MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2133 CondReg = createResultReg(&X86::GR32RegClass);
2134 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2135 TII.get(TargetOpcode::COPY), CondReg)
2137 CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, X86::sub_8bit);
2139 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
2149 if (!LHSReg || !RHSReg)
2152 const TargetRegisterInfo &
TRI = *Subtarget->getRegisterInfo();
2154 Subtarget->hasNDD());
2155 Register ResultReg = fastEmitInst_rri(
Opc, RC, RHSReg, LHSReg, CC);
2156 updateValueMap(
I, ResultReg);
2165bool X86FastISel::X86FastEmitSSESelect(MVT RetVT,
const Instruction *
I) {
2170 if (!CI || (CI->getParent() !=
I->getParent()))
2174 !((Subtarget->hasSSE1() && RetVT == MVT::f32) ||
2175 (Subtarget->hasSSE2() && RetVT == MVT::f64)))
2187 if (CmpRHSC && CmpRHSC->isNullValue())
2194 if (CC > 7 && !Subtarget->hasAVX())
2205 Register CmpLHSReg = getRegForValue(CmpLHS);
2206 Register CmpRHSReg = getRegForValue(CmpRHS);
2207 if (!LHSReg || !RHSReg || !CmpLHSReg || !CmpRHSReg)
2210 const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
2213 if (Subtarget->hasAVX512()) {
2215 const TargetRegisterClass *VR128X = &X86::VR128XRegClass;
2216 const TargetRegisterClass *VK1 = &X86::VK1RegClass;
2218 unsigned CmpOpcode =
2219 (RetVT == MVT::f32) ? X86::VCMPSSZrri :
X86::VCMPSDZrri;
2220 Register CmpReg = fastEmitInst_rri(CmpOpcode, VK1, CmpLHSReg, CmpRHSReg,
2225 Register ImplicitDefReg = createResultReg(VR128X);
2226 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2227 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2231 unsigned MovOpcode =
2232 (RetVT == MVT::f32) ? X86::VMOVSSZrrk :
X86::VMOVSDZrrk;
2233 Register MovReg = fastEmitInst_rrrr(MovOpcode, VR128X, RHSReg, CmpReg,
2234 ImplicitDefReg, LHSReg);
2236 ResultReg = createResultReg(RC);
2237 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2238 TII.get(TargetOpcode::COPY), ResultReg).
addReg(MovReg);
2240 }
else if (Subtarget->hasAVX()) {
2241 const TargetRegisterClass *VR128 = &X86::VR128RegClass;
2248 unsigned CmpOpcode =
2249 (RetVT == MVT::f32) ? X86::VCMPSSrri :
X86::VCMPSDrri;
2250 unsigned BlendOpcode =
2251 (RetVT == MVT::f32) ? X86::VBLENDVPSrrr :
X86::VBLENDVPDrrr;
2253 Register CmpReg = fastEmitInst_rri(CmpOpcode, RC, CmpLHSReg, CmpRHSReg,
2255 Register VBlendReg = fastEmitInst_rrr(BlendOpcode, VR128, RHSReg, LHSReg,
2257 ResultReg = createResultReg(RC);
2258 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2259 TII.get(TargetOpcode::COPY), ResultReg).
addReg(VBlendReg);
2262 static const uint16_t OpcTable[2][4] = {
2263 { X86::CMPSSrri, X86::ANDPSrr, X86::ANDNPSrr, X86::ORPSrr },
2264 { X86::CMPSDrri, X86::ANDPDrr, X86::ANDNPDrr, X86::ORPDrr }
2267 const uint16_t *
Opc =
nullptr;
2269 default:
return false;
2270 case MVT::f32:
Opc = &OpcTable[0][0];
break;
2271 case MVT::f64:
Opc = &OpcTable[1][0];
break;
2274 const TargetRegisterClass *VR128 = &X86::VR128RegClass;
2275 Register CmpReg = fastEmitInst_rri(
Opc[0], RC, CmpLHSReg, CmpRHSReg, CC);
2276 Register AndReg = fastEmitInst_rr(
Opc[1], VR128, CmpReg, LHSReg);
2277 Register AndNReg = fastEmitInst_rr(
Opc[2], VR128, CmpReg, RHSReg);
2278 Register OrReg = fastEmitInst_rr(
Opc[3], VR128, AndNReg, AndReg);
2279 ResultReg = createResultReg(RC);
2280 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2281 TII.get(TargetOpcode::COPY), ResultReg).
addReg(OrReg);
2283 updateValueMap(
I, ResultReg);
2287bool X86FastISel::X86FastEmitPseudoSelect(MVT RetVT,
const Instruction *
I) {
2292 default:
return false;
2293 case MVT::i8:
Opc = X86::CMOV_GR8;
break;
2294 case MVT::i16:
Opc = X86::CMOV_GR16;
break;
2295 case MVT::i32:
Opc = X86::CMOV_GR32;
break;
2297 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR16X : X86::CMOV_FR16;
break;
2299 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR32X : X86::CMOV_FR32;
break;
2301 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR64X : X86::CMOV_FR64;
break;
2311 if (CI && (CI->getParent() ==
I->getParent())) {
2323 EVT CmpVT = TLI.getValueType(
DL, CmpLHS->
getType());
2324 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
2332 if (
MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2334 CondReg = createResultReg(&X86::GR32RegClass);
2335 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2336 TII.get(TargetOpcode::COPY), CondReg)
2338 CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, X86::sub_8bit);
2340 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
2350 if (!LHSReg || !RHSReg)
2353 const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
2356 fastEmitInst_rri(
Opc, RC, RHSReg, LHSReg, CC);
2357 updateValueMap(
I, ResultReg);
2361bool X86FastISel::X86SelectSelect(
const Instruction *
I) {
2363 if (!isTypeLegal(
I->getType(), RetVT))
2369 const Value *Opnd =
nullptr;
2370 switch (Predicate) {
2377 Register OpReg = getRegForValue(Opnd);
2380 const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
2381 Register ResultReg = createResultReg(RC);
2382 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2383 TII.get(TargetOpcode::COPY), ResultReg)
2385 updateValueMap(
I, ResultReg);
2391 if (X86FastEmitCMoveSelect(RetVT,
I))
2395 if (X86FastEmitSSESelect(RetVT,
I))
2400 if (X86FastEmitPseudoSelect(RetVT,
I))
2407bool X86FastISel::X86SelectIntToFP(
const Instruction *
I,
bool IsSigned) {
2412 bool HasAVX512 = Subtarget->hasAVX512();
2413 if (!Subtarget->hasAVX() || (!IsSigned && !HasAVX512))
2417 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
2418 if (SrcVT != MVT::i32 && SrcVT != MVT::i64)
2422 Register OpReg = getRegForValue(
I->getOperand(0));
2428 static const uint16_t SCvtOpc[2][2][2] = {
2429 { { X86::VCVTSI2SSrr, X86::VCVTSI642SSrr },
2430 { X86::VCVTSI2SDrr, X86::VCVTSI642SDrr } },
2431 { { X86::VCVTSI2SSZrr, X86::VCVTSI642SSZrr },
2432 { X86::VCVTSI2SDZrr, X86::VCVTSI642SDZrr } },
2434 static const uint16_t UCvtOpc[2][2] = {
2435 { X86::VCVTUSI2SSZrr, X86::VCVTUSI642SSZrr },
2436 { X86::VCVTUSI2SDZrr, X86::VCVTUSI642SDZrr },
2438 bool Is64Bit = SrcVT == MVT::i64;
2440 if (
I->getType()->isDoubleTy()) {
2442 Opcode = IsSigned ? SCvtOpc[HasAVX512][1][Is64Bit] : UCvtOpc[1][Is64Bit];
2443 }
else if (
I->getType()->isFloatTy()) {
2445 Opcode = IsSigned ? SCvtOpc[HasAVX512][0][Is64Bit] : UCvtOpc[0][Is64Bit];
2450 const TargetRegisterClass *RC = TLI.getRegClassFor(DstVT);
2451 Register ImplicitDefReg = createResultReg(RC);
2452 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2453 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2454 Register ResultReg = fastEmitInst_rr(Opcode, RC, ImplicitDefReg, OpReg);
2455 updateValueMap(
I, ResultReg);
2459bool X86FastISel::X86SelectSIToFP(
const Instruction *
I) {
2460 return X86SelectIntToFP(
I,
true);
2463bool X86FastISel::X86SelectUIToFP(
const Instruction *
I) {
2464 return X86SelectIntToFP(
I,
false);
2468bool X86FastISel::X86SelectFPExtOrFPTrunc(
const Instruction *
I,
2470 const TargetRegisterClass *RC) {
2471 assert((
I->getOpcode() == Instruction::FPExt ||
2472 I->getOpcode() == Instruction::FPTrunc) &&
2473 "Instruction must be an FPExt or FPTrunc!");
2474 bool HasAVX = Subtarget->hasAVX();
2476 Register OpReg = getRegForValue(
I->getOperand(0));
2482 ImplicitDefReg = createResultReg(RC);
2483 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2484 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2488 Register ResultReg = createResultReg(RC);
2489 MachineInstrBuilder MIB;
2490 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpc),
2494 MIB.
addReg(ImplicitDefReg);
2497 updateValueMap(
I, ResultReg);
2501bool X86FastISel::X86SelectFPExt(
const Instruction *
I) {
2502 if (Subtarget->hasSSE2() &&
I->getType()->isDoubleTy() &&
2503 I->getOperand(0)->getType()->isFloatTy()) {
2504 bool HasAVX512 = Subtarget->hasAVX512();
2507 HasAVX512 ? X86::VCVTSS2SDZrr
2508 : Subtarget->hasAVX() ? X86::VCVTSS2SDrr : X86::CVTSS2SDrr;
2509 return X86SelectFPExtOrFPTrunc(
I,
Opc, TLI.getRegClassFor(MVT::f64));
2515bool X86FastISel::X86SelectFPTrunc(
const Instruction *
I) {
2516 if (Subtarget->hasSSE2() &&
I->getType()->isFloatTy() &&
2517 I->getOperand(0)->getType()->isDoubleTy()) {
2518 bool HasAVX512 = Subtarget->hasAVX512();
2521 HasAVX512 ? X86::VCVTSD2SSZrr
2522 : Subtarget->hasAVX() ? X86::VCVTSD2SSrr : X86::CVTSD2SSrr;
2523 return X86SelectFPExtOrFPTrunc(
I,
Opc, TLI.getRegClassFor(MVT::f32));
2529bool X86FastISel::X86SelectTrunc(
const Instruction *
I) {
2530 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
2531 EVT DstVT = TLI.getValueType(
DL,
I->getType());
2534 if (DstVT != MVT::i8 && DstVT != MVT::i1)
2536 if (!TLI.isTypeLegal(SrcVT))
2539 Register InputReg = getRegForValue(
I->getOperand(0));
2544 if (SrcVT == MVT::i8) {
2546 updateValueMap(
I, InputReg);
2551 Register ResultReg = fastEmitInst_extractsubreg(MVT::i8, InputReg,
2556 updateValueMap(
I, ResultReg);
2560bool X86FastISel::X86SelectBitCast(
const Instruction *
I) {
2563 if (!Subtarget->hasSSE2() ||
2564 !isTypeLegal(
I->getOperand(0)->getType(), SrcVT) ||
2565 !isTypeLegal(
I->getType(), DstVT))
2580 const TargetRegisterClass *DstClass = TLI.getRegClassFor(DstVT);
2581 Register ResultReg = createResultReg(DstClass);
2582 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
2586 updateValueMap(
I, ResultReg);
2590bool X86FastISel::IsMemcpySmall(uint64_t Len) {
2591 return Len <= (Subtarget->is64Bit() ? 32 : 16);
2594bool X86FastISel::TryEmitSmallMemcpy(X86AddressMode DestAM,
2595 X86AddressMode SrcAM, uint64_t Len) {
2598 if (!IsMemcpySmall(Len))
2601 bool i64Legal = Subtarget->is64Bit();
2606 if (Len >= 8 && i64Legal)
2616 bool RV = X86FastEmitLoad(VT, SrcAM,
nullptr,
Reg);
2617 RV &= X86FastEmitStore(VT,
Reg, DestAM);
2618 assert(RV &&
"Failed to emit load or store??");
2630bool X86FastISel::fastLowerIntrinsicCall(
const IntrinsicInst *
II) {
2632 switch (
II->getIntrinsicID()) {
2633 default:
return false;
2634 case Intrinsic::convert_from_fp16:
2635 case Intrinsic::convert_to_fp16: {
2636 if (Subtarget->useSoftFloat() || !Subtarget->hasF16C())
2645 bool IsFloatToHalf =
II->getIntrinsicID() == Intrinsic::convert_to_fp16;
2646 if (IsFloatToHalf) {
2647 if (!
Op->getType()->isFloatTy())
2650 if (!
II->getType()->isFloatTy())
2655 const TargetRegisterClass *RC = TLI.getRegClassFor(MVT::v8i16);
2656 if (IsFloatToHalf) {
2664 unsigned Opc = Subtarget->hasVLX() ? X86::VCVTPS2PHZ128rr
2666 InputReg = fastEmitInst_ri(
Opc, RC, InputReg, 4);
2669 Opc = Subtarget->hasAVX512() ? X86::VMOVPDI2DIZrr
2670 : X86::VMOVPDI2DIrr;
2671 ResultReg = createResultReg(&X86::GR32RegClass);
2672 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
2676 unsigned RegIdx = X86::sub_16bit;
2677 ResultReg = fastEmitInst_extractsubreg(MVT::i16, ResultReg, RegIdx);
2679 assert(
Op->getType()->isIntegerTy(16) &&
"Expected a 16-bit integer!");
2687 unsigned Opc = Subtarget->hasVLX() ? X86::VCVTPH2PSZ128rr
2689 InputReg = fastEmitInst_r(
Opc, RC, InputReg);
2693 ResultReg = createResultReg(TLI.getRegClassFor(MVT::f32));
2694 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2695 TII.get(TargetOpcode::COPY), ResultReg)
2699 updateValueMap(
II, ResultReg);
2702 case Intrinsic::frameaddress: {
2703 MachineFunction *MF = FuncInfo.MF;
2707 Type *RetTy =
II->getCalledFunction()->getReturnType();
2710 if (!isTypeLegal(RetTy, VT))
2714 const TargetRegisterClass *RC =
nullptr;
2718 case MVT::i32:
Opc = X86::MOV32rm; RC = &X86::GR32RegClass;
break;
2719 case MVT::i64:
Opc = X86::MOV64rm; RC = &X86::GR64RegClass;
break;
2727 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2729 assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
2730 (FrameReg == X86::EBP && VT == MVT::i32)) &&
2731 "Invalid Frame Register!");
2736 Register SrcReg = createResultReg(RC);
2737 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2738 TII.get(TargetOpcode::COPY), SrcReg).
addReg(FrameReg);
2747 Register DestReg = createResultReg(RC);
2749 TII.get(
Opc), DestReg), SrcReg);
2753 updateValueMap(
II, SrcReg);
2756 case Intrinsic::memcpy: {
2766 if (IsMemcpySmall(Len)) {
2767 X86AddressMode DestAM, SrcAM;
2771 TryEmitSmallMemcpy(DestAM, SrcAM, Len);
2776 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2783 return lowerCallTo(
II,
"memcpy",
II->arg_size() - 1);
2785 case Intrinsic::memset: {
2791 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2798 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
2800 case Intrinsic::stackprotector: {
2802 EVT PtrTy = TLI.getPointerTy(
DL);
2804 const Value *Op1 =
II->getArgOperand(0);
2812 if (!X86FastEmitStore(PtrTy, Op1, AM))
return false;
2815 case Intrinsic::dbg_declare: {
2821 const MCInstrDesc &
II =
TII.get(TargetOpcode::DBG_VALUE);
2823 "Expected inlined-at fields to agree");
2830 case Intrinsic::trap: {
2831 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TRAP));
2834 case Intrinsic::sqrt: {
2835 if (!Subtarget->hasSSE1())
2838 Type *RetTy =
II->getCalledFunction()->getReturnType();
2841 if (!isTypeLegal(RetTy, VT))
2847 static const uint16_t SqrtOpc[3][2] = {
2848 { X86::SQRTSSr, X86::SQRTSDr },
2849 { X86::VSQRTSSr, X86::VSQRTSDr },
2850 { X86::VSQRTSSZr, X86::VSQRTSDZr },
2852 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
2853 Subtarget->hasAVX() ? 1 :
2857 default:
return false;
2858 case MVT::f32:
Opc = SqrtOpc[AVXLevel][0];
break;
2859 case MVT::f64:
Opc = SqrtOpc[AVXLevel][1];
break;
2862 const Value *SrcVal =
II->getArgOperand(0);
2863 Register SrcReg = getRegForValue(SrcVal);
2868 const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
2871 ImplicitDefReg = createResultReg(RC);
2872 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2873 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2876 Register ResultReg = createResultReg(RC);
2877 MachineInstrBuilder MIB;
2878 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
2882 MIB.
addReg(ImplicitDefReg);
2886 updateValueMap(
II, ResultReg);
2889 case Intrinsic::sadd_with_overflow:
2890 case Intrinsic::uadd_with_overflow:
2891 case Intrinsic::ssub_with_overflow:
2892 case Intrinsic::usub_with_overflow:
2893 case Intrinsic::smul_with_overflow:
2894 case Intrinsic::umul_with_overflow: {
2899 Type *RetTy = Ty->getTypeAtIndex(0U);
2902 "Overflow value expected to be an i1");
2905 if (!isTypeLegal(RetTy, VT))
2908 if (VT < MVT::i8 || VT > MVT::i64)
2919 switch (
II->getIntrinsicID()) {
2921 case Intrinsic::sadd_with_overflow:
2923 case Intrinsic::uadd_with_overflow:
2925 case Intrinsic::ssub_with_overflow:
2927 case Intrinsic::usub_with_overflow:
2929 case Intrinsic::smul_with_overflow:
2931 case Intrinsic::umul_with_overflow:
2942 static const uint16_t
Opc[2][4] = {
2943 { X86::INC8r, X86::INC16r, X86::INC32r, X86::INC64r },
2944 { X86::DEC8r, X86::DEC16r, X86::DEC32r, X86::DEC64r }
2950 ResultReg = createResultReg(TLI.getRegClassFor(VT));
2952 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2956 ResultReg = fastEmit_ri(VT, VT, BaseOpc, LHSReg, CI->
getZExtValue());
2961 RHSReg = getRegForValue(
RHS);
2964 ResultReg = fastEmit_rr(VT, VT, BaseOpc, LHSReg, RHSReg);
2970 static const uint16_t MULOpc[] =
2971 { X86::MUL8r, X86::MUL16r, X86::MUL32r, X86::MUL64r };
2972 static const MCPhysReg Reg[] = { X86::AL, X86::AX, X86::EAX, X86::RAX };
2975 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2978 ResultReg = fastEmitInst_r(MULOpc[VT.
SimpleTy-MVT::i8],
2979 TLI.getRegClassFor(VT), RHSReg);
2981 static const uint16_t MULOpc[] =
2982 { X86::IMUL8r, X86::IMUL16rr, X86::IMUL32rr, X86::IMUL64rr };
2983 if (VT == MVT::i8) {
2986 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2987 TII.get(TargetOpcode::COPY), X86::AL)
2989 ResultReg = fastEmitInst_r(MULOpc[0], TLI.getRegClassFor(VT), RHSReg);
2991 ResultReg = fastEmitInst_rr(MULOpc[VT.
SimpleTy-MVT::i8],
2992 TLI.getRegClassFor(VT), LHSReg, RHSReg);
2999 Register ResultReg2 = createResultReg(&X86::GR8RegClass);
3000 assert((ResultReg+1) == ResultReg2 &&
"Nonconsecutive result registers.");
3005 updateValueMap(
II, ResultReg, 2);
3008 case Intrinsic::x86_sse_cvttss2si:
3009 case Intrinsic::x86_sse_cvttss2si64:
3010 case Intrinsic::x86_sse2_cvttsd2si:
3011 case Intrinsic::x86_sse2_cvttsd2si64: {
3013 switch (
II->getIntrinsicID()) {
3015 case Intrinsic::x86_sse_cvttss2si:
3016 case Intrinsic::x86_sse_cvttss2si64:
3017 if (!Subtarget->hasSSE1())
3019 IsInputDouble =
false;
3021 case Intrinsic::x86_sse2_cvttsd2si:
3022 case Intrinsic::x86_sse2_cvttsd2si64:
3023 if (!Subtarget->hasSSE2())
3025 IsInputDouble =
true;
3029 Type *RetTy =
II->getCalledFunction()->getReturnType();
3031 if (!isTypeLegal(RetTy, VT))
3034 static const uint16_t CvtOpc[3][2][2] = {
3035 { { X86::CVTTSS2SIrr, X86::CVTTSS2SI64rr },
3036 { X86::CVTTSD2SIrr, X86::CVTTSD2SI64rr } },
3037 { { X86::VCVTTSS2SIrr, X86::VCVTTSS2SI64rr },
3038 { X86::VCVTTSD2SIrr, X86::VCVTTSD2SI64rr } },
3039 { { X86::VCVTTSS2SIZrr, X86::VCVTTSS2SI64Zrr },
3040 { X86::VCVTTSD2SIZrr, X86::VCVTTSD2SI64Zrr } },
3042 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
3043 Subtarget->hasAVX() ? 1 :
3048 case MVT::i32:
Opc = CvtOpc[AVXLevel][IsInputDouble][0];
break;
3049 case MVT::i64:
Opc = CvtOpc[AVXLevel][IsInputDouble][1];
break;
3061 Op =
IE->getOperand(1);
3064 Op =
IE->getOperand(0);
3071 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3072 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
3075 updateValueMap(
II, ResultReg);
3078 case Intrinsic::x86_sse42_crc32_32_8:
3079 case Intrinsic::x86_sse42_crc32_32_16:
3080 case Intrinsic::x86_sse42_crc32_32_32:
3081 case Intrinsic::x86_sse42_crc32_64_64: {
3082 if (!Subtarget->hasCRC32())
3085 Type *RetTy =
II->getCalledFunction()->getReturnType();
3088 if (!isTypeLegal(RetTy, VT))
3092 const TargetRegisterClass *RC =
nullptr;
3094 switch (
II->getIntrinsicID()) {
3097#define GET_EGPR_IF_ENABLED(OPC) Subtarget->hasEGPR() ? OPC##_EVEX : OPC
3098 case Intrinsic::x86_sse42_crc32_32_8:
3100 RC = &X86::GR32RegClass;
3102 case Intrinsic::x86_sse42_crc32_32_16:
3104 RC = &X86::GR32RegClass;
3106 case Intrinsic::x86_sse42_crc32_32_32:
3108 RC = &X86::GR32RegClass;
3110 case Intrinsic::x86_sse42_crc32_64_64:
3112 RC = &X86::GR64RegClass;
3114#undef GET_EGPR_IF_ENABLED
3122 if (!LHSReg || !RHSReg)
3125 Register ResultReg = fastEmitInst_rr(
Opc, RC, LHSReg, RHSReg);
3129 updateValueMap(
II, ResultReg);
3135bool X86FastISel::fastLowerArguments() {
3136 if (!FuncInfo.CanLowerReturn)
3143 CallingConv::ID CC =
F->getCallingConv();
3144 if (CC != CallingConv::C)
3147 if (Subtarget->isCallingConvWin64(CC))
3150 if (!Subtarget->is64Bit())
3153 if (Subtarget->useSoftFloat())
3157 unsigned GPRCnt = 0;
3158 unsigned FPRCnt = 0;
3159 for (
auto const &Arg :
F->args()) {
3160 if (Arg.hasAttribute(Attribute::ByVal) ||
3161 Arg.hasAttribute(Attribute::InReg) ||
3162 Arg.hasAttribute(Attribute::StructRet) ||
3163 Arg.hasAttribute(Attribute::SwiftSelf) ||
3164 Arg.hasAttribute(Attribute::SwiftAsync) ||
3165 Arg.hasAttribute(Attribute::SwiftError) ||
3166 Arg.hasAttribute(Attribute::Nest))
3169 Type *ArgTy = Arg.getType();
3173 EVT ArgVT = TLI.getValueType(
DL, ArgTy);
3174 if (!ArgVT.
isSimple())
return false;
3176 default:
return false;
3183 if (!Subtarget->hasSSE1())
3196 static const MCPhysReg GPR32ArgRegs[] = {
3197 X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
3199 static const MCPhysReg GPR64ArgRegs[] = {
3200 X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8 , X86::R9
3203 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3204 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3207 unsigned GPRIdx = 0;
3208 unsigned FPRIdx = 0;
3209 for (
auto const &Arg :
F->args()) {
3210 MVT VT = TLI.getSimpleValueType(
DL, Arg.getType());
3211 const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
3215 case MVT::i32: SrcReg = GPR32ArgRegs[GPRIdx++];
break;
3216 case MVT::i64: SrcReg = GPR64ArgRegs[GPRIdx++];
break;
3217 case MVT::f32: [[fallthrough]];
3218 case MVT::f64: SrcReg = XMMArgRegs[FPRIdx++];
break;
3220 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
3224 Register ResultReg = createResultReg(RC);
3225 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3226 TII.get(TargetOpcode::COPY), ResultReg)
3228 updateValueMap(&Arg, ResultReg);
3236 if (Subtarget->is64Bit())
3253bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
3254 auto &OutVals = CLI.OutVals;
3255 auto &OutFlags = CLI.OutFlags;
3256 auto &OutRegs = CLI.OutRegs;
3257 auto &Ins = CLI.Ins;
3258 auto &InRegs = CLI.InRegs;
3259 CallingConv::ID CC = CLI.CallConv;
3260 bool &IsTailCall = CLI.IsTailCall;
3261 bool IsVarArg = CLI.IsVarArg;
3264 const auto *CB = CLI.CB;
3266 bool Is64Bit = Subtarget->is64Bit();
3267 bool IsWin64 = Subtarget->isCallingConvWin64(CC);
3271 if (CB && CB->doesNoCfCheck())
3275 if ((CB &&
isa<CallInst>(CB) && CB->hasFnAttr(
"no_caller_saved_registers")))
3279 if ((CB && CB->hasFnAttr(
"no_callee_saved_registers")))
3287 if (Subtarget->useIndirectThunkCalls())
3292 default:
return false;
3293 case CallingConv::C:
3294 case CallingConv::Fast:
3295 case CallingConv::Tail:
3296 case CallingConv::Swift:
3297 case CallingConv::SwiftTail:
3298 case CallingConv::X86_FastCall:
3299 case CallingConv::X86_StdCall:
3300 case CallingConv::X86_ThisCall:
3301 case CallingConv::Win64:
3302 case CallingConv::X86_64_SysV:
3303 case CallingConv::CFGuard_Check:
3313 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
3314 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
3319 if (IsVarArg && IsWin64)
3323 if (CLI.CB && CLI.CB->hasInAllocaArgument())
3326 for (
auto Flag : CLI.OutFlags)
3327 if (
Flag.isSwiftError() ||
Flag.isPreallocated())
3337 SmallVector<Register, 16> ArgRegs;
3342 for (
int i = 0, e = OutVals.size(); i != e; ++i) {
3343 Value *&Val = OutVals[i];
3344 ISD::ArgFlagsTy
Flags = OutFlags[i];
3359 if (TI && TI->getType()->isIntegerTy(1) && CLI.CB &&
3360 (TI->getParent() == CLI.CB->getParent()) && TI->hasOneUse()) {
3361 Value *PrevVal = TI->getOperand(0);
3362 ResultReg = getRegForValue(PrevVal);
3367 if (!isTypeLegal(PrevVal->
getType(), VT))
3370 ResultReg = fastEmit_ri(VT, VT,
ISD::AND, ResultReg, 1);
3372 if (!isTypeLegal(Val->
getType(), VT) ||
3375 ResultReg = getRegForValue(Val);
3388 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, CLI.RetTy->getContext());
3392 CCInfo.AllocateStack(32,
Align(8));
3394 CCInfo.AnalyzeCallOperands(OutVTs, OutFlags, ArgTys,
CC_X86);
3397 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
3400 unsigned AdjStackDown =
TII.getCallFrameSetupOpcode();
3401 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackDown))
3405 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3406 for (
const CCValAssign &VA : ArgLocs) {
3410 if (ArgVT == MVT::x86mmx)
3420 "Unexpected extend");
3422 if (ArgVT == MVT::i1)
3427 assert(Emitted &&
"Failed to emit a sext!"); (void)Emitted;
3433 "Unexpected extend");
3436 if (ArgVT == MVT::i1) {
3438 ArgReg = fastEmitZExtFromI1(MVT::i8, ArgReg);
3447 assert(Emitted &&
"Failed to emit a zext!"); (void)Emitted;
3453 "Unexpected extend");
3463 assert(Emitted &&
"Failed to emit a aext!"); (void)Emitted;
3469 assert(ArgReg &&
"Failed to emit a bitcast!");
3490 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3503 AM.
Disp = LocMemOffset;
3506 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3509 if (
Flags.isByVal()) {
3510 X86AddressMode SrcAM;
3512 if (!TryEmitSmallMemcpy(AM, SrcAM,
Flags.getByValSize()))
3518 if (!X86FastEmitStore(ArgVT, ArgVal, AM, MMO))
3521 if (!X86FastEmitStore(ArgVT, ArgReg, AM, MMO))
3529 if (Subtarget->isPICStyleGOT()) {
3530 Register Base = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3531 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3535 if (Is64Bit && IsVarArg && !IsWin64) {
3546 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3547 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3549 unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs);
3550 assert((Subtarget->hasSSE1() || !NumXMMRegs)
3551 &&
"SSE registers cannot be used when SSE is disabled");
3552 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
3553 X86::AL).
addImm(NumXMMRegs);
3558 X86AddressMode CalleeAM;
3559 if (!X86SelectCallAddress(Callee, CalleeAM))
3563 const GlobalValue *GV =
nullptr;
3564 if (CalleeAM.
GV !=
nullptr) {
3566 }
else if (CalleeAM.
Base.
Reg) {
3572 MachineInstrBuilder MIB;
3575 unsigned CallOpc = Is64Bit ? X86::CALL64r : X86::CALL32r;
3576 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc))
3580 assert(GV &&
"Not a direct call");
3582 unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV);
3594 unsigned CallOpc = NeedLoad
3595 ? (Is64Bit ? X86::CALL64m : X86::CALL32m)
3596 : (Is64Bit ?
X86::CALL64pcrel32 :
X86::CALLpcrel32);
3598 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc));
3602 MIB.
addSym(Symbol, OpFlags);
3614 if (Subtarget->isPICStyleGOT())
3617 if (Is64Bit && IsVarArg && !IsWin64)
3621 for (
auto Reg : OutRegs)
3625 unsigned NumBytesForCalleeToPop =
3627 TM.Options.GuaranteedTailCallOpt)
3630 unsigned AdjStackUp =
TII.getCallFrameDestroyOpcode();
3631 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackUp))
3636 CCState CCRetInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs,
3637 CLI.RetTy->getContext());
3638 CCRetInfo.AnalyzeCallResult(Ins,
RetCC_X86);
3641 Register ResultReg = FuncInfo.CreateRegs(CLI.RetTy);
3642 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
3643 CCValAssign &VA = RVLocs[i];
3649 if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) &&
3650 ((Is64Bit || Ins[i].
Flags.isInReg()) && !Subtarget->hasSSE1())) {
3656 if ((SrcReg == X86::FP0 || SrcReg == X86::FP1) &&
3657 isScalarFPTypeInSSEReg(VA.
getValVT())) {
3659 CopyReg = createResultReg(&X86::RFP80RegClass);
3663 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3664 TII.get(TargetOpcode::COPY), CopyReg).
addReg(SrcReg);
3672 unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
3678 Opc = ResVT == MVT::f32 ? X86::MOVSSrm_alt : X86::MOVSDrm_alt;
3680 TII.get(
Opc), ResultReg + i), FI);
3684 CLI.ResultReg = ResultReg;
3685 CLI.NumResultRegs = RVLocs.
size();
3689 if (TM.Options.EmitCallGraphSection && CB && CB->isIndirectCall()) {
3690 MachineFunction::CallSiteInfo CSInfo(*CB);
3698X86FastISel::fastSelectInstruction(
const Instruction *
I) {
3699 switch (
I->getOpcode()) {
3701 case Instruction::Load:
3702 return X86SelectLoad(
I);
3703 case Instruction::Store:
3704 return X86SelectStore(
I);
3705 case Instruction::Ret:
3706 return X86SelectRet(
I);
3707 case Instruction::ICmp:
3708 case Instruction::FCmp:
3709 return X86SelectCmp(
I);
3710 case Instruction::ZExt:
3711 return X86SelectZExt(
I);
3712 case Instruction::SExt:
3713 return X86SelectSExt(
I);
3714 case Instruction::Br:
3715 return X86SelectBranch(
I);
3716 case Instruction::LShr:
3717 case Instruction::AShr:
3718 case Instruction::Shl:
3719 return X86SelectShift(
I);
3720 case Instruction::SDiv:
3721 case Instruction::UDiv:
3722 case Instruction::SRem:
3723 case Instruction::URem:
3724 return X86SelectDivRem(
I);
3725 case Instruction::Select:
3726 return X86SelectSelect(
I);
3727 case Instruction::Trunc:
3728 return X86SelectTrunc(
I);
3729 case Instruction::FPExt:
3730 return X86SelectFPExt(
I);
3731 case Instruction::FPTrunc:
3732 return X86SelectFPTrunc(
I);
3733 case Instruction::SIToFP:
3734 return X86SelectSIToFP(
I);
3735 case Instruction::UIToFP:
3736 return X86SelectUIToFP(
I);
3737 case Instruction::IntToPtr:
3738 case Instruction::PtrToInt: {
3739 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
3740 EVT DstVT = TLI.getValueType(
DL,
I->getType());
3742 return X86SelectZExt(
I);
3744 return X86SelectTrunc(
I);
3748 updateValueMap(
I,
Reg);
3751 case Instruction::BitCast:
3752 return X86SelectBitCast(
I);
3758Register X86FastISel::X86MaterializeInt(
const ConstantInt *CI, MVT VT) {
3764 Register SrcReg = fastEmitInst_(X86::MOV32r0, &X86::GR32RegClass);
3769 return fastEmitInst_extractsubreg(MVT::i8, SrcReg, X86::sub_8bit);
3771 return fastEmitInst_extractsubreg(MVT::i16, SrcReg, X86::sub_16bit);
3775 Register ResultReg = createResultReg(&X86::GR64RegClass);
3776 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3777 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3790 case MVT::i8:
Opc = X86::MOV8ri;
break;
3791 case MVT::i16:
Opc = X86::MOV16ri;
break;
3792 case MVT::i32:
Opc = X86::MOV32ri;
break;
3795 Opc = X86::MOV32ri64;
3797 Opc = X86::MOV64ri32;
3803 return fastEmitInst_i(
Opc, TLI.getRegClassFor(VT), Imm);
3806Register X86FastISel::X86MaterializeFP(
const ConstantFP *CFP, MVT VT) {
3808 return fastMaterializeFloatZero(CFP);
3818 bool HasSSE1 = Subtarget->hasSSE1();
3819 bool HasSSE2 = Subtarget->hasSSE2();
3820 bool HasAVX = Subtarget->hasAVX();
3821 bool HasAVX512 = Subtarget->hasAVX512();
3826 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
3827 : HasAVX ? X86::VMOVSSrm_alt
3828 : HasSSE1 ? X86::MOVSSrm_alt
3832 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
3833 : HasAVX ? X86::VMOVSDrm_alt
3834 : HasSSE2 ? X86::MOVSDrm_alt
3847 unsigned char OpFlag = Subtarget->classifyLocalReference(
nullptr);
3849 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3851 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3856 unsigned CPI = MCP.getConstantPoolIndex(CFP, Alignment);
3861 Register AddrReg = createResultReg(&X86::GR64RegClass);
3862 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3865 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3866 TII.get(
Opc), ResultReg);
3867 addRegReg(MIB, AddrReg,
false, X86::NoSubRegister, PICBase,
false,
3868 X86::NoSubRegister);
3869 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3877 TII.get(
Opc), ResultReg),
3878 CPI, PICBase, OpFlag);
3882Register X86FastISel::X86MaterializeGV(
const GlobalValue *GV, MVT VT) {
3887 if (TM.isLargeGlobalValue(GV))
3899 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3901 TLI.getPointerTy(
DL) == MVT::i64) {
3904 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3909 TLI.getPointerTy(
DL) == MVT::i32
3910 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3913 TII.get(
Opc), ResultReg), AM);
3920Register X86FastISel::fastMaterializeConstant(
const Constant *
C) {
3921 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
3929 return X86MaterializeInt(CI, VT);
3931 return X86MaterializeFP(CFP, VT);
3933 return X86MaterializeGV(GV, VT);
3940 if (!Subtarget->hasSSE1())
3941 Opc = X86::LD_Fp032;
3944 if (!Subtarget->hasSSE2())
3945 Opc = X86::LD_Fp064;
3948 Opc = X86::LD_Fp080;
3953 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3954 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
3963Register X86FastISel::fastMaterializeAlloca(
const AllocaInst *
C) {
3971 if (!FuncInfo.StaticAllocaMap.count(
C))
3973 assert(
C->isStaticAlloca() &&
"dynamic alloca in the static alloca map?");
3979 TLI.getPointerTy(
DL) == MVT::i32
3980 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3982 const TargetRegisterClass *RC = TLI.getRegClassFor(TLI.getPointerTy(
DL));
3983 Register ResultReg = createResultReg(RC);
3985 TII.get(
Opc), ResultReg), AM);
3989Register X86FastISel::fastMaterializeFloatZero(
const ConstantFP *CF) {
3991 if (!isTypeLegal(CF->
getType(), VT))
3995 bool HasSSE1 = Subtarget->hasSSE1();
3996 bool HasSSE2 = Subtarget->hasSSE2();
3997 bool HasAVX512 = Subtarget->hasAVX512();
4002 Opc = HasAVX512 ? X86::AVX512_FsFLD0SH : X86::FsFLD0SH;
4005 Opc = HasAVX512 ? X86::AVX512_FsFLD0SS
4006 : HasSSE1 ? X86::FsFLD0SS
4010 Opc = HasAVX512 ? X86::AVX512_FsFLD0SD
4011 : HasSSE2 ? X86::FsFLD0SD
4019 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
4020 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
4024bool X86FastISel::tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
4025 const LoadInst *LI) {
4031 const X86InstrInfo &XII = (
const X86InstrInfo &)
TII;
4039 *FuncInfo.MF, *
MI, OpNo, AddrOps, FuncInfo.InsertPt,
Size, LI->
getAlign(),
4049 unsigned OperandNo = 0;
4051 E =
Result->operands_end();
I !=
E; ++
I, ++OperandNo) {
4052 MachineOperand &MO = *
I;
4058 if (IndexReg == MO.
getReg())
4064 FuncInfo.MF->moveAdditionalCallInfo(
MI, Result);
4065 Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
4066 Result->cloneInstrSymbols(*FuncInfo.MF, *
MI);
4068 removeDeadCode(
I, std::next(
I));
4072Register X86FastISel::fastEmitInst_rrrr(
unsigned MachineInstOpcode,
4073 const TargetRegisterClass *RC,
4076 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
4078 Register ResultReg = createResultReg(RC);
4084 if (
II.getNumDefs() >= 1)
4085 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
4091 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
4096 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
4107 return new X86FastISel(funcInfo, libInfo, libcallLowering);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
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,...
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.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
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.
Value * getPointerOperand()
Align getAlign() const
Return the alignment of the access that is being performed.
bool usesWindowsCFI() const
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 & 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 & addReg(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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 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 contains(Register Reg) const
Return true if the specified register is included in this register class.
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, MachineBasicBlock::iterator InsertPt, int FrameIndex, 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 ...
@ C
The default llvm calling convention, compatible with C.
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.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ 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.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ 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 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 ...
FunctionAddr VTableAddr Value
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 unsigned getKillRegState(bool B)
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.
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)
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...
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