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);
92 bool X86SelectCallAddress(
const Value *V, X86AddressMode &AM);
94 bool X86SelectLoad(
const Instruction *
I);
96 bool X86SelectStore(
const Instruction *
I);
98 bool X86SelectRet(
const Instruction *
I);
100 bool X86SelectCmp(
const Instruction *
I);
102 bool X86SelectZExt(
const Instruction *
I);
104 bool X86SelectSExt(
const Instruction *
I);
106 bool X86SelectBranch(
const Instruction *
I);
108 bool X86SelectShift(
const Instruction *
I);
110 bool X86SelectDivRem(
const Instruction *
I);
112 bool X86FastEmitCMoveSelect(MVT RetVT,
const Instruction *
I);
114 bool X86FastEmitSSESelect(MVT RetVT,
const Instruction *
I);
116 bool X86FastEmitPseudoSelect(MVT RetVT,
const Instruction *
I);
118 bool X86SelectSelect(
const Instruction *
I);
120 bool X86SelectTrunc(
const Instruction *
I);
122 bool X86SelectFPExtOrFPTrunc(
const Instruction *
I,
unsigned Opc,
125 bool X86SelectFPExt(
const Instruction *
I);
126 bool X86SelectFPTrunc(
const Instruction *
I);
127 bool X86SelectSIToFP(
const Instruction *
I);
128 bool X86SelectUIToFP(
const Instruction *
I);
129 bool X86SelectIntToFP(
const Instruction *
I,
bool IsSigned);
130 bool X86SelectBitCast(
const Instruction *
I);
132 const X86InstrInfo *getInstrInfo()
const {
133 return Subtarget->getInstrInfo();
135 const X86TargetMachine *getTargetMachine()
const {
136 return static_cast<const X86TargetMachine *
>(&TM);
139 bool handleConstantAddresses(
const Value *V, X86AddressMode &AM);
143 Register X86MaterializeInt(
const ConstantInt *CI, MVT VT);
144 Register X86MaterializeFP(
const ConstantFP *CFP, MVT VT);
145 Register X86MaterializeGV(
const GlobalValue *GV, MVT VT);
146 Register fastMaterializeConstant(
const Constant *
C)
override;
148 Register fastMaterializeAlloca(
const AllocaInst *
C)
override;
150 Register fastMaterializeFloatZero(
const ConstantFP *CF)
override;
154 bool isScalarFPTypeInSSEReg(EVT VT)
const {
155 return (VT == MVT::f64 && Subtarget->hasSSE2()) ||
156 (VT == MVT::f32 && Subtarget->hasSSE1()) || VT == MVT::f16;
159 bool isTypeLegal(
Type *Ty, MVT &VT,
bool AllowI1 =
false);
163 bool TryEmitSmallMemcpy(X86AddressMode DestAM,
164 X86AddressMode SrcAM,
uint64_t Len);
166 bool foldX86XALUIntrinsic(
X86::CondCode &CC,
const Instruction *
I,
169 const MachineInstrBuilder &
addFullAddress(
const MachineInstrBuilder &MIB,
172 Register fastEmitInst_rrrr(
unsigned MachineInstOpcode,
179static std::pair<unsigned, bool>
182 bool NeedSwap =
false;
211 return std::make_pair(CC, NeedSwap);
225 return ::addFullAddress(MIB, AM);
230bool X86FastISel::foldX86XALUIntrinsic(
X86::CondCode &CC,
const Instruction *
I,
244 if (!isTypeLegal(RetTy, RetVT))
247 if (RetVT != MVT::i32 && RetVT != MVT::i64)
251 switch (
II->getIntrinsicID()) {
252 default:
return false;
253 case Intrinsic::sadd_with_overflow:
254 case Intrinsic::ssub_with_overflow: TmpCC =
X86::COND_O;
break;
255 case Intrinsic::smul_with_overflow:
256 case Intrinsic::umul_with_overflow:
257 case Intrinsic::uadd_with_overflow:
258 case Intrinsic::usub_with_overflow: TmpCC =
X86::COND_B;
break;
262 if (
II->getParent() !=
I->getParent())
268 for (
auto Itr = std::prev(Start); Itr != End; --Itr) {
276 if (EVI->getAggregateOperand() !=
II)
282 auto HasPhis = [](
const BasicBlock *Succ) {
return !Succ->phis().empty(); };
295bool X86FastISel::isTypeLegal(
Type *Ty, MVT &VT,
bool AllowI1) {
296 EVT evt = TLI.getValueType(
DL, Ty,
true);
297 if (evt == MVT::Other || !evt.
isSimple())
304 if (VT == MVT::f64 && !Subtarget->hasSSE2())
306 if (VT == MVT::f32 && !Subtarget->hasSSE1())
315 return (AllowI1 && VT == MVT::i1) || TLI.isTypeLegal(VT);
321bool X86FastISel::X86FastEmitLoad(MVT VT, X86AddressMode &AM,
322 MachineMemOperand *MMO,
Register &ResultReg,
323 unsigned Alignment) {
324 bool HasSSE1 = Subtarget->hasSSE1();
325 bool HasSSE2 = Subtarget->hasSSE2();
326 bool HasSSE41 = Subtarget->hasSSE41();
327 bool HasAVX = Subtarget->hasAVX();
328 bool HasAVX2 = Subtarget->hasAVX2();
329 bool HasAVX512 = Subtarget->hasAVX512();
330 bool HasVLX = Subtarget->hasVLX();
340 default:
return false;
355 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
356 : HasAVX ? X86::VMOVSSrm_alt
357 : HasSSE1 ? X86::MOVSSrm_alt
361 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
362 : HasAVX ? X86::VMOVSDrm_alt
363 : HasSSE2 ? X86::MOVSDrm_alt
370 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
371 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
372 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
373 else if (Alignment >= 16)
374 Opc = HasVLX ? X86::VMOVAPSZ128rm :
375 HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm;
377 Opc = HasVLX ? X86::VMOVUPSZ128rm :
378 HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm;
381 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
382 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
383 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
384 else if (Alignment >= 16)
385 Opc = HasVLX ? X86::VMOVAPDZ128rm :
386 HasAVX ? X86::VMOVAPDrm : X86::MOVAPDrm;
388 Opc = HasVLX ? X86::VMOVUPDZ128rm :
389 HasAVX ? X86::VMOVUPDrm : X86::MOVUPDrm;
395 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
396 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
397 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
398 else if (Alignment >= 16)
399 Opc = HasVLX ? X86::VMOVDQA64Z128rm :
400 HasAVX ? X86::VMOVDQArm : X86::MOVDQArm;
402 Opc = HasVLX ? X86::VMOVDQU64Z128rm :
403 HasAVX ? X86::VMOVDQUrm : X86::MOVDQUrm;
407 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
408 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
409 else if (IsNonTemporal && Alignment >= 16)
411 else if (Alignment >= 32)
412 Opc = HasVLX ? X86::VMOVAPSZ256rm : X86::VMOVAPSYrm;
414 Opc = HasVLX ? X86::VMOVUPSZ256rm : X86::VMOVUPSYrm;
418 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
419 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
420 else if (IsNonTemporal && Alignment >= 16)
422 else if (Alignment >= 32)
423 Opc = HasVLX ? X86::VMOVAPDZ256rm : X86::VMOVAPDYrm;
425 Opc = HasVLX ? X86::VMOVUPDZ256rm : X86::VMOVUPDYrm;
432 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
433 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
434 else if (IsNonTemporal && Alignment >= 16)
436 else if (Alignment >= 32)
437 Opc = HasVLX ? X86::VMOVDQA64Z256rm : X86::VMOVDQAYrm;
439 Opc = HasVLX ? X86::VMOVDQU64Z256rm : X86::VMOVDQUYrm;
443 if (IsNonTemporal && Alignment >= 64)
444 Opc = X86::VMOVNTDQAZrm;
450 if (IsNonTemporal && Alignment >= 64)
451 Opc = X86::VMOVNTDQAZrm;
462 if (IsNonTemporal && Alignment >= 64)
463 Opc = X86::VMOVNTDQAZrm;
471 ResultReg = createResultReg(RC);
472 MachineInstrBuilder MIB =
473 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
484bool X86FastISel::X86FastEmitStore(EVT VT,
Register ValReg, X86AddressMode &AM,
485 MachineMemOperand *MMO,
bool Aligned) {
486 bool HasSSE1 = Subtarget->hasSSE1();
487 bool HasSSE2 = Subtarget->hasSSE2();
488 bool HasSSE4A = Subtarget->hasSSE4A();
489 bool HasAVX = Subtarget->hasAVX();
490 bool HasAVX512 = Subtarget->hasAVX512();
491 bool HasVLX = Subtarget->hasVLX();
498 default:
return false;
501 Register AndResult = createResultReg(&X86::GR8RegClass);
502 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
503 TII.get(X86::AND8ri), AndResult)
508 case MVT::i8:
Opc = X86::MOV8mr;
break;
509 case MVT::i16:
Opc = X86::MOV16mr;
break;
511 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTImr :
X86::MOV32mr;
515 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTI_64mr :
X86::MOV64mr;
519 if (IsNonTemporal && HasSSE4A)
522 Opc = HasAVX512 ? X86::VMOVSSZmr :
523 HasAVX ? X86::VMOVSSmr : X86::MOVSSmr;
529 if (IsNonTemporal && HasSSE4A)
532 Opc = HasAVX512 ? X86::VMOVSDZmr :
533 HasAVX ? X86::VMOVSDmr : X86::MOVSDmr;
538 Opc = (IsNonTemporal && HasSSE1) ? X86::MMX_MOVNTQmr :
X86::MMX_MOVQ64mr;
543 Opc = HasVLX ? X86::VMOVNTPSZ128mr :
544 HasAVX ? X86::VMOVNTPSmr : X86::MOVNTPSmr;
546 Opc = HasVLX ? X86::VMOVAPSZ128mr :
547 HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr;
549 Opc = HasVLX ? X86::VMOVUPSZ128mr :
550 HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr;
555 Opc = HasVLX ? X86::VMOVNTPDZ128mr :
556 HasAVX ? X86::VMOVNTPDmr : X86::MOVNTPDmr;
558 Opc = HasVLX ? X86::VMOVAPDZ128mr :
559 HasAVX ? X86::VMOVAPDmr : X86::MOVAPDmr;
561 Opc = HasVLX ? X86::VMOVUPDZ128mr :
562 HasAVX ? X86::VMOVUPDmr : X86::MOVUPDmr;
570 Opc = HasVLX ? X86::VMOVNTDQZ128mr :
571 HasAVX ? X86::VMOVNTDQmr : X86::MOVNTDQmr;
573 Opc = HasVLX ? X86::VMOVDQA64Z128mr :
574 HasAVX ? X86::VMOVDQAmr : X86::MOVDQAmr;
576 Opc = HasVLX ? X86::VMOVDQU64Z128mr :
577 HasAVX ? X86::VMOVDQUmr : X86::MOVDQUmr;
583 Opc = HasVLX ? X86::VMOVNTPSZ256mr : X86::VMOVNTPSYmr;
585 Opc = HasVLX ? X86::VMOVAPSZ256mr : X86::VMOVAPSYmr;
587 Opc = HasVLX ? X86::VMOVUPSZ256mr : X86::VMOVUPSYmr;
593 Opc = HasVLX ? X86::VMOVNTPDZ256mr : X86::VMOVNTPDYmr;
595 Opc = HasVLX ? X86::VMOVAPDZ256mr : X86::VMOVAPDYmr;
597 Opc = HasVLX ? X86::VMOVUPDZ256mr : X86::VMOVUPDYmr;
606 Opc = HasVLX ? X86::VMOVNTDQZ256mr : X86::VMOVNTDQYmr;
608 Opc = HasVLX ? X86::VMOVDQA64Z256mr : X86::VMOVDQAYmr;
610 Opc = HasVLX ? X86::VMOVDQU64Z256mr : X86::VMOVDQUYmr;
615 Opc = IsNonTemporal ? X86::VMOVNTPSZmr : X86::VMOVAPSZmr;
617 Opc = X86::VMOVUPSZmr;
622 Opc = IsNonTemporal ? X86::VMOVNTPDZmr : X86::VMOVAPDZmr;
624 Opc = X86::VMOVUPDZmr;
634 Opc = IsNonTemporal ? X86::VMOVNTDQZmr : X86::VMOVDQA64Zmr;
636 Opc = X86::VMOVDQU64Zmr;
648 MachineInstrBuilder MIB =
649 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
Desc);
657bool X86FastISel::X86FastEmitStore(EVT VT,
const Value *Val,
659 MachineMemOperand *MMO,
bool Aligned) {
673 case MVT::i8:
Opc = X86::MOV8mi;
break;
674 case MVT::i16:
Opc = X86::MOV16mi;
break;
675 case MVT::i32:
Opc = X86::MOV32mi;
break;
679 Opc = X86::MOV64mi32;
684 MachineInstrBuilder MIB =
685 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc));
687 : CI->getZExtValue());
694 Register ValReg = getRegForValue(Val);
698 return X86FastEmitStore(VT, ValReg, AM, MMO,
Aligned);
714bool X86FastISel::handleConstantAddresses(
const Value *V, X86AddressMode &AM) {
723 if (TM.isLargeGlobalValue(GV))
727 if (GV->isThreadLocal())
731 if (GV->isAbsoluteSymbolRef())
737 if (!Subtarget->isPICStyleRIPRel() ||
743 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
748 AM.
Base.
Reg = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
754 if (Subtarget->isPICStyleRIPRel()) {
766 auto I = LocalValueMap.find(V);
768 if (
I != LocalValueMap.end() &&
I->second) {
774 X86AddressMode StubAM;
780 SavePoint SaveInsertPt = enterLocalValueArea();
782 if (TLI.getPointerTy(
DL) == MVT::i64) {
784 RC = &X86::GR64RegClass;
787 RC = &X86::GR32RegClass;
794 LoadReg = createResultReg(RC);
795 MachineInstrBuilder LoadMI =
796 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), LoadReg);
800 leaveLocalValueArea(SaveInsertPt);
803 LocalValueMap[
V] = LoadReg;
815 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
817 AM.
Base.
Reg = getRegForValue(V);
832bool X86FastISel::X86SelectAddress(
const Value *V, X86AddressMode &AM) {
835 const User *
U =
nullptr;
836 unsigned Opcode = Instruction::UserOp1;
841 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(V)) ||
842 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
843 Opcode =
I->getOpcode();
847 Opcode =
C->getOpcode();
852 if (Ty->getAddressSpace() > 255)
859 case Instruction::BitCast:
863 case Instruction::IntToPtr:
865 if (TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
866 TLI.getPointerTy(
DL))
870 case Instruction::PtrToInt:
872 if (TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
876 case Instruction::Alloca: {
879 auto SI = FuncInfo.StaticAllocaMap.find(
A);
880 if (SI != FuncInfo.StaticAllocaMap.end()) {
888 case Instruction::Add: {
894 AM.
Disp = (uint32_t)Disp;
901 case Instruction::GetElementPtr: {
902 X86AddressMode SavedAM = AM;
907 unsigned Scale = AM.
Scale;
908 MVT PtrVT = TLI.getValueType(
DL,
U->getType()).getSimpleVT();
914 i != e; ++i, ++GTI) {
917 const StructLayout *SL =
DL.getStructLayout(STy);
929 Disp += CI->getValue().sextOrTrunc(64).getSExtValue() * S;
932 if (canFoldAddIntoGEP(U,
Op)) {
941 if (!IndexReg && (!AM.
GV || !Subtarget->isPICStyleRIPRel()) &&
942 (S == 1 || S == 2 || S == 4 || S == 8)) {
945 IndexReg = getRegForGEPIndex(PtrVT,
Op);
951 goto unsupported_gep;
961 AM.
Disp = (uint32_t)Disp;
964 if (
const GetElementPtrInst *
GEP =
979 if (handleConstantAddresses(
I, AM))
989 return handleConstantAddresses(V, AM);
994bool X86FastISel::X86SelectCallAddress(
const Value *V, X86AddressMode &AM) {
995 const User *
U =
nullptr;
996 unsigned Opcode = Instruction::UserOp1;
1023 Opcode =
I->getOpcode();
1025 InMBB =
I->getParent() == FuncInfo.MBB->getBasicBlock();
1027 Opcode =
C->getOpcode();
1033 case Instruction::BitCast:
1036 return X86SelectCallAddress(
U->getOperand(0), AM);
1039 case Instruction::IntToPtr:
1042 TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
1043 TLI.getPointerTy(
DL))
1044 return X86SelectCallAddress(
U->getOperand(0), AM);
1047 case Instruction::PtrToInt:
1049 if (InMBB && TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
1050 return X86SelectCallAddress(
U->getOperand(0), AM);
1062 if (Subtarget->isPICStyleRIPRel() &&
1068 if (GVar->isThreadLocal())
1077 if (Subtarget->isPICStyleRIPRel()) {
1083 AM.
GVOpFlags = Subtarget->classifyLocalReference(
nullptr);
1090 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
1091 auto GetCallRegForValue = [
this](
const Value *
V) {
1095 if (
Reg && Subtarget->isTarget64BitILP32()) {
1096 Register CopyReg = createResultReg(&X86::GR32RegClass);
1097 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32rr),
1101 Register ExtReg = createResultReg(&X86::GR64RegClass);
1102 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1103 TII.get(TargetOpcode::SUBREG_TO_REG), ExtReg)
1113 AM.
Base.
Reg = GetCallRegForValue(V);
1118 AM.
IndexReg = GetCallRegForValue(V);
1128bool X86FastISel::X86SelectStore(
const Instruction *
I) {
1135 const Value *PtrV =
I->getOperand(1);
1136 if (TLI.supportSwiftError()) {
1140 if (Arg->hasSwiftErrorAttr())
1145 if (Alloca->isSwiftError())
1154 if (!isTypeLegal(Val->
getType(), VT,
true))
1165 return X86FastEmitStore(VT, Val, AM, createMachineMemOperandFor(
I),
Aligned);
1169bool X86FastISel::X86SelectRet(
const Instruction *
I) {
1171 const Function &
F = *
I->getParent()->getParent();
1172 const X86MachineFunctionInfo *X86MFInfo =
1173 FuncInfo.MF->getInfo<X86MachineFunctionInfo>();
1175 if (!FuncInfo.CanLowerReturn)
1178 if (TLI.supportSwiftError() &&
1179 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
1182 if (TLI.supportSplitCSR(FuncInfo.MF))
1185 CallingConv::ID CC =
F.getCallingConv();
1186 if (CC != CallingConv::C &&
1187 CC != CallingConv::Fast &&
1188 CC != CallingConv::Tail &&
1189 CC != CallingConv::SwiftTail &&
1190 CC != CallingConv::X86_FastCall &&
1191 CC != CallingConv::X86_StdCall &&
1192 CC != CallingConv::X86_ThisCall &&
1193 CC != CallingConv::X86_64_SysV &&
1194 CC != CallingConv::Win64)
1203 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
1204 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
1220 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
I->getContext());
1229 if (ValLocs.
size() != 1)
1232 CCValAssign &VA = ValLocs[0];
1247 EVT SrcVT = TLI.getValueType(
DL, RV->
getType());
1250 if (SrcVT != DstVT) {
1251 if (SrcVT != MVT::i1 && SrcVT != MVT::i8 && SrcVT != MVT::i16)
1254 if (!Outs[0].
Flags.isZExt() && !Outs[0].Flags.isSExt())
1257 if (SrcVT == MVT::i1) {
1258 if (Outs[0].
Flags.isSExt())
1260 SrcReg = fastEmitZExtFromI1(MVT::i8, SrcReg);
1263 if (SrcVT != DstVT) {
1277 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1278 TII.get(TargetOpcode::COPY), DstReg).
addReg(SrcReg);
1291 if (
F.hasStructRetAttr() && CC != CallingConv::Swift &&
1292 CC != CallingConv::SwiftTail) {
1295 "SRetReturnReg should have been set in LowerFormalArguments()!");
1296 Register RetReg = Subtarget->isTarget64BitLP64() ? X86::RAX : X86::EAX;
1297 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1303 MachineInstrBuilder MIB;
1305 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1306 TII.get(Subtarget->is64Bit() ? X86::RETI64 : X86::RETI32))
1309 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1310 TII.get(Subtarget->is64Bit() ? X86::RET64 : X86::RET32));
1319bool X86FastISel::X86SelectLoad(
const Instruction *
I) {
1326 const Value *
SV =
I->getOperand(0);
1327 if (TLI.supportSwiftError()) {
1331 if (Arg->hasSwiftErrorAttr())
1336 if (Alloca->isSwiftError())
1342 if (!isTypeLegal(LI->
getType(), VT,
true))
1352 if (!X86FastEmitLoad(VT, AM, createMachineMemOperandFor(LI), ResultReg,
1356 updateValueMap(
I, ResultReg);
1361 bool HasAVX512 = Subtarget->
hasAVX512();
1362 bool HasAVX = Subtarget->
hasAVX();
1363 bool HasSSE1 = Subtarget->
hasSSE1();
1364 bool HasSSE2 = Subtarget->
hasSSE2();
1368 case MVT::i8:
return X86::CMP8rr;
1369 case MVT::i16:
return X86::CMP16rr;
1370 case MVT::i32:
return X86::CMP32rr;
1371 case MVT::i64:
return X86::CMP64rr;
1373 return HasAVX512 ? X86::VUCOMISSZrr
1374 : HasAVX ? X86::VUCOMISSrr
1375 : HasSSE1 ? X86::UCOMISSrr
1378 return HasAVX512 ? X86::VUCOMISDZrr
1379 : HasAVX ? X86::VUCOMISDrr
1380 : HasSSE2 ? X86::UCOMISDrr
1395 return X86::CMP16ri;
1397 return X86::CMP32ri;
1405bool X86FastISel::X86FastEmitCompare(
const Value *Op0,
const Value *Op1, EVT VT,
1407 Register Op0Reg = getRegForValue(Op0);
1420 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareImmOpc))
1422 .
addImm(Op1C->getSExtValue());
1428 if (CompareOpc == 0)
return false;
1430 Register Op1Reg = getRegForValue(Op1);
1433 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareOpc))
1441 ((!Subtarget->hasZU() || Subtarget->preferLegacySetCC()) ? X86::SETCCr \
1448 if (!isTypeLegal(
I->getOperand(0)->getType(), VT))
1461 ResultReg = emitMOV32r0();
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,
1578 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
1581 }
else if (DstVT == MVT::i16) {
1584 Register Result32 = createResultReg(&X86::GR32RegClass);
1585 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVZX32rr8),
1586 Result32).
addReg(ResultReg);
1588 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1589 }
else if (DstVT != MVT::i8) {
1596 updateValueMap(
I, ResultReg);
1600bool X86FastISel::X86SelectSExt(
const Instruction *
I) {
1601 EVT DstVT = TLI.getValueType(
DL,
I->getType());
1602 if (!TLI.isTypeLegal(DstVT))
1605 Register ResultReg = getRegForValue(
I->getOperand(0));
1610 MVT SrcVT = TLI.getSimpleValueType(
DL,
I->getOperand(0)->getType());
1611 if (SrcVT == MVT::i1) {
1613 Register ZExtReg = fastEmitZExtFromI1(MVT::i8, ResultReg);
1618 ResultReg = createResultReg(&X86::GR8RegClass);
1619 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::NEG8r),
1620 ResultReg).
addReg(ZExtReg);
1625 if (DstVT == MVT::i16) {
1628 Register Result32 = createResultReg(&X86::GR32RegClass);
1629 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVSX32rr8),
1630 Result32).
addReg(ResultReg);
1632 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1633 }
else if (DstVT != MVT::i8) {
1640 updateValueMap(
I, ResultReg);
1644bool X86FastISel::X86SelectBranch(
const Instruction *
I) {
1648 MachineBasicBlock *TrueMBB = FuncInfo.getMBB(BI->
getSuccessor(0));
1649 MachineBasicBlock *FalseMBB = FuncInfo.getMBB(BI->
getSuccessor(1));
1656 if (CI->
hasOneUse() && CI->getParent() ==
I->getParent()) {
1661 switch (Predicate) {
1676 if (CmpRHSC && CmpRHSC->isNullValue())
1681 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1691 bool NeedExtraBranch =
false;
1692 switch (Predicate) {
1698 NeedExtraBranch =
true;
1711 if (!X86FastEmitCompare(CmpLHS, CmpRHS, VT, CI->getDebugLoc()))
1714 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1719 if (NeedExtraBranch) {
1720 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1724 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1731 if (TI->hasOneUse() && TI->getParent() ==
I->getParent() &&
1732 isTypeLegal(TI->getOperand(0)->getType(), SourceVT)) {
1733 unsigned TestOpc = 0;
1736 case MVT::i8: TestOpc = X86::TEST8ri;
break;
1737 case MVT::i16: TestOpc = X86::TEST16ri;
break;
1738 case MVT::i32: TestOpc = X86::TEST32ri;
break;
1739 case MVT::i64: TestOpc = X86::TEST64ri32;
break;
1742 Register OpReg = getRegForValue(TI->getOperand(0));
1746 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TestOpc))
1750 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1755 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1758 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1762 }
else if (foldX86XALUIntrinsic(CC, BI, BI->
getCondition())) {
1769 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1771 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1783 if (MRI.getRegClass(OpReg) == &X86::VK1RegClass) {
1785 OpReg = createResultReg(&X86::GR32RegClass);
1786 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1787 TII.get(TargetOpcode::COPY), OpReg)
1789 OpReg = fastEmitInst_extractsubreg(MVT::i8, OpReg, X86::sub_8bit);
1791 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
1794 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1796 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1800bool X86FastISel::X86SelectShift(
const Instruction *
I) {
1804 if (
I->getType()->isIntegerTy(8)) {
1806 RC = &X86::GR8RegClass;
1807 switch (
I->getOpcode()) {
1808 case Instruction::LShr: OpReg = X86::SHR8rCL;
break;
1809 case Instruction::AShr: OpReg = X86::SAR8rCL;
break;
1810 case Instruction::Shl: OpReg = X86::SHL8rCL;
break;
1811 default:
return false;
1813 }
else if (
I->getType()->isIntegerTy(16)) {
1815 RC = &X86::GR16RegClass;
1816 switch (
I->getOpcode()) {
1818 case Instruction::LShr: OpReg = X86::SHR16rCL;
break;
1819 case Instruction::AShr: OpReg = X86::SAR16rCL;
break;
1820 case Instruction::Shl: OpReg = X86::SHL16rCL;
break;
1822 }
else if (
I->getType()->isIntegerTy(32)) {
1824 RC = &X86::GR32RegClass;
1825 switch (
I->getOpcode()) {
1827 case Instruction::LShr: OpReg = X86::SHR32rCL;
break;
1828 case Instruction::AShr: OpReg = X86::SAR32rCL;
break;
1829 case Instruction::Shl: OpReg = X86::SHL32rCL;
break;
1831 }
else if (
I->getType()->isIntegerTy(64)) {
1833 RC = &X86::GR64RegClass;
1834 switch (
I->getOpcode()) {
1836 case Instruction::LShr: OpReg = X86::SHR64rCL;
break;
1837 case Instruction::AShr: OpReg = X86::SAR64rCL;
break;
1838 case Instruction::Shl: OpReg = X86::SHL64rCL;
break;
1845 if (!isTypeLegal(
I->getType(), VT))
1848 Register Op0Reg = getRegForValue(
I->getOperand(0));
1852 Register Op1Reg = getRegForValue(
I->getOperand(1));
1855 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
1860 if (CReg != X86::CL)
1861 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1862 TII.get(TargetOpcode::KILL), X86::CL)
1863 .
addReg(CReg, RegState::Kill);
1865 Register ResultReg = createResultReg(RC);
1866 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(OpReg), ResultReg)
1868 updateValueMap(
I, ResultReg);
1872bool X86FastISel::X86SelectDivRem(
const Instruction *
I) {
1873 const static unsigned NumTypes = 4;
1874 const static unsigned NumOps = 4;
1875 const static bool S =
true;
1876 const static bool U =
false;
1877 const static unsigned Copy = TargetOpcode::COPY;
1887 const static struct DivRemEntry {
1893 struct DivRemResult {
1895 unsigned OpSignExtend;
1899 unsigned DivRemResultReg;
1902 } OpTable[NumTypes] = {
1903 { &X86::GR8RegClass, X86::AX, 0, {
1904 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S },
1905 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S },
1906 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U },
1907 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U },
1910 { &X86::GR16RegClass, X86::AX, X86::DX, {
1911 { X86::IDIV16r, X86::CWD,
Copy, X86::AX, S },
1912 { X86::IDIV16r, X86::CWD,
Copy, X86::DX, S },
1913 { X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U },
1914 { X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U },
1917 { &X86::GR32RegClass, X86::EAX, X86::EDX, {
1918 { X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S },
1919 { X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S },
1920 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U },
1921 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U },
1924 { &X86::GR64RegClass, X86::RAX, X86::RDX, {
1925 { X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S },
1926 { X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S },
1927 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U },
1928 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U },
1934 if (!isTypeLegal(
I->getType(), VT))
1937 unsigned TypeIndex, OpIndex;
1939 default:
return false;
1940 case MVT::i8: TypeIndex = 0;
break;
1941 case MVT::i16: TypeIndex = 1;
break;
1942 case MVT::i32: TypeIndex = 2;
break;
1943 case MVT::i64: TypeIndex = 3;
1944 if (!Subtarget->is64Bit())
1949 switch (
I->getOpcode()) {
1951 case Instruction::SDiv: OpIndex = 0;
break;
1952 case Instruction::SRem: OpIndex = 1;
break;
1953 case Instruction::UDiv: OpIndex = 2;
break;
1954 case Instruction::URem: OpIndex = 3;
break;
1957 const DivRemEntry &
TypeEntry = OpTable[TypeIndex];
1958 const DivRemEntry::DivRemResult &OpEntry =
TypeEntry.ResultTable[OpIndex];
1959 Register Op0Reg = getRegForValue(
I->getOperand(0));
1962 Register Op1Reg = getRegForValue(
I->getOperand(1));
1967 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1970 if (OpEntry.OpSignExtend) {
1971 if (OpEntry.IsOpSigned)
1972 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1973 TII.get(OpEntry.OpSignExtend));
1980 if (VT == MVT::i16) {
1981 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Copy),
1983 .
addReg(Zero32, {}, X86::sub_16bit);
1984 }
else if (VT == MVT::i32) {
1985 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1988 }
else if (VT == MVT::i64) {
1989 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1990 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)
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)
2213 if (Subtarget->hasAVX512()) {
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()) {
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;
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)
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);
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];
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,
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))
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()) {
2635 case Intrinsic::frameaddress: {
2640 Type *RetTy =
II->getCalledFunction()->getReturnType();
2643 if (!isTypeLegal(RetTy, VT))
2651 case MVT::i32:
Opc = X86::MOV32rm; RC = &X86::GR32RegClass;
break;
2652 case MVT::i64:
Opc = X86::MOV64rm; RC = &X86::GR64RegClass;
break;
2660 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2662 assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
2663 (FrameReg == X86::EBP && VT == MVT::i32)) &&
2664 "Invalid Frame Register!");
2669 Register SrcReg = createResultReg(RC);
2670 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2671 TII.get(TargetOpcode::COPY), SrcReg).
addReg(FrameReg);
2680 Register DestReg = createResultReg(RC);
2682 TII.get(
Opc), DestReg), SrcReg);
2686 updateValueMap(
II, SrcReg);
2689 case Intrinsic::memcpy: {
2699 if (IsMemcpySmall(Len)) {
2700 X86AddressMode DestAM, SrcAM;
2704 TryEmitSmallMemcpy(DestAM, SrcAM, Len);
2709 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2716 return lowerCallTo(
II,
"memcpy",
II->arg_size() - 1);
2718 case Intrinsic::memset: {
2724 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2731 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
2733 case Intrinsic::stackprotector: {
2735 EVT PtrTy = TLI.getPointerTy(
DL);
2737 const Value *Op1 =
II->getArgOperand(0);
2745 if (!X86FastEmitStore(PtrTy, Op1, AM))
return false;
2748 case Intrinsic::dbg_declare: {
2754 const MCInstrDesc &
II =
TII.get(TargetOpcode::DBG_VALUE);
2756 "Expected inlined-at fields to agree");
2763 case Intrinsic::trap: {
2764 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TRAP));
2767 case Intrinsic::sqrt: {
2768 if (!Subtarget->hasSSE1())
2771 Type *RetTy =
II->getCalledFunction()->getReturnType();
2774 if (!isTypeLegal(RetTy, VT))
2780 static const uint16_t SqrtOpc[3][2] = {
2781 { X86::SQRTSSr, X86::SQRTSDr },
2782 { X86::VSQRTSSr, X86::VSQRTSDr },
2783 { X86::VSQRTSSZr, X86::VSQRTSDZr },
2785 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
2786 Subtarget->hasAVX() ? 1 :
2790 default:
return false;
2791 case MVT::f32:
Opc = SqrtOpc[AVXLevel][0];
break;
2792 case MVT::f64:
Opc = SqrtOpc[AVXLevel][1];
break;
2795 const Value *SrcVal =
II->getArgOperand(0);
2796 Register SrcReg = getRegForValue(SrcVal);
2804 ImplicitDefReg = createResultReg(RC);
2805 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2806 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2809 Register ResultReg = createResultReg(RC);
2810 MachineInstrBuilder MIB;
2811 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
2815 MIB.
addReg(ImplicitDefReg);
2819 updateValueMap(
II, ResultReg);
2822 case Intrinsic::sadd_with_overflow:
2823 case Intrinsic::uadd_with_overflow:
2824 case Intrinsic::ssub_with_overflow:
2825 case Intrinsic::usub_with_overflow:
2826 case Intrinsic::smul_with_overflow:
2827 case Intrinsic::umul_with_overflow: {
2832 Type *RetTy = Ty->getTypeAtIndex(0U);
2835 "Overflow value expected to be an i1");
2838 if (!isTypeLegal(RetTy, VT))
2841 if (VT < MVT::i8 || VT > MVT::i64)
2852 switch (
II->getIntrinsicID()) {
2854 case Intrinsic::sadd_with_overflow:
2856 case Intrinsic::uadd_with_overflow:
2858 case Intrinsic::ssub_with_overflow:
2860 case Intrinsic::usub_with_overflow:
2862 case Intrinsic::smul_with_overflow:
2864 case Intrinsic::umul_with_overflow:
2875 static const uint16_t
Opc[2][4] = {
2876 { X86::INC8r, X86::INC16r, X86::INC32r, X86::INC64r },
2877 { X86::DEC8r, X86::DEC16r, X86::DEC32r, X86::DEC64r }
2883 ResultReg = createResultReg(TLI.getRegClassFor(VT));
2885 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2889 ResultReg = fastEmit_ri(VT, VT, BaseOpc, LHSReg, CI->
getZExtValue());
2894 RHSReg = getRegForValue(
RHS);
2897 ResultReg = fastEmit_rr(VT, VT, BaseOpc, LHSReg, RHSReg);
2902 if (BaseOpc == X86ISD::UMUL && !ResultReg) {
2903 static const uint16_t MULOpc[] =
2904 { X86::MUL8r, X86::MUL16r, X86::MUL32r, X86::MUL64r };
2905 static const MCPhysReg Reg[] = { X86::AL, X86::AX, X86::EAX, X86::RAX };
2908 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2911 ResultReg = fastEmitInst_r(MULOpc[VT.
SimpleTy-MVT::i8],
2912 TLI.getRegClassFor(VT), RHSReg);
2913 }
else if (BaseOpc == X86ISD::SMUL && !ResultReg) {
2914 static const uint16_t MULOpc[] =
2915 { X86::IMUL8r, X86::IMUL16rr, X86::IMUL32rr, X86::IMUL64rr };
2916 if (VT == MVT::i8) {
2919 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2920 TII.get(TargetOpcode::COPY), X86::AL)
2922 ResultReg = fastEmitInst_r(MULOpc[0], TLI.getRegClassFor(VT), RHSReg);
2924 ResultReg = fastEmitInst_rr(MULOpc[VT.
SimpleTy-MVT::i8],
2925 TLI.getRegClassFor(VT), LHSReg, RHSReg);
2932 Register ResultReg2 = createResultReg(&X86::GR8RegClass);
2933 assert((ResultReg+1) == ResultReg2 &&
"Nonconsecutive result registers.");
2938 updateValueMap(
II, ResultReg, 2);
2941 case Intrinsic::x86_sse_cvttss2si:
2942 case Intrinsic::x86_sse_cvttss2si64:
2943 case Intrinsic::x86_sse2_cvttsd2si:
2944 case Intrinsic::x86_sse2_cvttsd2si64: {
2946 switch (
II->getIntrinsicID()) {
2948 case Intrinsic::x86_sse_cvttss2si:
2949 case Intrinsic::x86_sse_cvttss2si64:
2950 if (!Subtarget->hasSSE1())
2952 IsInputDouble =
false;
2954 case Intrinsic::x86_sse2_cvttsd2si:
2955 case Intrinsic::x86_sse2_cvttsd2si64:
2956 if (!Subtarget->hasSSE2())
2958 IsInputDouble =
true;
2962 Type *RetTy =
II->getCalledFunction()->getReturnType();
2964 if (!isTypeLegal(RetTy, VT))
2967 static const uint16_t CvtOpc[3][2][2] = {
2968 { { X86::CVTTSS2SIrr, X86::CVTTSS2SI64rr },
2969 { X86::CVTTSD2SIrr, X86::CVTTSD2SI64rr } },
2970 { { X86::VCVTTSS2SIrr, X86::VCVTTSS2SI64rr },
2971 { X86::VCVTTSD2SIrr, X86::VCVTTSD2SI64rr } },
2972 { { X86::VCVTTSS2SIZrr, X86::VCVTTSS2SI64Zrr },
2973 { X86::VCVTTSD2SIZrr, X86::VCVTTSD2SI64Zrr } },
2975 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
2976 Subtarget->hasAVX() ? 1 :
2981 case MVT::i32:
Opc = CvtOpc[AVXLevel][IsInputDouble][0];
break;
2982 case MVT::i64:
Opc = CvtOpc[AVXLevel][IsInputDouble][1];
break;
2994 Op =
IE->getOperand(1);
2997 Op =
IE->getOperand(0);
3004 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3005 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
3008 updateValueMap(
II, ResultReg);
3011 case Intrinsic::x86_sse42_crc32_32_8:
3012 case Intrinsic::x86_sse42_crc32_32_16:
3013 case Intrinsic::x86_sse42_crc32_32_32:
3014 case Intrinsic::x86_sse42_crc32_64_64: {
3015 if (!Subtarget->hasCRC32())
3018 Type *RetTy =
II->getCalledFunction()->getReturnType();
3021 if (!isTypeLegal(RetTy, VT))
3027 switch (
II->getIntrinsicID()) {
3030#define GET_EGPR_IF_ENABLED(OPC) Subtarget->hasEGPR() ? OPC##_EVEX : OPC
3031 case Intrinsic::x86_sse42_crc32_32_8:
3033 RC = &X86::GR32RegClass;
3035 case Intrinsic::x86_sse42_crc32_32_16:
3037 RC = &X86::GR32RegClass;
3039 case Intrinsic::x86_sse42_crc32_32_32:
3041 RC = &X86::GR32RegClass;
3043 case Intrinsic::x86_sse42_crc32_64_64:
3045 RC = &X86::GR64RegClass;
3047#undef GET_EGPR_IF_ENABLED
3055 if (!LHSReg || !RHSReg)
3058 Register ResultReg = fastEmitInst_rr(
Opc, RC, LHSReg, RHSReg);
3062 updateValueMap(
II, ResultReg);
3068bool X86FastISel::fastLowerArguments() {
3069 if (!FuncInfo.CanLowerReturn)
3076 CallingConv::ID CC =
F->getCallingConv();
3077 if (CC != CallingConv::C)
3080 if (Subtarget->isCallingConvWin64(CC))
3083 if (!Subtarget->is64Bit())
3086 if (Subtarget->useSoftFloat())
3090 unsigned GPRCnt = 0;
3091 unsigned FPRCnt = 0;
3092 for (
auto const &Arg :
F->args()) {
3093 if (Arg.hasAttribute(Attribute::ByVal) ||
3094 Arg.hasAttribute(Attribute::InReg) ||
3095 Arg.hasAttribute(Attribute::StructRet) ||
3096 Arg.hasAttribute(Attribute::SwiftSelf) ||
3097 Arg.hasAttribute(Attribute::SwiftAsync) ||
3098 Arg.hasAttribute(Attribute::SwiftError) ||
3099 Arg.hasAttribute(Attribute::Nest))
3102 Type *ArgTy = Arg.getType();
3106 EVT ArgVT = TLI.getValueType(
DL, ArgTy);
3107 if (!ArgVT.
isSimple())
return false;
3109 default:
return false;
3116 if (!Subtarget->hasSSE1())
3129 static const MCPhysReg GPR32ArgRegs[] = {
3130 X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
3132 static const MCPhysReg GPR64ArgRegs[] = {
3133 X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8 , X86::R9
3136 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3137 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3140 unsigned GPRIdx = 0;
3141 unsigned FPRIdx = 0;
3142 for (
auto const &Arg :
F->args()) {
3143 MVT VT = TLI.getSimpleValueType(
DL, Arg.getType());
3148 case MVT::i32: SrcReg = GPR32ArgRegs[GPRIdx++];
break;
3149 case MVT::i64: SrcReg = GPR64ArgRegs[GPRIdx++];
break;
3150 case MVT::f32: [[fallthrough]];
3151 case MVT::f64: SrcReg = XMMArgRegs[FPRIdx++];
break;
3153 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
3157 Register ResultReg = createResultReg(RC);
3158 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3159 TII.get(TargetOpcode::COPY), ResultReg)
3161 updateValueMap(&Arg, ResultReg);
3169 if (Subtarget->is64Bit())
3186bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
3187 auto &OutVals = CLI.OutVals;
3188 auto &OutFlags = CLI.OutFlags;
3189 auto &OutRegs = CLI.OutRegs;
3190 auto &Ins = CLI.Ins;
3191 auto &InRegs = CLI.InRegs;
3192 CallingConv::ID CC = CLI.CallConv;
3193 bool &IsTailCall = CLI.IsTailCall;
3194 bool IsVarArg = CLI.IsVarArg;
3197 const auto *CB = CLI.CB;
3199 bool Is64Bit = Subtarget->is64Bit();
3200 bool IsWin64 = Subtarget->isCallingConvWin64(CC);
3212 for (
Type *RetTy : RetTys) {
3213 MVT RetVT = MVT::Other;
3214 if (!isTypeLegal(RetTy, RetVT)) {
3215 if (RetVT == MVT::Other)
3220 MVT ABIVT = TLI.getRegisterTypeForCallingConv(CLI.RetTy->getContext(),
3221 CLI.CallConv, RetVT);
3222 MVT RegVT = TLI.getRegisterType(CLI.RetTy->getContext(), RetVT);
3230 if (CB && CB->doesNoCfCheck())
3234 if ((CB &&
isa<CallInst>(CB) && CB->hasFnAttr(
"no_caller_saved_registers")))
3238 if ((CB && CB->hasFnAttr(
"no_callee_saved_registers")))
3246 if (Subtarget->useIndirectThunkCalls())
3251 default:
return false;
3252 case CallingConv::C:
3253 case CallingConv::Fast:
3254 case CallingConv::Tail:
3255 case CallingConv::Swift:
3256 case CallingConv::SwiftTail:
3257 case CallingConv::X86_FastCall:
3258 case CallingConv::X86_StdCall:
3259 case CallingConv::X86_ThisCall:
3260 case CallingConv::Win64:
3261 case CallingConv::X86_64_SysV:
3262 case CallingConv::CFGuard_Check:
3272 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
3273 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
3278 if (IsVarArg && IsWin64)
3282 if (CLI.CB && CLI.CB->hasInAllocaArgument())
3285 for (
auto Flag : CLI.OutFlags)
3286 if (
Flag.isSwiftError() ||
Flag.isPreallocated())
3296 SmallVector<Register, 16> ArgRegs;
3301 for (
int i = 0, e = OutVals.size(); i != e; ++i) {
3302 Value *&Val = OutVals[i];
3303 ISD::ArgFlagsTy
Flags = OutFlags[i];
3318 if (TI && TI->getType()->isIntegerTy(1) && CLI.CB &&
3319 (TI->getParent() == CLI.CB->getParent()) && TI->hasOneUse()) {
3320 Value *PrevVal = TI->getOperand(0);
3321 ResultReg = getRegForValue(PrevVal);
3326 if (!isTypeLegal(PrevVal->
getType(), VT))
3329 ResultReg = fastEmit_ri(VT, VT,
ISD::AND, ResultReg, 1);
3333 ResultReg = getRegForValue(Val);
3346 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, CLI.RetTy->getContext());
3350 CCInfo.AllocateStack(32,
Align(8));
3352 CCInfo.AnalyzeCallOperands(OutVTs, OutFlags, ArgTys,
CC_X86);
3355 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
3358 unsigned AdjStackDown =
TII.getCallFrameSetupOpcode();
3359 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackDown))
3363 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3364 for (
const CCValAssign &VA : ArgLocs) {
3368 if (ArgVT == MVT::x86mmx)
3378 "Unexpected extend");
3380 if (ArgVT == MVT::i1)
3385 assert(Emitted &&
"Failed to emit a sext!"); (void)Emitted;
3391 "Unexpected extend");
3394 if (ArgVT == MVT::i1) {
3396 ArgReg = fastEmitZExtFromI1(MVT::i8, ArgReg);
3405 assert(Emitted &&
"Failed to emit a zext!"); (void)Emitted;
3411 "Unexpected extend");
3421 assert(Emitted &&
"Failed to emit a aext!"); (void)Emitted;
3427 assert(ArgReg &&
"Failed to emit a bitcast!");
3448 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3461 AM.
Disp = LocMemOffset;
3464 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3467 if (
Flags.isByVal()) {
3468 X86AddressMode SrcAM;
3470 if (!TryEmitSmallMemcpy(AM, SrcAM,
Flags.getByValSize()))
3476 if (!X86FastEmitStore(ArgVT, ArgVal, AM, MMO))
3479 if (!X86FastEmitStore(ArgVT, ArgReg, AM, MMO))
3487 if (Subtarget->isPICStyleGOT()) {
3488 Register Base = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3489 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3493 if (Is64Bit && IsVarArg && !IsWin64) {
3504 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3505 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3507 unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs);
3508 assert((Subtarget->hasSSE1() || !NumXMMRegs)
3509 &&
"SSE registers cannot be used when SSE is disabled");
3510 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
3511 X86::AL).
addImm(NumXMMRegs);
3516 X86AddressMode CalleeAM;
3517 if (!X86SelectCallAddress(Callee, CalleeAM))
3521 const GlobalValue *GV =
nullptr;
3522 if (CalleeAM.
GV !=
nullptr) {
3524 }
else if (CalleeAM.
Base.
Reg) {
3530 MachineInstrBuilder MIB;
3533 unsigned CallOpc = Is64Bit ? X86::CALL64r : X86::CALL32r;
3534 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc))
3538 assert(GV &&
"Not a direct call");
3540 unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV);
3552 unsigned CallOpc = NeedLoad
3553 ? (Is64Bit ? X86::CALL64m : X86::CALL32m)
3554 : (Is64Bit ?
X86::CALL64pcrel32 :
X86::CALLpcrel32);
3556 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc));
3560 MIB.
addSym(Symbol, OpFlags);
3572 if (Subtarget->isPICStyleGOT())
3573 MIB.
addReg(X86::EBX, RegState::Implicit);
3575 if (Is64Bit && IsVarArg && !IsWin64)
3576 MIB.
addReg(X86::AL, RegState::Implicit);
3579 for (
auto Reg : OutRegs)
3583 unsigned NumBytesForCalleeToPop =
3585 TM.Options.GuaranteedTailCallOpt)
3588 unsigned AdjStackUp =
TII.getCallFrameDestroyOpcode();
3589 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackUp))
3594 CCState CCRetInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs,
3595 CLI.RetTy->getContext());
3596 CCRetInfo.AnalyzeCallResult(Ins,
RetCC_X86);
3599 Register ResultReg = FuncInfo.CreateRegs(CLI.RetTy);
3600 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
3601 CCValAssign &VA = RVLocs[i];
3607 if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) &&
3608 ((Is64Bit || Ins[i].
Flags.isInReg()) && !Subtarget->hasSSE1())) {
3614 if ((SrcReg == X86::FP0 || SrcReg == X86::FP1) &&
3615 isScalarFPTypeInSSEReg(VA.
getValVT())) {
3617 CopyReg = createResultReg(&X86::RFP80RegClass);
3621 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3622 TII.get(TargetOpcode::COPY), CopyReg).
addReg(SrcReg);
3630 unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
3636 Opc = ResVT == MVT::f32 ? X86::MOVSSrm_alt : X86::MOVSDrm_alt;
3638 TII.get(
Opc), ResultReg + i), FI);
3642 CLI.ResultReg = ResultReg;
3643 CLI.NumResultRegs = RVLocs.
size();
3647 if (TM.Options.EmitCallGraphSection && CB && CB->isIndirectCall()) {
3648 MachineFunction::CallSiteInfo CSInfo(*CB);
3656X86FastISel::fastSelectInstruction(
const Instruction *
I) {
3657 switch (
I->getOpcode()) {
3659 case Instruction::Load:
3660 return X86SelectLoad(
I);
3661 case Instruction::Store:
3662 return X86SelectStore(
I);
3663 case Instruction::Ret:
3664 return X86SelectRet(
I);
3665 case Instruction::ICmp:
3666 case Instruction::FCmp:
3667 return X86SelectCmp(
I);
3668 case Instruction::ZExt:
3669 return X86SelectZExt(
I);
3670 case Instruction::SExt:
3671 return X86SelectSExt(
I);
3672 case Instruction::CondBr:
3673 return X86SelectBranch(
I);
3674 case Instruction::LShr:
3675 case Instruction::AShr:
3676 case Instruction::Shl:
3677 return X86SelectShift(
I);
3678 case Instruction::SDiv:
3679 case Instruction::UDiv:
3680 case Instruction::SRem:
3681 case Instruction::URem:
3682 return X86SelectDivRem(
I);
3683 case Instruction::Select:
3684 return X86SelectSelect(
I);
3685 case Instruction::Trunc:
3686 return X86SelectTrunc(
I);
3687 case Instruction::FPExt:
3688 return X86SelectFPExt(
I);
3689 case Instruction::FPTrunc:
3690 return X86SelectFPTrunc(
I);
3691 case Instruction::SIToFP:
3692 return X86SelectSIToFP(
I);
3693 case Instruction::UIToFP:
3694 return X86SelectUIToFP(
I);
3695 case Instruction::IntToPtr:
3696 case Instruction::PtrToInt: {
3697 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
3698 EVT DstVT = TLI.getValueType(
DL,
I->getType());
3700 return X86SelectZExt(
I);
3702 return X86SelectTrunc(
I);
3706 updateValueMap(
I,
Reg);
3709 case Instruction::BitCast:
3710 return X86SelectBitCast(
I);
3716Register X86FastISel::emitMOV32r0() {
3717 Register ResultReg = createResultReg(&X86::GR32RegClass);
3718 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32r0),
3724Register X86FastISel::X86MaterializeInt(
const ConstantInt *CI, MVT VT) {
3735 return fastEmitInst_extractsubreg(MVT::i8, SrcReg, X86::sub_8bit);
3737 return fastEmitInst_extractsubreg(MVT::i16, SrcReg, X86::sub_16bit);
3741 Register ResultReg = createResultReg(&X86::GR64RegClass);
3742 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3743 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3757 case MVT::i8:
Opc = X86::MOV8ri;
break;
3758 case MVT::i16:
Opc = X86::MOV16ri;
break;
3759 case MVT::i32:
Opc = X86::MOV32ri;
break;
3764 return fastEmitInst_i(
Opc, TLI.getRegClassFor(VT),
Imm);
3767Register X86FastISel::X86MaterializeFP(
const ConstantFP *CFP, MVT VT) {
3769 return fastMaterializeFloatZero(CFP);
3779 bool HasSSE1 = Subtarget->hasSSE1();
3780 bool HasSSE2 = Subtarget->hasSSE2();
3781 bool HasAVX = Subtarget->hasAVX();
3782 bool HasAVX512 = Subtarget->hasAVX512();
3787 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
3788 : HasAVX ? X86::VMOVSSrm_alt
3789 : HasSSE1 ? X86::MOVSSrm_alt
3793 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
3794 : HasAVX ? X86::VMOVSDrm_alt
3795 : HasSSE2 ? X86::MOVSDrm_alt
3808 unsigned char OpFlag = Subtarget->classifyLocalReference(
nullptr);
3810 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3812 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3817 unsigned CPI = MCP.getConstantPoolIndex(CFP, Alignment);
3822 Register AddrReg = createResultReg(&X86::GR64RegClass);
3823 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3826 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3827 TII.get(
Opc), ResultReg);
3828 addRegReg(MIB, AddrReg,
false, X86::NoSubRegister, PICBase,
false,
3829 X86::NoSubRegister);
3830 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3838 TII.get(
Opc), ResultReg),
3839 CPI, PICBase, OpFlag);
3843Register X86FastISel::X86MaterializeGV(
const GlobalValue *GV, MVT VT) {
3848 if (TM.isLargeGlobalValue(GV))
3860 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3862 TLI.getPointerTy(
DL) == MVT::i64) {
3865 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3870 TLI.getPointerTy(
DL) == MVT::i32
3871 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3874 TII.get(
Opc), ResultReg), AM);
3881Register X86FastISel::fastMaterializeConstant(
const Constant *
C) {
3882 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
3890 return X86MaterializeInt(CI, VT);
3892 return X86MaterializeFP(CFP, VT);
3894 return X86MaterializeGV(GV, VT);
3901 if (!Subtarget->hasSSE1())
3902 Opc = X86::LD_Fp032;
3905 if (!Subtarget->hasSSE2())
3906 Opc = X86::LD_Fp064;
3909 Opc = X86::LD_Fp080;
3914 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3915 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
3924Register X86FastISel::fastMaterializeAlloca(
const AllocaInst *
C) {
3932 if (!FuncInfo.StaticAllocaMap.count(
C))
3934 assert(
C->isStaticAlloca() &&
"dynamic alloca in the static alloca map?");
3940 TLI.getPointerTy(
DL) == MVT::i32
3941 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3944 Register ResultReg = createResultReg(RC);
3946 TII.get(
Opc), ResultReg), AM);
3950Register X86FastISel::fastMaterializeFloatZero(
const ConstantFP *CF) {
3952 if (!isTypeLegal(CF->
getType(), VT))
3956 bool HasSSE1 = Subtarget->hasSSE1();
3957 bool HasSSE2 = Subtarget->hasSSE2();
3958 bool HasAVX512 = Subtarget->hasAVX512();
3963 Opc = HasAVX512 ? X86::AVX512_FsFLD0SH : X86::FsFLD0SH;
3966 Opc = HasAVX512 ? X86::AVX512_FsFLD0SS
3967 : HasSSE1 ? X86::FsFLD0SS
3971 Opc = HasAVX512 ? X86::AVX512_FsFLD0SD
3972 : HasSSE2 ? X86::FsFLD0SD
3980 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3981 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
3985bool X86FastISel::tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
3986 const LoadInst *LI) {
3992 const X86InstrInfo &XII = (
const X86InstrInfo &)
TII;
3999 MachineInstr *CopyMI =
nullptr;
4001 *FuncInfo.MF, *
MI, OpNo, AddrOps, FuncInfo.InsertPt,
Size, LI->
getAlign(),
4011 unsigned OperandNo = 0;
4013 E =
Result->operands_end();
I !=
E; ++
I, ++OperandNo) {
4014 MachineOperand &MO = *
I;
4020 if (IndexReg == MO.
getReg())
4026 FuncInfo.MF->moveAdditionalCallInfo(
MI, Result);
4027 Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
4028 Result->cloneInstrSymbols(*FuncInfo.MF, *
MI);
4030 removeDeadCode(
I, std::next(
I));
4034Register X86FastISel::fastEmitInst_rrrr(
unsigned MachineInstOpcode,
4038 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
4040 Register ResultReg = createResultReg(RC);
4046 if (
II.getNumDefs() >= 1)
4047 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
4053 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
4058 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
4069 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 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