36#include "llvm/IR/IntrinsicsX86.h"
47class X86FastISel final :
public FastISel {
50 const X86Subtarget *Subtarget;
53 explicit X86FastISel(FunctionLoweringInfo &funcInfo,
54 const TargetLibraryInfo *libInfo)
55 : FastISel(funcInfo, libInfo) {
59 bool fastSelectInstruction(
const Instruction *
I)
override;
65 bool tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
66 const LoadInst *LI)
override;
68 bool fastLowerArguments()
override;
69 bool fastLowerCall(CallLoweringInfo &CLI)
override;
70 bool fastLowerIntrinsicCall(
const IntrinsicInst *
II)
override;
72#include "X86GenFastISel.inc"
78 bool X86FastEmitLoad(MVT VT, X86AddressMode &AM, MachineMemOperand *MMO,
79 Register &ResultReg,
unsigned Alignment = 1);
81 bool X86FastEmitStore(EVT VT,
const Value *Val, X86AddressMode &AM,
82 MachineMemOperand *MMO =
nullptr,
bool Aligned =
false);
83 bool X86FastEmitStore(EVT VT,
Register ValReg, X86AddressMode &AM,
84 MachineMemOperand *MMO =
nullptr,
bool Aligned =
false);
90 bool X86SelectCallAddress(
const Value *V, X86AddressMode &AM);
92 bool X86SelectLoad(
const Instruction *
I);
94 bool X86SelectStore(
const Instruction *
I);
96 bool X86SelectRet(
const Instruction *
I);
98 bool X86SelectCmp(
const Instruction *
I);
100 bool X86SelectZExt(
const Instruction *
I);
102 bool X86SelectSExt(
const Instruction *
I);
104 bool X86SelectBranch(
const Instruction *
I);
106 bool X86SelectShift(
const Instruction *
I);
108 bool X86SelectDivRem(
const Instruction *
I);
110 bool X86FastEmitCMoveSelect(MVT RetVT,
const Instruction *
I);
112 bool X86FastEmitSSESelect(MVT RetVT,
const Instruction *
I);
114 bool X86FastEmitPseudoSelect(MVT RetVT,
const Instruction *
I);
116 bool X86SelectSelect(
const Instruction *
I);
118 bool X86SelectTrunc(
const Instruction *
I);
120 bool X86SelectFPExtOrFPTrunc(
const Instruction *
I,
unsigned Opc,
121 const TargetRegisterClass *RC);
123 bool X86SelectFPExt(
const Instruction *
I);
124 bool X86SelectFPTrunc(
const Instruction *
I);
125 bool X86SelectSIToFP(
const Instruction *
I);
126 bool X86SelectUIToFP(
const Instruction *
I);
127 bool X86SelectIntToFP(
const Instruction *
I,
bool IsSigned);
128 bool X86SelectBitCast(
const Instruction *
I);
130 const X86InstrInfo *getInstrInfo()
const {
131 return Subtarget->getInstrInfo();
133 const X86TargetMachine *getTargetMachine()
const {
134 return static_cast<const X86TargetMachine *
>(&TM);
137 bool handleConstantAddresses(
const Value *V, X86AddressMode &AM);
139 Register X86MaterializeInt(
const ConstantInt *CI, MVT VT);
140 Register X86MaterializeFP(
const ConstantFP *CFP, MVT VT);
141 Register X86MaterializeGV(
const GlobalValue *GV, MVT VT);
142 Register fastMaterializeConstant(
const Constant *
C)
override;
144 Register fastMaterializeAlloca(
const AllocaInst *
C)
override;
146 Register fastMaterializeFloatZero(
const ConstantFP *CF)
override;
150 bool isScalarFPTypeInSSEReg(EVT VT)
const {
151 return (VT == MVT::f64 && Subtarget->hasSSE2()) ||
152 (VT == MVT::f32 && Subtarget->hasSSE1()) || VT == MVT::f16;
155 bool isTypeLegal(
Type *Ty, MVT &VT,
bool AllowI1 =
false);
157 bool IsMemcpySmall(uint64_t Len);
159 bool TryEmitSmallMemcpy(X86AddressMode DestAM,
160 X86AddressMode SrcAM, uint64_t Len);
162 bool foldX86XALUIntrinsic(
X86::CondCode &CC,
const Instruction *
I,
165 const MachineInstrBuilder &
addFullAddress(
const MachineInstrBuilder &MIB,
168 Register fastEmitInst_rrrr(
unsigned MachineInstOpcode,
169 const TargetRegisterClass *RC,
Register Op0,
175static std::pair<unsigned, bool>
178 bool NeedSwap =
false;
207 return std::make_pair(CC, NeedSwap);
221 return ::addFullAddress(MIB, AM);
226bool X86FastISel::foldX86XALUIntrinsic(
X86::CondCode &CC,
const Instruction *
I,
240 if (!isTypeLegal(RetTy, RetVT))
243 if (RetVT != MVT::i32 && RetVT != MVT::i64)
247 switch (
II->getIntrinsicID()) {
248 default:
return false;
249 case Intrinsic::sadd_with_overflow:
250 case Intrinsic::ssub_with_overflow:
251 case Intrinsic::smul_with_overflow:
252 case Intrinsic::umul_with_overflow: TmpCC =
X86::COND_O;
break;
253 case Intrinsic::uadd_with_overflow:
254 case Intrinsic::usub_with_overflow: TmpCC =
X86::COND_B;
break;
258 if (
II->getParent() !=
I->getParent())
264 for (
auto Itr = std::prev(Start); Itr != End; --Itr) {
272 if (EVI->getAggregateOperand() !=
II)
278 auto HasPhis = [](
const BasicBlock *Succ) {
return !Succ->phis().empty(); };
291bool X86FastISel::isTypeLegal(
Type *Ty, MVT &VT,
bool AllowI1) {
292 EVT evt = TLI.getValueType(
DL, Ty,
true);
293 if (evt == MVT::Other || !evt.
isSimple())
300 if (VT == MVT::f64 && !Subtarget->hasSSE2())
302 if (VT == MVT::f32 && !Subtarget->hasSSE1())
311 return (AllowI1 && VT == MVT::i1) || TLI.isTypeLegal(VT);
317bool X86FastISel::X86FastEmitLoad(MVT VT, X86AddressMode &AM,
318 MachineMemOperand *MMO,
Register &ResultReg,
319 unsigned Alignment) {
320 bool HasSSE1 = Subtarget->hasSSE1();
321 bool HasSSE2 = Subtarget->hasSSE2();
322 bool HasSSE41 = Subtarget->hasSSE41();
323 bool HasAVX = Subtarget->hasAVX();
324 bool HasAVX2 = Subtarget->hasAVX2();
325 bool HasAVX512 = Subtarget->hasAVX512();
326 bool HasVLX = Subtarget->hasVLX();
336 default:
return false;
351 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
352 : HasAVX ? X86::VMOVSSrm_alt
353 : HasSSE1 ? X86::MOVSSrm_alt
357 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
358 : HasAVX ? X86::VMOVSDrm_alt
359 : HasSSE2 ? X86::MOVSDrm_alt
366 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
367 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
368 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
369 else if (Alignment >= 16)
370 Opc = HasVLX ? X86::VMOVAPSZ128rm :
371 HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm;
373 Opc = HasVLX ? X86::VMOVUPSZ128rm :
374 HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm;
377 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
378 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
379 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
380 else if (Alignment >= 16)
381 Opc = HasVLX ? X86::VMOVAPDZ128rm :
382 HasAVX ? X86::VMOVAPDrm : X86::MOVAPDrm;
384 Opc = HasVLX ? X86::VMOVUPDZ128rm :
385 HasAVX ? X86::VMOVUPDrm : X86::MOVUPDrm;
391 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
392 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
393 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
394 else if (Alignment >= 16)
395 Opc = HasVLX ? X86::VMOVDQA64Z128rm :
396 HasAVX ? X86::VMOVDQArm : X86::MOVDQArm;
398 Opc = HasVLX ? X86::VMOVDQU64Z128rm :
399 HasAVX ? X86::VMOVDQUrm : X86::MOVDQUrm;
403 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
404 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
405 else if (IsNonTemporal && Alignment >= 16)
407 else if (Alignment >= 32)
408 Opc = HasVLX ? X86::VMOVAPSZ256rm : X86::VMOVAPSYrm;
410 Opc = HasVLX ? X86::VMOVUPSZ256rm : X86::VMOVUPSYrm;
414 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
415 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
416 else if (IsNonTemporal && Alignment >= 16)
418 else if (Alignment >= 32)
419 Opc = HasVLX ? X86::VMOVAPDZ256rm : X86::VMOVAPDYrm;
421 Opc = HasVLX ? X86::VMOVUPDZ256rm : X86::VMOVUPDYrm;
428 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
429 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
430 else if (IsNonTemporal && Alignment >= 16)
432 else if (Alignment >= 32)
433 Opc = HasVLX ? X86::VMOVDQA64Z256rm : X86::VMOVDQAYrm;
435 Opc = HasVLX ? X86::VMOVDQU64Z256rm : X86::VMOVDQUYrm;
439 if (IsNonTemporal && Alignment >= 64)
440 Opc = X86::VMOVNTDQAZrm;
442 Opc = (Alignment >= 64) ? X86::VMOVAPSZrm :
X86::VMOVUPSZrm;
446 if (IsNonTemporal && Alignment >= 64)
447 Opc = X86::VMOVNTDQAZrm;
449 Opc = (Alignment >= 64) ? X86::VMOVAPDZrm :
X86::VMOVUPDZrm;
458 if (IsNonTemporal && Alignment >= 64)
459 Opc = X86::VMOVNTDQAZrm;
461 Opc = (Alignment >= 64) ? X86::VMOVDQA64Zrm :
X86::VMOVDQU64Zrm;
465 const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
467 ResultReg = createResultReg(RC);
468 MachineInstrBuilder MIB =
469 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
480bool X86FastISel::X86FastEmitStore(EVT VT,
Register ValReg, X86AddressMode &AM,
481 MachineMemOperand *MMO,
bool Aligned) {
482 bool HasSSE1 = Subtarget->hasSSE1();
483 bool HasSSE2 = Subtarget->hasSSE2();
484 bool HasSSE4A = Subtarget->hasSSE4A();
485 bool HasAVX = Subtarget->hasAVX();
486 bool HasAVX512 = Subtarget->hasAVX512();
487 bool HasVLX = Subtarget->hasVLX();
494 default:
return false;
497 Register AndResult = createResultReg(&X86::GR8RegClass);
498 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
499 TII.get(X86::AND8ri), AndResult)
504 case MVT::i8:
Opc = X86::MOV8mr;
break;
505 case MVT::i16:
Opc = X86::MOV16mr;
break;
507 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTImr :
X86::MOV32mr;
511 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTI_64mr :
X86::MOV64mr;
515 if (IsNonTemporal && HasSSE4A)
518 Opc = HasAVX512 ? X86::VMOVSSZmr :
519 HasAVX ? X86::VMOVSSmr : X86::MOVSSmr;
525 if (IsNonTemporal && HasSSE4A)
528 Opc = HasAVX512 ? X86::VMOVSDZmr :
529 HasAVX ? X86::VMOVSDmr : X86::MOVSDmr;
534 Opc = (IsNonTemporal && HasSSE1) ? X86::MMX_MOVNTQmr :
X86::MMX_MOVQ64mr;
539 Opc = HasVLX ? X86::VMOVNTPSZ128mr :
540 HasAVX ? X86::VMOVNTPSmr : X86::MOVNTPSmr;
542 Opc = HasVLX ? X86::VMOVAPSZ128mr :
543 HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr;
545 Opc = HasVLX ? X86::VMOVUPSZ128mr :
546 HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr;
551 Opc = HasVLX ? X86::VMOVNTPDZ128mr :
552 HasAVX ? X86::VMOVNTPDmr : X86::MOVNTPDmr;
554 Opc = HasVLX ? X86::VMOVAPDZ128mr :
555 HasAVX ? X86::VMOVAPDmr : X86::MOVAPDmr;
557 Opc = HasVLX ? X86::VMOVUPDZ128mr :
558 HasAVX ? X86::VMOVUPDmr : X86::MOVUPDmr;
566 Opc = HasVLX ? X86::VMOVNTDQZ128mr :
567 HasAVX ? X86::VMOVNTDQmr : X86::MOVNTDQmr;
569 Opc = HasVLX ? X86::VMOVDQA64Z128mr :
570 HasAVX ? X86::VMOVDQAmr : X86::MOVDQAmr;
572 Opc = HasVLX ? X86::VMOVDQU64Z128mr :
573 HasAVX ? X86::VMOVDQUmr : X86::MOVDQUmr;
579 Opc = HasVLX ? X86::VMOVNTPSZ256mr : X86::VMOVNTPSYmr;
581 Opc = HasVLX ? X86::VMOVAPSZ256mr : X86::VMOVAPSYmr;
583 Opc = HasVLX ? X86::VMOVUPSZ256mr : X86::VMOVUPSYmr;
589 Opc = HasVLX ? X86::VMOVNTPDZ256mr : X86::VMOVNTPDYmr;
591 Opc = HasVLX ? X86::VMOVAPDZ256mr : X86::VMOVAPDYmr;
593 Opc = HasVLX ? X86::VMOVUPDZ256mr : X86::VMOVUPDYmr;
602 Opc = HasVLX ? X86::VMOVNTDQZ256mr : X86::VMOVNTDQYmr;
604 Opc = HasVLX ? X86::VMOVDQA64Z256mr : X86::VMOVDQAYmr;
606 Opc = HasVLX ? X86::VMOVDQU64Z256mr : X86::VMOVDQUYmr;
611 Opc = IsNonTemporal ? X86::VMOVNTPSZmr : X86::VMOVAPSZmr;
613 Opc = X86::VMOVUPSZmr;
618 Opc = IsNonTemporal ? X86::VMOVNTPDZmr : X86::VMOVAPDZmr;
620 Opc = X86::VMOVUPDZmr;
630 Opc = IsNonTemporal ? X86::VMOVNTDQZmr : X86::VMOVDQA64Zmr;
632 Opc = X86::VMOVDQU64Zmr;
644 MachineInstrBuilder MIB =
645 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
Desc);
653bool X86FastISel::X86FastEmitStore(EVT VT,
const Value *Val,
655 MachineMemOperand *MMO,
bool Aligned) {
669 case MVT::i8:
Opc = X86::MOV8mi;
break;
670 case MVT::i16:
Opc = X86::MOV16mi;
break;
671 case MVT::i32:
Opc = X86::MOV32mi;
break;
675 Opc = X86::MOV64mi32;
680 MachineInstrBuilder MIB =
681 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc));
683 : CI->getZExtValue());
690 Register ValReg = getRegForValue(Val);
694 return X86FastEmitStore(VT, ValReg, AM, MMO,
Aligned);
710bool X86FastISel::handleConstantAddresses(
const Value *V, X86AddressMode &AM) {
719 if (TM.isLargeGlobalValue(GV))
723 if (GV->isThreadLocal())
727 if (GV->isAbsoluteSymbolRef())
733 if (!Subtarget->isPICStyleRIPRel() ||
739 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
744 AM.
Base.
Reg = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
750 if (Subtarget->isPICStyleRIPRel()) {
762 DenseMap<const Value *, Register>::iterator
I = LocalValueMap.find(V);
764 if (
I != LocalValueMap.end() &&
I->second) {
769 const TargetRegisterClass *RC =
nullptr;
770 X86AddressMode StubAM;
776 SavePoint SaveInsertPt = enterLocalValueArea();
778 if (TLI.getPointerTy(
DL) == MVT::i64) {
780 RC = &X86::GR64RegClass;
783 RC = &X86::GR32RegClass;
790 LoadReg = createResultReg(RC);
791 MachineInstrBuilder LoadMI =
792 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), LoadReg);
796 leaveLocalValueArea(SaveInsertPt);
799 LocalValueMap[
V] = LoadReg;
811 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
813 AM.
Base.
Reg = getRegForValue(V);
828bool X86FastISel::X86SelectAddress(
const Value *V, X86AddressMode &AM) {
831 const User *
U =
nullptr;
832 unsigned Opcode = Instruction::UserOp1;
837 if (FuncInfo.StaticAllocaMap.count(
static_cast<const AllocaInst *
>(V)) ||
838 FuncInfo.getMBB(
I->getParent()) == FuncInfo.MBB) {
839 Opcode =
I->getOpcode();
843 Opcode =
C->getOpcode();
848 if (Ty->getAddressSpace() > 255)
855 case Instruction::BitCast:
859 case Instruction::IntToPtr:
861 if (TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
862 TLI.getPointerTy(
DL))
866 case Instruction::PtrToInt:
868 if (TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
872 case Instruction::Alloca: {
875 DenseMap<const AllocaInst *, int>::iterator
SI =
876 FuncInfo.StaticAllocaMap.find(
A);
877 if (SI != FuncInfo.StaticAllocaMap.end()) {
885 case Instruction::Add: {
888 uint64_t Disp = (int32_t)AM.
Disp + (uint64_t)CI->getSExtValue();
891 AM.
Disp = (uint32_t)Disp;
898 case Instruction::GetElementPtr: {
899 X86AddressMode SavedAM = AM;
902 uint64_t Disp = (int32_t)AM.
Disp;
904 unsigned Scale = AM.
Scale;
905 MVT PtrVT = TLI.getValueType(
DL,
U->getType()).getSimpleVT();
911 i != e; ++i, ++GTI) {
914 const StructLayout *SL =
DL.getStructLayout(STy);
925 Disp += CI->getSExtValue() * S;
928 if (canFoldAddIntoGEP(U,
Op)) {
937 if (!IndexReg && (!AM.
GV || !Subtarget->isPICStyleRIPRel()) &&
938 (S == 1 || S == 2 || S == 4 || S == 8)) {
941 IndexReg = getRegForGEPIndex(PtrVT,
Op);
947 goto unsupported_gep;
957 AM.
Disp = (uint32_t)Disp;
960 if (
const GetElementPtrInst *
GEP =
975 if (handleConstantAddresses(
I, AM))
985 return handleConstantAddresses(V, AM);
990bool X86FastISel::X86SelectCallAddress(
const Value *V, X86AddressMode &AM) {
991 const User *
U =
nullptr;
992 unsigned Opcode = Instruction::UserOp1;
1019 Opcode =
I->getOpcode();
1021 InMBB =
I->getParent() == FuncInfo.MBB->getBasicBlock();
1023 Opcode =
C->getOpcode();
1029 case Instruction::BitCast:
1032 return X86SelectCallAddress(
U->getOperand(0), AM);
1035 case Instruction::IntToPtr:
1038 TLI.getValueType(
DL,
U->getOperand(0)->getType()) ==
1039 TLI.getPointerTy(
DL))
1040 return X86SelectCallAddress(
U->getOperand(0), AM);
1043 case Instruction::PtrToInt:
1045 if (InMBB && TLI.getValueType(
DL,
U->getType()) == TLI.getPointerTy(
DL))
1046 return X86SelectCallAddress(
U->getOperand(0), AM);
1058 if (Subtarget->isPICStyleRIPRel() &&
1064 if (GVar->isThreadLocal())
1073 if (Subtarget->isPICStyleRIPRel()) {
1079 AM.
GVOpFlags = Subtarget->classifyLocalReference(
nullptr);
1086 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
1087 auto GetCallRegForValue = [
this](
const Value *
V) {
1091 if (
Reg && Subtarget->isTarget64BitILP32()) {
1092 Register CopyReg = createResultReg(&X86::GR32RegClass);
1093 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32rr),
1097 Register ExtReg = createResultReg(&X86::GR64RegClass);
1098 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1099 TII.get(TargetOpcode::SUBREG_TO_REG), ExtReg)
1110 AM.
Base.
Reg = GetCallRegForValue(V);
1115 AM.
IndexReg = GetCallRegForValue(V);
1125bool X86FastISel::X86SelectStore(
const Instruction *
I) {
1132 const Value *PtrV =
I->getOperand(1);
1133 if (TLI.supportSwiftError()) {
1137 if (Arg->hasSwiftErrorAttr())
1142 if (Alloca->isSwiftError())
1151 if (!isTypeLegal(Val->
getType(), VT,
true))
1156 bool Aligned = Alignment >= ABIAlignment;
1162 return X86FastEmitStore(VT, Val, AM, createMachineMemOperandFor(
I),
Aligned);
1166bool X86FastISel::X86SelectRet(
const Instruction *
I) {
1168 const Function &
F = *
I->getParent()->getParent();
1169 const X86MachineFunctionInfo *X86MFInfo =
1170 FuncInfo.MF->getInfo<X86MachineFunctionInfo>();
1172 if (!FuncInfo.CanLowerReturn)
1175 if (TLI.supportSwiftError() &&
1176 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
1179 if (TLI.supportSplitCSR(FuncInfo.MF))
1182 CallingConv::ID CC =
F.getCallingConv();
1183 if (CC != CallingConv::C &&
1184 CC != CallingConv::Fast &&
1185 CC != CallingConv::Tail &&
1186 CC != CallingConv::SwiftTail &&
1187 CC != CallingConv::X86_FastCall &&
1188 CC != CallingConv::X86_StdCall &&
1189 CC != CallingConv::X86_ThisCall &&
1190 CC != CallingConv::X86_64_SysV &&
1191 CC != CallingConv::Win64)
1200 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
1201 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
1217 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
I->getContext());
1226 if (ValLocs.
size() != 1)
1229 CCValAssign &VA = ValLocs[0];
1244 EVT SrcVT = TLI.getValueType(
DL, RV->
getType());
1247 if (SrcVT != DstVT) {
1248 if (SrcVT != MVT::i1 && SrcVT != MVT::i8 && SrcVT != MVT::i16)
1251 if (!Outs[0].
Flags.isZExt() && !Outs[0].Flags.isSExt())
1254 if (SrcVT == MVT::i1) {
1255 if (Outs[0].
Flags.isSExt())
1257 SrcReg = fastEmitZExtFromI1(MVT::i8, SrcReg);
1260 if (SrcVT != DstVT) {
1270 const TargetRegisterClass *SrcRC =
MRI.getRegClass(SrcReg);
1274 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1275 TII.get(TargetOpcode::COPY), DstReg).
addReg(SrcReg);
1288 if (
F.hasStructRetAttr() && CC != CallingConv::Swift &&
1289 CC != CallingConv::SwiftTail) {
1292 "SRetReturnReg should have been set in LowerFormalArguments()!");
1293 Register RetReg = Subtarget->isTarget64BitLP64() ? X86::RAX : X86::EAX;
1294 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1300 MachineInstrBuilder MIB;
1302 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1303 TII.get(Subtarget->is64Bit() ? X86::RETI64 : X86::RETI32))
1306 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1307 TII.get(Subtarget->is64Bit() ? X86::RET64 : X86::RET32));
1316bool X86FastISel::X86SelectLoad(
const Instruction *
I) {
1323 const Value *SV =
I->getOperand(0);
1324 if (TLI.supportSwiftError()) {
1328 if (Arg->hasSwiftErrorAttr())
1333 if (Alloca->isSwiftError())
1339 if (!isTypeLegal(LI->
getType(), VT,
true))
1349 if (!X86FastEmitLoad(VT, AM, createMachineMemOperandFor(LI), ResultReg,
1353 updateValueMap(
I, ResultReg);
1358 bool HasAVX512 = Subtarget->
hasAVX512();
1359 bool HasAVX = Subtarget->
hasAVX();
1360 bool HasSSE1 = Subtarget->
hasSSE1();
1361 bool HasSSE2 = Subtarget->
hasSSE2();
1365 case MVT::i8:
return X86::CMP8rr;
1366 case MVT::i16:
return X86::CMP16rr;
1367 case MVT::i32:
return X86::CMP32rr;
1368 case MVT::i64:
return X86::CMP64rr;
1370 return HasAVX512 ? X86::VUCOMISSZrr
1371 : HasAVX ? X86::VUCOMISSrr
1372 : HasSSE1 ? X86::UCOMISSrr
1375 return HasAVX512 ? X86::VUCOMISDZrr
1376 : HasAVX ? X86::VUCOMISDrr
1377 : HasSSE2 ? X86::UCOMISDrr
1392 return X86::CMP16ri;
1394 return X86::CMP32ri;
1402bool X86FastISel::X86FastEmitCompare(
const Value *Op0,
const Value *Op1, EVT VT,
1404 Register Op0Reg = getRegForValue(Op0);
1417 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareImmOpc))
1419 .
addImm(Op1C->getSExtValue());
1425 if (CompareOpc == 0)
return false;
1427 Register Op1Reg = getRegForValue(Op1);
1430 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurMIMD,
TII.get(CompareOpc))
1438 ((!Subtarget->hasZU() || Subtarget->preferLegacySetCC()) ? X86::SETCCr \
1445 if (!isTypeLegal(
I->getOperand(0)->getType(), VT))
1458 ResultReg = createResultReg(&X86::GR32RegClass);
1459 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32r0),
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,
TII.get(TargetOpcode::SUBREG_TO_REG),
1579 }
else if (DstVT == MVT::i16) {
1582 Register Result32 = createResultReg(&X86::GR32RegClass);
1583 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVZX32rr8),
1584 Result32).
addReg(ResultReg);
1586 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1587 }
else if (DstVT != MVT::i8) {
1594 updateValueMap(
I, ResultReg);
1598bool X86FastISel::X86SelectSExt(
const Instruction *
I) {
1599 EVT DstVT = TLI.getValueType(
DL,
I->getType());
1600 if (!TLI.isTypeLegal(DstVT))
1603 Register ResultReg = getRegForValue(
I->getOperand(0));
1608 MVT SrcVT = TLI.getSimpleValueType(
DL,
I->getOperand(0)->getType());
1609 if (SrcVT == MVT::i1) {
1611 Register ZExtReg = fastEmitZExtFromI1(MVT::i8, ResultReg);
1616 ResultReg = createResultReg(&X86::GR8RegClass);
1617 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::NEG8r),
1618 ResultReg).
addReg(ZExtReg);
1623 if (DstVT == MVT::i16) {
1626 Register Result32 = createResultReg(&X86::GR32RegClass);
1627 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVSX32rr8),
1628 Result32).
addReg(ResultReg);
1630 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1631 }
else if (DstVT != MVT::i8) {
1638 updateValueMap(
I, ResultReg);
1642bool X86FastISel::X86SelectBranch(
const Instruction *
I) {
1646 MachineBasicBlock *TrueMBB = FuncInfo.getMBB(BI->
getSuccessor(0));
1647 MachineBasicBlock *FalseMBB = FuncInfo.getMBB(BI->
getSuccessor(1));
1654 if (CI->
hasOneUse() && CI->getParent() ==
I->getParent()) {
1659 switch (Predicate) {
1674 if (CmpRHSC && CmpRHSC->isNullValue())
1679 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1689 bool NeedExtraBranch =
false;
1690 switch (Predicate) {
1696 NeedExtraBranch =
true;
1709 if (!X86FastEmitCompare(CmpLHS, CmpRHS, VT, CI->getDebugLoc()))
1712 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1717 if (NeedExtraBranch) {
1718 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1722 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1729 if (TI->hasOneUse() && TI->getParent() ==
I->getParent() &&
1730 isTypeLegal(TI->getOperand(0)->getType(), SourceVT)) {
1731 unsigned TestOpc = 0;
1734 case MVT::i8: TestOpc = X86::TEST8ri;
break;
1735 case MVT::i16: TestOpc = X86::TEST16ri;
break;
1736 case MVT::i32: TestOpc = X86::TEST32ri;
break;
1737 case MVT::i64: TestOpc = X86::TEST64ri32;
break;
1740 Register OpReg = getRegForValue(TI->getOperand(0));
1744 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TestOpc))
1748 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1753 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1756 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1760 }
else if (foldX86XALUIntrinsic(CC, BI, BI->
getCondition())) {
1767 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1769 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1781 if (
MRI.getRegClass(OpReg) == &X86::VK1RegClass) {
1783 OpReg = createResultReg(&X86::GR32RegClass);
1784 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1785 TII.get(TargetOpcode::COPY), OpReg)
1787 OpReg = fastEmitInst_extractsubreg(MVT::i8, OpReg, X86::sub_8bit);
1789 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
1792 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1794 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1798bool X86FastISel::X86SelectShift(
const Instruction *
I) {
1801 const TargetRegisterClass *RC =
nullptr;
1802 if (
I->getType()->isIntegerTy(8)) {
1804 RC = &X86::GR8RegClass;
1805 switch (
I->getOpcode()) {
1806 case Instruction::LShr: OpReg = X86::SHR8rCL;
break;
1807 case Instruction::AShr: OpReg = X86::SAR8rCL;
break;
1808 case Instruction::Shl: OpReg = X86::SHL8rCL;
break;
1809 default:
return false;
1811 }
else if (
I->getType()->isIntegerTy(16)) {
1813 RC = &X86::GR16RegClass;
1814 switch (
I->getOpcode()) {
1816 case Instruction::LShr: OpReg = X86::SHR16rCL;
break;
1817 case Instruction::AShr: OpReg = X86::SAR16rCL;
break;
1818 case Instruction::Shl: OpReg = X86::SHL16rCL;
break;
1820 }
else if (
I->getType()->isIntegerTy(32)) {
1822 RC = &X86::GR32RegClass;
1823 switch (
I->getOpcode()) {
1825 case Instruction::LShr: OpReg = X86::SHR32rCL;
break;
1826 case Instruction::AShr: OpReg = X86::SAR32rCL;
break;
1827 case Instruction::Shl: OpReg = X86::SHL32rCL;
break;
1829 }
else if (
I->getType()->isIntegerTy(64)) {
1831 RC = &X86::GR64RegClass;
1832 switch (
I->getOpcode()) {
1834 case Instruction::LShr: OpReg = X86::SHR64rCL;
break;
1835 case Instruction::AShr: OpReg = X86::SAR64rCL;
break;
1836 case Instruction::Shl: OpReg = X86::SHL64rCL;
break;
1843 if (!isTypeLegal(
I->getType(), VT))
1846 Register Op0Reg = getRegForValue(
I->getOperand(0));
1850 Register Op1Reg = getRegForValue(
I->getOperand(1));
1853 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
1858 if (CReg != X86::CL)
1859 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1860 TII.get(TargetOpcode::KILL), X86::CL)
1863 Register ResultReg = createResultReg(RC);
1864 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(OpReg), ResultReg)
1866 updateValueMap(
I, ResultReg);
1870bool X86FastISel::X86SelectDivRem(
const Instruction *
I) {
1871 const static unsigned NumTypes = 4;
1872 const static unsigned NumOps = 4;
1873 const static bool S =
true;
1874 const static bool U =
false;
1875 const static unsigned Copy = TargetOpcode::COPY;
1885 const static struct DivRemEntry {
1887 const TargetRegisterClass *RC;
1891 struct DivRemResult {
1893 unsigned OpSignExtend;
1897 unsigned DivRemResultReg;
1900 } OpTable[NumTypes] = {
1901 { &X86::GR8RegClass, X86::AX, 0, {
1902 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S },
1903 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S },
1904 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U },
1905 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U },
1908 { &X86::GR16RegClass, X86::AX, X86::DX, {
1909 { X86::IDIV16r, X86::CWD,
Copy, X86::AX, S },
1910 { X86::IDIV16r, X86::CWD,
Copy, X86::DX, S },
1911 { X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U },
1912 { X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U },
1915 { &X86::GR32RegClass, X86::EAX, X86::EDX, {
1916 { X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S },
1917 { X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S },
1918 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U },
1919 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U },
1922 { &X86::GR64RegClass, X86::RAX, X86::RDX, {
1923 { X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S },
1924 { X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S },
1925 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U },
1926 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U },
1932 if (!isTypeLegal(
I->getType(), VT))
1937 default:
return false;
1938 case MVT::i8: TypeIndex = 0;
break;
1939 case MVT::i16: TypeIndex = 1;
break;
1940 case MVT::i32: TypeIndex = 2;
break;
1941 case MVT::i64: TypeIndex = 3;
1942 if (!Subtarget->is64Bit())
1947 switch (
I->getOpcode()) {
1949 case Instruction::SDiv:
OpIndex = 0;
break;
1950 case Instruction::SRem:
OpIndex = 1;
break;
1951 case Instruction::UDiv:
OpIndex = 2;
break;
1952 case Instruction::URem:
OpIndex = 3;
break;
1955 const DivRemEntry &
TypeEntry = OpTable[TypeIndex];
1957 Register Op0Reg = getRegForValue(
I->getOperand(0));
1960 Register Op1Reg = getRegForValue(
I->getOperand(1));
1965 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1968 if (OpEntry.OpSignExtend) {
1969 if (OpEntry.IsOpSigned)
1970 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1971 TII.get(OpEntry.OpSignExtend));
1973 Register Zero32 = createResultReg(&X86::GR32RegClass);
1974 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1975 TII.get(X86::MOV32r0), Zero32);
1980 if (VT == MVT::i16) {
1981 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1983 .
addReg(Zero32, 0, 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)
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)
2046 const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
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)
2209 const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
2212 if (Subtarget->hasAVX512()) {
2214 const TargetRegisterClass *VR128X = &X86::VR128XRegClass;
2215 const TargetRegisterClass *VK1 = &X86::VK1RegClass;
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()) {
2240 const TargetRegisterClass *VR128 = &X86::VR128RegClass;
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;
2273 const TargetRegisterClass *VR128 = &X86::VR128RegClass;
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)
2352 const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
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);
2379 const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);
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];
2449 const TargetRegisterClass *RC = TLI.getRegClassFor(DstVT);
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,
2469 const TargetRegisterClass *RC) {
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))
2579 const TargetRegisterClass *DstClass = TLI.getRegClassFor(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()) {
2632 default:
return false;
2633 case Intrinsic::convert_from_fp16:
2634 case Intrinsic::convert_to_fp16: {
2635 if (Subtarget->useSoftFloat() || !Subtarget->hasF16C())
2644 bool IsFloatToHalf =
II->getIntrinsicID() == Intrinsic::convert_to_fp16;
2645 if (IsFloatToHalf) {
2646 if (!
Op->getType()->isFloatTy())
2649 if (!
II->getType()->isFloatTy())
2654 const TargetRegisterClass *RC = TLI.getRegClassFor(MVT::v8i16);
2655 if (IsFloatToHalf) {
2663 unsigned Opc = Subtarget->hasVLX() ? X86::VCVTPS2PHZ128rr
2665 InputReg = fastEmitInst_ri(
Opc, RC, InputReg, 4);
2668 Opc = Subtarget->hasAVX512() ? X86::VMOVPDI2DIZrr
2669 : X86::VMOVPDI2DIrr;
2670 ResultReg = createResultReg(&X86::GR32RegClass);
2671 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
2675 unsigned RegIdx = X86::sub_16bit;
2676 ResultReg = fastEmitInst_extractsubreg(MVT::i16, ResultReg, RegIdx);
2678 assert(
Op->getType()->isIntegerTy(16) &&
"Expected a 16-bit integer!");
2686 unsigned Opc = Subtarget->hasVLX() ? X86::VCVTPH2PSZ128rr
2688 InputReg = fastEmitInst_r(
Opc, RC, InputReg);
2692 ResultReg = createResultReg(TLI.getRegClassFor(MVT::f32));
2693 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2694 TII.get(TargetOpcode::COPY), ResultReg)
2698 updateValueMap(
II, ResultReg);
2701 case Intrinsic::frameaddress: {
2702 MachineFunction *MF = FuncInfo.MF;
2706 Type *RetTy =
II->getCalledFunction()->getReturnType();
2709 if (!isTypeLegal(RetTy, VT))
2713 const TargetRegisterClass *RC =
nullptr;
2717 case MVT::i32:
Opc = X86::MOV32rm; RC = &X86::GR32RegClass;
break;
2718 case MVT::i64:
Opc = X86::MOV64rm; RC = &X86::GR64RegClass;
break;
2726 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2728 assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
2729 (FrameReg == X86::EBP && VT == MVT::i32)) &&
2730 "Invalid Frame Register!");
2735 Register SrcReg = createResultReg(RC);
2736 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2737 TII.get(TargetOpcode::COPY), SrcReg).
addReg(FrameReg);
2746 Register DestReg = createResultReg(RC);
2748 TII.get(
Opc), DestReg), SrcReg);
2752 updateValueMap(
II, SrcReg);
2755 case Intrinsic::memcpy: {
2765 if (IsMemcpySmall(Len)) {
2766 X86AddressMode DestAM, SrcAM;
2770 TryEmitSmallMemcpy(DestAM, SrcAM, Len);
2775 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2782 return lowerCallTo(
II,
"memcpy",
II->arg_size() - 1);
2784 case Intrinsic::memset: {
2790 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2797 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
2799 case Intrinsic::stackprotector: {
2801 EVT PtrTy = TLI.getPointerTy(
DL);
2803 const Value *Op1 =
II->getArgOperand(0);
2811 if (!X86FastEmitStore(PtrTy, Op1, AM))
return false;
2814 case Intrinsic::dbg_declare: {
2820 const MCInstrDesc &
II =
TII.get(TargetOpcode::DBG_VALUE);
2822 "Expected inlined-at fields to agree");
2829 case Intrinsic::trap: {
2830 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TRAP));
2833 case Intrinsic::sqrt: {
2834 if (!Subtarget->hasSSE1())
2837 Type *RetTy =
II->getCalledFunction()->getReturnType();
2840 if (!isTypeLegal(RetTy, VT))
2846 static const uint16_t SqrtOpc[3][2] = {
2847 { X86::SQRTSSr, X86::SQRTSDr },
2848 { X86::VSQRTSSr, X86::VSQRTSDr },
2849 { X86::VSQRTSSZr, X86::VSQRTSDZr },
2851 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
2852 Subtarget->hasAVX() ? 1 :
2856 default:
return false;
2857 case MVT::f32:
Opc = SqrtOpc[AVXLevel][0];
break;
2858 case MVT::f64:
Opc = SqrtOpc[AVXLevel][1];
break;
2861 const Value *SrcVal =
II->getArgOperand(0);
2862 Register SrcReg = getRegForValue(SrcVal);
2867 const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
2870 ImplicitDefReg = createResultReg(RC);
2871 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2872 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2875 Register ResultReg = createResultReg(RC);
2876 MachineInstrBuilder MIB;
2877 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
2881 MIB.
addReg(ImplicitDefReg);
2885 updateValueMap(
II, ResultReg);
2888 case Intrinsic::sadd_with_overflow:
2889 case Intrinsic::uadd_with_overflow:
2890 case Intrinsic::ssub_with_overflow:
2891 case Intrinsic::usub_with_overflow:
2892 case Intrinsic::smul_with_overflow:
2893 case Intrinsic::umul_with_overflow: {
2898 Type *RetTy = Ty->getTypeAtIndex(0U);
2901 "Overflow value expected to be an i1");
2904 if (!isTypeLegal(RetTy, VT))
2907 if (VT < MVT::i8 || VT > MVT::i64)
2918 switch (
II->getIntrinsicID()) {
2920 case Intrinsic::sadd_with_overflow:
2922 case Intrinsic::uadd_with_overflow:
2924 case Intrinsic::ssub_with_overflow:
2926 case Intrinsic::usub_with_overflow:
2928 case Intrinsic::smul_with_overflow:
2930 case Intrinsic::umul_with_overflow:
2941 static const uint16_t
Opc[2][4] = {
2942 { X86::INC8r, X86::INC16r, X86::INC32r, X86::INC64r },
2943 { X86::DEC8r, X86::DEC16r, X86::DEC32r, X86::DEC64r }
2949 ResultReg = createResultReg(TLI.getRegClassFor(VT));
2951 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2955 ResultReg = fastEmit_ri(VT, VT, BaseOpc, LHSReg, CI->
getZExtValue());
2960 RHSReg = getRegForValue(
RHS);
2963 ResultReg = fastEmit_rr(VT, VT, BaseOpc, LHSReg, RHSReg);
2969 static const uint16_t MULOpc[] =
2970 { X86::MUL8r, X86::MUL16r, X86::MUL32r, X86::MUL64r };
2971 static const MCPhysReg Reg[] = { X86::AL, X86::AX, X86::EAX, X86::RAX };
2974 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2977 ResultReg = fastEmitInst_r(MULOpc[VT.
SimpleTy-MVT::i8],
2978 TLI.getRegClassFor(VT), RHSReg);
2980 static const uint16_t MULOpc[] =
2981 { X86::IMUL8r, X86::IMUL16rr, X86::IMUL32rr, X86::IMUL64rr };
2982 if (VT == MVT::i8) {
2985 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2986 TII.get(TargetOpcode::COPY), X86::AL)
2988 ResultReg = fastEmitInst_r(MULOpc[0], TLI.getRegClassFor(VT), RHSReg);
2990 ResultReg = fastEmitInst_rr(MULOpc[VT.
SimpleTy-MVT::i8],
2991 TLI.getRegClassFor(VT), LHSReg, RHSReg);
2998 Register ResultReg2 = createResultReg(&X86::GR8RegClass);
2999 assert((ResultReg+1) == ResultReg2 &&
"Nonconsecutive result registers.");
3004 updateValueMap(
II, ResultReg, 2);
3007 case Intrinsic::x86_sse_cvttss2si:
3008 case Intrinsic::x86_sse_cvttss2si64:
3009 case Intrinsic::x86_sse2_cvttsd2si:
3010 case Intrinsic::x86_sse2_cvttsd2si64: {
3012 switch (
II->getIntrinsicID()) {
3014 case Intrinsic::x86_sse_cvttss2si:
3015 case Intrinsic::x86_sse_cvttss2si64:
3016 if (!Subtarget->hasSSE1())
3018 IsInputDouble =
false;
3020 case Intrinsic::x86_sse2_cvttsd2si:
3021 case Intrinsic::x86_sse2_cvttsd2si64:
3022 if (!Subtarget->hasSSE2())
3024 IsInputDouble =
true;
3028 Type *RetTy =
II->getCalledFunction()->getReturnType();
3030 if (!isTypeLegal(RetTy, VT))
3033 static const uint16_t CvtOpc[3][2][2] = {
3034 { { X86::CVTTSS2SIrr, X86::CVTTSS2SI64rr },
3035 { X86::CVTTSD2SIrr, X86::CVTTSD2SI64rr } },
3036 { { X86::VCVTTSS2SIrr, X86::VCVTTSS2SI64rr },
3037 { X86::VCVTTSD2SIrr, X86::VCVTTSD2SI64rr } },
3038 { { X86::VCVTTSS2SIZrr, X86::VCVTTSS2SI64Zrr },
3039 { X86::VCVTTSD2SIZrr, X86::VCVTTSD2SI64Zrr } },
3041 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
3042 Subtarget->hasAVX() ? 1 :
3047 case MVT::i32:
Opc = CvtOpc[AVXLevel][IsInputDouble][0];
break;
3048 case MVT::i64:
Opc = CvtOpc[AVXLevel][IsInputDouble][1];
break;
3060 Op =
IE->getOperand(1);
3063 Op =
IE->getOperand(0);
3070 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3071 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
3074 updateValueMap(
II, ResultReg);
3077 case Intrinsic::x86_sse42_crc32_32_8:
3078 case Intrinsic::x86_sse42_crc32_32_16:
3079 case Intrinsic::x86_sse42_crc32_32_32:
3080 case Intrinsic::x86_sse42_crc32_64_64: {
3081 if (!Subtarget->hasCRC32())
3084 Type *RetTy =
II->getCalledFunction()->getReturnType();
3087 if (!isTypeLegal(RetTy, VT))
3091 const TargetRegisterClass *RC =
nullptr;
3093 switch (
II->getIntrinsicID()) {
3096#define GET_EGPR_IF_ENABLED(OPC) Subtarget->hasEGPR() ? OPC##_EVEX : OPC
3097 case Intrinsic::x86_sse42_crc32_32_8:
3099 RC = &X86::GR32RegClass;
3101 case Intrinsic::x86_sse42_crc32_32_16:
3103 RC = &X86::GR32RegClass;
3105 case Intrinsic::x86_sse42_crc32_32_32:
3107 RC = &X86::GR32RegClass;
3109 case Intrinsic::x86_sse42_crc32_64_64:
3111 RC = &X86::GR64RegClass;
3113#undef GET_EGPR_IF_ENABLED
3121 if (!LHSReg || !RHSReg)
3124 Register ResultReg = fastEmitInst_rr(
Opc, RC, LHSReg, RHSReg);
3128 updateValueMap(
II, ResultReg);
3134bool X86FastISel::fastLowerArguments() {
3135 if (!FuncInfo.CanLowerReturn)
3142 CallingConv::ID CC =
F->getCallingConv();
3143 if (CC != CallingConv::C)
3146 if (Subtarget->isCallingConvWin64(CC))
3149 if (!Subtarget->is64Bit())
3152 if (Subtarget->useSoftFloat())
3156 unsigned GPRCnt = 0;
3157 unsigned FPRCnt = 0;
3158 for (
auto const &Arg :
F->args()) {
3159 if (Arg.hasAttribute(Attribute::ByVal) ||
3160 Arg.hasAttribute(Attribute::InReg) ||
3161 Arg.hasAttribute(Attribute::StructRet) ||
3162 Arg.hasAttribute(Attribute::SwiftSelf) ||
3163 Arg.hasAttribute(Attribute::SwiftAsync) ||
3164 Arg.hasAttribute(Attribute::SwiftError) ||
3165 Arg.hasAttribute(Attribute::Nest))
3168 Type *ArgTy = Arg.getType();
3172 EVT ArgVT = TLI.getValueType(
DL, ArgTy);
3173 if (!ArgVT.
isSimple())
return false;
3175 default:
return false;
3182 if (!Subtarget->hasSSE1())
3195 static const MCPhysReg GPR32ArgRegs[] = {
3196 X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
3198 static const MCPhysReg GPR64ArgRegs[] = {
3199 X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8 , X86::R9
3202 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3203 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3206 unsigned GPRIdx = 0;
3207 unsigned FPRIdx = 0;
3208 for (
auto const &Arg :
F->args()) {
3209 MVT VT = TLI.getSimpleValueType(
DL, Arg.getType());
3210 const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
3214 case MVT::i32: SrcReg = GPR32ArgRegs[GPRIdx++];
break;
3215 case MVT::i64: SrcReg = GPR64ArgRegs[GPRIdx++];
break;
3216 case MVT::f32: [[fallthrough]];
3217 case MVT::f64: SrcReg = XMMArgRegs[FPRIdx++];
break;
3219 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
3223 Register ResultReg = createResultReg(RC);
3224 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3225 TII.get(TargetOpcode::COPY), ResultReg)
3227 updateValueMap(&Arg, ResultReg);
3235 if (Subtarget->is64Bit())
3252bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
3253 auto &OutVals = CLI.OutVals;
3254 auto &OutFlags = CLI.OutFlags;
3255 auto &OutRegs = CLI.OutRegs;
3256 auto &Ins = CLI.Ins;
3257 auto &InRegs = CLI.InRegs;
3258 CallingConv::ID CC = CLI.CallConv;
3259 bool &IsTailCall = CLI.IsTailCall;
3260 bool IsVarArg = CLI.IsVarArg;
3263 const auto *CB = CLI.CB;
3265 bool Is64Bit = Subtarget->is64Bit();
3266 bool IsWin64 = Subtarget->isCallingConvWin64(CC);
3270 if (CB && CB->doesNoCfCheck())
3274 if ((CB &&
isa<CallInst>(CB) && CB->hasFnAttr(
"no_caller_saved_registers")))
3278 if ((CB && CB->hasFnAttr(
"no_callee_saved_registers")))
3286 if (Subtarget->useIndirectThunkCalls())
3291 default:
return false;
3292 case CallingConv::C:
3293 case CallingConv::Fast:
3294 case CallingConv::Tail:
3295 case CallingConv::Swift:
3296 case CallingConv::SwiftTail:
3297 case CallingConv::X86_FastCall:
3298 case CallingConv::X86_StdCall:
3299 case CallingConv::X86_ThisCall:
3300 case CallingConv::Win64:
3301 case CallingConv::X86_64_SysV:
3302 case CallingConv::CFGuard_Check:
3312 if ((CC == CallingConv::Fast && TM.Options.GuaranteedTailCallOpt) ||
3313 CC == CallingConv::Tail || CC == CallingConv::SwiftTail)
3318 if (IsVarArg && IsWin64)
3322 if (CLI.CB && CLI.CB->hasInAllocaArgument())
3325 for (
auto Flag : CLI.OutFlags)
3326 if (
Flag.isSwiftError() ||
Flag.isPreallocated())
3336 SmallVector<Register, 16> ArgRegs;
3341 for (
int i = 0, e = OutVals.size(); i != e; ++i) {
3342 Value *&Val = OutVals[i];
3343 ISD::ArgFlagsTy
Flags = OutFlags[i];
3358 if (TI && TI->getType()->isIntegerTy(1) && CLI.CB &&
3359 (TI->getParent() == CLI.CB->getParent()) && TI->hasOneUse()) {
3360 Value *PrevVal = TI->getOperand(0);
3361 ResultReg = getRegForValue(PrevVal);
3366 if (!isTypeLegal(PrevVal->
getType(), VT))
3369 ResultReg = fastEmit_ri(VT, VT,
ISD::AND, ResultReg, 1);
3371 if (!isTypeLegal(Val->
getType(), VT) ||
3374 ResultReg = getRegForValue(Val);
3387 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, CLI.RetTy->getContext());
3391 CCInfo.AllocateStack(32,
Align(8));
3393 CCInfo.AnalyzeCallOperands(OutVTs, OutFlags, ArgTys,
CC_X86);
3396 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
3399 unsigned AdjStackDown =
TII.getCallFrameSetupOpcode();
3400 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackDown))
3404 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
3405 for (
const CCValAssign &VA : ArgLocs) {
3409 if (ArgVT == MVT::x86mmx)
3419 "Unexpected extend");
3421 if (ArgVT == MVT::i1)
3426 assert(Emitted &&
"Failed to emit a sext!"); (void)Emitted;
3432 "Unexpected extend");
3435 if (ArgVT == MVT::i1) {
3437 ArgReg = fastEmitZExtFromI1(MVT::i8, ArgReg);
3446 assert(Emitted &&
"Failed to emit a zext!"); (void)Emitted;
3452 "Unexpected extend");
3462 assert(Emitted &&
"Failed to emit a aext!"); (void)Emitted;
3468 assert(ArgReg &&
"Failed to emit a bitcast!");
3489 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3502 AM.
Disp = LocMemOffset;
3505 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3508 if (
Flags.isByVal()) {
3509 X86AddressMode SrcAM;
3511 if (!TryEmitSmallMemcpy(AM, SrcAM,
Flags.getByValSize()))
3517 if (!X86FastEmitStore(ArgVT, ArgVal, AM, MMO))
3520 if (!X86FastEmitStore(ArgVT, ArgReg, AM, MMO))
3528 if (Subtarget->isPICStyleGOT()) {
3529 Register Base = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3530 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3534 if (Is64Bit && IsVarArg && !IsWin64) {
3545 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3546 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3548 unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs);
3549 assert((Subtarget->hasSSE1() || !NumXMMRegs)
3550 &&
"SSE registers cannot be used when SSE is disabled");
3551 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
3552 X86::AL).
addImm(NumXMMRegs);
3557 X86AddressMode CalleeAM;
3558 if (!X86SelectCallAddress(Callee, CalleeAM))
3562 const GlobalValue *GV =
nullptr;
3563 if (CalleeAM.
GV !=
nullptr) {
3565 }
else if (CalleeAM.
Base.
Reg) {
3571 MachineInstrBuilder MIB;
3574 unsigned CallOpc = Is64Bit ? X86::CALL64r : X86::CALL32r;
3575 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc))
3579 assert(GV &&
"Not a direct call");
3581 unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV);
3593 unsigned CallOpc = NeedLoad
3594 ? (Is64Bit ? X86::CALL64m : X86::CALL32m)
3595 : (Is64Bit ?
X86::CALL64pcrel32 :
X86::CALLpcrel32);
3597 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc));
3601 MIB.
addSym(Symbol, OpFlags);
3613 if (Subtarget->isPICStyleGOT())
3616 if (Is64Bit && IsVarArg && !IsWin64)
3620 for (
auto Reg : OutRegs)
3624 unsigned NumBytesForCalleeToPop =
3626 TM.Options.GuaranteedTailCallOpt)
3629 unsigned AdjStackUp =
TII.getCallFrameDestroyOpcode();
3630 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackUp))
3635 CCState CCRetInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs,
3636 CLI.RetTy->getContext());
3637 CCRetInfo.AnalyzeCallResult(Ins,
RetCC_X86);
3640 Register ResultReg = FuncInfo.CreateRegs(CLI.RetTy);
3641 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
3642 CCValAssign &VA = RVLocs[i];
3648 if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) &&
3649 ((Is64Bit || Ins[i].
Flags.isInReg()) && !Subtarget->hasSSE1())) {
3655 if ((SrcReg == X86::FP0 || SrcReg == X86::FP1) &&
3656 isScalarFPTypeInSSEReg(VA.
getValVT())) {
3658 CopyReg = createResultReg(&X86::RFP80RegClass);
3662 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3663 TII.get(TargetOpcode::COPY), CopyReg).
addReg(SrcReg);
3671 unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
3677 Opc = ResVT == MVT::f32 ? X86::MOVSSrm_alt : X86::MOVSDrm_alt;
3679 TII.get(
Opc), ResultReg + i), FI);
3683 CLI.ResultReg = ResultReg;
3684 CLI.NumResultRegs = RVLocs.
size();
3688 if (TM.Options.EmitCallGraphSection && CB && CB->isIndirectCall()) {
3689 MachineFunction::CallSiteInfo CSInfo(*CB);
3697X86FastISel::fastSelectInstruction(
const Instruction *
I) {
3698 switch (
I->getOpcode()) {
3700 case Instruction::Load:
3701 return X86SelectLoad(
I);
3702 case Instruction::Store:
3703 return X86SelectStore(
I);
3704 case Instruction::Ret:
3705 return X86SelectRet(
I);
3706 case Instruction::ICmp:
3707 case Instruction::FCmp:
3708 return X86SelectCmp(
I);
3709 case Instruction::ZExt:
3710 return X86SelectZExt(
I);
3711 case Instruction::SExt:
3712 return X86SelectSExt(
I);
3713 case Instruction::Br:
3714 return X86SelectBranch(
I);
3715 case Instruction::LShr:
3716 case Instruction::AShr:
3717 case Instruction::Shl:
3718 return X86SelectShift(
I);
3719 case Instruction::SDiv:
3720 case Instruction::UDiv:
3721 case Instruction::SRem:
3722 case Instruction::URem:
3723 return X86SelectDivRem(
I);
3724 case Instruction::Select:
3725 return X86SelectSelect(
I);
3726 case Instruction::Trunc:
3727 return X86SelectTrunc(
I);
3728 case Instruction::FPExt:
3729 return X86SelectFPExt(
I);
3730 case Instruction::FPTrunc:
3731 return X86SelectFPTrunc(
I);
3732 case Instruction::SIToFP:
3733 return X86SelectSIToFP(
I);
3734 case Instruction::UIToFP:
3735 return X86SelectUIToFP(
I);
3736 case Instruction::IntToPtr:
3737 case Instruction::PtrToInt: {
3738 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
3739 EVT DstVT = TLI.getValueType(
DL,
I->getType());
3741 return X86SelectZExt(
I);
3743 return X86SelectTrunc(
I);
3747 updateValueMap(
I,
Reg);
3750 case Instruction::BitCast:
3751 return X86SelectBitCast(
I);
3757Register X86FastISel::X86MaterializeInt(
const ConstantInt *CI, MVT VT) {
3763 Register SrcReg = fastEmitInst_(X86::MOV32r0, &X86::GR32RegClass);
3768 return fastEmitInst_extractsubreg(MVT::i8, SrcReg, X86::sub_8bit);
3770 return fastEmitInst_extractsubreg(MVT::i16, SrcReg, X86::sub_16bit);
3774 Register ResultReg = createResultReg(&X86::GR64RegClass);
3775 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3776 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3789 case MVT::i8:
Opc = X86::MOV8ri;
break;
3790 case MVT::i16:
Opc = X86::MOV16ri;
break;
3791 case MVT::i32:
Opc = X86::MOV32ri;
break;
3794 Opc = X86::MOV32ri64;
3796 Opc = X86::MOV64ri32;
3802 return fastEmitInst_i(
Opc, TLI.getRegClassFor(VT), Imm);
3805Register X86FastISel::X86MaterializeFP(
const ConstantFP *CFP, MVT VT) {
3807 return fastMaterializeFloatZero(CFP);
3817 bool HasSSE1 = Subtarget->hasSSE1();
3818 bool HasSSE2 = Subtarget->hasSSE2();
3819 bool HasAVX = Subtarget->hasAVX();
3820 bool HasAVX512 = Subtarget->hasAVX512();
3825 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
3826 : HasAVX ? X86::VMOVSSrm_alt
3827 : HasSSE1 ? X86::MOVSSrm_alt
3831 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
3832 : HasAVX ? X86::VMOVSDrm_alt
3833 : HasSSE2 ? X86::MOVSDrm_alt
3846 unsigned char OpFlag = Subtarget->classifyLocalReference(
nullptr);
3848 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3850 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3855 unsigned CPI = MCP.getConstantPoolIndex(CFP, Alignment);
3860 Register AddrReg = createResultReg(&X86::GR64RegClass);
3861 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3864 MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3865 TII.get(
Opc), ResultReg);
3866 addRegReg(MIB, AddrReg,
false, X86::NoSubRegister, PICBase,
false,
3867 X86::NoSubRegister);
3868 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
3876 TII.get(
Opc), ResultReg),
3877 CPI, PICBase, OpFlag);
3881Register X86FastISel::X86MaterializeGV(
const GlobalValue *GV, MVT VT) {
3886 if (TM.isLargeGlobalValue(GV))
3898 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3900 TLI.getPointerTy(
DL) == MVT::i64) {
3903 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3908 TLI.getPointerTy(
DL) == MVT::i32
3909 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3912 TII.get(
Opc), ResultReg), AM);
3919Register X86FastISel::fastMaterializeConstant(
const Constant *
C) {
3920 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
3928 return X86MaterializeInt(CI, VT);
3930 return X86MaterializeFP(CFP, VT);
3932 return X86MaterializeGV(GV, VT);
3939 if (!Subtarget->hasSSE1())
3940 Opc = X86::LD_Fp032;
3943 if (!Subtarget->hasSSE2())
3944 Opc = X86::LD_Fp064;
3947 Opc = X86::LD_Fp080;
3952 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3953 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
3962Register X86FastISel::fastMaterializeAlloca(
const AllocaInst *
C) {
3970 if (!FuncInfo.StaticAllocaMap.count(
C))
3972 assert(
C->isStaticAlloca() &&
"dynamic alloca in the static alloca map?");
3978 TLI.getPointerTy(
DL) == MVT::i32
3979 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3981 const TargetRegisterClass *RC = TLI.getRegClassFor(TLI.getPointerTy(
DL));
3982 Register ResultReg = createResultReg(RC);
3984 TII.get(
Opc), ResultReg), AM);
3988Register X86FastISel::fastMaterializeFloatZero(
const ConstantFP *CF) {
3990 if (!isTypeLegal(CF->
getType(), VT))
3994 bool HasSSE1 = Subtarget->hasSSE1();
3995 bool HasSSE2 = Subtarget->hasSSE2();
3996 bool HasAVX512 = Subtarget->hasAVX512();
4001 Opc = HasAVX512 ? X86::AVX512_FsFLD0SH : X86::FsFLD0SH;
4004 Opc = HasAVX512 ? X86::AVX512_FsFLD0SS
4005 : HasSSE1 ? X86::FsFLD0SS
4009 Opc = HasAVX512 ? X86::AVX512_FsFLD0SD
4010 : HasSSE2 ? X86::FsFLD0SD
4018 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
4019 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
4023bool X86FastISel::tryToFoldLoadIntoMI(MachineInstr *
MI,
unsigned OpNo,
4024 const LoadInst *LI) {
4030 const X86InstrInfo &XII = (
const X86InstrInfo &)
TII;
4038 *FuncInfo.MF, *
MI, OpNo, AddrOps, FuncInfo.InsertPt,
Size, LI->
getAlign(),
4048 unsigned OperandNo = 0;
4050 E =
Result->operands_end();
I !=
E; ++
I, ++OperandNo) {
4051 MachineOperand &MO = *
I;
4057 if (IndexReg == MO.
getReg())
4063 FuncInfo.MF->moveAdditionalCallInfo(
MI, Result);
4064 Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
4065 Result->cloneInstrSymbols(*FuncInfo.MF, *
MI);
4067 removeDeadCode(
I, std::next(
I));
4071Register X86FastISel::fastEmitInst_rrrr(
unsigned MachineInstOpcode,
4072 const TargetRegisterClass *RC,
4075 const MCInstrDesc &
II =
TII.get(MachineInstOpcode);
4077 Register ResultReg = createResultReg(RC);
4083 if (
II.getNumDefs() >= 1)
4084 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
4090 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
4095 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
4105 return new X86FastISel(funcInfo, libInfo);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the FastISel class.
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
#define GET_EGPR_IF_ENABLED(OPC)
static unsigned X86ChooseCmpImmediateOpcode(EVT VT, const ConstantInt *RHSC)
If we have a comparison with RHS as the RHS of the comparison, return an opcode that works for the co...
static std::pair< unsigned, bool > getX86SSEConditionCode(CmpInst::Predicate Predicate)
static unsigned computeBytesPoppedByCalleeForSRet(const X86Subtarget *Subtarget, CallingConv::ID CC, const CallBase *CB)
static unsigned X86ChooseCmpOpcode(EVT VT, const X86Subtarget *Subtarget)
static bool X86SelectAddress(MachineInstr &I, const X86TargetMachine &TM, const MachineRegisterInfo &MRI, const X86Subtarget &STI, X86AddressMode &AM)
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
InstListType::const_iterator const_iterator
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
unsigned getValNo() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
This is the shared class of boolean and integer constants.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this variable.
Value * getAddress() const
DILocalVariable * getVariable() const
DIExpression * getExpression() const
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
Value * getPointerOperand()
Align getAlign() const
Return the alignment of the access that is being performed.
bool usesWindowsCFI() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
MVT getVectorElementType() const
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setStackProtectorIndex(int I)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
void addCallSiteInfo(const MachineInstr *CallI, CallSiteInfo &&CallInfo)
Start tracking the arguments passed to the call CallI.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
unsigned getNumOperands() const
Retuns the total number of operands.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
LLVM_ABI void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
bool isNonTemporal() const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
Value * getLength() const
Value * getRawDest() const
unsigned getDestAddressSpace() const
Value * getRawSource() const
Return the arguments to the instruction.
unsigned getSourceAddressSpace() const
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Wrapper class representing virtual and physical registers.
void push_back(const T &Elt)
Value * getValueOperand()
Value * getPointerOperand()
TypeSize getElementOffset(unsigned Idx) const
Provides information about what library functions are available for the current target.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
bool isOSMSVCRT() const
Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isArrayTy() const
True if this is an instance of ArrayType.
bool isStructTy() const
True if this is an instance of StructType.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
const Use * const_op_iterator
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
Fold a load or store of the specified stack slot into the specified machine instruction for the speci...
Register getSRetReturnReg() const
unsigned getBytesToPopOnReturn() const
Register getPtrSizedFrameRegister(const MachineFunction &MF) const
Register getStackRegister() const
const Triple & getTargetTriple() const
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ HiPE
Used by the High-Performance Erlang Compiler (HiPE).
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ Fast
Attempts to make calls as fast as possible (e.g.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
@ C
The default llvm calling convention, compatible with C.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BasicBlock
Various leaf nodes.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ AND
Bitwise operators - logical and, logical or, logical xor.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ X86
Windows x64, Windows Itanium (IA-64)
@ MO_GOTPCREL_NORELAX
MO_GOTPCREL_NORELAX - Same as MO_GOTPCREL except that R_X86_64_GOTPCREL relocations are guaranteed to...
@ MO_GOTOFF
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
@ MO_PLT
MO_PLT - On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol n...
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...
@ MO_PIC_BASE_OFFSET
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
@ MO_GOTPCREL
MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for th...
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.
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
unsigned getCMovOpcode(unsigned RegBytes, bool HasMemoryOperand=false, bool HasNDD=false)
Return a cmov opcode for the given register size in bytes, and operand type.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
@ User
could "use" a pointer
@ Emitted
Assigned address, still materializing.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
static bool isGlobalStubReference(unsigned char TargetFlag)
isGlobalStubReference - Return true if the specified TargetFlag operand is a reference to a stub for ...
FunctionAddr VTableAddr Value
static bool isGlobalRelativeToPICBase(unsigned char TargetFlag)
isGlobalRelativeToPICBase - Return true if the specified global value reference is relative to a 32-b...
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
static const MachineInstrBuilder & addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI, Register GlobalBaseReg, unsigned char OpFlags)
addConstantPoolReference - This function is used to add a reference to the base of a constant value s...
static const MachineInstrBuilder & addRegReg(const MachineInstrBuilder &MIB, Register Reg1, bool isKill1, unsigned SubReg1, Register Reg2, bool isKill2, unsigned SubReg2)
addRegReg - This function is used to add a memory reference of the form: [Reg + Reg].
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
static const MachineInstrBuilder & addFullAddress(const MachineInstrBuilder &MIB, const X86AddressMode &AM)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
bool CC_X86(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool RetCC_X86(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
static const MachineInstrBuilder & addDirectMem(const MachineInstrBuilder &MIB, Register Reg)
addDirectMem - This function is used to add a direct memory reference to the current instruction – th...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
X86AddressMode - This struct holds a generalized full x86 address mode.
void getFullAddress(SmallVectorImpl< MachineOperand > &MO)
union llvm::X86AddressMode::BaseUnion Base
enum llvm::X86AddressMode::@202116273335065351270200035056227005202106004277 BaseType