36#include "llvm/IR/IntrinsicsX86.h"
47class X86FastISel final :
public FastISel {
72#include "X86GenFastISel.inc"
75 bool X86FastEmitCompare(
const Value *LHS,
const Value *RHS,
EVT VT,
79 Register &ResultReg,
unsigned Alignment = 1);
127 bool X86SelectIntToFP(
const Instruction *
I,
bool IsSigned);
131 return Subtarget->getInstrInfo();
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);
168 Register fastEmitInst_rrrr(
unsigned MachineInstOpcode,
175static std::pair<unsigned, bool>
178 bool NeedSwap =
false;
207 return std::make_pair(CC, NeedSwap);
221 return ::addFullAddress(MIB, AM);
228 if (!isa<ExtractValueInst>(
Cond))
231 const auto *EV = cast<ExtractValueInst>(
Cond);
232 if (!isa<IntrinsicInst>(EV->getAggregateOperand()))
235 const auto *
II = cast<IntrinsicInst>(EV->getAggregateOperand());
239 cast<StructType>(
Callee->getReturnType())->getTypeAtIndex(0U);
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) {
267 if (!isa<ExtractValueInst>(Itr))
271 const auto *EVI = cast<ExtractValueInst>(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);
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;
467 ResultReg = createResultReg(RC);
469 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
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;
645 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
Desc);
653bool X86FastISel::X86FastEmitStore(
EVT VT,
const Value *Val,
657 if (isa<ConstantPointerNull>(Val))
661 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
669 case MVT::i8:
Opc = X86::MOV8mi;
break;
670 case MVT::i16:
Opc = X86::MOV16mi;
break;
671 case MVT::i32:
Opc = X86::MOV32mi;
break;
674 if (isInt<32>(CI->getSExtValue()))
675 Opc = X86::MOV64mi32;
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);
712 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
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()) {
764 if (
I != LocalValueMap.end() &&
I->second) {
776 SavePoint SaveInsertPt = enterLocalValueArea();
778 if (TLI.getPointerTy(
DL) == MVT::i64) {
780 RC = &X86::GR64RegClass;
783 RC = &X86::GR32RegClass;
790 LoadReg = createResultReg(RC);
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);
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();
842 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(V)) {
843 Opcode =
C->getOpcode();
847 if (
PointerType *Ty = dyn_cast<PointerType>(
V->getType()))
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: {
876 FuncInfo.StaticAllocaMap.find(
A);
877 if (SI != FuncInfo.StaticAllocaMap.end()) {
885 case Instruction::Add: {
887 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(
U->getOperand(1))) {
890 if (isInt<32>(Disp)) {
898 case Instruction::GetElementPtr: {
904 unsigned Scale = AM.
Scale;
911 i != e; ++i, ++GTI) {
925 Disp += CI->getSExtValue() * S;
928 if (canFoldAddIntoGEP(U,
Op)) {
931 cast<ConstantInt>(cast<AddOperator>(
Op)->getOperand(1));
934 Op = cast<AddOperator>(
Op)->getOperand(0);
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;
952 if (!isInt<32>(Disp))
961 dyn_cast<GetElementPtrInst>(
U->getOperand(0))) {
975 if (handleConstantAddresses(
I, AM))
985 return handleConstantAddresses(V, AM);
991 const User *
U =
nullptr;
992 unsigned Opcode = Instruction::UserOp1;
1019 Opcode =
I->getOpcode();
1021 InMBB =
I->getParent() == FuncInfo.MBB->getBasicBlock();
1022 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(V)) {
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);
1051 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
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()) {
1136 if (
const Argument *Arg = dyn_cast<Argument>(PtrV)) {
1137 if (Arg->hasSwiftErrorAttr())
1141 if (
const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
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);
1168 const Function &
F = *
I->getParent()->getParent();
1172 if (!FuncInfo.CanLowerReturn)
1175 if (TLI.supportSwiftError() &&
1176 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
1179 if (TLI.supportSplitCSR(FuncInfo.MF))
1211 if (
Ret->getNumOperands() > 0) {
1217 CCState CCInfo(CC,
F.isVarArg(), *FuncInfo.MF, ValLocs,
I->getContext());
1220 const Value *RV =
Ret->getOperand(0);
1226 if (ValLocs.
size() != 1)
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) {
1274 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1275 TII.get(TargetOpcode::COPY), DstReg).
addReg(SrcReg);
1292 "SRetReturnReg should have been set in LowerFormalArguments()!");
1293 Register RetReg = Subtarget->isTarget64BitLP64() ? X86::RAX : X86::EAX;
1294 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1295 TII.get(TargetOpcode::COPY), RetReg).
addReg(Reg);
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));
1323 const Value *SV =
I->getOperand(0);
1324 if (TLI.supportSwiftError()) {
1327 if (
const Argument *Arg = dyn_cast<Argument>(SV)) {
1328 if (Arg->hasSwiftErrorAttr())
1332 if (
const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
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;
1398 return isInt<32>(RHSC->
getSExtValue()) ? X86::CMP64ri32 : 0;
1402bool X86FastISel::X86FastEmitCompare(
const Value *Op0,
const Value *Op1,
EVT VT,
1404 Register Op0Reg = getRegForValue(Op0);
1409 if (isa<ConstantPointerNull>(Op1))
1415 if (
const ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
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 const CmpInst *CI = cast<CmpInst>(
I);
1441 if (!isTypeLegal(
I->getOperand(0)->getType(), VT))
1454 ResultReg = createResultReg(&X86::GR32RegClass);
1455 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV32r0),
1457 ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultReg, X86::sub_8bit);
1463 ResultReg = createResultReg(&X86::GR8RegClass);
1464 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
1471 updateValueMap(
I, ResultReg);
1482 const auto *RHSC = dyn_cast<ConstantFP>(RHS);
1483 if (RHSC && RHSC->isNullValue())
1488 static const uint16_t SETFOpcTable[2][3] = {
1499 ResultReg = createResultReg(&X86::GR8RegClass);
1501 if (!X86FastEmitCompare(LHS, RHS, VT,
I->getDebugLoc()))
1504 Register FlagReg1 = createResultReg(&X86::GR8RegClass);
1505 Register FlagReg2 = createResultReg(&X86::GR8RegClass);
1506 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SETCCr),
1507 FlagReg1).
addImm(SETFOpc[0]);
1508 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SETCCr),
1509 FlagReg2).
addImm(SETFOpc[1]);
1510 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(SETFOpc[2]),
1512 updateValueMap(
I, ResultReg);
1525 if (!X86FastEmitCompare(LHS, RHS, VT,
I->getDebugLoc()))
1528 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SETCCr),
1530 updateValueMap(
I, ResultReg);
1535 EVT DstVT = TLI.getValueType(
DL,
I->getType());
1536 if (!TLI.isTypeLegal(DstVT))
1539 Register ResultReg = getRegForValue(
I->getOperand(0));
1544 MVT SrcVT = TLI.getSimpleValueType(
DL,
I->getOperand(0)->getType());
1545 if (SrcVT == MVT::i1) {
1547 ResultReg = fastEmitZExtFromI1(MVT::i8, ResultReg);
1554 if (DstVT == MVT::i64) {
1559 case MVT::i8: MovInst = X86::MOVZX32rr8;
break;
1560 case MVT::i16: MovInst = X86::MOVZX32rr16;
break;
1561 case MVT::i32: MovInst = X86::MOV32rr;
break;
1565 Register Result32 = createResultReg(&X86::GR32RegClass);
1566 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(MovInst), Result32)
1569 ResultReg = createResultReg(&X86::GR64RegClass);
1570 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::SUBREG_TO_REG),
1573 }
else if (DstVT == MVT::i16) {
1576 Register Result32 = createResultReg(&X86::GR32RegClass);
1577 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVZX32rr8),
1578 Result32).
addReg(ResultReg);
1580 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1581 }
else if (DstVT != MVT::i8) {
1588 updateValueMap(
I, ResultReg);
1593 EVT DstVT = TLI.getValueType(
DL,
I->getType());
1594 if (!TLI.isTypeLegal(DstVT))
1597 Register ResultReg = getRegForValue(
I->getOperand(0));
1602 MVT SrcVT = TLI.getSimpleValueType(
DL,
I->getOperand(0)->getType());
1603 if (SrcVT == MVT::i1) {
1605 Register ZExtReg = fastEmitZExtFromI1(MVT::i8, ResultReg);
1610 ResultReg = createResultReg(&X86::GR8RegClass);
1611 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::NEG8r),
1612 ResultReg).
addReg(ZExtReg);
1617 if (DstVT == MVT::i16) {
1620 Register Result32 = createResultReg(&X86::GR32RegClass);
1621 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOVSX32rr8),
1622 Result32).
addReg(ResultReg);
1624 ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, X86::sub_16bit);
1625 }
else if (DstVT != MVT::i8) {
1632 updateValueMap(
I, ResultReg);
1636bool X86FastISel::X86SelectBranch(
const Instruction *
I) {
1667 const auto *CmpRHSC = dyn_cast<ConstantFP>(CmpRHS);
1668 if (CmpRHSC && CmpRHSC->isNullValue())
1673 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1683 bool NeedExtraBranch =
false;
1690 NeedExtraBranch =
true;
1703 if (!X86FastEmitCompare(CmpLHS, CmpRHS, VT, CI->
getDebugLoc()))
1706 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1711 if (NeedExtraBranch) {
1712 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1716 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1723 if (TI->hasOneUse() && TI->getParent() ==
I->getParent() &&
1724 isTypeLegal(TI->getOperand(0)->getType(), SourceVT)) {
1725 unsigned TestOpc = 0;
1728 case MVT::i8: TestOpc = X86::TEST8ri;
break;
1729 case MVT::i16: TestOpc = X86::TEST16ri;
break;
1730 case MVT::i32: TestOpc = X86::TEST32ri;
break;
1731 case MVT::i64: TestOpc = X86::TEST64ri32;
break;
1734 Register OpReg = getRegForValue(TI->getOperand(0));
1738 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TestOpc))
1742 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1747 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1750 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1754 }
else if (foldX86XALUIntrinsic(CC, BI, BI->
getCondition())) {
1761 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1763 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1775 if (
MRI.getRegClass(OpReg) == &X86::VK1RegClass) {
1777 OpReg = createResultReg(&X86::GR32RegClass);
1778 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1779 TII.get(TargetOpcode::COPY), OpReg)
1781 OpReg = fastEmitInst_extractsubreg(MVT::i8, OpReg, X86::sub_8bit);
1783 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
1786 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::JCC_1))
1788 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1792bool X86FastISel::X86SelectShift(
const Instruction *
I) {
1796 if (
I->getType()->isIntegerTy(8)) {
1798 RC = &X86::GR8RegClass;
1799 switch (
I->getOpcode()) {
1800 case Instruction::LShr: OpReg = X86::SHR8rCL;
break;
1801 case Instruction::AShr: OpReg = X86::SAR8rCL;
break;
1802 case Instruction::Shl: OpReg = X86::SHL8rCL;
break;
1803 default:
return false;
1805 }
else if (
I->getType()->isIntegerTy(16)) {
1807 RC = &X86::GR16RegClass;
1808 switch (
I->getOpcode()) {
1810 case Instruction::LShr: OpReg = X86::SHR16rCL;
break;
1811 case Instruction::AShr: OpReg = X86::SAR16rCL;
break;
1812 case Instruction::Shl: OpReg = X86::SHL16rCL;
break;
1814 }
else if (
I->getType()->isIntegerTy(32)) {
1816 RC = &X86::GR32RegClass;
1817 switch (
I->getOpcode()) {
1819 case Instruction::LShr: OpReg = X86::SHR32rCL;
break;
1820 case Instruction::AShr: OpReg = X86::SAR32rCL;
break;
1821 case Instruction::Shl: OpReg = X86::SHL32rCL;
break;
1823 }
else if (
I->getType()->isIntegerTy(64)) {
1825 RC = &X86::GR64RegClass;
1826 switch (
I->getOpcode()) {
1828 case Instruction::LShr: OpReg = X86::SHR64rCL;
break;
1829 case Instruction::AShr: OpReg = X86::SAR64rCL;
break;
1830 case Instruction::Shl: OpReg = X86::SHL64rCL;
break;
1837 if (!isTypeLegal(
I->getType(), VT))
1840 Register Op0Reg = getRegForValue(
I->getOperand(0));
1844 Register Op1Reg = getRegForValue(
I->getOperand(1));
1847 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
1852 if (CReg != X86::CL)
1853 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1854 TII.get(TargetOpcode::KILL), X86::CL)
1857 Register ResultReg = createResultReg(RC);
1858 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(OpReg), ResultReg)
1860 updateValueMap(
I, ResultReg);
1864bool X86FastISel::X86SelectDivRem(
const Instruction *
I) {
1865 const static unsigned NumTypes = 4;
1866 const static unsigned NumOps = 4;
1867 const static bool S =
true;
1868 const static bool U =
false;
1869 const static unsigned Copy = TargetOpcode::COPY;
1879 const static struct DivRemEntry {
1885 struct DivRemResult {
1887 unsigned OpSignExtend;
1891 unsigned DivRemResultReg;
1893 } ResultTable[NumOps];
1894 } OpTable[NumTypes] = {
1895 { &X86::GR8RegClass, X86::AX, 0, {
1896 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S },
1897 { X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S },
1898 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL,
U },
1899 { X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH,
U },
1902 { &X86::GR16RegClass, X86::AX, X86::DX, {
1903 { X86::IDIV16r, X86::CWD,
Copy, X86::AX, S },
1904 { X86::IDIV16r, X86::CWD,
Copy, X86::DX, S },
1905 { X86::DIV16r, X86::MOV32r0,
Copy, X86::AX,
U },
1906 { X86::DIV16r, X86::MOV32r0,
Copy, X86::DX,
U },
1909 { &X86::GR32RegClass, X86::EAX, X86::EDX, {
1910 { X86::IDIV32r, X86::CDQ,
Copy, X86::EAX, S },
1911 { X86::IDIV32r, X86::CDQ,
Copy, X86::EDX, S },
1912 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EAX,
U },
1913 { X86::DIV32r, X86::MOV32r0,
Copy, X86::EDX,
U },
1916 { &X86::GR64RegClass, X86::RAX, X86::RDX, {
1917 { X86::IDIV64r, X86::CQO,
Copy, X86::RAX, S },
1918 { X86::IDIV64r, X86::CQO,
Copy, X86::RDX, S },
1919 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RAX,
U },
1920 { X86::DIV64r, X86::MOV32r0,
Copy, X86::RDX,
U },
1926 if (!isTypeLegal(
I->getType(), VT))
1931 default:
return false;
1932 case MVT::i8: TypeIndex = 0;
break;
1933 case MVT::i16: TypeIndex = 1;
break;
1934 case MVT::i32: TypeIndex = 2;
break;
1935 case MVT::i64: TypeIndex = 3;
1936 if (!Subtarget->is64Bit())
1941 switch (
I->getOpcode()) {
1943 case Instruction::SDiv:
OpIndex = 0;
break;
1944 case Instruction::SRem:
OpIndex = 1;
break;
1945 case Instruction::UDiv:
OpIndex = 2;
break;
1946 case Instruction::URem:
OpIndex = 3;
break;
1949 const DivRemEntry &
TypeEntry = OpTable[TypeIndex];
1951 Register Op0Reg = getRegForValue(
I->getOperand(0));
1954 Register Op1Reg = getRegForValue(
I->getOperand(1));
1959 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1962 if (OpEntry.OpSignExtend) {
1963 if (OpEntry.IsOpSigned)
1964 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1965 TII.get(OpEntry.OpSignExtend));
1967 Register Zero32 = createResultReg(&X86::GR32RegClass);
1968 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1969 TII.get(X86::MOV32r0), Zero32);
1974 if (VT == MVT::i16) {
1975 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1977 .
addReg(Zero32, 0, X86::sub_16bit);
1978 }
else if (VT == MVT::i32) {
1979 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1982 }
else if (VT == MVT::i64) {
1983 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1984 TII.get(TargetOpcode::SUBREG_TO_REG),
TypeEntry.HighInReg)
1990 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1991 TII.get(OpEntry.OpDivRem)).
addReg(Op1Reg);
2001 if ((
I->getOpcode() == Instruction::SRem ||
2002 I->getOpcode() == Instruction::URem) &&
2003 OpEntry.DivRemResultReg == X86::AH && Subtarget->is64Bit()) {
2004 Register SourceSuperReg = createResultReg(&X86::GR16RegClass);
2005 Register ResultSuperReg = createResultReg(&X86::GR16RegClass);
2006 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2007 TII.get(Copy), SourceSuperReg).
addReg(X86::AX);
2010 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SHR16ri),
2014 ResultReg = fastEmitInst_extractsubreg(MVT::i8, ResultSuperReg,
2019 ResultReg = createResultReg(
TypeEntry.RC);
2020 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(Copy), ResultReg)
2021 .
addReg(OpEntry.DivRemResultReg);
2023 updateValueMap(
I, ResultReg);
2030bool X86FastISel::X86FastEmitCMoveSelect(
MVT RetVT,
const Instruction *
I) {
2032 if (!Subtarget->canUseCMOV())
2036 if (RetVT < MVT::i16 || RetVT > MVT::i64)
2041 bool NeedTest =
true;
2047 const auto *CI = dyn_cast<CmpInst>(
Cond);
2048 if (CI && (CI->
getParent() ==
I->getParent())) {
2052 static const uint16_t SETFOpcTable[2][3] = {
2060 SETFOpc = &SETFOpcTable[0][0];
2064 SETFOpc = &SETFOpcTable[1][0];
2080 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->
getDebugLoc()))
2084 Register FlagReg1 = createResultReg(&X86::GR8RegClass);
2085 Register FlagReg2 = createResultReg(&X86::GR8RegClass);
2086 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SETCCr),
2087 FlagReg1).
addImm(SETFOpc[0]);
2088 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SETCCr),
2089 FlagReg2).
addImm(SETFOpc[1]);
2090 auto const &
II =
TII.get(SETFOpc[2]);
2091 if (
II.getNumDefs()) {
2092 Register TmpReg = createResultReg(&X86::GR8RegClass);
2093 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, TmpReg)
2096 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
2101 }
else if (foldX86XALUIntrinsic(CC,
I,
Cond)) {
2122 if (
MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2124 CondReg = createResultReg(&X86::GR32RegClass);
2125 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2126 TII.get(TargetOpcode::COPY), CondReg)
2128 CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, X86::sub_8bit);
2130 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
2138 Register RHSReg = getRegForValue(RHS);
2139 Register LHSReg = getRegForValue(LHS);
2140 if (!LHSReg || !RHSReg)
2145 Subtarget->hasNDD());
2146 Register ResultReg = fastEmitInst_rri(
Opc, RC, RHSReg, LHSReg, CC);
2147 updateValueMap(
I, ResultReg);
2156bool X86FastISel::X86FastEmitSSESelect(
MVT RetVT,
const Instruction *
I) {
2160 const auto *CI = dyn_cast<FCmpInst>(
I->getOperand(0));
2161 if (!CI || (CI->
getParent() !=
I->getParent()))
2165 !((Subtarget->hasSSE1() && RetVT == MVT::f32) ||
2166 (Subtarget->hasSSE2() && RetVT == MVT::f64)))
2177 const auto *CmpRHSC = dyn_cast<ConstantFP>(CmpRHS);
2178 if (CmpRHSC && CmpRHSC->isNullValue())
2185 if (CC > 7 && !Subtarget->hasAVX())
2194 Register LHSReg = getRegForValue(LHS);
2195 Register RHSReg = getRegForValue(RHS);
2196 Register CmpLHSReg = getRegForValue(CmpLHS);
2197 Register CmpRHSReg = getRegForValue(CmpRHS);
2198 if (!LHSReg || !RHSReg || !CmpLHSReg || !CmpRHSReg)
2204 if (Subtarget->hasAVX512()) {
2209 unsigned CmpOpcode =
2210 (RetVT == MVT::f32) ? X86::VCMPSSZrri : X86::VCMPSDZrri;
2211 Register CmpReg = fastEmitInst_rri(CmpOpcode, VK1, CmpLHSReg, CmpRHSReg,
2216 Register ImplicitDefReg = createResultReg(VR128X);
2217 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2218 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2222 unsigned MovOpcode =
2223 (RetVT == MVT::f32) ? X86::VMOVSSZrrk : X86::VMOVSDZrrk;
2224 Register MovReg = fastEmitInst_rrrr(MovOpcode, VR128X, RHSReg, CmpReg,
2225 ImplicitDefReg, LHSReg);
2227 ResultReg = createResultReg(RC);
2228 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2229 TII.get(TargetOpcode::COPY), ResultReg).
addReg(MovReg);
2231 }
else if (Subtarget->hasAVX()) {
2239 unsigned CmpOpcode =
2240 (RetVT == MVT::f32) ? X86::VCMPSSrri : X86::VCMPSDrri;
2241 unsigned BlendOpcode =
2242 (RetVT == MVT::f32) ? X86::VBLENDVPSrrr : X86::VBLENDVPDrrr;
2244 Register CmpReg = fastEmitInst_rri(CmpOpcode, RC, CmpLHSReg, CmpRHSReg,
2246 Register VBlendReg = fastEmitInst_rrr(BlendOpcode, VR128, RHSReg, LHSReg,
2248 ResultReg = createResultReg(RC);
2249 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2250 TII.get(TargetOpcode::COPY), ResultReg).
addReg(VBlendReg);
2253 static const uint16_t OpcTable[2][4] = {
2254 { X86::CMPSSrri, X86::ANDPSrr, X86::ANDNPSrr, X86::ORPSrr },
2255 { X86::CMPSDrri, X86::ANDPDrr, X86::ANDNPDrr, X86::ORPDrr }
2260 default:
return false;
2261 case MVT::f32:
Opc = &OpcTable[0][0];
break;
2262 case MVT::f64:
Opc = &OpcTable[1][0];
break;
2266 Register CmpReg = fastEmitInst_rri(
Opc[0], RC, CmpLHSReg, CmpRHSReg, CC);
2267 Register AndReg = fastEmitInst_rr(
Opc[1], VR128, CmpReg, LHSReg);
2268 Register AndNReg = fastEmitInst_rr(
Opc[2], VR128, CmpReg, RHSReg);
2269 Register OrReg = fastEmitInst_rr(
Opc[3], VR128, AndNReg, AndReg);
2270 ResultReg = createResultReg(RC);
2271 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2272 TII.get(TargetOpcode::COPY), ResultReg).
addReg(OrReg);
2274 updateValueMap(
I, ResultReg);
2278bool X86FastISel::X86FastEmitPseudoSelect(
MVT RetVT,
const Instruction *
I) {
2283 default:
return false;
2284 case MVT::i8:
Opc = X86::CMOV_GR8;
break;
2285 case MVT::i16:
Opc = X86::CMOV_GR16;
break;
2286 case MVT::i32:
Opc = X86::CMOV_GR32;
break;
2288 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR16X : X86::CMOV_FR16;
break;
2290 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR32X : X86::CMOV_FR32;
break;
2292 Opc = Subtarget->hasAVX512() ? X86::CMOV_FR64X : X86::CMOV_FR64;
break;
2301 const auto *CI = dyn_cast<CmpInst>(
Cond);
2302 if (CI && (CI->
getParent() ==
I->getParent())) {
2315 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->
getDebugLoc()))
2323 if (
MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2325 CondReg = createResultReg(&X86::GR32RegClass);
2326 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2327 TII.get(TargetOpcode::COPY), CondReg)
2329 CondReg = fastEmitInst_extractsubreg(MVT::i8, CondReg, X86::sub_8bit);
2331 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TEST8ri))
2339 Register LHSReg = getRegForValue(LHS);
2340 Register RHSReg = getRegForValue(RHS);
2341 if (!LHSReg || !RHSReg)
2347 fastEmitInst_rri(
Opc, RC, RHSReg, LHSReg, CC);
2348 updateValueMap(
I, ResultReg);
2352bool X86FastISel::X86SelectSelect(
const Instruction *
I) {
2354 if (!isTypeLegal(
I->getType(), RetVT))
2358 if (
const auto *CI = dyn_cast<CmpInst>(
I->getOperand(0))) {
2360 const Value *Opnd =
nullptr;
2368 Register OpReg = getRegForValue(Opnd);
2372 Register ResultReg = createResultReg(RC);
2373 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2374 TII.get(TargetOpcode::COPY), ResultReg)
2376 updateValueMap(
I, ResultReg);
2382 if (X86FastEmitCMoveSelect(RetVT,
I))
2386 if (X86FastEmitSSESelect(RetVT,
I))
2391 if (X86FastEmitPseudoSelect(RetVT,
I))
2398bool X86FastISel::X86SelectIntToFP(
const Instruction *
I,
bool IsSigned) {
2403 bool HasAVX512 = Subtarget->hasAVX512();
2404 if (!Subtarget->hasAVX() || (!IsSigned && !HasAVX512))
2408 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
2409 if (SrcVT != MVT::i32 && SrcVT != MVT::i64)
2413 Register OpReg = getRegForValue(
I->getOperand(0));
2419 static const uint16_t SCvtOpc[2][2][2] = {
2420 { { X86::VCVTSI2SSrr, X86::VCVTSI642SSrr },
2421 { X86::VCVTSI2SDrr, X86::VCVTSI642SDrr } },
2422 { { X86::VCVTSI2SSZrr, X86::VCVTSI642SSZrr },
2423 { X86::VCVTSI2SDZrr, X86::VCVTSI642SDZrr } },
2425 static const uint16_t UCvtOpc[2][2] = {
2426 { X86::VCVTUSI2SSZrr, X86::VCVTUSI642SSZrr },
2427 { X86::VCVTUSI2SDZrr, X86::VCVTUSI642SDZrr },
2429 bool Is64Bit = SrcVT == MVT::i64;
2431 if (
I->getType()->isDoubleTy()) {
2433 Opcode = IsSigned ? SCvtOpc[HasAVX512][1][Is64Bit] : UCvtOpc[1][Is64Bit];
2434 }
else if (
I->getType()->isFloatTy()) {
2436 Opcode = IsSigned ? SCvtOpc[HasAVX512][0][Is64Bit] : UCvtOpc[0][Is64Bit];
2442 Register ImplicitDefReg = createResultReg(RC);
2443 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2444 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2445 Register ResultReg = fastEmitInst_rr(Opcode, RC, ImplicitDefReg, OpReg);
2446 updateValueMap(
I, ResultReg);
2450bool X86FastISel::X86SelectSIToFP(
const Instruction *
I) {
2451 return X86SelectIntToFP(
I,
true);
2454bool X86FastISel::X86SelectUIToFP(
const Instruction *
I) {
2455 return X86SelectIntToFP(
I,
false);
2459bool X86FastISel::X86SelectFPExtOrFPTrunc(
const Instruction *
I,
2462 assert((
I->getOpcode() == Instruction::FPExt ||
2463 I->getOpcode() == Instruction::FPTrunc) &&
2464 "Instruction must be an FPExt or FPTrunc!");
2465 bool HasAVX = Subtarget->hasAVX();
2467 Register OpReg = getRegForValue(
I->getOperand(0));
2473 ImplicitDefReg = createResultReg(RC);
2474 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2475 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2479 Register ResultReg = createResultReg(RC);
2481 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpc),
2485 MIB.
addReg(ImplicitDefReg);
2488 updateValueMap(
I, ResultReg);
2492bool X86FastISel::X86SelectFPExt(
const Instruction *
I) {
2493 if (Subtarget->hasSSE2() &&
I->getType()->isDoubleTy() &&
2494 I->getOperand(0)->getType()->isFloatTy()) {
2495 bool HasAVX512 = Subtarget->hasAVX512();
2498 HasAVX512 ? X86::VCVTSS2SDZrr
2499 : Subtarget->hasAVX() ? X86::VCVTSS2SDrr : X86::CVTSS2SDrr;
2500 return X86SelectFPExtOrFPTrunc(
I,
Opc, TLI.getRegClassFor(MVT::f64));
2506bool X86FastISel::X86SelectFPTrunc(
const Instruction *
I) {
2507 if (Subtarget->hasSSE2() &&
I->getType()->isFloatTy() &&
2508 I->getOperand(0)->getType()->isDoubleTy()) {
2509 bool HasAVX512 = Subtarget->hasAVX512();
2512 HasAVX512 ? X86::VCVTSD2SSZrr
2513 : Subtarget->hasAVX() ? X86::VCVTSD2SSrr : X86::CVTSD2SSrr;
2514 return X86SelectFPExtOrFPTrunc(
I,
Opc, TLI.getRegClassFor(MVT::f32));
2520bool X86FastISel::X86SelectTrunc(
const Instruction *
I) {
2521 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
2522 EVT DstVT = TLI.getValueType(
DL,
I->getType());
2525 if (DstVT != MVT::i8 && DstVT != MVT::i1)
2527 if (!TLI.isTypeLegal(SrcVT))
2530 Register InputReg = getRegForValue(
I->getOperand(0));
2535 if (SrcVT == MVT::i8) {
2537 updateValueMap(
I, InputReg);
2542 Register ResultReg = fastEmitInst_extractsubreg(MVT::i8, InputReg,
2547 updateValueMap(
I, ResultReg);
2551bool X86FastISel::X86SelectBitCast(
const Instruction *
I) {
2554 if (!Subtarget->hasSSE2() ||
2555 !isTypeLegal(
I->getOperand(0)->getType(), SrcVT) ||
2556 !isTypeLegal(
I->getType(), DstVT))
2572 Register ResultReg = createResultReg(DstClass);
2573 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
2577 updateValueMap(
I, ResultReg);
2581bool X86FastISel::IsMemcpySmall(
uint64_t Len) {
2582 return Len <= (Subtarget->is64Bit() ? 32 : 16);
2589 if (!IsMemcpySmall(Len))
2592 bool i64Legal = Subtarget->is64Bit();
2597 if (Len >= 8 && i64Legal)
2607 bool RV = X86FastEmitLoad(VT, SrcAM,
nullptr, Reg);
2608 RV &= X86FastEmitStore(VT, Reg, DestAM);
2609 assert(RV &&
"Failed to emit load or store??");
2623 switch (
II->getIntrinsicID()) {
2624 default:
return false;
2625 case Intrinsic::convert_from_fp16:
2626 case Intrinsic::convert_to_fp16: {
2627 if (Subtarget->useSoftFloat() || !Subtarget->hasF16C())
2636 bool IsFloatToHalf =
II->getIntrinsicID() == Intrinsic::convert_to_fp16;
2637 if (IsFloatToHalf) {
2638 if (!
Op->getType()->isFloatTy())
2641 if (!
II->getType()->isFloatTy())
2647 if (IsFloatToHalf) {
2655 unsigned Opc = Subtarget->hasVLX() ? X86::VCVTPS2PHZ128rr
2657 InputReg = fastEmitInst_ri(
Opc, RC, InputReg, 4);
2660 Opc = Subtarget->hasAVX512() ? X86::VMOVPDI2DIZrr
2661 : X86::VMOVPDI2DIrr;
2662 ResultReg = createResultReg(&X86::GR32RegClass);
2663 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
2667 unsigned RegIdx = X86::sub_16bit;
2668 ResultReg = fastEmitInst_extractsubreg(MVT::i16, ResultReg, RegIdx);
2670 assert(
Op->getType()->isIntegerTy(16) &&
"Expected a 16-bit integer!");
2678 unsigned Opc = Subtarget->hasVLX() ? X86::VCVTPH2PSZ128rr
2680 InputReg = fastEmitInst_r(
Opc, RC, InputReg);
2684 ResultReg = createResultReg(TLI.getRegClassFor(MVT::f32));
2685 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2686 TII.get(TargetOpcode::COPY), ResultReg)
2690 updateValueMap(
II, ResultReg);
2693 case Intrinsic::frameaddress: {
2698 Type *
RetTy =
II->getCalledFunction()->getReturnType();
2701 if (!isTypeLegal(
RetTy, VT))
2709 case MVT::i32:
Opc = X86::MOV32rm; RC = &X86::GR32RegClass;
break;
2710 case MVT::i64:
Opc = X86::MOV64rm; RC = &X86::GR64RegClass;
break;
2720 assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
2721 (FrameReg == X86::EBP && VT == MVT::i32)) &&
2722 "Invalid Frame Register!");
2727 Register SrcReg = createResultReg(RC);
2728 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2729 TII.get(TargetOpcode::COPY), SrcReg).
addReg(FrameReg);
2736 unsigned Depth = cast<ConstantInt>(
II->getOperand(0))->getZExtValue();
2738 Register DestReg = createResultReg(RC);
2740 TII.get(
Opc), DestReg), SrcReg);
2744 updateValueMap(
II, SrcReg);
2747 case Intrinsic::memcpy: {
2753 if (isa<ConstantInt>(MCI->
getLength())) {
2757 if (IsMemcpySmall(Len)) {
2762 TryEmitSmallMemcpy(DestAM, SrcAM, Len);
2767 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2774 return lowerCallTo(
II,
"memcpy",
II->arg_size() - 1);
2776 case Intrinsic::memset: {
2782 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2789 return lowerCallTo(
II,
"memset",
II->arg_size() - 1);
2791 case Intrinsic::stackprotector: {
2793 EVT PtrTy = TLI.getPointerTy(
DL);
2795 const Value *Op1 =
II->getArgOperand(0);
2803 if (!X86FastEmitStore(PtrTy, Op1, AM))
return false;
2806 case Intrinsic::dbg_declare: {
2814 "Expected inlined-at fields to agree");
2821 case Intrinsic::trap: {
2822 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::TRAP));
2825 case Intrinsic::sqrt: {
2826 if (!Subtarget->hasSSE1())
2829 Type *
RetTy =
II->getCalledFunction()->getReturnType();
2832 if (!isTypeLegal(
RetTy, VT))
2838 static const uint16_t SqrtOpc[3][2] = {
2839 { X86::SQRTSSr, X86::SQRTSDr },
2840 { X86::VSQRTSSr, X86::VSQRTSDr },
2841 { X86::VSQRTSSZr, X86::VSQRTSDZr },
2843 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
2844 Subtarget->hasAVX() ? 1 :
2848 default:
return false;
2849 case MVT::f32:
Opc = SqrtOpc[AVXLevel][0];
break;
2850 case MVT::f64:
Opc = SqrtOpc[AVXLevel][1];
break;
2853 const Value *SrcVal =
II->getArgOperand(0);
2854 Register SrcReg = getRegForValue(SrcVal);
2862 ImplicitDefReg = createResultReg(RC);
2863 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2864 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2867 Register ResultReg = createResultReg(RC);
2869 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
2873 MIB.
addReg(ImplicitDefReg);
2877 updateValueMap(
II, ResultReg);
2880 case Intrinsic::sadd_with_overflow:
2881 case Intrinsic::uadd_with_overflow:
2882 case Intrinsic::ssub_with_overflow:
2883 case Intrinsic::usub_with_overflow:
2884 case Intrinsic::smul_with_overflow:
2885 case Intrinsic::umul_with_overflow: {
2889 auto *Ty = cast<StructType>(
Callee->getReturnType());
2893 "Overflow value expected to be an i1");
2896 if (!isTypeLegal(
RetTy, VT))
2899 if (VT < MVT::i8 || VT > MVT::i64)
2906 if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) &&
II->isCommutative())
2910 switch (
II->getIntrinsicID()) {
2912 case Intrinsic::sadd_with_overflow:
2914 case Intrinsic::uadd_with_overflow:
2916 case Intrinsic::ssub_with_overflow:
2918 case Intrinsic::usub_with_overflow:
2920 case Intrinsic::smul_with_overflow:
2922 case Intrinsic::umul_with_overflow:
2926 Register LHSReg = getRegForValue(LHS);
2932 if (
const auto *CI = dyn_cast<ConstantInt>(RHS)) {
2934 { X86::INC8r, X86::INC16r, X86::INC32r, X86::INC64r },
2935 { X86::DEC8r, X86::DEC16r, X86::DEC32r, X86::DEC64r }
2941 ResultReg = createResultReg(TLI.getRegClassFor(VT));
2943 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2947 ResultReg = fastEmit_ri(VT, VT, BaseOpc, LHSReg, CI->getZExtValue());
2952 RHSReg = getRegForValue(RHS);
2955 ResultReg = fastEmit_rr(VT, VT, BaseOpc, LHSReg, RHSReg);
2962 { X86::MUL8r, X86::MUL16r, X86::MUL32r, X86::MUL64r };
2963 static const MCPhysReg Reg[] = { X86::AL, X86::AX, X86::EAX, X86::RAX };
2966 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2967 TII.get(TargetOpcode::COPY), Reg[VT.
SimpleTy-MVT::i8])
2969 ResultReg = fastEmitInst_r(MULOpc[VT.
SimpleTy-MVT::i8],
2970 TLI.getRegClassFor(VT), RHSReg);
2973 { X86::IMUL8r, X86::IMUL16rr, X86::IMUL32rr, X86::IMUL64rr };
2974 if (VT == MVT::i8) {
2977 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2978 TII.get(TargetOpcode::COPY), X86::AL)
2980 ResultReg = fastEmitInst_r(MULOpc[0], TLI.getRegClassFor(VT), RHSReg);
2982 ResultReg = fastEmitInst_rr(MULOpc[VT.
SimpleTy-MVT::i8],
2983 TLI.getRegClassFor(VT), LHSReg, RHSReg);
2990 Register ResultReg2 = createResultReg(&X86::GR8RegClass);
2991 assert((ResultReg+1) == ResultReg2 &&
"Nonconsecutive result registers.");
2992 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::SETCCr),
2993 ResultReg2).
addImm(CondCode);
2995 updateValueMap(
II, ResultReg, 2);
2998 case Intrinsic::x86_sse_cvttss2si:
2999 case Intrinsic::x86_sse_cvttss2si64:
3000 case Intrinsic::x86_sse2_cvttsd2si:
3001 case Intrinsic::x86_sse2_cvttsd2si64: {
3003 switch (
II->getIntrinsicID()) {
3005 case Intrinsic::x86_sse_cvttss2si:
3006 case Intrinsic::x86_sse_cvttss2si64:
3007 if (!Subtarget->hasSSE1())
3009 IsInputDouble =
false;
3011 case Intrinsic::x86_sse2_cvttsd2si:
3012 case Intrinsic::x86_sse2_cvttsd2si64:
3013 if (!Subtarget->hasSSE2())
3015 IsInputDouble =
true;
3019 Type *
RetTy =
II->getCalledFunction()->getReturnType();
3021 if (!isTypeLegal(
RetTy, VT))
3024 static const uint16_t CvtOpc[3][2][2] = {
3025 { { X86::CVTTSS2SIrr, X86::CVTTSS2SI64rr },
3026 { X86::CVTTSD2SIrr, X86::CVTTSD2SI64rr } },
3027 { { X86::VCVTTSS2SIrr, X86::VCVTTSS2SI64rr },
3028 { X86::VCVTTSD2SIrr, X86::VCVTTSD2SI64rr } },
3029 { { X86::VCVTTSS2SIZrr, X86::VCVTTSS2SI64Zrr },
3030 { X86::VCVTTSD2SIZrr, X86::VCVTTSD2SI64Zrr } },
3032 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
3033 Subtarget->hasAVX() ? 1 :
3038 case MVT::i32:
Opc = CvtOpc[AVXLevel][IsInputDouble][0];
break;
3039 case MVT::i64:
Opc = CvtOpc[AVXLevel][IsInputDouble][1];
break;
3044 while (
auto *IE = dyn_cast<InsertElementInst>(
Op)) {
3046 if (!isa<ConstantInt>(Index))
3048 unsigned Idx = cast<ConstantInt>(Index)->getZExtValue();
3051 Op =
IE->getOperand(1);
3054 Op =
IE->getOperand(0);
3061 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3062 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg)
3065 updateValueMap(
II, ResultReg);
3068 case Intrinsic::x86_sse42_crc32_32_8:
3069 case Intrinsic::x86_sse42_crc32_32_16:
3070 case Intrinsic::x86_sse42_crc32_32_32:
3071 case Intrinsic::x86_sse42_crc32_64_64: {
3072 if (!Subtarget->hasCRC32())
3075 Type *
RetTy =
II->getCalledFunction()->getReturnType();
3078 if (!isTypeLegal(
RetTy, VT))
3084 switch (
II->getIntrinsicID()) {
3087#define GET_EGPR_IF_ENABLED(OPC) Subtarget->hasEGPR() ? OPC##_EVEX : OPC
3088 case Intrinsic::x86_sse42_crc32_32_8:
3090 RC = &X86::GR32RegClass;
3092 case Intrinsic::x86_sse42_crc32_32_16:
3094 RC = &X86::GR32RegClass;
3096 case Intrinsic::x86_sse42_crc32_32_32:
3098 RC = &X86::GR32RegClass;
3100 case Intrinsic::x86_sse42_crc32_64_64:
3102 RC = &X86::GR64RegClass;
3104#undef GET_EGPR_IF_ENABLED
3110 Register LHSReg = getRegForValue(LHS);
3111 Register RHSReg = getRegForValue(RHS);
3112 if (!LHSReg || !RHSReg)
3115 Register ResultReg = fastEmitInst_rr(
Opc, RC, LHSReg, RHSReg);
3119 updateValueMap(
II, ResultReg);
3125bool X86FastISel::fastLowerArguments() {
3126 if (!FuncInfo.CanLowerReturn)
3137 if (Subtarget->isCallingConvWin64(CC))
3140 if (!Subtarget->is64Bit())
3143 if (Subtarget->useSoftFloat())
3147 unsigned GPRCnt = 0;
3148 unsigned FPRCnt = 0;
3149 for (
auto const &Arg :
F->args()) {
3150 if (Arg.hasAttribute(Attribute::ByVal) ||
3151 Arg.hasAttribute(Attribute::InReg) ||
3152 Arg.hasAttribute(Attribute::StructRet) ||
3153 Arg.hasAttribute(Attribute::SwiftSelf) ||
3154 Arg.hasAttribute(Attribute::SwiftAsync) ||
3155 Arg.hasAttribute(Attribute::SwiftError) ||
3156 Arg.hasAttribute(Attribute::Nest))
3159 Type *ArgTy = Arg.getType();
3163 EVT ArgVT = TLI.getValueType(
DL, ArgTy);
3164 if (!ArgVT.
isSimple())
return false;
3166 default:
return false;
3173 if (!Subtarget->hasSSE1())
3186 static const MCPhysReg GPR32ArgRegs[] = {
3187 X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
3189 static const MCPhysReg GPR64ArgRegs[] = {
3190 X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8 , X86::R9
3193 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3194 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3198 unsigned FPRIdx = 0;
3199 for (
auto const &Arg :
F->args()) {
3200 MVT VT = TLI.getSimpleValueType(
DL, Arg.getType());
3205 case MVT::i32: SrcReg = GPR32ArgRegs[
GPRIdx++];
break;
3206 case MVT::i64: SrcReg = GPR64ArgRegs[
GPRIdx++];
break;
3207 case MVT::f32: [[fallthrough]];
3208 case MVT::f64: SrcReg = XMMArgRegs[FPRIdx++];
break;
3210 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
3214 Register ResultReg = createResultReg(RC);
3215 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3216 TII.get(TargetOpcode::COPY), ResultReg)
3218 updateValueMap(&Arg, ResultReg);
3226 if (Subtarget->is64Bit())
3243bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
3244 auto &OutVals = CLI.OutVals;
3245 auto &OutFlags = CLI.OutFlags;
3246 auto &OutRegs = CLI.OutRegs;
3247 auto &
Ins = CLI.Ins;
3248 auto &InRegs = CLI.InRegs;
3250 bool &IsTailCall = CLI.IsTailCall;
3251 bool IsVarArg = CLI.IsVarArg;
3254 const auto *CB = CLI.CB;
3256 bool Is64Bit = Subtarget->is64Bit();
3257 bool IsWin64 = Subtarget->isCallingConvWin64(CC);
3261 if (CB && CB->doesNoCfCheck())
3265 if ((CB && isa<CallInst>(CB) && CB->hasFnAttr(
"no_caller_saved_registers")))
3269 if ((CB && CB->hasFnAttr(
"no_callee_saved_registers")))
3277 if (Subtarget->useIndirectThunkCalls())
3282 default:
return false;
3309 if (IsVarArg && IsWin64)
3313 if (CLI.CB && CLI.CB->hasInAllocaArgument())
3316 for (
auto Flag : CLI.OutFlags)
3317 if (
Flag.isSwiftError() ||
Flag.isPreallocated())
3332 for (
int i = 0, e = OutVals.size(); i != e; ++i) {
3333 Value *&Val = OutVals[i];
3335 if (
auto *CI = dyn_cast<ConstantInt>(Val)) {
3336 if (CI->getBitWidth() < 32) {
3338 Val = ConstantInt::get(CI->
getContext(), CI->getValue().sext(32));
3340 Val = ConstantInt::get(CI->
getContext(), CI->getValue().zext(32));
3347 auto *TI = dyn_cast<TruncInst>(Val);
3349 if (TI && TI->getType()->isIntegerTy(1) && CLI.CB &&
3350 (TI->getParent() == CLI.CB->getParent()) && TI->hasOneUse()) {
3351 Value *PrevVal = TI->getOperand(0);
3352 ResultReg = getRegForValue(PrevVal);
3357 if (!isTypeLegal(PrevVal->
getType(), VT))
3360 ResultReg = fastEmit_ri(VT, VT,
ISD::AND, ResultReg, 1);
3362 if (!isTypeLegal(Val->
getType(), VT) ||
3365 ResultReg = getRegForValue(Val);
3378 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, CLI.RetTy->getContext());
3382 CCInfo.AllocateStack(32,
Align(8));
3384 CCInfo.AnalyzeCallOperands(OutVTs, OutFlags, ArgTys,
CC_X86);
3387 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
3390 unsigned AdjStackDown =
TII.getCallFrameSetupOpcode();
3391 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackDown))
3400 if (ArgVT == MVT::x86mmx)
3410 "Unexpected extend");
3412 if (ArgVT == MVT::i1)
3417 assert(Emitted &&
"Failed to emit a sext!"); (void)Emitted;
3423 "Unexpected extend");
3426 if (ArgVT == MVT::i1) {
3428 ArgReg = fastEmitZExtFromI1(MVT::i8, ArgReg);
3437 assert(Emitted &&
"Failed to emit a zext!"); (void)Emitted;
3443 "Unexpected extend");
3453 assert(Emitted &&
"Failed to emit a aext!"); (void)Emitted;
3459 assert(ArgReg &&
"Failed to emit a bitcast!");
3480 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3487 if (isa<UndefValue>(ArgVal))
3493 AM.
Disp = LocMemOffset;
3499 if (
Flags.isByVal()) {
3502 if (!TryEmitSmallMemcpy(AM, SrcAM,
Flags.getByValSize()))
3504 }
else if (isa<ConstantInt>(ArgVal) || isa<ConstantPointerNull>(ArgVal)) {
3508 if (!X86FastEmitStore(ArgVT, ArgVal, AM, MMO))
3511 if (!X86FastEmitStore(ArgVT, ArgReg, AM, MMO))
3519 if (Subtarget->isPICStyleGOT()) {
3520 Register Base = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3521 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3525 if (Is64Bit && IsVarArg && !IsWin64) {
3536 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3537 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3539 unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs);
3540 assert((Subtarget->hasSSE1() || !NumXMMRegs)
3541 &&
"SSE registers cannot be used when SSE is disabled");
3542 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV8ri),
3543 X86::AL).
addImm(NumXMMRegs);
3549 if (!X86SelectCallAddress(Callee, CalleeAM))
3554 if (CalleeAM.
GV !=
nullptr) {
3556 }
else if (CalleeAM.
Base.
Reg) {
3565 unsigned CallOpc = Is64Bit ? X86::CALL64r : X86::CALL32r;
3566 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc))
3570 assert(GV &&
"Not a direct call");
3572 unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV);
3575 cast<Function>(GV)->isIntrinsic())
3584 unsigned CallOpc = NeedLoad
3585 ? (Is64Bit ? X86::CALL64m : X86::CALL32m)
3586 : (Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32);
3588 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(CallOpc));
3592 MIB.
addSym(Symbol, OpFlags);
3604 if (Subtarget->isPICStyleGOT())
3607 if (Is64Bit && IsVarArg && !IsWin64)
3611 for (
auto Reg : OutRegs)
3615 unsigned NumBytesForCalleeToPop =
3617 TM.Options.GuaranteedTailCallOpt)
3620 unsigned AdjStackUp =
TII.getCallFrameDestroyOpcode();
3621 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(AdjStackUp))
3626 CCState CCRetInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs,
3627 CLI.RetTy->getContext());
3628 CCRetInfo.AnalyzeCallResult(Ins,
RetCC_X86);
3631 Register ResultReg = FuncInfo.CreateRegs(CLI.RetTy);
3632 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
3639 if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) &&
3640 ((Is64Bit || Ins[i].
Flags.isInReg()) && !Subtarget->hasSSE1())) {
3646 if ((SrcReg == X86::FP0 || SrcReg == X86::FP1) &&
3647 isScalarFPTypeInSSEReg(VA.
getValVT())) {
3649 CopyReg = createResultReg(&X86::RFP80RegClass);
3653 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3654 TII.get(TargetOpcode::COPY), CopyReg).
addReg(SrcReg);
3662 unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
3668 Opc = ResVT == MVT::f32 ? X86::MOVSSrm_alt : X86::MOVSDrm_alt;
3670 TII.get(
Opc), ResultReg + i), FI);
3674 CLI.ResultReg = ResultReg;
3675 CLI.NumResultRegs = RVLocs.
size();
3679 if (
TM.Options.EmitCallGraphSection && CB && CB->isIndirectCall()) {
3688X86FastISel::fastSelectInstruction(
const Instruction *
I) {
3689 switch (
I->getOpcode()) {
3691 case Instruction::Load:
3692 return X86SelectLoad(
I);
3693 case Instruction::Store:
3694 return X86SelectStore(
I);
3695 case Instruction::Ret:
3696 return X86SelectRet(
I);
3697 case Instruction::ICmp:
3698 case Instruction::FCmp:
3699 return X86SelectCmp(
I);
3700 case Instruction::ZExt:
3701 return X86SelectZExt(
I);
3702 case Instruction::SExt:
3703 return X86SelectSExt(
I);
3704 case Instruction::Br:
3705 return X86SelectBranch(
I);
3706 case Instruction::LShr:
3707 case Instruction::AShr:
3708 case Instruction::Shl:
3709 return X86SelectShift(
I);
3710 case Instruction::SDiv:
3711 case Instruction::UDiv:
3712 case Instruction::SRem:
3713 case Instruction::URem:
3714 return X86SelectDivRem(
I);
3715 case Instruction::Select:
3716 return X86SelectSelect(
I);
3717 case Instruction::Trunc:
3718 return X86SelectTrunc(
I);
3719 case Instruction::FPExt:
3720 return X86SelectFPExt(
I);
3721 case Instruction::FPTrunc:
3722 return X86SelectFPTrunc(
I);
3723 case Instruction::SIToFP:
3724 return X86SelectSIToFP(
I);
3725 case Instruction::UIToFP:
3726 return X86SelectUIToFP(
I);
3727 case Instruction::IntToPtr:
3728 case Instruction::PtrToInt: {
3729 EVT SrcVT = TLI.getValueType(
DL,
I->getOperand(0)->getType());
3730 EVT DstVT = TLI.getValueType(
DL,
I->getType());
3732 return X86SelectZExt(
I);
3734 return X86SelectTrunc(
I);
3738 updateValueMap(
I, Reg);
3741 case Instruction::BitCast:
3742 return X86SelectBitCast(
I);
3754 Register SrcReg = fastEmitInst_(X86::MOV32r0, &X86::GR32RegClass);
3759 return fastEmitInst_extractsubreg(MVT::i8, SrcReg, X86::sub_8bit);
3761 return fastEmitInst_extractsubreg(MVT::i16, SrcReg, X86::sub_16bit);
3765 Register ResultReg = createResultReg(&X86::GR64RegClass);
3766 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
3767 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3780 case MVT::i8:
Opc = X86::MOV8ri;
break;
3781 case MVT::i16:
Opc = X86::MOV16ri;
break;
3782 case MVT::i32:
Opc = X86::MOV32ri;
break;
3784 if (isUInt<32>(Imm))
3785 Opc = X86::MOV32ri64;
3786 else if (isInt<32>(Imm))
3787 Opc = X86::MOV64ri32;
3793 return fastEmitInst_i(
Opc, TLI.getRegClassFor(VT), Imm);
3798 return fastMaterializeFloatZero(CFP);
3808 bool HasSSE1 = Subtarget->hasSSE1();
3809 bool HasSSE2 = Subtarget->hasSSE2();
3810 bool HasAVX = Subtarget->hasAVX();
3811 bool HasAVX512 = Subtarget->hasAVX512();
3816 Opc = HasAVX512 ? X86::VMOVSSZrm_alt
3817 : HasAVX ? X86::VMOVSSrm_alt
3818 : HasSSE1 ? X86::MOVSSrm_alt
3822 Opc = HasAVX512 ? X86::VMOVSDZrm_alt
3823 : HasAVX ? X86::VMOVSDrm_alt
3824 : HasSSE2 ? X86::MOVSDrm_alt
3837 unsigned char OpFlag = Subtarget->classifyLocalReference(
nullptr);
3839 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3841 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3846 unsigned CPI = MCP.getConstantPoolIndex(CFP, Alignment);
3851 Register AddrReg = createResultReg(&X86::GR64RegClass);
3852 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3856 TII.get(
Opc), ResultReg);
3857 addRegReg(MIB, AddrReg,
false, X86::NoSubRegister, PICBase,
false,
3858 X86::NoSubRegister);
3867 TII.get(
Opc), ResultReg),
3868 CPI, PICBase, OpFlag);
3877 if (
TM.isLargeGlobalValue(GV))
3889 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3891 TLI.getPointerTy(
DL) == MVT::i64) {
3894 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(X86::MOV64ri),
3899 TLI.getPointerTy(
DL) == MVT::i32
3900 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3903 TII.get(
Opc), ResultReg), AM);
3911 EVT CEVT = TLI.getValueType(
DL,
C->getType(),
true);
3918 if (
const auto *CI = dyn_cast<ConstantInt>(
C))
3919 return X86MaterializeInt(CI, VT);
3920 if (
const auto *CFP = dyn_cast<ConstantFP>(
C))
3921 return X86MaterializeFP(CFP, VT);
3922 if (
const auto *GV = dyn_cast<GlobalValue>(
C))
3923 return X86MaterializeGV(GV, VT);
3924 if (isa<UndefValue>(
C)) {
3930 if (!Subtarget->hasSSE1())
3931 Opc = X86::LD_Fp032;
3934 if (!Subtarget->hasSSE2())
3935 Opc = X86::LD_Fp064;
3938 Opc = X86::LD_Fp080;
3943 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
3944 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc),
3961 if (!FuncInfo.StaticAllocaMap.count(
C))
3963 assert(
C->isStaticAlloca() &&
"dynamic alloca in the static alloca map?");
3969 TLI.getPointerTy(
DL) == MVT::i32
3970 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3973 Register ResultReg = createResultReg(RC);
3975 TII.get(
Opc), ResultReg), AM);
3981 if (!isTypeLegal(CF->
getType(), VT))
3985 bool HasSSE1 = Subtarget->hasSSE1();
3986 bool HasSSE2 = Subtarget->hasSSE2();
3987 bool HasAVX512 = Subtarget->hasAVX512();
3992 Opc = HasAVX512 ? X86::AVX512_FsFLD0SH : X86::FsFLD0SH;
3995 Opc = HasAVX512 ? X86::AVX512_FsFLD0SS
3996 : HasSSE1 ? X86::FsFLD0SS
4000 Opc = HasAVX512 ? X86::AVX512_FsFLD0SD
4001 : HasSSE2 ? X86::FsFLD0SD
4009 Register ResultReg = createResultReg(TLI.getRegClassFor(VT));
4010 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(
Opc), ResultReg);
4014bool X86FastISel::tryToFoldLoadIntoMI(
MachineInstr *
MI,
unsigned OpNo,
4029 *FuncInfo.MF, *
MI, OpNo, AddrOps, FuncInfo.InsertPt,
Size, LI->
getAlign(),
4039 unsigned OperandNo = 0;
4041 E =
Result->operands_end();
I != E; ++
I, ++OperandNo) {
4048 if (IndexReg == MO.
getReg())
4054 FuncInfo.MF->moveAdditionalCallInfo(
MI, Result);
4055 Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
4056 Result->cloneInstrSymbols(*FuncInfo.MF, *
MI);
4058 removeDeadCode(
I, std::next(
I));
4062Register X86FastISel::fastEmitInst_rrrr(
unsigned MachineInstOpcode,
4068 Register ResultReg = createResultReg(RC);
4074 if (
II.getNumDefs() >= 1)
4075 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II, ResultReg)
4081 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
II)
4086 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::COPY),
4096 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")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the FastISel class.
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
static LLVM_ATTRIBUTE_ALWAYS_INLINE MVT::SimpleValueType getSimpleVT(const unsigned char *MatcherTable, unsigned &MatcherIndex)
getSimpleVT - Decode a value in MatcherTable, if it's a VBR encoded value, use GetVBR to decode it.
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...
#define GET_EGPR_IF_ENABLED(OPC)
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)
an instruction to allocate memory on the stack
This class represents an incoming formal argument to a Function.
LLVM Basic Block Representation.
InstListType::const_iterator const_iterator
Conditional or Unconditional Branch instruction.
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
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,...
Predicate getPredicate() const
Return the predicate for this instruction.
A constant value that is initialized with an expression using other constant values.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
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.
This class represents an Operation in the Expression.
This represents the llvm.dbg.declare instruction.
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 ...
virtual bool fastLowerIntrinsicCall(const IntrinsicInst *II)
This method is called by target-independent code to do target- specific intrinsic lowering.
virtual Register fastMaterializeConstant(const Constant *C)
Emit a constant in a register using target-specific logic, such as constant pool loads.
virtual Register fastMaterializeFloatZero(const ConstantFP *CF)
Emit the floating-point constant +0.0 in a register using target- specific logic.
virtual bool tryToFoldLoadIntoMI(MachineInstr *, unsigned, const LoadInst *)
The specified machine instr operand is a vreg, and that vreg is being provided by the specified load ...
virtual bool fastLowerCall(CallLoweringInfo &CLI)
This method is called by target-independent code to do target- specific call lowering.
virtual Register fastMaterializeAlloca(const AllocaInst *C)
Emit an alloca address in a register using target-specific logic.
virtual bool fastLowerArguments()
This method is called by target-independent code to do target- specific argument lowering.
virtual bool fastSelectInstruction(const Instruction *I)=0
This method is called by target-independent code when the normal FastISel process fails to select an ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Module * getParent()
Get the module that this global value is contained inside of...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Value * getPointerOperand()
Align getAlign() const
Return the alignment of the access that is being performed.
bool usesWindowsCFI() const
Describe properties that are true of each instruction in the target description file.
Wrapper class representing physical registers. Should be passed by value.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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
Representation of each machine instruction.
unsigned getNumOperands() const
Retuns the total number of operands.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
A description of a memory reference used in the backend.
bool isNonTemporal() const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
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.
This class wraps the llvm.memcpy intrinsic.
Value * getLength() const
Value * getRawDest() const
unsigned getDestAddressSpace() const
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
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.
Return a value (possibly void), from a function.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Value * getValueOperand()
Value * getPointerOperand()
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
TypeSize getElementOffset(unsigned Idx) const
Class to represent struct types.
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isOSMSVCRT() const
Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
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.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) 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...
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
Register getSRetReturnReg() const
unsigned getBytesToPopOnReturn() 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.
@ X86_64_SysV
The C convention as specified in the x86-64 supplement to the System V ABI, used on most non-Windows ...
@ HiPE
Used by the High-Performance Erlang Compiler (HiPE).
@ Swift
Calling convention for Swift.
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ X86_ThisCall
Similar to X86_StdCall.
@ X86_StdCall
stdcall is mostly used by the Win32 API.
@ 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...
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
@ 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.
@ X86_FastCall
'fast' analog of X86_StdCall.
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...
@ 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.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
Reg
All possible values of the reg field in the ModR/M byte.
@ 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
@ Emitted
Assigned address, still materializing.
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.
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)
unsigned getKillRegState(bool B)
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)
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Description of the encoding of one expression Op.
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.
enum llvm::X86AddressMode::@679 BaseType
void getFullAddress(SmallVectorImpl< MachineOperand > &MO)
union llvm::X86AddressMode::BaseUnion Base