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);
928 Disp += CI->getSExtValue() * S;
931 if (canFoldAddIntoGEP(U,
Op)) {
940 if (!IndexReg && (!AM.
GV || !Subtarget->isPICStyleRIPRel()) &&
941 (S == 1 || S == 2 || S == 4 || S == 8)) {
944 IndexReg = getRegForGEPIndex(PtrVT,
Op);
950 goto unsupported_gep;
960 AM.
Disp = (uint32_t)Disp;
963 if (
const GetElementPtrInst *
GEP =
978 if (handleConstantAddresses(
I, AM))
988 return handleConstantAddresses(V, AM);
993bool X86FastISel::X86SelectCallAddress(
const Value *V, X86AddressMode &AM) {
994 const User *
U =
nullptr;
995 unsigned Opcode = Instruction::UserOp1;
1022 Opcode =
I->getOpcode();
1024 InMBB =
I->getParent() == FuncInfo.MBB->getBasicBlock();
1026 Opcode =
C->getOpcode();
1032 case Instruction::BitCast:
1035 return X86SelectCallAddress(
U->getOperand(0), AM);
1038 case Instruction::IntToPtr:
1041 TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
1042 TLI.getPointerTy(
DL))
1043 return X86SelectCallAddress(
U->getOperand(0), AM);
1046 case Instruction::PtrToInt:
1048 if (InMBB && TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
1049 return X86SelectCallAddress(
U->getOperand(0), AM);
1061 if (Subtarget->isPICStyleRIPRel() &&
1067 if (GVar->isThreadLocal())
1076 if (Subtarget->isPICStyleRIPRel()) {
1082 AM.
GVOpFlags = Subtarget->classifyLocalReference(
nullptr);
1089 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
1090 auto GetCallRegForValue = [
this](
const Value *
V) {
1094 if (
Reg && Subtarget->isTarget64BitILP32()) {
1095 Register CopyReg = createResultReg(&X86::GR32RegClass);
1096 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32rr),
1100 Register ExtReg = createResultReg(&X86::GR64RegClass);
1101 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1102 TII.get(TargetOpcode::SUBREG_TO_REG), ExtReg)
1112 AM.
Base.
Reg = GetCallRegForValue(V);
1117 AM.
IndexReg = GetCallRegForValue(V);
1127bool X86FastISel::X86SelectStore(
const Instruction *
I) {
1134 const Value *PtrV =
I->getOperand(1);
1135 if (TLI.supportSwiftError()) {
1139 if (Arg->hasSwiftErrorAttr())
1144 if (Alloca->isSwiftError())
1153 if (!isTypeLegal(Val->
getType(), VT,
true))
1164 return X86FastEmitStore(VT, Val, AM, createMachineMemOperandFor(
I),
Aligned);
1168bool X86FastISel::X86SelectRet(
const Instruction *
I) {
1170 const Function &
F = *
I->getParent()->getParent();
1171 const X86MachineFunctionInfo *X86MFInfo =
1172 FuncInfo.MF->getInfo<X86MachineFunctionInfo>();
1174 if (!FuncInfo.CanLowerReturn)
1177 if (TLI.supportSwiftError() &&
1178 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
1181 if (TLI.supportSplitCSR(FuncInfo.MF))
1184 CallingConv::ID CC =
F.getCallingConv();
1185 if (CC != CallingConv::C &&
1186 CC != CallingConv::Fast &&
1187 CC != CallingConv::Tail &&
1188 CC != CallingConv::SwiftTail &&
1189 CC != CallingConv::X86_FastCall &&
1190 CC != CallingConv::X86_StdCall &&
1191 CC != CallingConv::X86_ThisCall &&
1192 CC != CallingConv::X86_64_SysV &&
1193 CC != CallingConv::Win64)
1202 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
1203 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
1219 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
I->getContext());
1228 if (ValLocs.
size() != 1)
1231 CCValAssign &VA = ValLocs[0];
1246 EVT SrcVT = TLI.getValueType(
DL, RV->
getType());
1249 if (SrcVT != DstVT) {
1250 if (SrcVT != MVT::i1 && SrcVT != MVT::i8 && SrcVT != MVT::i16)
1253 if (!Outs[0].
Flags.isZExt() && !Outs[0].Flags.isSExt())
1256 if (SrcVT == MVT::i1) {
1257 if (Outs[0].
Flags.isSExt())
1259 SrcReg = fastEmitZExtFromI1(MVT::i8, SrcReg);
1262 if (SrcVT != DstVT) {
1276 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1277 TII.get(TargetOpcode::COPY), DstReg).
addReg(SrcReg);
1290 if (
F.hasStructRetAttr() && CC != CallingConv::Swift &&
1291 CC != CallingConv::SwiftTail) {
1294 "SRetReturnReg should have been set in LowerFormalArguments()!");
1295 Register RetReg = Subtarget->isTarget64BitLP64() ? X86::RAX : X86::EAX;
1296 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1302 MachineInstrBuilder MIB;
1304 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1305 TII.get(Subtarget->is64Bit() ? X86::RETI64 : X86::RETI32))
1308 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1309 TII.get(Subtarget->is64Bit() ? X86::RET64 : X86::RET32));
1318bool X86FastISel::X86SelectLoad(
const Instruction *
I) {
1325 const Value *
SV =
I->getOperand(0);
1326 if (TLI.supportSwiftError()) {
1330 if (Arg->hasSwiftErrorAttr())
1335 if (Alloca->isSwiftError())
1341 if (!isTypeLegal(LI->
getType(), VT,
true))
1351 if (!X86FastEmitLoad(VT, AM, createMachineMemOperandFor(LI), ResultReg,
1355 updateValueMap(
I, ResultReg);
1360 bool HasAVX512 = Subtarget->
hasAVX512();
1361 bool HasAVX = Subtarget->
hasAVX();
1362 bool HasSSE1 = Subtarget->
hasSSE1();
1363 bool HasSSE2 = Subtarget->
hasSSE2();
1367 case MVT::i8:
return X86::CMP8rr;
1368 case MVT::i16:
return X86::CMP16rr;
1369 case MVT::i32:
return X86::CMP32rr;
1370 case MVT::i64:
return X86::CMP64rr;
1372 return HasAVX512 ? X86::VUCOMISSZrr
1373 : HasAVX ? X86::VUCOMISSrr
1374 : HasSSE1 ? X86::UCOMISSrr
1377 return HasAVX512 ? X86::VUCOMISDZrr
1378 : HasAVX ? X86::VUCOMISDrr
1379 : HasSSE2 ? X86::UCOMISDrr
1394 return X86::CMP16ri;
1396 return X86::CMP32ri;
1404bool X86FastISel::X86FastEmitCompare(
const Value *Op0,
const Value *Op1, EVT VT,
1406 Register Op0Reg = getRegForValue(Op0);
1419 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareImmOpc))
1421 .
addImm(Op1C->getSExtValue());
1427 if (CompareOpc == 0)
return false;
1429 Register Op1Reg = getRegForValue(Op1);
1432 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareOpc))
1440 ((!Subtarget->hasZU() || Subtarget->preferLegacySetCC()) ? X86::SETCCr \
1447 if (!isTypeLegal(
I->getOperand(0)->getType(), VT))
1460 ResultReg = emitMOV32r0();
1461 ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultReg, X86::sub_8bit);
1467 ResultReg = createResultReg(&X86::GR8RegClass);
1468 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
1475 updateValueMap(
I, ResultReg);
1487 if (RHSC && RHSC->isNullValue())
1492 static const uint16_t SETFOpcTable[2][3] = {
1503 ResultReg = createResultReg(&X86::GR8RegClass);
1505 if (!X86FastEmitCompare(
LHS,
RHS, VT,
I->getDebugLoc()))
1508 Register FlagReg1 = createResultReg(&X86::GR8RegClass);
1509 Register FlagReg2 = createResultReg(&X86::GR8RegClass);
1516 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(SETFOpc[2]),
1518 updateValueMap(
I, ResultReg);
1531 if (!X86FastEmitCompare(
LHS,
RHS, VT,
I->getDebugLoc()))
1536 updateValueMap(
I, ResultReg);
1540bool X86FastISel::X86SelectZExt(
const Instruction *
I) {
1541 EVT DstVT = TLI.getValueType(
DL,
I->getType());
1542 if (!TLI.isTypeLegal(DstVT))
1545 Register ResultReg = getRegForValue(
I->getOperand(0));
1550 MVT SrcVT = TLI.getSimpleValueType(
DL,
I->getOperand(0)->getType());
1551 if (SrcVT == MVT::i1) {
1553 ResultReg = fastEmitZExtFromI1(MVT::i8, ResultReg);
1560 if (DstVT == MVT::i64) {
1565 case MVT::i8: MovInst = X86::MOVZX32rr8;
break;
1566 case MVT::i16: MovInst = X86::MOVZX32rr16;
break;
1567 case MVT::i32: MovInst = X86::MOV32rr;
break;
1571 Register Result32 = createResultReg(&X86::GR32RegClass);
1572 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(MovInst), Result32)
1575 ResultReg = createResultReg(&X86::GR64RegClass);
1576 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1577 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
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) {
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)
1862 .
addReg(CReg, RegState::Kill);
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 {
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))
1936 unsigned TypeIndex, OpIndex;
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];
1957 const DivRemEntry::DivRemResult &OpEntry =
TypeEntry.ResultTable[OpIndex];
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));
1979 if (VT == MVT::i16) {
1980 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Copy),
1982 .
addReg(Zero32, {}, X86::sub_16bit);
1983 }
else if (VT == MVT::i32) {
1984 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1987 }
else if (VT == MVT::i64) {
1988 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1989 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
1996 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1997 TII.get(OpEntry.OpDivRem)).
addReg(Op1Reg);
2007 if ((
I->getOpcode() == Instruction::SRem ||
2008 I->getOpcode() == Instruction::URem) &&
2009 OpEntry.DivRemResultReg == X86::AH && Subtarget->is64Bit()) {
2010 Register SourceSuperReg = createResultReg(&X86::GR16RegClass);
2011 Register ResultSuperReg = createResultReg(&X86::GR16RegClass);
2012 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2013 TII.get(Copy), SourceSuperReg).
addReg(X86::AX);
2016 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SHR16ri),
2020 ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultSuperReg,
2025 ResultReg = createResultReg(
TypeEntry.RC);
2026 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Copy), ResultReg)
2027 .
addReg(OpEntry.DivRemResultReg);
2029 updateValueMap(
I, ResultReg);
2036bool X86FastISel::X86FastEmitCMoveSelect(MVT RetVT,
const Instruction *
I) {
2038 if (!Subtarget->canUseCMOV())
2042 if (RetVT < MVT::i16 || RetVT > MVT::i64)
2047 bool NeedTest =
true;
2054 if (CI && (CI->getParent() ==
I->getParent())) {
2058 static const uint16_t SETFOpcTable[2][3] = {
2062 const uint16_t *SETFOpc =
nullptr;
2063 switch (Predicate) {
2066 SETFOpc = &SETFOpcTable[0][0];
2070 SETFOpc = &SETFOpcTable[1][0];
2084 EVT CmpVT = TLI.getValueType(
DL, CmpLHS->
getType());
2086 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
2090 Register FlagReg1 = createResultReg(&X86::GR8RegClass);
2091 Register FlagReg2 = createResultReg(&X86::GR8RegClass);
2098 auto const &
II =
TII.get(SETFOpc[2]);
2099 if (
II.getNumDefs()) {
2100 Register TmpReg = createResultReg(&X86::GR8RegClass);
2101 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, TmpReg)
2104 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
2109 }
else if (foldX86XALUIntrinsic(CC,
I,
Cond)) {
2130 if (MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2132 CondReg = createResultReg(&X86::GR32RegClass);
2133 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2134 TII.get(TargetOpcode::COPY), CondReg)
2136 CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, X86::sub_8bit);
2138 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
2148 if (!LHSReg || !RHSReg)
2151 const TargetRegisterInfo &
TRI = *Subtarget->getRegisterInfo();
2153 Subtarget->hasNDD());
2154 Register ResultReg = fastEmitInst_rri(
Opc, RC, RHSReg, LHSReg, CC);
2155 updateValueMap(
I, ResultReg);
2164bool X86FastISel::X86FastEmitSSESelect(MVT RetVT,
const Instruction *
I) {
2169 if (!CI || (CI->getParent() !=
I->getParent()))
2173 !((Subtarget->hasSSE1() && RetVT == MVT::f32) ||
2174 (Subtarget->hasSSE2() && RetVT == MVT::f64)))
2186 if (CmpRHSC && CmpRHSC->isNullValue())
2193 if (CC > 7 && !Subtarget->hasAVX())
2204 Register CmpLHSReg = getRegForValue(CmpLHS);
2205 Register CmpRHSReg = getRegForValue(CmpRHS);
2206 if (!LHSReg || !RHSReg || !CmpLHSReg || !CmpRHSReg)
2212 if (Subtarget->hasAVX512()) {
2217 unsigned CmpOpcode =
2218 (RetVT == MVT::f32) ? X86::VCMPSSZrri :
X86::VCMPSDZrri;
2219 Register CmpReg = fastEmitInst_rri(CmpOpcode, VK1, CmpLHSReg, CmpRHSReg,
2224 Register ImplicitDefReg = createResultReg(VR128X);
2225 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2226 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2230 unsigned MovOpcode =
2231 (RetVT == MVT::f32) ? X86::VMOVSSZrrk :
X86::VMOVSDZrrk;
2232 Register MovReg = fastEmitInst_rrrr(MovOpcode, VR128X, RHSReg, CmpReg,
2233 ImplicitDefReg, LHSReg);
2235 ResultReg = createResultReg(RC);
2236 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2237 TII.get(TargetOpcode::COPY), ResultReg).
addReg(MovReg);
2239 }
else if (Subtarget->hasAVX()) {
2247 unsigned CmpOpcode =
2248 (RetVT == MVT::f32) ? X86::VCMPSSrri :
X86::VCMPSDrri;
2249 unsigned BlendOpcode =
2250 (RetVT == MVT::f32) ? X86::VBLENDVPSrrr :
X86::VBLENDVPDrrr;
2252 Register CmpReg = fastEmitInst_rri(CmpOpcode, RC, CmpLHSReg, CmpRHSReg,
2254 Register VBlendReg = fastEmitInst_rrr(BlendOpcode, VR128, RHSReg, LHSReg,
2256 ResultReg = createResultReg(RC);
2257 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2258 TII.get(TargetOpcode::COPY), ResultReg).
addReg(VBlendReg);
2261 static const uint16_t OpcTable[2][4] = {
2262 { X86::CMPSSrri, X86::ANDPSrr, X86::ANDNPSrr, X86::ORPSrr },
2263 { X86::CMPSDrri, X86::ANDPDrr, X86::ANDNPDrr, X86::ORPDrr }
2266 const uint16_t *
Opc =
nullptr;
2268 default:
return false;
2269 case MVT::f32:
Opc = &OpcTable[0][0];
break;
2270 case MVT::f64:
Opc = &OpcTable[1][0];
break;
2274 Register CmpReg = fastEmitInst_rri(
Opc[0], RC, CmpLHSReg, CmpRHSReg, CC);
2275 Register AndReg = fastEmitInst_rr(
Opc[1], VR128, CmpReg, LHSReg);
2276 Register AndNReg = fastEmitInst_rr(
Opc[2], VR128, CmpReg, RHSReg);
2277 Register OrReg = fastEmitInst_rr(
Opc[3], VR128, AndNReg, AndReg);
2278 ResultReg = createResultReg(RC);
2279 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2280 TII.get(TargetOpcode::COPY), ResultReg).
addReg(OrReg);
2282 updateValueMap(
I, ResultReg);
2286bool X86FastISel::X86FastEmitPseudoSelect(MVT RetVT,
const Instruction *
I) {
2291 default:
return false;
2292 case MVT::i8:
Opc = X86::CMOV_GR8;
break;
2293 case MVT::i16:
Opc = X86::CMOV_GR16;
break;
2294 case MVT::i32:
Opc = X86::CMOV_GR32;
break;
2296 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR16X : X86::CMOV_FR16;
break;
2298 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR32X : X86::CMOV_FR32;
break;
2300 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR64X : X86::CMOV_FR64;
break;
2310 if (CI && (CI->getParent() ==
I->getParent())) {
2322 EVT CmpVT = TLI.getValueType(
DL, CmpLHS->
getType());
2323 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
2331 if (MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2333 CondReg = createResultReg(&X86::GR32RegClass);
2334 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2335 TII.get(TargetOpcode::COPY), CondReg)
2337 CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, X86::sub_8bit);
2339 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
2349 if (!LHSReg || !RHSReg)
2355 fastEmitInst_rri(
Opc, RC, RHSReg, LHSReg, CC);
2356 updateValueMap(
I, ResultReg);
2360bool X86FastISel::X86SelectSelect(
const Instruction *
I) {
2362 if (!isTypeLegal(
I->getType(), RetVT))
2368 const Value *Opnd =
nullptr;
2369 switch (Predicate) {
2376 Register OpReg = getRegForValue(Opnd);
2380 Register ResultReg = createResultReg(RC);
2381 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2382 TII.get(TargetOpcode::COPY), ResultReg)
2384 updateValueMap(
I, ResultReg);
2390 if (X86FastEmitCMoveSelect(RetVT,
I))
2394 if (X86FastEmitSSESelect(RetVT,
I))
2399 if (X86FastEmitPseudoSelect(RetVT,
I))
2406bool X86FastISel::X86SelectIntToFP(
const Instruction *
I,
bool IsSigned) {
2411 bool HasAVX512 = Subtarget->hasAVX512();
2412 if (!Subtarget->hasAVX() || (!IsSigned && !HasAVX512))
2416 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
2417 if (SrcVT != MVT::i32 && SrcVT != MVT::i64)
2421 Register OpReg = getRegForValue(
I->getOperand(0));
2427 static const uint16_t SCvtOpc[2][2][2] = {
2428 { { X86::VCVTSI2SSrr, X86::VCVTSI642SSrr },
2429 { X86::VCVTSI2SDrr, X86::VCVTSI642SDrr } },
2430 { { X86::VCVTSI2SSZrr, X86::VCVTSI642SSZrr },
2431 { X86::VCVTSI2SDZrr, X86::VCVTSI642SDZrr } },
2433 static const uint16_t UCvtOpc[2][2] = {
2434 { X86::VCVTUSI2SSZrr, X86::VCVTUSI642SSZrr },
2435 { X86::VCVTUSI2SDZrr, X86::VCVTUSI642SDZrr },
2437 bool Is64Bit = SrcVT == MVT::i64;
2439 if (
I->getType()->isDoubleTy()) {
2441 Opcode = IsSigned ? SCvtOpc[HasAVX512][1][Is64Bit] : UCvtOpc[1][Is64Bit];
2442 }
else if (
I->getType()->isFloatTy()) {
2444 Opcode = IsSigned ? SCvtOpc[HasAVX512][0][Is64Bit] : UCvtOpc[0][Is64Bit];
2450 Register ImplicitDefReg = createResultReg(RC);
2451 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2452 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2453 Register ResultReg = fastEmitInst_rr(Opcode, RC, ImplicitDefReg, OpReg);
2454 updateValueMap(
I, ResultReg);
2458bool X86FastISel::X86SelectSIToFP(
const Instruction *
I) {
2459 return X86SelectIntToFP(
I,
true);
2462bool X86FastISel::X86SelectUIToFP(
const Instruction *
I) {
2463 return X86SelectIntToFP(
I,
false);
2467bool X86FastISel::X86SelectFPExtOrFPTrunc(
const Instruction *
I,
2470 assert((
I->getOpcode() == Instruction::FPExt ||
2471 I->getOpcode() == Instruction::FPTrunc) &&
2472 "Instruction must be an FPExt or FPTrunc!");
2473 bool HasAVX = Subtarget->hasAVX();
2475 Register OpReg = getRegForValue(
I->getOperand(0));
2481 ImplicitDefReg = createResultReg(RC);
2482 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2483 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2487 Register ResultReg = createResultReg(RC);
2488 MachineInstrBuilder MIB;
2489 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpc),
2493 MIB.
addReg(ImplicitDefReg);
2496 updateValueMap(
I, ResultReg);
2500bool X86FastISel::X86SelectFPExt(
const Instruction *
I) {
2501 if (Subtarget->hasSSE2() &&
I->getType()->isDoubleTy() &&
2502 I->getOperand(0)->getType()->isFloatTy()) {
2503 bool HasAVX512 = Subtarget->hasAVX512();
2506 HasAVX512 ? X86::VCVTSS2SDZrr
2507 : Subtarget->hasAVX() ? X86::VCVTSS2SDrr : X86::CVTSS2SDrr;
2508 return X86SelectFPExtOrFPTrunc(
I,
Opc, TLI.getRegClassFor(MVT::f64));
2514bool X86FastISel::X86SelectFPTrunc(
const Instruction *
I) {
2515 if (Subtarget->hasSSE2() &&
I->getType()->isFloatTy() &&
2516 I->getOperand(0)->getType()->isDoubleTy()) {
2517 bool HasAVX512 = Subtarget->hasAVX512();
2520 HasAVX512 ? X86::VCVTSD2SSZrr
2521 : Subtarget->hasAVX() ? X86::VCVTSD2SSrr : X86::CVTSD2SSrr;
2522 return X86SelectFPExtOrFPTrunc(
I,
Opc, TLI.getRegClassFor(MVT::f32));
2528bool X86FastISel::X86SelectTrunc(
const Instruction *
I) {
2529 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
2530 EVT DstVT = TLI.getValueType(
DL,
I->getType());
2533 if (DstVT != MVT::i8 && DstVT != MVT::i1)
2535 if (!TLI.isTypeLegal(SrcVT))
2538 Register InputReg = getRegForValue(
I->getOperand(0));
2543 if (SrcVT == MVT::i8) {
2545 updateValueMap(
I, InputReg);
2550 Register ResultReg = fastEmitInst_extractsubreg(MVT::i8, InputReg,
2555 updateValueMap(
I, ResultReg);
2559bool X86FastISel::X86SelectBitCast(
const Instruction *
I) {
2562 if (!Subtarget->hasSSE2() ||
2563 !isTypeLegal(
I->getOperand(0)->getType(), SrcVT) ||
2564 !isTypeLegal(
I->getType(), DstVT))
2580 Register ResultReg = createResultReg(DstClass);
2581 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
2585 updateValueMap(
I, ResultReg);
2589bool X86FastISel::IsMemcpySmall(
uint64_t Len) {
2590 return Len <= (Subtarget->is64Bit() ? 32 : 16);
2593bool X86FastISel::TryEmitSmallMemcpy(X86AddressMode DestAM,
2594 X86AddressMode SrcAM,
uint64_t Len) {
2597 if (!IsMemcpySmall(Len))
2600 bool i64Legal = Subtarget->is64Bit();
2605 if (Len >= 8 && i64Legal)
2615 bool RV = X86FastEmitLoad(VT, SrcAM,
nullptr,
Reg);
2616 RV &= X86FastEmitStore(VT,
Reg, DestAM);
2617 assert(RV &&
"Failed to emit load or store??");
2629bool X86FastISel::fastLowerIntrinsicCall(
const IntrinsicInst *
II) {
2631 switch (
II->getIntrinsicID()) {
2634 case Intrinsic::frameaddress: {
2639 Type *RetTy =
II->getCalledFunction()->getReturnType();
2642 if (!isTypeLegal(RetTy, VT))
2650 case MVT::i32:
Opc = X86::MOV32rm; RC = &X86::GR32RegClass;
break;
2651 case MVT::i64:
Opc = X86::MOV64rm; RC = &X86::GR64RegClass;
break;
2659 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2661 assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
2662 (FrameReg == X86::EBP && VT == MVT::i32)) &&
2663 "Invalid Frame Register!");
2668 Register SrcReg = createResultReg(RC);
2669 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2670 TII.get(TargetOpcode::COPY), SrcReg).
addReg(FrameReg);
2679 Register DestReg = createResultReg(RC);
2681 TII.get(
Opc), DestReg), SrcReg);
2685 updateValueMap(
II, SrcReg);
2688 case Intrinsic::memcpy: {
2698 if (IsMemcpySmall(Len)) {
2699 X86AddressMode DestAM, SrcAM;
2703 TryEmitSmallMemcpy(DestAM, SrcAM, Len);
2708 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2715 return lowerCallTo(
II,
"memcpy",
II->arg_size() - 1);
2717 case Intrinsic::memset: {
2723 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2730 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
2732 case Intrinsic::stackprotector: {
2734 EVT PtrTy = TLI.getPointerTy(
DL);
2736 const Value *Op1 =
II->getArgOperand(0);
2744 if (!X86FastEmitStore(PtrTy, Op1, AM))
return false;
2747 case Intrinsic::dbg_declare: {
2753 const MCInstrDesc &
II =
TII.get(TargetOpcode::DBG_VALUE);
2755 "Expected inlined-at fields to agree");
2762 case Intrinsic::trap: {
2763 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TRAP));
2766 case Intrinsic::sqrt: {
2767 if (!Subtarget->hasSSE1())
2770 Type *RetTy =
II->getCalledFunction()->getReturnType();
2773 if (!isTypeLegal(RetTy, VT))
2779 static const uint16_t SqrtOpc[3][2] = {
2780 { X86::SQRTSSr, X86::SQRTSDr },
2781 { X86::VSQRTSSr, X86::VSQRTSDr },
2782 { X86::VSQRTSSZr, X86::VSQRTSDZr },
2784 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
2785 Subtarget->hasAVX() ? 1 :
2789 default:
return false;
2790 case MVT::f32:
Opc = SqrtOpc[AVXLevel][0];
break;
2791 case MVT::f64:
Opc = SqrtOpc[AVXLevel][1];
break;
2794 const Value *SrcVal =
II->getArgOperand(0);
2795 Register SrcReg = getRegForValue(SrcVal);
2803 ImplicitDefReg = createResultReg(RC);
2804 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2805 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2808 Register ResultReg = createResultReg(RC);
2809 MachineInstrBuilder MIB;
2810 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
2814 MIB.
addReg(ImplicitDefReg);
2818 updateValueMap(
II, ResultReg);
2821 case Intrinsic::sadd_with_overflow:
2822 case Intrinsic::uadd_with_overflow:
2823 case Intrinsic::ssub_with_overflow:
2824 case Intrinsic::usub_with_overflow:
2825 case Intrinsic::smul_with_overflow:
2826 case Intrinsic::umul_with_overflow: {
2831 Type *RetTy = Ty->getTypeAtIndex(0U);
2834 "Overflow value expected to be an i1");
2837 if (!isTypeLegal(RetTy, VT))
2840 if (VT < MVT::i8 || VT > MVT::i64)
2851 switch (
II->getIntrinsicID()) {
2853 case Intrinsic::sadd_with_overflow:
2855 case Intrinsic::uadd_with_overflow:
2857 case Intrinsic::ssub_with_overflow:
2859 case Intrinsic::usub_with_overflow:
2861 case Intrinsic::smul_with_overflow:
2863 case Intrinsic::umul_with_overflow:
2874 static const uint16_t
Opc[2][4] = {
2875 { X86::INC8r, X86::INC16r, X86::INC32r, X86::INC64r },
2876 { X86::DEC8r, X86::DEC16r, X86::DEC32r, X86::DEC64r }
2882 ResultReg = createResultReg(TLI.getRegClassFor(VT));
2884 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2888 ResultReg = fastEmit_ri(VT, VT, BaseOpc, LHSReg, CI->
getZExtValue());
2893 RHSReg = getRegForValue(
RHS);
2896 ResultReg = fastEmit_rr(VT, VT, BaseOpc, LHSReg, RHSReg);
2901 if (BaseOpc == X86ISD::UMUL && !ResultReg) {
2902 static const uint16_t MULOpc[] =
2903 { X86::MUL8r, X86::MUL16r, X86::MUL32r, X86::MUL64r };
2904 static const MCPhysReg Reg[] = { X86::AL, X86::AX, X86::EAX, X86::RAX };
2907 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2910 ResultReg = fastEmitInst_r(MULOpc[VT.
SimpleTy-MVT::i8],
2911 TLI.getRegClassFor(VT), RHSReg);
2912 }
else if (BaseOpc == X86ISD::SMUL && !ResultReg) {
2913 static const uint16_t MULOpc[] =
2914 { X86::IMUL8r, X86::IMUL16rr, X86::IMUL32rr, X86::IMUL64rr };
2915 if (VT == MVT::i8) {
2918 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2919 TII.get(TargetOpcode::COPY), X86::AL)
2921 ResultReg = fastEmitInst_r(MULOpc[0], TLI.getRegClassFor(VT), RHSReg);
2923 ResultReg = fastEmitInst_rr(MULOpc[VT.
SimpleTy-MVT::i8],
2924 TLI.getRegClassFor(VT), LHSReg, RHSReg);
2931 Register ResultReg2 = createResultReg(&X86::GR8RegClass);
2932 assert((ResultReg+1) == ResultReg2 &&
"Nonconsecutive result registers.");
2937 updateValueMap(
II, ResultReg, 2);
2940 case Intrinsic::x86_sse_cvttss2si:
2941 case Intrinsic::x86_sse_cvttss2si64:
2942 case Intrinsic::x86_sse2_cvttsd2si:
2943 case Intrinsic::x86_sse2_cvttsd2si64: {
2945 switch (
II->getIntrinsicID()) {
2947 case Intrinsic::x86_sse_cvttss2si:
2948 case Intrinsic::x86_sse_cvttss2si64:
2949 if (!Subtarget->hasSSE1())
2951 IsInputDouble =
false;
2953 case Intrinsic::x86_sse2_cvttsd2si:
2954 case Intrinsic::x86_sse2_cvttsd2si64:
2955 if (!Subtarget->hasSSE2())
2957 IsInputDouble =
true;
2961 Type *RetTy =
II->getCalledFunction()->getReturnType();
2963 if (!isTypeLegal(RetTy, VT))
2966 static const uint16_t CvtOpc[3][2][2] = {
2967 { { X86::CVTTSS2SIrr, X86::CVTTSS2SI64rr },
2968 { X86::CVTTSD2SIrr, X86::CVTTSD2SI64rr } },
2969 { { X86::VCVTTSS2SIrr, X86::VCVTTSS2SI64rr },
2970 { X86::VCVTTSD2SIrr, X86::VCVTTSD2SI64rr } },
2971 { { X86::VCVTTSS2SIZrr, X86::VCVTTSS2SI64Zrr },
2972 { X86::VCVTTSD2SIZrr, X86::VCVTTSD2SI64Zrr } },
2974 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
2975 Subtarget->hasAVX() ? 1 :
2980 case MVT::i32:
Opc = CvtOpc[AVXLevel][IsInputDouble][0];
break;
2981 case MVT::i64:
Opc = CvtOpc[AVXLevel][IsInputDouble][1];
break;
2993 Op =
IE->getOperand(1);
2996 Op =
IE->getOperand(0);
3003 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3004 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
3007 updateValueMap(
II, ResultReg);
3010 case Intrinsic::x86_sse42_crc32_32_8:
3011 case Intrinsic::x86_sse42_crc32_32_16:
3012 case Intrinsic::x86_sse42_crc32_32_32:
3013 case Intrinsic::x86_sse42_crc32_64_64: {
3014 if (!Subtarget->hasCRC32())
3017 Type *RetTy =
II->getCalledFunction()->getReturnType();
3020 if (!isTypeLegal(RetTy, VT))
3026 switch (
II->getIntrinsicID()) {
3029#define GET_EGPR_IF_ENABLED(OPC) Subtarget->hasEGPR() ? OPC##_EVEX : OPC
3030 case Intrinsic::x86_sse42_crc32_32_8:
3032 RC = &X86::GR32RegClass;
3034 case Intrinsic::x86_sse42_crc32_32_16:
3036 RC = &X86::GR32RegClass;
3038 case Intrinsic::x86_sse42_crc32_32_32:
3040 RC = &X86::GR32RegClass;
3042 case Intrinsic::x86_sse42_crc32_64_64:
3044 RC = &X86::GR64RegClass;
3046#undef GET_EGPR_IF_ENABLED
3054 if (!LHSReg || !RHSReg)
3057 Register ResultReg = fastEmitInst_rr(
Opc, RC, LHSReg, RHSReg);
3061 updateValueMap(
II, ResultReg);
3067bool X86FastISel::fastLowerArguments() {
3068 if (!FuncInfo.CanLowerReturn)
3075 CallingConv::ID CC =
F->getCallingConv();
3076 if (CC != CallingConv::C)
3079 if (Subtarget->isCallingConvWin64(CC))
3082 if (!Subtarget->is64Bit())
3085 if (Subtarget->useSoftFloat())
3089 unsigned GPRCnt = 0;
3090 unsigned FPRCnt = 0;
3091 for (
auto const &Arg :
F->args()) {
3092 if (Arg.hasAttribute(Attribute::ByVal) ||
3093 Arg.hasAttribute(Attribute::InReg) ||
3094 Arg.hasAttribute(Attribute::StructRet) ||
3095 Arg.hasAttribute(Attribute::SwiftSelf) ||
3096 Arg.hasAttribute(Attribute::SwiftAsync) ||
3097 Arg.hasAttribute(Attribute::SwiftError) ||
3098 Arg.hasAttribute(Attribute::Nest))
3101 Type *ArgTy = Arg.getType();
3105 EVT ArgVT = TLI.getValueType(
DL, ArgTy);
3106 if (!ArgVT.
isSimple())
return false;
3108 default:
return false;
3115 if (!Subtarget->hasSSE1())
3128 static const MCPhysReg GPR32ArgRegs[] = {
3129 X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
3131 static const MCPhysReg GPR64ArgRegs[] = {
3132 X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8 , X86::R9
3135 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3136 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3139 unsigned GPRIdx = 0;
3140 unsigned FPRIdx = 0;
3141 for (
auto const &Arg :
F->args()) {
3142 MVT VT = TLI.getSimpleValueType(
DL, Arg.getType());
3147 case MVT::i32: SrcReg = GPR32ArgRegs[GPRIdx++];
break;
3148 case MVT::i64: SrcReg = GPR64ArgRegs[GPRIdx++];
break;
3149 case MVT::f32: [[fallthrough]];
3150 case MVT::f64: SrcReg = XMMArgRegs[FPRIdx++];
break;
3152 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
3156 Register ResultReg = createResultReg(RC);
3157 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3158 TII.get(TargetOpcode::COPY), ResultReg)
3160 updateValueMap(&Arg, ResultReg);
3168 if (Subtarget->is64Bit())
3185bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
3186 auto &OutVals = CLI.OutVals;
3187 auto &OutFlags = CLI.OutFlags;
3188 auto &OutRegs = CLI.OutRegs;
3189 auto &Ins = CLI.Ins;
3190 auto &InRegs = CLI.InRegs;
3191 CallingConv::ID CC = CLI.CallConv;
3192 bool &IsTailCall = CLI.IsTailCall;
3193 bool IsVarArg = CLI.IsVarArg;
3196 const auto *CB = CLI.CB;
3198 bool Is64Bit = Subtarget->is64Bit();
3199 bool IsWin64 = Subtarget->isCallingConvWin64(CC);
3211 for (
Type *RetTy : RetTys) {
3212 MVT RetVT = MVT::Other;
3213 if (!isTypeLegal(RetTy, RetVT)) {
3214 if (RetVT == MVT::Other)
3219 MVT ABIVT = TLI.getRegisterTypeForCallingConv(CLI.RetTy->getContext(),
3220 CLI.CallConv, RetVT);
3221 MVT RegVT = TLI.getRegisterType(CLI.RetTy->getContext(), RetVT);
3229 if (CB && CB->doesNoCfCheck())
3233 if ((CB &&
isa<CallInst>(CB) && CB->hasFnAttr(
"no_caller_saved_registers")))
3237 if ((CB && CB->hasFnAttr(
"no_callee_saved_registers")))
3245 if (Subtarget->useIndirectThunkCalls())
3250 default:
return false;
3251 case CallingConv::C:
3252 case CallingConv::Fast:
3253 case CallingConv::Tail:
3254 case CallingConv::Swift:
3255 case CallingConv::SwiftTail:
3256 case CallingConv::X86_FastCall:
3257 case CallingConv::X86_StdCall:
3258 case CallingConv::X86_ThisCall:
3259 case CallingConv::Win64:
3260 case CallingConv::X86_64_SysV:
3261 case CallingConv::CFGuard_Check:
3271 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
3272 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
3277 if (IsVarArg && IsWin64)
3281 if (CLI.CB && CLI.CB->hasInAllocaArgument())
3284 for (
auto Flag : CLI.OutFlags)
3285 if (
Flag.isSwiftError() ||
Flag.isPreallocated())
3295 SmallVector<Register, 16> ArgRegs;
3300 for (
int i = 0, e = OutVals.size(); i != e; ++i) {
3301 Value *&Val = OutVals[i];
3302 ISD::ArgFlagsTy
Flags = OutFlags[i];
3317 if (TI && TI->getType()->isIntegerTy(1) && CLI.CB &&
3318 (TI->getParent() == CLI.CB->getParent()) && TI->hasOneUse()) {
3319 Value *PrevVal = TI->getOperand(0);
3320 ResultReg = getRegForValue(PrevVal);
3325 if (!isTypeLegal(PrevVal->
getType(), VT))
3328 ResultReg = fastEmit_ri(VT, VT,
ISD::AND, ResultReg, 1);
3332 ResultReg = getRegForValue(Val);
3345 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, CLI.RetTy->getContext());
3349 CCInfo.AllocateStack(32,
Align(8));
3351 CCInfo.AnalyzeCallOperands(OutVTs, OutFlags, ArgTys,
CC_X86);
3354 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
3357 unsigned AdjStackDown =
TII.getCallFrameSetupOpcode();
3358 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackDown))
3362 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3363 for (
const CCValAssign &VA : ArgLocs) {
3367 if (ArgVT == MVT::x86mmx)
3377 "Unexpected extend");
3379 if (ArgVT == MVT::i1)
3384 assert(Emitted &&
"Failed to emit a sext!"); (void)Emitted;
3390 "Unexpected extend");
3393 if (ArgVT == MVT::i1) {
3395 ArgReg = fastEmitZExtFromI1(MVT::i8, ArgReg);
3404 assert(Emitted &&
"Failed to emit a zext!"); (void)Emitted;
3410 "Unexpected extend");
3420 assert(Emitted &&
"Failed to emit a aext!"); (void)Emitted;
3426 assert(ArgReg &&
"Failed to emit a bitcast!");
3447 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3460 AM.
Disp = LocMemOffset;
3463 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3466 if (
Flags.isByVal()) {
3467 X86AddressMode SrcAM;
3469 if (!TryEmitSmallMemcpy(AM, SrcAM,
Flags.getByValSize()))
3475 if (!X86FastEmitStore(ArgVT, ArgVal, AM, MMO))
3478 if (!X86FastEmitStore(ArgVT, ArgReg, AM, MMO))
3486 if (Subtarget->isPICStyleGOT()) {
3487 Register Base = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3488 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3492 if (Is64Bit && IsVarArg && !IsWin64) {
3503 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3504 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3506 unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs);
3507 assert((Subtarget->hasSSE1() || !NumXMMRegs)
3508 &&
"SSE registers cannot be used when SSE is disabled");
3509 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
3510 X86::AL).
addImm(NumXMMRegs);
3515 X86AddressMode CalleeAM;
3516 if (!X86SelectCallAddress(Callee, CalleeAM))
3520 const GlobalValue *GV =
nullptr;
3521 if (CalleeAM.
GV !=
nullptr) {
3523 }
else if (CalleeAM.
Base.
Reg) {
3529 MachineInstrBuilder MIB;
3532 unsigned CallOpc = Is64Bit ? X86::CALL64r : X86::CALL32r;
3533 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc))
3537 assert(GV &&
"Not a direct call");
3539 unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV);
3551 unsigned CallOpc = NeedLoad
3552 ? (Is64Bit ? X86::CALL64m : X86::CALL32m)
3553 : (Is64Bit ?
X86::CALL64pcrel32 :
X86::CALLpcrel32);
3555 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc));
3559 MIB.
addSym(Symbol, OpFlags);
3571 if (Subtarget->isPICStyleGOT())
3572 MIB.
addReg(X86::EBX, RegState::Implicit);
3574 if (Is64Bit && IsVarArg && !IsWin64)
3575 MIB.
addReg(X86::AL, RegState::Implicit);
3578 for (
auto Reg : OutRegs)
3582 unsigned NumBytesForCalleeToPop =
3584 TM.Options.GuaranteedTailCallOpt)
3587 unsigned AdjStackUp =
TII.getCallFrameDestroyOpcode();
3588 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackUp))
3593 CCState CCRetInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs,
3594 CLI.RetTy->getContext());
3595 CCRetInfo.AnalyzeCallResult(Ins,
RetCC_X86);
3598 Register ResultReg = FuncInfo.CreateRegs(CLI.RetTy);
3599 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
3600 CCValAssign &VA = RVLocs[i];
3606 if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) &&
3607 ((Is64Bit || Ins[i].
Flags.isInReg()) && !Subtarget->hasSSE1())) {
3613 if ((SrcReg == X86::FP0 || SrcReg == X86::FP1) &&
3614 isScalarFPTypeInSSEReg(VA.
getValVT())) {
3616 CopyReg = createResultReg(&X86::RFP80RegClass);
3620 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3621 TII.get(TargetOpcode::COPY), CopyReg).
addReg(SrcReg);
3629 unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
3635 Opc = ResVT == MVT::f32 ? X86::MOVSSrm_alt : X86::MOVSDrm_alt;
3637 TII.get(
Opc), ResultReg + i), FI);
3641 CLI.ResultReg = ResultReg;
3642 CLI.NumResultRegs = RVLocs.
size();
3646 if (TM.Options.EmitCallGraphSection && CB && CB->isIndirectCall()) {
3647 MachineFunction::CallSiteInfo CSInfo(*CB);
3655X86FastISel::fastSelectInstruction(
const Instruction *
I) {
3656 switch (
I->getOpcode()) {
3658 case Instruction::Load:
3659 return X86SelectLoad(
I);
3660 case Instruction::Store:
3661 return X86SelectStore(
I);
3662 case Instruction::Ret:
3663 return X86SelectRet(
I);
3664 case Instruction::ICmp:
3665 case Instruction::FCmp:
3666 return X86SelectCmp(
I);
3667 case Instruction::ZExt:
3668 return X86SelectZExt(
I);
3669 case Instruction::SExt:
3670 return X86SelectSExt(
I);
3671 case Instruction::CondBr:
3672 return X86SelectBranch(
I);
3673 case Instruction::LShr:
3674 case Instruction::AShr:
3675 case Instruction::Shl:
3676 return X86SelectShift(
I);
3677 case Instruction::SDiv:
3678 case Instruction::UDiv:
3679 case Instruction::SRem:
3680 case Instruction::URem:
3681 return X86SelectDivRem(
I);
3682 case Instruction::Select:
3683 return X86SelectSelect(
I);
3684 case Instruction::Trunc:
3685 return X86SelectTrunc(
I);
3686 case Instruction::FPExt:
3687 return X86SelectFPExt(
I);
3688 case Instruction::FPTrunc:
3689 return X86SelectFPTrunc(
I);
3690 case Instruction::SIToFP:
3691 return X86SelectSIToFP(
I);
3692 case Instruction::UIToFP:
3693 return X86SelectUIToFP(
I);
3694 case Instruction::IntToPtr:
3695 case Instruction::PtrToInt: {
3696 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
3697 EVT DstVT = TLI.getValueType(
DL,
I->getType());
3699 return X86SelectZExt(
I);
3701 return X86SelectTrunc(
I);
3705 updateValueMap(
I,
Reg);
3708 case Instruction::BitCast:
3709 return X86SelectBitCast(
I);
3715Register X86FastISel::emitMOV32r0() {
3716 Register ResultReg = createResultReg(&X86::GR32RegClass);
3717 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32r0),
3723Register X86FastISel::X86MaterializeInt(
const ConstantInt *CI, MVT VT) {
3734 return fastEmitInst_extractsubreg(MVT::i8, SrcReg, X86::sub_8bit);
3736 return fastEmitInst_extractsubreg(MVT::i16, SrcReg, X86::sub_16bit);
3740 Register ResultReg = createResultReg(&X86::GR64RegClass);
3741 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3742 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3756 case MVT::i8:
Opc = X86::MOV8ri;
break;
3757 case MVT::i16:
Opc = X86::MOV16ri;
break;
3758 case MVT::i32:
Opc = X86::MOV32ri;
break;
3763 return fastEmitInst_i(
Opc, TLI.getRegClassFor(VT),
Imm);
3766Register X86FastISel::X86MaterializeFP(
const ConstantFP *CFP, MVT VT) {
3768 return fastMaterializeFloatZero(CFP);
3778 bool HasSSE1 = Subtarget->hasSSE1();
3779 bool HasSSE2 = Subtarget->hasSSE2();
3780 bool HasAVX = Subtarget->hasAVX();
3781 bool HasAVX512 = Subtarget->hasAVX512();
3786 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
3787 : HasAVX ? X86::VMOVSSrm_alt
3788 : HasSSE1 ? X86::MOVSSrm_alt
3792 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
3793 : HasAVX ? X86::VMOVSDrm_alt
3794 : HasSSE2 ? X86::MOVSDrm_alt
3807 unsigned char OpFlag = Subtarget->classifyLocalReference(
nullptr);
3809 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3811 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3816 unsigned CPI = MCP.getConstantPoolIndex(CFP, Alignment);
3821 Register AddrReg = createResultReg(&X86::GR64RegClass);
3822 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3825 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3826 TII.get(
Opc), ResultReg);
3827 addRegReg(MIB, AddrReg,
false, X86::NoSubRegister, PICBase,
false,
3828 X86::NoSubRegister);
3829 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3837 TII.get(
Opc), ResultReg),
3838 CPI, PICBase, OpFlag);
3842Register X86FastISel::X86MaterializeGV(
const GlobalValue *GV, MVT VT) {
3847 if (TM.isLargeGlobalValue(GV))
3859 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3861 TLI.getPointerTy(
DL) == MVT::i64) {
3864 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3869 TLI.getPointerTy(
DL) == MVT::i32
3870 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3873 TII.get(
Opc), ResultReg), AM);
3880Register X86FastISel::fastMaterializeConstant(
const Constant *
C) {
3881 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
3889 return X86MaterializeInt(CI, VT);
3891 return X86MaterializeFP(CFP, VT);
3893 return X86MaterializeGV(GV, VT);
3900 if (!Subtarget->hasSSE1())
3901 Opc = X86::LD_Fp032;
3904 if (!Subtarget->hasSSE2())
3905 Opc = X86::LD_Fp064;
3908 Opc = X86::LD_Fp080;
3913 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3914 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
3923Register X86FastISel::fastMaterializeAlloca(
const AllocaInst *
C) {
3931 if (!FuncInfo.StaticAllocaMap.count(
C))
3933 assert(
C->isStaticAlloca() &&
"dynamic alloca in the static alloca map?");
3939 TLI.getPointerTy(
DL) == MVT::i32
3940 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3943 Register ResultReg = createResultReg(RC);
3945 TII.get(
Opc), ResultReg), AM);
3949Register X86FastISel::fastMaterializeFloatZero(
const ConstantFP *CF) {
3951 if (!isTypeLegal(CF->
getType(), VT))
3955 bool HasSSE1 = Subtarget->hasSSE1();
3956 bool HasSSE2 = Subtarget->hasSSE2();
3957 bool HasAVX512 = Subtarget->hasAVX512();
3962 Opc = HasAVX512 ? X86::AVX512_FsFLD0SH : X86::FsFLD0SH;
3965 Opc = HasAVX512 ? X86::AVX512_FsFLD0SS
3966 : HasSSE1 ? X86::FsFLD0SS
3970 Opc = HasAVX512 ? X86::AVX512_FsFLD0SD
3971 : HasSSE2 ? X86::FsFLD0SD
3979 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3980 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
3984bool X86FastISel::tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
3985 const LoadInst *LI) {
3991 const X86InstrInfo &XII = (
const X86InstrInfo &)
TII;
3998 MachineInstr *CopyMI =
nullptr;
4000 *FuncInfo.MF, *
MI, OpNo, AddrOps, FuncInfo.InsertPt,
Size, LI->
getAlign(),
4010 unsigned OperandNo = 0;
4012 E =
Result->operands_end();
I !=
E; ++
I, ++OperandNo) {
4013 MachineOperand &MO = *
I;
4019 if (IndexReg == MO.
getReg())
4025 FuncInfo.MF->moveAdditionalCallInfo(
MI, Result);
4026 Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
4027 Result->cloneInstrSymbols(*FuncInfo.MF, *
MI);
4029 removeDeadCode(
I, std::next(
I));
4033Register X86FastISel::fastEmitInst_rrrr(
unsigned MachineInstOpcode,
4037 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
4039 Register ResultReg = createResultReg(RC);
4045 if (
II.getNumDefs() >= 1)
4046 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
4052 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
4057 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
4068 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