48 class X86FastISel final :
public FastISel {
65 X86ScalarSSEf64 = Subtarget->hasSSE2();
66 X86ScalarSSEf32 = Subtarget->hasSSE1();
69 bool fastSelectInstruction(
const Instruction *
I)
override;
78 bool fastLowerArguments()
override;
79 bool fastLowerCall(CallLoweringInfo &CLI)
override;
80 bool fastLowerIntrinsicCall(
const IntrinsicInst *II)
override;
82 #include "X86GenFastISel.inc" 85 bool X86FastEmitCompare(
const Value *LHS,
const Value *RHS,
EVT VT,
89 unsigned &ResultReg,
unsigned Alignment = 1);
93 bool X86FastEmitStore(
EVT VT,
unsigned ValReg,
bool ValIsKill,
131 bool X86SelectFPExtOrFPTrunc(
const Instruction *
I,
unsigned Opc,
138 bool X86SelectIntToFP(
const Instruction *
I,
bool IsSigned);
141 return Subtarget->getInstrInfo();
152 unsigned fastMaterializeConstant(
const Constant *
C)
override;
154 unsigned fastMaterializeAlloca(
const AllocaInst *
C)
override;
156 unsigned fastMaterializeFloatZero(
const ConstantFP *CF)
override;
160 bool isScalarFPTypeInSSEReg(
EVT VT)
const {
161 return (VT ==
MVT::f64 && X86ScalarSSEf64) ||
162 (VT ==
MVT::f32 && X86ScalarSSEf32);
165 bool isTypeLegal(
Type *Ty,
MVT &VT,
bool AllowI1 =
false);
167 bool IsMemcpySmall(uint64_t Len);
178 unsigned fastEmitInst_rrrr(
unsigned MachineInstOpcode,
180 bool Op0IsKill,
unsigned Op1,
bool Op1IsKill,
181 unsigned Op2,
bool Op2IsKill,
unsigned Op3,
187 static std::pair<unsigned, bool>
190 bool NeedSwap =
false;
219 return std::make_pair(CC, NeedSwap);
240 if (!isa<ExtractValueInst>(Cond))
243 const auto *EV = cast<ExtractValueInst>(Cond);
244 if (!isa<IntrinsicInst>(EV->getAggregateOperand()))
247 const auto *II = cast<IntrinsicInst>(EV->getAggregateOperand());
251 cast<StructType>(Callee->
getReturnType())->getTypeAtIndex(0U);
252 if (!isTypeLegal(RetTy, RetVT))
259 switch (II->getIntrinsicID()) {
260 default:
return false;
276 for (
auto Itr = std::prev(Start); Itr != End; --Itr) {
279 if (!isa<ExtractValueInst>(Itr))
283 const auto *EVI = cast<ExtractValueInst>(Itr);
284 if (EVI->getAggregateOperand() != II)
292 bool X86FastISel::isTypeLegal(
Type *Ty,
MVT &VT,
bool AllowI1) {
293 EVT evt = TLI.getValueType(DL, Ty,
true);
301 if (VT ==
MVT::f64 && !X86ScalarSSEf64)
303 if (VT ==
MVT::f32 && !X86ScalarSSEf32)
312 return (AllowI1 && VT ==
MVT::i1) || TLI.isTypeLegal(VT);
315 #include "X86GenCallingConv.inc" 322 unsigned Alignment) {
323 bool HasSSE41 = Subtarget->hasSSE41();
324 bool HasAVX = Subtarget->hasAVX();
325 bool HasAVX2 = Subtarget->hasAVX2();
326 bool HasAVX512 = Subtarget->hasAVX512();
327 bool HasVLX = Subtarget->hasVLX();
334 default:
return false;
338 RC = &X86::GR8RegClass;
342 RC = &X86::GR16RegClass;
346 RC = &X86::GR32RegClass;
351 RC = &X86::GR64RegClass;
354 if (X86ScalarSSEf32) {
355 Opc = HasAVX512 ? X86::VMOVSSZrm : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm;
356 RC = HasAVX512 ? &X86::FR32XRegClass : &X86::FR32RegClass;
359 RC = &X86::RFP32RegClass;
363 if (X86ScalarSSEf64) {
364 Opc = HasAVX512 ? X86::VMOVSDZrm : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm;
365 RC = HasAVX512 ? &X86::FR64XRegClass : &X86::FR64RegClass;
368 RC = &X86::RFP64RegClass;
375 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
376 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
377 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
378 else if (Alignment >= 16)
379 Opc = HasVLX ? X86::VMOVAPSZ128rm :
380 HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm;
382 Opc = HasVLX ? X86::VMOVUPSZ128rm :
383 HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm;
384 RC = HasVLX ? &X86::VR128XRegClass : &X86::VR128RegClass;
387 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
388 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
389 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
390 else if (Alignment >= 16)
391 Opc = HasVLX ? X86::VMOVAPDZ128rm :
392 HasAVX ? X86::VMOVAPDrm : X86::MOVAPDrm;
394 Opc = HasVLX ? X86::VMOVUPDZ128rm :
395 HasAVX ? X86::VMOVUPDrm : X86::MOVUPDrm;
396 RC = HasVLX ? &X86::VR128XRegClass : &X86::VR128RegClass;
402 if (IsNonTemporal && Alignment >= 16 && HasSSE41)
403 Opc = HasVLX ? X86::VMOVNTDQAZ128rm :
404 HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm;
405 else if (Alignment >= 16)
406 Opc = HasVLX ? X86::VMOVDQA64Z128rm :
407 HasAVX ? X86::VMOVDQArm : X86::MOVDQArm;
409 Opc = HasVLX ? X86::VMOVDQU64Z128rm :
410 HasAVX ? X86::VMOVDQUrm : X86::MOVDQUrm;
411 RC = HasVLX ? &X86::VR128XRegClass : &X86::VR128RegClass;
415 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
416 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
417 else if (IsNonTemporal && Alignment >= 16)
419 else if (Alignment >= 32)
420 Opc = HasVLX ? X86::VMOVAPSZ256rm : X86::VMOVAPSYrm;
422 Opc = HasVLX ? X86::VMOVUPSZ256rm : X86::VMOVUPSYrm;
423 RC = HasVLX ? &X86::VR256XRegClass : &X86::VR256RegClass;
427 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
428 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
429 else if (IsNonTemporal && Alignment >= 16)
431 else if (Alignment >= 32)
432 Opc = HasVLX ? X86::VMOVAPDZ256rm : X86::VMOVAPDYrm;
434 Opc = HasVLX ? X86::VMOVUPDZ256rm : X86::VMOVUPDYrm;
435 RC = HasVLX ? &X86::VR256XRegClass : &X86::VR256RegClass;
442 if (IsNonTemporal && Alignment >= 32 && HasAVX2)
443 Opc = HasVLX ? X86::VMOVNTDQAZ256rm : X86::VMOVNTDQAYrm;
444 else if (IsNonTemporal && Alignment >= 16)
446 else if (Alignment >= 32)
447 Opc = HasVLX ? X86::VMOVDQA64Z256rm : X86::VMOVDQAYrm;
449 Opc = HasVLX ? X86::VMOVDQU64Z256rm : X86::VMOVDQUYrm;
450 RC = HasVLX ? &X86::VR256XRegClass : &X86::VR256RegClass;
454 if (IsNonTemporal && Alignment >= 64)
455 Opc = X86::VMOVNTDQAZrm;
457 Opc = (Alignment >= 64) ? X86::VMOVAPSZrm : X86::VMOVUPSZrm;
458 RC = &X86::VR512RegClass;
462 if (IsNonTemporal && Alignment >= 64)
463 Opc = X86::VMOVNTDQAZrm;
465 Opc = (Alignment >= 64) ? X86::VMOVAPDZrm : X86::VMOVUPDZrm;
466 RC = &X86::VR512RegClass;
475 if (IsNonTemporal && Alignment >= 64)
476 Opc = X86::VMOVNTDQAZrm;
478 Opc = (Alignment >= 64) ? X86::VMOVDQA64Zrm : X86::VMOVDQU64Zrm;
479 RC = &X86::VR512RegClass;
483 ResultReg = createResultReg(RC);
485 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc), ResultReg);
496 bool X86FastISel::X86FastEmitStore(
EVT VT,
unsigned ValReg,
bool ValIsKill,
499 bool HasSSE1 = Subtarget->hasSSE1();
500 bool HasSSE2 = Subtarget->hasSSE2();
501 bool HasSSE4A = Subtarget->hasSSE4A();
502 bool HasAVX = Subtarget->hasAVX();
503 bool HasAVX512 = Subtarget->hasAVX512();
504 bool HasVLX = Subtarget->hasVLX();
511 default:
return false;
514 unsigned AndResult = createResultReg(&X86::GR8RegClass);
515 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
516 TII.get(X86::AND8ri), AndResult)
521 case MVT::i8: Opc = X86::MOV8mr;
break;
522 case MVT::i16: Opc = X86::MOV16mr;
break;
524 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTImr : X86::MOV32mr;
528 Opc = (IsNonTemporal && HasSSE2) ? X86::MOVNTI_64mr : X86::MOV64mr;
531 if (X86ScalarSSEf32) {
532 if (IsNonTemporal && HasSSE4A)
535 Opc = HasAVX512 ? X86::VMOVSSZmr :
536 HasAVX ? X86::VMOVSSmr : X86::MOVSSmr;
541 if (X86ScalarSSEf32) {
542 if (IsNonTemporal && HasSSE4A)
545 Opc = HasAVX512 ? X86::VMOVSDZmr :
546 HasAVX ? X86::VMOVSDmr : X86::MOVSDmr;
551 Opc = (IsNonTemporal && HasSSE1) ? X86::MMX_MOVNTQmr : X86::MMX_MOVQ64mr;
556 Opc = HasVLX ? X86::VMOVNTPSZ128mr :
557 HasAVX ? X86::VMOVNTPSmr : X86::MOVNTPSmr;
559 Opc = HasVLX ? X86::VMOVAPSZ128mr :
560 HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr;
562 Opc = HasVLX ? X86::VMOVUPSZ128mr :
563 HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr;
568 Opc = HasVLX ? X86::VMOVNTPDZ128mr :
569 HasAVX ? X86::VMOVNTPDmr : X86::MOVNTPDmr;
571 Opc = HasVLX ? X86::VMOVAPDZ128mr :
572 HasAVX ? X86::VMOVAPDmr : X86::MOVAPDmr;
574 Opc = HasVLX ? X86::VMOVUPDZ128mr :
575 HasAVX ? X86::VMOVUPDmr : X86::MOVUPDmr;
583 Opc = HasVLX ? X86::VMOVNTDQZ128mr :
584 HasAVX ? X86::VMOVNTDQmr : X86::MOVNTDQmr;
586 Opc = HasVLX ? X86::VMOVDQA64Z128mr :
587 HasAVX ? X86::VMOVDQAmr : X86::MOVDQAmr;
589 Opc = HasVLX ? X86::VMOVDQU64Z128mr :
590 HasAVX ? X86::VMOVDQUmr : X86::MOVDQUmr;
596 Opc = HasVLX ? X86::VMOVNTPSZ256mr : X86::VMOVNTPSYmr;
598 Opc = HasVLX ? X86::VMOVAPSZ256mr : X86::VMOVAPSYmr;
600 Opc = HasVLX ? X86::VMOVUPSZ256mr : X86::VMOVUPSYmr;
606 Opc = HasVLX ? X86::VMOVNTPDZ256mr : X86::VMOVNTPDYmr;
608 Opc = HasVLX ? X86::VMOVAPDZ256mr : X86::VMOVAPDYmr;
610 Opc = HasVLX ? X86::VMOVUPDZ256mr : X86::VMOVUPDYmr;
619 Opc = HasVLX ? X86::VMOVNTDQZ256mr : X86::VMOVNTDQYmr;
621 Opc = HasVLX ? X86::VMOVDQA64Z256mr : X86::VMOVDQAYmr;
623 Opc = HasVLX ? X86::VMOVDQU64Z256mr : X86::VMOVDQUYmr;
628 Opc = IsNonTemporal ? X86::VMOVNTPSZmr : X86::VMOVAPSZmr;
630 Opc = X86::VMOVUPSZmr;
635 Opc = IsNonTemporal ? X86::VMOVNTPDZmr : X86::VMOVAPDZmr;
637 Opc = X86::VMOVUPDZmr;
647 Opc = IsNonTemporal ? X86::VMOVNTDQZmr : X86::VMOVDQA64Zmr;
649 Opc = X86::VMOVDQU64Zmr;
662 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, Desc);
670 bool X86FastISel::X86FastEmitStore(
EVT VT,
const Value *Val,
674 if (isa<ConstantPointerNull>(Val))
678 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
686 case MVT::i8: Opc = X86::MOV8mi;
break;
687 case MVT::i16: Opc = X86::MOV16mi;
break;
688 case MVT::i32: Opc = X86::MOV32mi;
break;
692 Opc = X86::MOV64mi32;
698 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc));
700 : CI->getZExtValue());
707 unsigned ValReg = getRegForValue(Val);
711 bool ValKill = hasTrivialKill(Val);
712 return X86FastEmitStore(VT, ValReg, ValKill, AM, MMO, Aligned);
719 unsigned Src,
EVT SrcVT,
720 unsigned &ResultReg) {
732 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
738 if (GV->isThreadLocal())
742 if (GV->isAbsoluteSymbolRef())
748 if (!Subtarget->isPICStyleRIPRel() ||
754 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
759 AM.
Base.
Reg = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
765 if (Subtarget->isPICStyleRIPRel()) {
779 if (I != LocalValueMap.
end() && I->second != 0) {
791 SavePoint SaveInsertPt = enterLocalValueArea();
793 if (TLI.getPointerTy(DL) ==
MVT::i64) {
795 RC = &X86::GR64RegClass;
797 if (Subtarget->isPICStyleRIPRel())
801 RC = &X86::GR32RegClass;
804 LoadReg = createResultReg(RC);
806 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc), LoadReg);
810 leaveLocalValueArea(SaveInsertPt);
813 LocalValueMap[V] = LoadReg;
825 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
827 AM.
Base.
Reg = getRegForValue(V);
845 const User *U =
nullptr;
846 unsigned Opcode = Instruction::UserOp1;
847 if (
const Instruction *I = dyn_cast<Instruction>(V)) {
851 if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(V)) ||
852 FuncInfo.MBBMap[I->
getParent()] == FuncInfo.MBB) {
856 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(V)) {
862 if (Ty->getAddressSpace() > 255)
869 case Instruction::BitCast:
873 case Instruction::IntToPtr:
876 TLI.getPointerTy(DL))
880 case Instruction::PtrToInt:
882 if (TLI.getValueType(DL, U->
getType()) == TLI.getPointerTy(DL))
886 case Instruction::Alloca: {
890 FuncInfo.StaticAllocaMap.find(A);
891 if (SI != FuncInfo.StaticAllocaMap.end()) {
902 uint64_t Disp = (int32_t)AM.
Disp + (uint64_t)CI->getSExtValue();
912 case Instruction::GetElementPtr: {
916 uint64_t Disp = (int32_t)AM.
Disp;
918 unsigned Scale = AM.
Scale;
923 i != e; ++i, ++GTI) {
925 if (
StructType *STy = GTI.getStructTypeOrNull()) {
933 uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
935 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
937 Disp += CI->getSExtValue() * S;
940 if (canFoldAddIntoGEP(U, Op)) {
943 cast<ConstantInt>(cast<AddOperator>(
Op)->getOperand(1));
946 Op = cast<AddOperator>(
Op)->getOperand(0);
950 (!AM.
GV || !Subtarget->isPICStyleRIPRel()) &&
951 (S == 1 || S == 2 || S == 4 || S == 8)) {
954 IndexReg = getRegForGEPIndex(Op).first;
960 goto unsupported_gep;
974 dyn_cast<GetElementPtrInst>(U->
getOperand(0))) {
988 if (handleConstantAddresses(I, AM))
998 return handleConstantAddresses(V, AM);
1004 const User *U =
nullptr;
1005 unsigned Opcode = Instruction::UserOp1;
1034 InMBB = I->
getParent() == FuncInfo.MBB->getBasicBlock();
1035 }
else if (
const ConstantExpr *
C = dyn_cast<ConstantExpr>(V)) {
1042 case Instruction::BitCast:
1045 return X86SelectCallAddress(U->
getOperand(0), AM);
1048 case Instruction::IntToPtr:
1052 TLI.getPointerTy(DL))
1053 return X86SelectCallAddress(U->
getOperand(0), AM);
1056 case Instruction::PtrToInt:
1058 if (InMBB && TLI.getValueType(DL, U->
getType()) == TLI.getPointerTy(DL))
1059 return X86SelectCallAddress(U->
getOperand(0), AM);
1064 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
1070 if (Subtarget->isPICStyleRIPRel() &&
1076 if (GVar->isThreadLocal())
1085 if (Subtarget->isPICStyleRIPRel()) {
1091 AM.
GVOpFlags = Subtarget->classifyLocalReference(
nullptr);
1098 if (!AM.
GV || !Subtarget->isPICStyleRIPRel()) {
1100 AM.
Base.
Reg = getRegForValue(V);
1115 bool X86FastISel::X86SelectStore(
const Instruction *I) {
1123 if (TLI.supportSwiftError()) {
1126 if (
const Argument *
Arg = dyn_cast<Argument>(PtrV)) {
1127 if (
Arg->hasSwiftErrorAttr())
1131 if (
const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
1132 if (Alloca->isSwiftError())
1141 if (!isTypeLegal(Val->
getType(), VT,
true))
1145 unsigned ABIAlignment = DL.getABITypeAlignment(Val->
getType());
1147 Alignment = ABIAlignment;
1148 bool Aligned = Alignment >= ABIAlignment;
1154 return X86FastEmitStore(VT, Val, AM, createMachineMemOperandFor(I), Aligned);
1158 bool X86FastISel::X86SelectRet(
const Instruction *I) {
1164 if (!FuncInfo.CanLowerReturn)
1167 if (TLI.supportSwiftError() &&
1171 if (TLI.supportSplitCSR(FuncInfo.MF))
1202 GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);
1210 unsigned Reg = getRegForValue(RV);
1215 if (ValLocs.size() != 1)
1232 unsigned SrcReg = Reg + VA.
getValNo();
1233 EVT SrcVT = TLI.getValueType(DL, RV->
getType());
1236 if (SrcVT != DstVT) {
1240 if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt())
1246 if (Outs[0].Flags.isSExt())
1248 SrcReg = fastEmitZExtFromI1(
MVT::i8, SrcReg,
false);
1263 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1264 TII.get(TargetOpcode::COPY), DstReg).addReg(SrcReg);
1280 "SRetReturnReg should have been set in LowerFormalArguments()!");
1281 unsigned RetReg = Subtarget->isTarget64BitLP64() ? X86::RAX :
X86::EAX;
1282 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1283 TII.get(TargetOpcode::COPY), RetReg).addReg(Reg);
1290 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1291 TII.get(Subtarget->is64Bit() ? X86::RETIQ : X86::RETIL))
1294 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1295 TII.get(Subtarget->is64Bit() ? X86::RETQ : X86::RETL));
1297 for (
unsigned i = 0, e = RetRegs.
size(); i != e; ++i)
1304 bool X86FastISel::X86SelectLoad(
const Instruction *I) {
1312 if (TLI.supportSwiftError()) {
1315 if (
const Argument *
Arg = dyn_cast<Argument>(SV)) {
1316 if (
Arg->hasSwiftErrorAttr())
1320 if (
const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
1321 if (Alloca->isSwiftError())
1327 if (!isTypeLegal(LI->
getType(), VT,
true))
1337 unsigned ABIAlignment = DL.getABITypeAlignment(LI->
getType());
1339 Alignment = ABIAlignment;
1341 unsigned ResultReg = 0;
1342 if (!X86FastEmitLoad(VT, AM, createMachineMemOperandFor(LI), ResultReg,
1346 updateValueMap(I, ResultReg);
1351 bool HasAVX512 = Subtarget->
hasAVX512();
1352 bool HasAVX = Subtarget->
hasAVX();
1353 bool X86ScalarSSEf32 = Subtarget->
hasSSE1();
1354 bool X86ScalarSSEf64 = Subtarget->
hasSSE2();
1358 case MVT::i8:
return X86::CMP8rr;
1359 case MVT::i16:
return X86::CMP16rr;
1360 case MVT::i32:
return X86::CMP32rr;
1361 case MVT::i64:
return X86::CMP64rr;
1363 return X86ScalarSSEf32
1364 ? (HasAVX512 ? X86::VUCOMISSZrr
1365 : HasAVX ? X86::VUCOMISSrr : X86::UCOMISSrr)
1368 return X86ScalarSSEf64
1369 ? (HasAVX512 ? X86::VUCOMISDZrr
1370 : HasAVX ? X86::VUCOMISDrr : X86::UCOMISDrr)
1387 return X86::CMP16ri8;
1388 return X86::CMP16ri;
1391 return X86::CMP32ri8;
1392 return X86::CMP32ri;
1395 return X86::CMP64ri8;
1399 return X86::CMP64ri32;
1404 bool X86FastISel::X86FastEmitCompare(
const Value *Op0,
const Value *Op1,
EVT VT,
1406 unsigned Op0Reg = getRegForValue(Op0);
1407 if (Op0Reg == 0)
return false;
1410 if (isa<ConstantPointerNull>(Op1))
1416 if (
const ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
1418 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurDbgLoc,
TII.get(CompareImmOpc))
1420 .
addImm(Op1C->getSExtValue());
1426 if (CompareOpc == 0)
return false;
1428 unsigned Op1Reg = getRegForValue(Op1);
1429 if (Op1Reg == 0)
return false;
1430 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, CurDbgLoc,
TII.get(CompareOpc))
1437 bool X86FastISel::X86SelectCmp(
const Instruction *I) {
1438 const CmpInst *CI = cast<CmpInst>(
I);
1446 unsigned ResultReg = 0;
1447 switch (Predicate) {
1450 ResultReg = createResultReg(&X86::GR32RegClass);
1451 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::MOV32r0),
1453 ResultReg = fastEmitInst_extractsubreg(
MVT::i8, ResultReg,
true,
1460 ResultReg = createResultReg(&X86::GR8RegClass);
1461 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::MOV8ri),
1462 ResultReg).addImm(1);
1468 updateValueMap(I, ResultReg);
1480 if (RHSC && RHSC->isNullValue())
1485 static const uint16_t SETFOpcTable[2][3] = {
1486 { X86::SETEr, X86::SETNPr, X86::AND8rr },
1487 { X86::SETNEr, X86::SETPr, X86::OR8rr }
1489 const uint16_t *SETFOpc =
nullptr;
1490 switch (Predicate) {
1496 ResultReg = createResultReg(&X86::GR8RegClass);
1498 if (!X86FastEmitCompare(LHS, RHS, VT, I->
getDebugLoc()))
1501 unsigned FlagReg1 = createResultReg(&X86::GR8RegClass);
1502 unsigned FlagReg2 = createResultReg(&X86::GR8RegClass);
1503 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(SETFOpc[0]),
1505 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(SETFOpc[1]),
1507 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(SETFOpc[2]),
1508 ResultReg).addReg(FlagReg1).
addReg(FlagReg2);
1509 updateValueMap(I, ResultReg);
1523 if (!X86FastEmitCompare(LHS, RHS, VT, I->
getDebugLoc()))
1526 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc), ResultReg);
1527 updateValueMap(I, ResultReg);
1531 bool X86FastISel::X86SelectZExt(
const Instruction *I) {
1532 EVT DstVT = TLI.getValueType(DL, I->
getType());
1533 if (!TLI.isTypeLegal(DstVT))
1536 unsigned ResultReg = getRegForValue(I->
getOperand(0));
1544 ResultReg = fastEmitZExtFromI1(
MVT::i8, ResultReg,
false);
1556 case MVT::i8: MovInst = X86::MOVZX32rr8;
break;
1557 case MVT::i16: MovInst = X86::MOVZX32rr16;
break;
1558 case MVT::i32: MovInst = X86::MOV32rr;
break;
1562 unsigned Result32 = createResultReg(&X86::GR32RegClass);
1563 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(MovInst), Result32)
1566 ResultReg = createResultReg(&X86::GR64RegClass);
1567 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::SUBREG_TO_REG),
1573 unsigned Result32 = createResultReg(&X86::GR32RegClass);
1574 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::MOVZX32rr8),
1575 Result32).addReg(ResultReg);
1577 ResultReg = fastEmitInst_extractsubreg(
MVT::i16, Result32,
true,
1579 }
else if (DstVT !=
MVT::i8) {
1586 updateValueMap(I, ResultReg);
1590 bool X86FastISel::X86SelectSExt(
const Instruction *I) {
1591 EVT DstVT = TLI.getValueType(DL, I->
getType());
1592 if (!TLI.isTypeLegal(DstVT))
1595 unsigned ResultReg = getRegForValue(I->
getOperand(0));
1603 unsigned ZExtReg = fastEmitZExtFromI1(
MVT::i8, ResultReg,
1609 ResultReg = createResultReg(&X86::GR8RegClass);
1610 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::NEG8r),
1611 ResultReg).addReg(ZExtReg);
1619 unsigned Result32 = createResultReg(&X86::GR32RegClass);
1620 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::MOVSX32rr8),
1621 Result32).addReg(ResultReg);
1623 ResultReg = fastEmitInst_extractsubreg(
MVT::i16, Result32,
true,
1625 }
else if (DstVT !=
MVT::i8) {
1632 updateValueMap(I, ResultReg);
1636 bool X86FastISel::X86SelectBranch(
const Instruction *I) {
1648 if (CI->hasOneUse() && CI->getParent() == I->
getParent()) {
1649 EVT VT = TLI.getValueType(DL, CI->getOperand(0)->getType());
1653 switch (Predicate) {
1659 const Value *CmpLHS = CI->getOperand(0);
1660 const Value *CmpRHS = CI->getOperand(1);
1668 if (CmpRHSC && CmpRHSC->isNullValue())
1673 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1683 bool NeedExtraBranch =
false;
1684 switch (Predicate) {
1690 NeedExtraBranch =
true;
1705 if (!X86FastEmitCompare(CmpLHS, CmpRHS, VT, CI->getDebugLoc()))
1708 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(BranchOpc))
1713 if (NeedExtraBranch) {
1714 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::JP_1))
1718 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1725 if (TI->hasOneUse() && TI->getParent() == I->
getParent() &&
1726 isTypeLegal(TI->getOperand(0)->getType(), SourceVT)) {
1727 unsigned TestOpc = 0;
1730 case MVT::i8: TestOpc = X86::TEST8ri;
break;
1731 case MVT::i16: TestOpc = X86::TEST16ri;
break;
1732 case MVT::i32: TestOpc = X86::TEST32ri;
break;
1733 case MVT::i64: TestOpc = X86::TEST64ri32;
break;
1736 unsigned OpReg = getRegForValue(TI->getOperand(0));
1737 if (OpReg == 0)
return false;
1739 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TestOpc))
1740 .addReg(OpReg).
addImm(1);
1742 unsigned JmpOpc = X86::JNE_1;
1743 if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
1748 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(JmpOpc))
1751 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1755 }
else if (foldX86XALUIntrinsic(CC, BI, BI->
getCondition())) {
1764 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(BranchOpc))
1766 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1774 if (OpReg == 0)
return false;
1777 if (
MRI.getRegClass(OpReg) == &X86::VK1RegClass) {
1778 unsigned KOpReg = OpReg;
1779 OpReg = createResultReg(&X86::GR32RegClass);
1780 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1781 TII.get(TargetOpcode::COPY), OpReg)
1783 OpReg = fastEmitInst_extractsubreg(
MVT::i8, OpReg,
true,
1786 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::TEST8ri))
1789 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::JNE_1))
1791 finishCondBranch(BI->
getParent(), TrueMBB, FalseMBB);
1795 bool X86FastISel::X86SelectShift(
const Instruction *I) {
1796 unsigned CReg = 0, OpReg = 0;
1800 RC = &X86::GR8RegClass;
1802 case Instruction::LShr: OpReg = X86::SHR8rCL;
break;
1803 case Instruction::AShr: OpReg = X86::SAR8rCL;
break;
1804 case Instruction::Shl: OpReg = X86::SHL8rCL;
break;
1805 default:
return false;
1809 RC = &X86::GR16RegClass;
1812 case Instruction::LShr: OpReg = X86::SHR16rCL;
break;
1813 case Instruction::AShr: OpReg = X86::SAR16rCL;
break;
1814 case Instruction::Shl: OpReg = X86::SHL16rCL;
break;
1818 RC = &X86::GR32RegClass;
1821 case Instruction::LShr: OpReg = X86::SHR32rCL;
break;
1822 case Instruction::AShr: OpReg = X86::SAR32rCL;
break;
1823 case Instruction::Shl: OpReg = X86::SHL32rCL;
break;
1827 RC = &X86::GR64RegClass;
1830 case Instruction::LShr: OpReg = X86::SHR64rCL;
break;
1831 case Instruction::AShr: OpReg = X86::SAR64rCL;
break;
1832 case Instruction::Shl: OpReg = X86::SHL64rCL;
break;
1839 if (!isTypeLegal(I->
getType(), VT))
1842 unsigned Op0Reg = getRegForValue(I->
getOperand(0));
1843 if (Op0Reg == 0)
return false;
1845 unsigned Op1Reg = getRegForValue(I->
getOperand(1));
1846 if (Op1Reg == 0)
return false;
1847 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::COPY),
1848 CReg).addReg(Op1Reg);
1852 if (CReg != X86::CL)
1853 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1857 unsigned ResultReg = createResultReg(RC);
1858 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(OpReg), ResultReg)
1860 updateValueMap(I, ResultReg);
1864 bool 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 },
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))
1929 unsigned TypeIndex, OpIndex;
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;
1936 if (!Subtarget->is64Bit())
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];
1950 const DivRemEntry::DivRemResult &OpEntry = TypeEntry.ResultTable[OpIndex];
1951 unsigned Op0Reg = getRegForValue(I->
getOperand(0));
1954 unsigned Op1Reg = getRegForValue(I->
getOperand(1));
1959 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1960 TII.get(OpEntry.OpCopy), TypeEntry.LowInReg).addReg(Op0Reg);
1962 if (OpEntry.OpSignExtend) {
1963 if (OpEntry.IsOpSigned)
1964 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1965 TII.get(OpEntry.OpSignExtend));
1967 unsigned Zero32 = createResultReg(&X86::GR32RegClass);
1968 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1969 TII.get(X86::MOV32r0), Zero32);
1975 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1976 TII.get(Copy), TypeEntry.HighInReg)
1977 .addReg(Zero32, 0, X86::sub_16bit);
1979 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1980 TII.get(Copy), TypeEntry.HighInReg)
1983 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1984 TII.get(TargetOpcode::SUBREG_TO_REG), TypeEntry.HighInReg)
1990 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1991 TII.get(OpEntry.OpDivRem)).addReg(Op1Reg);
2000 unsigned ResultReg = 0;
2001 if ((I->
getOpcode() == Instruction::SRem ||
2003 OpEntry.DivRemResultReg == X86::AH && Subtarget->is64Bit()) {
2004 unsigned SourceSuperReg = createResultReg(&X86::GR16RegClass);
2005 unsigned ResultSuperReg = createResultReg(&X86::GR16RegClass);
2006 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2007 TII.get(Copy), SourceSuperReg).addReg(X86::AX);
2010 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::SHR16ri),
2011 ResultSuperReg).addReg(SourceSuperReg).
addImm(8);
2014 ResultReg = fastEmitInst_extractsubreg(
MVT::i8, ResultSuperReg,
2015 true, X86::sub_8bit);
2019 ResultReg = createResultReg(TypeEntry.RC);
2020 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Copy), ResultReg)
2021 .addReg(OpEntry.DivRemResultReg);
2023 updateValueMap(I, ResultReg);
2030 bool X86FastISel::X86FastEmitCMoveSelect(
MVT RetVT,
const Instruction *I) {
2032 if (!Subtarget->hasCMov())
2036 if (RetVT < MVT::i16 || RetVT >
MVT::i64)
2041 bool NeedTest =
true;
2048 if (CI && (CI->getParent() == I->
getParent())) {
2052 static const uint16_t SETFOpcTable[2][3] = {
2053 { X86::SETNPr, X86::SETEr , X86::TEST8rr },
2054 { X86::SETPr, X86::SETNEr, X86::OR8rr }
2056 const uint16_t *SETFOpc =
nullptr;
2057 switch (Predicate) {
2060 SETFOpc = &SETFOpcTable[0][0];
2064 SETFOpc = &SETFOpcTable[1][0];
2073 const Value *CmpLHS = CI->getOperand(0);
2074 const Value *CmpRHS = CI->getOperand(1);
2078 EVT CmpVT = TLI.getValueType(DL, CmpLHS->
getType());
2080 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
2084 unsigned FlagReg1 = createResultReg(&X86::GR8RegClass);
2085 unsigned FlagReg2 = createResultReg(&X86::GR8RegClass);
2086 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(SETFOpc[0]),
2088 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(SETFOpc[1]),
2090 auto const &II =
TII.get(SETFOpc[2]);
2091 if (II.getNumDefs()) {
2092 unsigned TmpReg = createResultReg(&X86::GR8RegClass);
2093 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, TmpReg)
2096 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
2101 }
else if (foldX86XALUIntrinsic(CC, I, Cond)) {
2104 unsigned TmpReg = getRegForValue(Cond);
2117 unsigned CondReg = getRegForValue(Cond);
2120 bool CondIsKill = hasTrivialKill(Cond);
2123 if (
MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2124 unsigned KCondReg = CondReg;
2125 CondReg = createResultReg(&X86::GR32RegClass);
2126 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2127 TII.get(TargetOpcode::COPY), CondReg)
2129 CondReg = fastEmitInst_extractsubreg(
MVT::i8, CondReg,
true,
2132 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::TEST8ri))
2140 unsigned RHSReg = getRegForValue(RHS);
2141 bool RHSIsKill = hasTrivialKill(RHS);
2143 unsigned LHSReg = getRegForValue(LHS);
2144 bool LHSIsKill = hasTrivialKill(LHS);
2146 if (!LHSReg || !RHSReg)
2151 unsigned ResultReg = fastEmitInst_rr(Opc, RC, RHSReg, RHSIsKill,
2153 updateValueMap(I, ResultReg);
2162 bool X86FastISel::X86FastEmitSSESelect(
MVT RetVT,
const Instruction *I) {
2167 if (!CI || (CI->getParent() != I->
getParent()))
2170 if (I->
getType() != CI->getOperand(0)->getType() ||
2171 !((Subtarget->hasSSE1() && RetVT ==
MVT::f32) ||
2172 (Subtarget->hasSSE2() && RetVT ==
MVT::f64)))
2175 const Value *CmpLHS = CI->getOperand(0);
2176 const Value *CmpRHS = CI->getOperand(1);
2184 if (CmpRHSC && CmpRHSC->isNullValue())
2191 if (CC > 7 && !Subtarget->hasAVX())
2198 static const uint16_t OpcTable[2][4] = {
2199 { X86::CMPSSrr, X86::ANDPSrr, X86::ANDNPSrr, X86::ORPSrr },
2200 { X86::CMPSDrr, X86::ANDPDrr, X86::ANDNPDrr, X86::ORPDrr }
2203 const uint16_t *Opc =
nullptr;
2205 default:
return false;
2206 case MVT::f32: Opc = &OpcTable[0][0];
break;
2207 case MVT::f64: Opc = &OpcTable[1][0];
break;
2213 unsigned LHSReg = getRegForValue(LHS);
2214 bool LHSIsKill = hasTrivialKill(LHS);
2216 unsigned RHSReg = getRegForValue(RHS);
2217 bool RHSIsKill = hasTrivialKill(RHS);
2219 unsigned CmpLHSReg = getRegForValue(CmpLHS);
2220 bool CmpLHSIsKill = hasTrivialKill(CmpLHS);
2222 unsigned CmpRHSReg = getRegForValue(CmpRHS);
2223 bool CmpRHSIsKill = hasTrivialKill(CmpRHS);
2225 if (!LHSReg || !RHSReg || !CmpLHS || !CmpRHS)
2231 if (Subtarget->hasAVX512()) {
2236 unsigned CmpOpcode =
2237 (RetVT ==
MVT::f32) ? X86::VCMPSSZrr : X86::VCMPSDZrr;
2238 unsigned CmpReg = fastEmitInst_rri(CmpOpcode, VK1, CmpLHSReg, CmpLHSIsKill,
2239 CmpRHSReg, CmpRHSIsKill, CC);
2243 unsigned ImplicitDefReg = createResultReg(VR128X);
2244 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2245 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2249 unsigned MovOpcode =
2250 (RetVT ==
MVT::f32) ? X86::VMOVSSZrrk : X86::VMOVSDZrrk;
2251 unsigned MovReg = fastEmitInst_rrrr(MovOpcode, VR128X, RHSReg, RHSIsKill,
2252 CmpReg,
true, ImplicitDefReg,
true,
2255 ResultReg = createResultReg(RC);
2256 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2257 TII.get(TargetOpcode::COPY), ResultReg).addReg(MovReg);
2259 }
else if (Subtarget->hasAVX()) {
2267 unsigned CmpOpcode =
2268 (RetVT ==
MVT::f32) ? X86::VCMPSSrr : X86::VCMPSDrr;
2269 unsigned BlendOpcode =
2270 (RetVT ==
MVT::f32) ? X86::VBLENDVPSrr : X86::VBLENDVPDrr;
2272 unsigned CmpReg = fastEmitInst_rri(CmpOpcode, RC, CmpLHSReg, CmpLHSIsKill,
2273 CmpRHSReg, CmpRHSIsKill, CC);
2274 unsigned VBlendReg = fastEmitInst_rrr(BlendOpcode, VR128, RHSReg, RHSIsKill,
2275 LHSReg, LHSIsKill, CmpReg,
true);
2276 ResultReg = createResultReg(RC);
2277 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2278 TII.get(TargetOpcode::COPY), ResultReg).addReg(VBlendReg);
2281 unsigned CmpReg = fastEmitInst_rri(Opc[0], RC, CmpLHSReg, CmpLHSIsKill,
2282 CmpRHSReg, CmpRHSIsKill, CC);
2283 unsigned AndReg = fastEmitInst_rr(Opc[1], VR128, CmpReg,
false,
2285 unsigned AndNReg = fastEmitInst_rr(Opc[2], VR128, CmpReg,
true,
2287 unsigned OrReg = fastEmitInst_rr(Opc[3], VR128, AndNReg,
true,
2289 ResultReg = createResultReg(RC);
2290 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2291 TII.get(TargetOpcode::COPY), ResultReg).addReg(OrReg);
2293 updateValueMap(I, ResultReg);
2297 bool X86FastISel::X86FastEmitPseudoSelect(
MVT RetVT,
const Instruction *I) {
2302 default:
return false;
2303 case MVT::i8: Opc = X86::CMOV_GR8;
break;
2304 case MVT::i16: Opc = X86::CMOV_GR16;
break;
2305 case MVT::i32: Opc = X86::CMOV_GR32;
break;
2306 case MVT::f32: Opc = X86::CMOV_FR32;
break;
2307 case MVT::f64: Opc = X86::CMOV_FR64;
break;
2317 if (CI && (CI->getParent() == I->
getParent())) {
2323 const Value *CmpLHS = CI->getOperand(0);
2324 const Value *CmpRHS = CI->getOperand(1);
2329 EVT CmpVT = TLI.getValueType(DL, CmpLHS->
getType());
2330 if (!X86FastEmitCompare(CmpLHS, CmpRHS, CmpVT, CI->getDebugLoc()))
2333 unsigned CondReg = getRegForValue(Cond);
2336 bool CondIsKill = hasTrivialKill(Cond);
2339 if (
MRI.getRegClass(CondReg) == &X86::VK1RegClass) {
2340 unsigned KCondReg = CondReg;
2341 CondReg = createResultReg(&X86::GR32RegClass);
2342 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2343 TII.get(TargetOpcode::COPY), CondReg)
2345 CondReg = fastEmitInst_extractsubreg(
MVT::i8, CondReg,
true,
2348 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::TEST8ri))
2356 unsigned LHSReg = getRegForValue(LHS);
2357 bool LHSIsKill = hasTrivialKill(LHS);
2359 unsigned RHSReg = getRegForValue(RHS);
2360 bool RHSIsKill = hasTrivialKill(RHS);
2362 if (!LHSReg || !RHSReg)
2367 unsigned ResultReg =
2368 fastEmitInst_rri(Opc, RC, RHSReg, RHSIsKill, LHSReg, LHSIsKill, CC);
2369 updateValueMap(I, ResultReg);
2373 bool X86FastISel::X86SelectSelect(
const Instruction *I) {
2375 if (!isTypeLegal(I->
getType(), RetVT))
2379 if (
const auto *CI = dyn_cast<CmpInst>(I->
getOperand(0))) {
2381 const Value *Opnd =
nullptr;
2382 switch (Predicate) {
2389 unsigned OpReg = getRegForValue(Opnd);
2392 bool OpIsKill = hasTrivialKill(Opnd);
2394 unsigned ResultReg = createResultReg(RC);
2395 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2396 TII.get(TargetOpcode::COPY), ResultReg)
2398 updateValueMap(I, ResultReg);
2404 if (X86FastEmitCMoveSelect(RetVT, I))
2408 if (X86FastEmitSSESelect(RetVT, I))
2413 if (X86FastEmitPseudoSelect(RetVT, I))
2420 bool X86FastISel::X86SelectIntToFP(
const Instruction *I,
bool IsSigned) {
2425 bool HasAVX512 = Subtarget->hasAVX512();
2426 if (!Subtarget->hasAVX() || (!IsSigned && !HasAVX512))
2435 unsigned OpReg = getRegForValue(I->
getOperand(0));
2441 static const uint16_t SCvtOpc[2][2][2] = {
2442 { { X86::VCVTSI2SSrr, X86::VCVTSI642SSrr },
2443 { X86::VCVTSI2SDrr, X86::VCVTSI642SDrr } },
2444 { { X86::VCVTSI2SSZrr, X86::VCVTSI642SSZrr },
2445 { X86::VCVTSI2SDZrr, X86::VCVTSI642SDZrr } },
2447 static const uint16_t UCvtOpc[2][2] = {
2448 { X86::VCVTUSI2SSZrr, X86::VCVTUSI642SSZrr },
2449 { X86::VCVTUSI2SDZrr, X86::VCVTUSI642SDZrr },
2455 Opcode = IsSigned ? SCvtOpc[HasAVX512][1][Is64Bit] : UCvtOpc[1][Is64Bit];
2458 Opcode = IsSigned ? SCvtOpc[HasAVX512][0][Is64Bit] : UCvtOpc[0][Is64Bit];
2462 MVT DstVT = TLI.getValueType(DL, I->
getType()).getSimpleVT();
2464 unsigned ImplicitDefReg = createResultReg(RC);
2465 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2466 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2467 unsigned ResultReg =
2468 fastEmitInst_rr(Opcode, RC, ImplicitDefReg,
true, OpReg,
false);
2469 updateValueMap(I, ResultReg);
2473 bool X86FastISel::X86SelectSIToFP(
const Instruction *I) {
2474 return X86SelectIntToFP(I,
true);
2477 bool X86FastISel::X86SelectUIToFP(
const Instruction *I) {
2478 return X86SelectIntToFP(I,
false);
2482 bool X86FastISel::X86SelectFPExtOrFPTrunc(
const Instruction *I,
2486 I->
getOpcode() == Instruction::FPTrunc) &&
2487 "Instruction must be an FPExt or FPTrunc!");
2489 unsigned OpReg = getRegForValue(I->
getOperand(0));
2493 unsigned ImplicitDefReg;
2494 if (Subtarget->hasAVX()) {
2495 ImplicitDefReg = createResultReg(RC);
2496 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2497 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2501 unsigned ResultReg = createResultReg(RC);
2503 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpc),
2506 if (Subtarget->hasAVX())
2507 MIB.
addReg(ImplicitDefReg);
2510 updateValueMap(I, ResultReg);
2514 bool X86FastISel::X86SelectFPExt(
const Instruction *I) {
2517 bool HasAVX512 = Subtarget->hasAVX512();
2520 HasAVX512 ? X86::VCVTSS2SDZrr
2521 : Subtarget->hasAVX() ? X86::VCVTSS2SDrr : X86::CVTSS2SDrr;
2522 return X86SelectFPExtOrFPTrunc(
2523 I, Opc, HasAVX512 ? &X86::FR64XRegClass : &X86::FR64RegClass);
2529 bool X86FastISel::X86SelectFPTrunc(
const Instruction *I) {
2532 bool HasAVX512 = Subtarget->hasAVX512();
2535 HasAVX512 ? X86::VCVTSD2SSZrr
2536 : Subtarget->hasAVX() ? X86::VCVTSD2SSrr : X86::CVTSD2SSrr;
2537 return X86SelectFPExtOrFPTrunc(
2538 I, Opc, HasAVX512 ? &X86::FR32XRegClass : &X86::FR32RegClass);
2544 bool X86FastISel::X86SelectTrunc(
const Instruction *I) {
2546 EVT DstVT = TLI.getValueType(DL, I->
getType());
2551 if (!TLI.isTypeLegal(SrcVT))
2554 unsigned InputReg = getRegForValue(I->
getOperand(0));
2561 updateValueMap(I, InputReg);
2566 unsigned ResultReg = fastEmitInst_extractsubreg(
MVT::i8,
2572 updateValueMap(I, ResultReg);
2576 bool X86FastISel::IsMemcpySmall(uint64_t Len) {
2577 return Len <= (Subtarget->is64Bit() ? 32 : 16);
2584 if (!IsMemcpySmall(Len))
2587 bool i64Legal = Subtarget->is64Bit();
2592 if (Len >= 8 && i64Legal)
2602 bool RV = X86FastEmitLoad(VT, SrcAM,
nullptr, Reg);
2603 RV &= X86FastEmitStore(VT, Reg,
true, DestAM);
2604 assert(RV &&
"Failed to emit load or store??");
2615 bool X86FastISel::fastLowerIntrinsicCall(
const IntrinsicInst *II) {
2618 default:
return false;
2621 if (Subtarget->useSoftFloat() || !Subtarget->hasF16C())
2625 unsigned InputReg = getRegForValue(Op);
2631 if (IsFloatToHalf) {
2639 unsigned ResultReg = 0;
2641 if (IsFloatToHalf) {
2649 InputReg = fastEmitInst_ri(X86::VCVTPS2PHrr, RC, InputReg,
false, 4);
2652 ResultReg = createResultReg(&X86::GR32RegClass);
2653 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2654 TII.get(X86::VMOVPDI2DIrr), ResultReg)
2658 unsigned RegIdx = X86::sub_16bit;
2659 ResultReg = fastEmitInst_extractsubreg(
MVT::i16, ResultReg,
true, RegIdx);
2670 InputReg = fastEmitInst_r(X86::VCVTPH2PSrr, RC, InputReg,
true);
2674 ResultReg = createResultReg(&X86::FR32RegClass);
2675 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2676 TII.get(TargetOpcode::COPY), ResultReg)
2680 updateValueMap(II, ResultReg);
2691 if (!isTypeLegal(RetTy, VT))
2699 case MVT::i32: Opc = X86::MOV32rm; RC = &X86::GR32RegClass;
break;
2700 case MVT::i64: Opc = X86::MOV64rm; RC = &X86::GR64RegClass;
break;
2711 (FrameReg == X86::EBP && VT ==
MVT::i32)) &&
2712 "Invalid Frame Register!");
2717 unsigned SrcReg = createResultReg(RC);
2718 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2719 TII.get(TargetOpcode::COPY), SrcReg).addReg(FrameReg);
2727 unsigned Depth = cast<ConstantInt>(II->
getOperand(0))->getZExtValue();
2729 DestReg = createResultReg(RC);
2731 TII.get(Opc), DestReg), SrcReg);
2735 updateValueMap(II, SrcReg);
2739 const MemCpyInst *MCI = cast<MemCpyInst>(II);
2744 if (isa<ConstantInt>(MCI->
getLength())) {
2747 uint64_t Len = cast<ConstantInt>(MCI->
getLength())->getZExtValue();
2748 if (IsMemcpySmall(Len)) {
2753 TryEmitSmallMemcpy(DestAM, SrcAM, Len);
2758 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2768 const MemSetInst *MSI = cast<MemSetInst>(II);
2773 unsigned SizeWidth = Subtarget->is64Bit() ? 64 : 32;
2784 EVT PtrTy = TLI.getPointerTy(DL);
2789 MFI.setStackProtectorIndex(FuncInfo.StaticAllocaMap[Slot]);
2794 if (!X86FastEmitStore(PtrTy, Op1, AM))
return false;
2807 "Expected inlined-at fields to agree");
2819 if (!Subtarget->hasSSE1())
2825 if (!isTypeLegal(RetTy, VT))
2831 static const uint16_t SqrtOpc[3][2] = {
2832 { X86::SQRTSSr, X86::SQRTSDr },
2833 { X86::VSQRTSSr, X86::VSQRTSDr },
2834 { X86::VSQRTSSZr, X86::VSQRTSDZr },
2836 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
2837 Subtarget->hasAVX() ? 1 :
2841 default:
return false;
2842 case MVT::f32: Opc = SqrtOpc[AVXLevel][0];
break;
2843 case MVT::f64: Opc = SqrtOpc[AVXLevel][1];
break;
2847 unsigned SrcReg = getRegForValue(SrcVal);
2853 unsigned ImplicitDefReg = 0;
2855 ImplicitDefReg = createResultReg(RC);
2856 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2857 TII.get(TargetOpcode::IMPLICIT_DEF), ImplicitDefReg);
2860 unsigned ResultReg = createResultReg(RC);
2862 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc),
2866 MIB.
addReg(ImplicitDefReg);
2870 updateValueMap(II, ResultReg);
2883 Type *RetTy = Ty->getTypeAtIndex(0U);
2886 "Overflow value expected to be an i1");
2889 if (!isTypeLegal(RetTy, VT))
2899 if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS) &&
2900 isCommutativeIntrinsic(II))
2903 unsigned BaseOpc, CondOpc;
2907 BaseOpc =
ISD::ADD; CondOpc = X86::SETOr;
break;
2909 BaseOpc =
ISD::ADD; CondOpc = X86::SETBr;
break;
2911 BaseOpc =
ISD::SUB; CondOpc = X86::SETOr;
break;
2913 BaseOpc =
ISD::SUB; CondOpc = X86::SETBr;
break;
2920 unsigned LHSReg = getRegForValue(LHS);
2923 bool LHSIsKill = hasTrivialKill(LHS);
2925 unsigned ResultReg = 0;
2927 if (
const auto *CI = dyn_cast<ConstantInt>(RHS)) {
2928 static const uint16_t Opc[2][4] = {
2929 { X86::INC8r, X86::INC16r, X86::INC32r, X86::INC64r },
2930 { X86::DEC8r, X86::DEC16r, X86::DEC32r, X86::DEC64r }
2934 CondOpc == X86::SETOr) {
2936 ResultReg = createResultReg(TLI.getRegClassFor(VT));
2938 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2939 TII.get(Opc[IsDec][VT.SimpleTy-
MVT::i8]), ResultReg)
2942 ResultReg = fastEmit_ri(VT, VT, BaseOpc, LHSReg, LHSIsKill,
2943 CI->getZExtValue());
2949 RHSReg = getRegForValue(RHS);
2952 RHSIsKill = hasTrivialKill(RHS);
2953 ResultReg = fastEmit_rr(VT, VT, BaseOpc, LHSReg, LHSIsKill, RHSReg,
2960 static const uint16_t MULOpc[] =
2961 { X86::MUL8r, X86::MUL16r, X86::MUL32r, X86::MUL64r };
2965 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2966 TII.get(TargetOpcode::COPY), Reg[VT.SimpleTy-
MVT::i8])
2968 ResultReg = fastEmitInst_r(MULOpc[VT.SimpleTy-
MVT::i8],
2969 TLI.getRegClassFor(VT), RHSReg, RHSIsKill);
2971 static const uint16_t MULOpc[] =
2972 { X86::IMUL8r, X86::IMUL16rr, X86::IMUL32rr, X86::IMUL64rr };
2976 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
2979 ResultReg = fastEmitInst_r(MULOpc[0], TLI.getRegClassFor(VT), RHSReg,
2982 ResultReg = fastEmitInst_rr(MULOpc[VT.SimpleTy-
MVT::i8],
2983 TLI.getRegClassFor(VT), LHSReg, LHSIsKill,
2991 unsigned ResultReg2 = createResultReg(&X86::GR8RegClass);
2992 assert((ResultReg+1) == ResultReg2 &&
"Nonconsecutive result registers.");
2993 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(CondOpc),
2996 updateValueMap(II, ResultReg, 2);
3008 if (!Subtarget->hasSSE1())
3010 IsInputDouble =
false;
3014 if (!Subtarget->hasSSE2())
3016 IsInputDouble =
true;
3022 if (!isTypeLegal(RetTy, VT))
3025 static const uint16_t CvtOpc[3][2][2] = {
3026 { { X86::CVTTSS2SIrr, X86::CVTTSS2SI64rr },
3027 { X86::CVTTSD2SIrr, X86::CVTTSD2SI64rr } },
3028 { { X86::VCVTTSS2SIrr, X86::VCVTTSS2SI64rr },
3029 { X86::VCVTTSD2SIrr, X86::VCVTTSD2SI64rr } },
3030 { { X86::VCVTTSS2SIZrr, X86::VCVTTSS2SI64Zrr },
3031 { X86::VCVTTSD2SIZrr, X86::VCVTTSD2SI64Zrr } },
3033 unsigned AVXLevel = Subtarget->hasAVX512() ? 2 :
3034 Subtarget->hasAVX() ? 1 :
3039 case MVT::i32: Opc = CvtOpc[AVXLevel][IsInputDouble][0];
break;
3040 case MVT::i64: Opc = CvtOpc[AVXLevel][IsInputDouble][1];
break;
3045 while (
auto *
IE = dyn_cast<InsertElementInst>(Op)) {
3047 if (!isa<ConstantInt>(Index))
3049 unsigned Idx = cast<ConstantInt>(
Index)->getZExtValue();
3052 Op =
IE->getOperand(1);
3055 Op =
IE->getOperand(0);
3058 unsigned Reg = getRegForValue(Op);
3062 unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
3063 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc), ResultReg)
3066 updateValueMap(II, ResultReg);
3072 bool X86FastISel::fastLowerArguments() {
3073 if (!FuncInfo.CanLowerReturn)
3084 if (Subtarget->isCallingConvWin64(CC))
3087 if (!Subtarget->is64Bit())
3090 if (Subtarget->useSoftFloat())
3094 unsigned GPRCnt = 0;
3095 unsigned FPRCnt = 0;
3096 for (
auto const &
Arg : F->
args()) {
3109 EVT ArgVT = TLI.getValueType(DL, ArgTy);
3110 if (!ArgVT.
isSimple())
return false;
3112 default:
return false;
3119 if (!Subtarget->hasSSE1())
3132 static const MCPhysReg GPR32ArgRegs[] = {
3135 static const MCPhysReg GPR64ArgRegs[] = {
3136 X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8 , X86::R9
3139 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3140 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3144 unsigned FPRIdx = 0;
3145 for (
auto const &
Arg : F->
args()) {
3151 case MVT::i32: SrcReg = GPR32ArgRegs[GPRIdx++];
break;
3152 case MVT::i64: SrcReg = GPR64ArgRegs[GPRIdx++];
break;
3154 case MVT::f64: SrcReg = XMMArgRegs[FPRIdx++];
break;
3156 unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
3160 unsigned ResultReg = createResultReg(RC);
3161 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3162 TII.get(TargetOpcode::COPY), ResultReg)
3164 updateValueMap(&
Arg, ResultReg);
3188 bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
3189 auto &OutVals = CLI.OutVals;
3190 auto &OutFlags = CLI.OutFlags;
3191 auto &OutRegs = CLI.OutRegs;
3192 auto &
Ins = CLI.Ins;
3193 auto &InRegs = CLI.InRegs;
3195 bool &IsTailCall = CLI.IsTailCall;
3196 bool IsVarArg = CLI.IsVarArg;
3200 bool Is64Bit = Subtarget->is64Bit();
3201 bool IsWin64 = Subtarget->isCallingConvWin64(CC);
3215 if ((CI && CI->
hasFnAttr(
"no_caller_saved_registers")) ||
3216 (CalledFn && CalledFn->hasFnAttribute(
"no_caller_saved_registers")))
3220 if (Subtarget->useRetpolineIndirectCalls())
3225 default:
return false;
3249 if (IsVarArg && IsWin64)
3253 if (CLI.CS && CLI.CS->hasInAllocaArgument())
3256 for (
auto Flag : CLI.OutFlags)
3257 if (
Flag.isSwiftError())
3266 for (
int i = 0, e = OutVals.size(); i != e; ++i) {
3267 Value *&Val = OutVals[i];
3269 if (
auto *CI = dyn_cast<ConstantInt>(Val)) {
3270 if (CI->getBitWidth() < 32) {
3283 if (TI && TI->getType()->isIntegerTy(1) && CLI.CS &&
3284 (TI->getParent() == CLI.CS->getInstruction()->getParent()) &&
3286 Value *PrevVal = TI->getOperand(0);
3287 ResultReg = getRegForValue(PrevVal);
3292 if (!isTypeLegal(PrevVal->
getType(), VT))
3296 fastEmit_ri(VT, VT,
ISD::AND, ResultReg, hasTrivialKill(PrevVal), 1);
3298 if (!isTypeLegal(Val->
getType(), VT))
3300 ResultReg = getRegForValue(Val);
3312 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, CLI.RetTy->getContext());
3318 CCInfo.AnalyzeCallOperands(OutVTs, OutFlags, CC_X86);
3321 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
3324 unsigned AdjStackDown =
TII.getCallFrameSetupOpcode();
3325 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(AdjStackDown))
3330 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
3338 unsigned ArgReg = ArgRegs[VA.
getValNo()];
3345 "Unexpected extend");
3352 assert(Emitted &&
"Failed to emit a sext!"); (void)Emitted;
3358 "Unexpected extend");
3363 ArgReg = fastEmitZExtFromI1(
MVT::i8, ArgReg,
false);
3372 assert(Emitted &&
"Failed to emit a zext!"); (void)Emitted;
3378 "Unexpected extend");
3388 assert(Emitted &&
"Failed to emit a aext!"); (void)Emitted;
3395 assert(ArgReg &&
"Failed to emit a bitcast!");
3415 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3416 TII.get(TargetOpcode::COPY), VA.
getLocReg()).addReg(ArgReg);
3422 if (isa<UndefValue>(ArgVal))
3428 AM.
Disp = LocMemOffset;
3430 unsigned Alignment = DL.getABITypeAlignment(ArgVal->
getType());
3437 if (!TryEmitSmallMemcpy(AM, SrcAM, Flags.
getByValSize()))
3439 }
else if (isa<ConstantInt>(ArgVal) || isa<ConstantPointerNull>(ArgVal)) {
3443 if (!X86FastEmitStore(ArgVT, ArgVal, AM, MMO))
3446 bool ValIsKill = hasTrivialKill(ArgVal);
3447 if (!X86FastEmitStore(ArgVT, ArgReg, ValIsKill, AM, MMO))
3455 if (Subtarget->isPICStyleGOT()) {
3456 unsigned Base = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3457 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3458 TII.get(TargetOpcode::COPY),
X86::EBX).addReg(Base);
3461 if (Is64Bit && IsVarArg && !IsWin64) {
3472 X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
3473 X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
3475 unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs);
3476 assert((Subtarget->hasSSE1() || !NumXMMRegs)
3477 &&
"SSE registers cannot be used when SSE is disabled");
3478 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::MOV8ri),
3485 if (!X86SelectCallAddress(Callee, CalleeAM))
3488 unsigned CalleeOp = 0;
3490 if (CalleeAM.
GV !=
nullptr) {
3492 }
else if (CalleeAM.
Base.
Reg != 0) {
3501 unsigned CallOpc = Is64Bit ? X86::CALL64r : X86::CALL32r;
3502 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(CallOpc))
3506 assert(GV &&
"Not a direct call");
3508 unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV);
3514 unsigned CallOpc = NeedLoad
3515 ? (Is64Bit ? X86::CALL64m : X86::CALL32m)
3516 : (Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32);
3518 MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(CallOpc));
3522 MIB.
addSym(Symbol, OpFlags);
3534 if (Subtarget->isPICStyleGOT())
3537 if (Is64Bit && IsVarArg && !IsWin64)
3541 for (
auto Reg : OutRegs)
3545 unsigned NumBytesForCalleeToPop =
3547 TM.Options.GuaranteedTailCallOpt)
3550 unsigned AdjStackUp =
TII.getCallFrameDestroyOpcode();
3551 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(AdjStackUp))
3552 .addImm(NumBytes).
addImm(NumBytesForCalleeToPop);
3556 CCState CCRetInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs,
3557 CLI.RetTy->getContext());
3561 unsigned ResultReg = FuncInfo.CreateRegs(CLI.RetTy);
3562 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
3565 unsigned CopyReg = ResultReg + i;
3570 ((Is64Bit ||
Ins[i].Flags.isInReg()) && !Subtarget->hasSSE1())) {
3576 if ((SrcReg == X86::FP0 || SrcReg == X86::FP1) &&
3577 isScalarFPTypeInSSEReg(VA.
getValVT())) {
3579 CopyReg = createResultReg(&X86::RFP80RegClass);
3583 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3584 TII.get(TargetOpcode::COPY), CopyReg).addReg(SrcReg);
3592 unsigned Opc = ResVT ==
MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
3594 int FI = MFI.CreateStackObject(MemSize, MemSize,
false);
3598 Opc = ResVT ==
MVT::f32 ? X86::MOVSSrm : X86::MOVSDrm;
3600 TII.get(Opc), ResultReg + i), FI);
3604 CLI.ResultReg = ResultReg;
3605 CLI.NumResultRegs = RVLocs.
size();
3612 X86FastISel::fastSelectInstruction(
const Instruction *I) {
3616 return X86SelectLoad(I);
3618 return X86SelectStore(I);
3620 return X86SelectRet(I);
3621 case Instruction::ICmp:
3622 case Instruction::FCmp:
3623 return X86SelectCmp(I);
3624 case Instruction::ZExt:
3625 return X86SelectZExt(I);
3626 case Instruction::SExt:
3627 return X86SelectSExt(I);
3628 case Instruction::Br:
3629 return X86SelectBranch(I);
3630 case Instruction::LShr:
3631 case Instruction::AShr:
3632 case Instruction::Shl:
3633 return X86SelectShift(I);
3634 case Instruction::SDiv:
3635 case Instruction::UDiv:
3636 case Instruction::SRem:
3637 case Instruction::URem:
3638 return X86SelectDivRem(I);
3640 return X86SelectSelect(I);
3641 case Instruction::Trunc:
3642 return X86SelectTrunc(I);
3643 case Instruction::FPExt:
3644 return X86SelectFPExt(I);
3645 case Instruction::FPTrunc:
3646 return X86SelectFPTrunc(I);
3647 case Instruction::SIToFP:
3648 return X86SelectSIToFP(I);
3649 case Instruction::UIToFP:
3650 return X86SelectUIToFP(I);
3651 case Instruction::IntToPtr:
3652 case Instruction::PtrToInt: {
3654 EVT DstVT = TLI.getValueType(DL, I->
getType());
3656 return X86SelectZExt(I);
3658 return X86SelectTrunc(I);
3660 if (Reg == 0)
return false;
3661 updateValueMap(I, Reg);
3664 case Instruction::BitCast: {
3666 if (!Subtarget->hasSSE2())
3670 EVT DstVT = TLI.getValueType(DL, I->
getType());
3691 updateValueMap(I, Reg);
3699 unsigned X86FastISel::X86MaterializeInt(
const ConstantInt *CI,
MVT VT) {
3705 unsigned SrcReg = fastEmitInst_(X86::MOV32r0, &X86::GR32RegClass);
3710 return fastEmitInst_extractsubreg(
MVT::i8, SrcReg,
true,
3713 return fastEmitInst_extractsubreg(
MVT::i16, SrcReg,
true,
3718 unsigned ResultReg = createResultReg(&X86::GR64RegClass);
3719 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
3720 TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
3733 case MVT::i8: Opc = X86::MOV8ri;
break;
3734 case MVT::i16: Opc = X86::MOV16ri;
break;
3735 case MVT::i32: Opc = X86::MOV32ri;
break;
3738 Opc = X86::MOV32ri64;
3740 Opc = X86::MOV64ri32;
3746 return fastEmitInst_i(Opc, TLI.getRegClassFor(VT), Imm);
3749 unsigned X86FastISel::X86MaterializeFP(
const ConstantFP *CFP,
MVT VT) {
3751 return fastMaterializeFloatZero(CFP);
3764 if (X86ScalarSSEf32) {
3765 Opc = Subtarget->hasAVX512()
3767 : Subtarget->hasAVX() ? X86::VMOVSSrm : X86::MOVSSrm;
3768 RC = Subtarget->hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
3770 Opc = X86::LD_Fp32m;
3771 RC = &X86::RFP32RegClass;
3775 if (X86ScalarSSEf64) {
3776 Opc = Subtarget->hasAVX512()
3778 : Subtarget->hasAVX() ? X86::VMOVSDrm : X86::MOVSDrm;
3779 RC = Subtarget->hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
3781 Opc = X86::LD_Fp64m;
3782 RC = &X86::RFP64RegClass;
3791 unsigned Align = DL.getPrefTypeAlignment(CFP->
getType());
3794 Align = DL.getTypeAllocSize(CFP->
getType());
3798 unsigned PICBase = 0;
3799 unsigned char OpFlag = Subtarget->classifyLocalReference(
nullptr);
3801 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3803 PICBase = getInstrInfo()->getGlobalBaseReg(FuncInfo.MF);
3808 unsigned CPI = MCP.getConstantPoolIndex(CFP, Align);
3809 unsigned ResultReg = createResultReg(RC);
3812 unsigned AddrReg = createResultReg(&X86::GR64RegClass);
3813 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::MOV64ri),
3815 .addConstantPoolIndex(CPI, 0, OpFlag);
3817 TII.get(Opc), ResultReg);
3827 TII.get(Opc), ResultReg),
3828 CPI, PICBase, OpFlag);
3832 unsigned X86FastISel::X86MaterializeGV(
const GlobalValue *GV,
MVT VT) {
3846 unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
3848 TLI.getPointerTy(DL) ==
MVT::i64) {
3851 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(X86::MOV64ri),
3853 .addGlobalAddress(GV);
3857 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3860 TII.get(Opc), ResultReg), AM);
3867 unsigned X86FastISel::fastMaterializeConstant(
const Constant *
C) {
3868 EVT CEVT = TLI.getValueType(DL, C->
getType(),
true);
3875 if (
const auto *CI = dyn_cast<ConstantInt>(C))
3876 return X86MaterializeInt(CI, VT);
3877 else if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
3878 return X86MaterializeFP(CFP, VT);
3879 else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(C))
3880 return X86MaterializeGV(GV, VT);
3885 unsigned X86FastISel::fastMaterializeAlloca(
const AllocaInst *C) {
3893 if (!FuncInfo.StaticAllocaMap.count(C))
3902 ? (Subtarget->isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r)
3905 unsigned ResultReg = createResultReg(RC);
3907 TII.get(Opc), ResultReg), AM);
3911 unsigned X86FastISel::fastMaterializeFloatZero(
const ConstantFP *CF) {
3913 if (!isTypeLegal(CF->
getType(), VT))
3917 bool HasAVX512 = Subtarget->hasAVX512();
3923 if (X86ScalarSSEf32) {
3924 Opc = HasAVX512 ? X86::AVX512_FsFLD0SS : X86::FsFLD0SS;
3925 RC = HasAVX512 ? &X86::FR32XRegClass : &X86::FR32RegClass;
3927 Opc = X86::LD_Fp032;
3928 RC = &X86::RFP32RegClass;
3932 if (X86ScalarSSEf64) {
3933 Opc = HasAVX512 ? X86::AVX512_FsFLD0SD : X86::FsFLD0SD;
3934 RC = HasAVX512 ? &X86::FR64XRegClass : &X86::FR64RegClass;
3936 Opc = X86::LD_Fp064;
3937 RC = &X86::RFP64RegClass;
3945 unsigned ResultReg = createResultReg(RC);
3946 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc), ResultReg);
3951 bool X86FastISel::tryToFoldLoadIntoMI(
MachineInstr *
MI,
unsigned OpNo,
3960 unsigned Size = DL.getTypeAllocSize(LI->
getType());
3964 Alignment = DL.getABITypeAlignment(LI->
getType());
3970 *FuncInfo.MF, *MI, OpNo, AddrOps, FuncInfo.InsertPt, Size, Alignment,
3980 unsigned OperandNo = 0;
3989 if (IndexReg == MO.
getReg())
3994 Result->
addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
3996 removeDeadCode(I, std::next(I));
4000 unsigned X86FastISel::fastEmitInst_rrrr(
unsigned MachineInstOpcode,
4002 unsigned Op0,
bool Op0IsKill,
4003 unsigned Op1,
bool Op1IsKill,
4004 unsigned Op2,
bool Op2IsKill,
4005 unsigned Op3,
bool Op3IsKill) {
4008 unsigned ResultReg = createResultReg(RC);
4015 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
4021 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
4026 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
4036 return new X86FastISel(funcInfo, libInfo);
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
void setFrameAddressIsTaken(bool T)
unsigned GetCondBranchFromCond(CondCode CC)
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
constexpr bool isUInt< 32 >(uint64_t x)
Return a value (possibly void), from a function.
Value * getValueOperand()
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
bool is64Bit() const
Is this x86_64? (disregarding specific ABI / programming model)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
bool usesWindowsCFI() const
mop_iterator operands_end()
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class is the base class for the comparison instructions.
C - The default llvm calling convention, compatible with C.
This class represents an incoming formal argument to a Function.
bool contains(unsigned 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.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
static const MachineInstrBuilder & addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI, unsigned GlobalBaseReg, unsigned char OpFlags)
addConstantPoolReference - This function is used to add a reference to the base of a constant value s...
bool isAtomic() const
Return true if this instruction has an AtomicOrdering of unordered or higher.
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.
void push_back(const T &Elt)
Describe properties that are true of each instruction in the target description file.
union llvm::X86AddressMode::@497 Base
unsigned getReg() const
getReg - Returns the register number.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
This class represents a function call, abstracting a target machine's calling convention.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
The C convention as implemented on Windows/x86-64 and AArch64.
0 1 0 0 True if ordered and less than
constexpr bool isInt< 8 >(int64_t x)
unsigned getSourceAddressSpace() const
unsigned getValNo() const
LLVMContext & getContext() const
All values hold a context through their type.
1 1 1 0 True if unordered or not equal
This class wraps the llvm.memset intrinsic.
BasicBlock * getSuccessor(unsigned i) const
unsigned const TargetRegisterInfo * TRI
unsigned getPtrSizedFrameRegister(const MachineFunction &MF) const
An instruction for reading from memory.
MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for th...
Value * getCondition() const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isCalleePop(CallingConv::ID CallingConv, bool is64Bit, bool IsVarArg, bool GuaranteeTCO)
Determines whether the callee is required to pop its own arguments.
Value * getLength() const
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
Value * getArgOperand(unsigned i) const
1 0 0 1 True if unordered or equal
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
A description of a memory reference used in the backend.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const HexagonInstrInfo * TII
bool isNonTemporal() const
unsigned getNumOperands() const
Retuns the total number of operands.
Class to represent struct types.
A Use represents the edge between a Value definition and its users.
static bool isGlobalStubReference(unsigned char TargetFlag)
isGlobalStubReference - Return true if the specified TargetFlag operand is a reference to a stub for ...
bool isIntegerTy() const
True if this is an instance of IntegerType.
0 1 0 1 True if ordered and less than or equal
static Constant * getSExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
LocInfo getLocInfo() const
unsigned getSizeInBits() const
enum llvm::X86AddressMode::@496 BaseType
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
static bool isGlobalRelativeToPICBase(unsigned char TargetFlag)
isGlobalRelativeToPICBase - Return true if the specified global value reference is relative to a 32-b...
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Fast - This calling convention attempts to make calls as fast as possible (e.g.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
A constant value that is initialized with an expression using other constant values.
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Type * getType() const
All values are typed, get the type of this value.
Simple integer binary arithmetic operators.
This instruction compares its operands according to the predicate given to the constructor.
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Return true if the call or the callee has the given attribute.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
An instruction for storing to memory.
bool doesNoCfCheck() const
Determine if the call should not perform indirect branch tracking.
void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
amdgpu Simplify well known AMD library false Value * Callee
This class represents a truncation of integer types.
Value * getOperand(unsigned i) const
Class to represent pointers.
unsigned getByValSize() const
unsigned getKillRegState(bool B)
unsigned getStackRegister() const
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Type * getReturnType() const
Returns the type of the ret val.
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...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
unsigned const MachineRegisterInfo * MRI
The instances of the Type class are immutable: once they are created, they are never changed...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Conditional or Unconditional Branch instruction.
Value * getAddress() const
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
unsigned getScalarSizeInBits() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
unsigned getSRetReturnReg() const
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
ConstantFP - Floating Point Values [float, double].
const MCPhysReg * ImplicitDefs
DIExpression * getExpression() const
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this variable.
static std::pair< unsigned, bool > getX86SSEConditionCode(CmpInst::Predicate Predicate)
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
TRAP - Trapping instruction.
0 1 1 1 True if ordered (no nans)
Value * getPointerOperand()
The C convention as specified in the x86-64 supplement to the System V ABI, used on most non-Windows ...
const Triple & getTargetTriple() const
static void X86SelectAddress(const MachineInstr &I, const MachineRegisterInfo &MRI, X86AddressMode &AM)
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
1 1 1 1 Always true (always folded)
unsigned getSETFromCond(CondCode CC, bool HasMemoryOperand=false)
Return a set opcode for the given condition and whether it has a memory operand.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
1 1 0 1 True if unordered, less than, or equal
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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...
The memory access writes data.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
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...
0 0 1 0 True if ordered and greater than
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
CCState - This class holds information needed while lowering arguments and return values...
This is the shared class of boolean and integer constants.
constexpr bool isInt< 32 >(int64_t x)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type...
X86_ThisCall - Similar to X86_StdCall.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
1 1 0 0 True if unordered or less than
Provides information about what library functions are available for the current target.
CCValAssign - Represent assignment of one arg/retval to a location.
void getFullAddress(SmallVectorImpl< MachineOperand > &MO)
This class wraps the llvm.memcpy intrinsic.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Value * getRawSource() const
Return the arguments to the instruction.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
X86_FastCall - 'fast' analog of X86_StdCall.
This file defines the FastISel class.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
unsigned getCMovFromCond(CondCode CC, unsigned RegBytes, bool HasMemoryOperand=false)
Return a cmov opcode for the given condition, register size in bytes, and operand type...
ZERO_EXTEND - Used for integer types, zeroing the new bits.
ANY_EXTEND - Used for integer types. The high bits are undefined.
amdgpu Simplify well known AMD library false Value Value * Arg
The memory access reads data.
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr) const override
foldMemoryOperand - If this target supports it, fold a load or store of the specified stack slot into...
Representation of each machine instruction.
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
static const MachineInstrBuilder & addDirectMem(const MachineInstrBuilder &MIB, unsigned Reg)
addDirectMem - This function is used to add a direct memory reference to the current instruction – t...
unsigned getNumArgOperands() const
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Bitwise operators - logical and, logical or, logical xor.
unsigned getDestAddressSpace() const
uint64_t getElementOffset(unsigned Idx) const
unsigned getAlignment() const
Return the alignment of the access that is being performed.
static IntegerType * getInt32Ty(LLVMContext &C)
unsigned getLocMemOffset() const
Establish a view to a call site for examination.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
const Function * getParent() const
Return the enclosing method, or null if none.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
0 1 1 0 True if ordered and operands are unequal
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool is512BitVector() const
Return true if this is a 512-bit vector type.
DILocalVariable * getVariable() const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
unsigned getBytesToPopOnReturn() const
1 0 1 0 True if unordered or greater than
constexpr bool isUInt< 16 >(uint64_t x)
static MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
unsigned getAlignment() const
Return the alignment of the access that is being performed.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
X86_StdCall - stdcall is the calling conventions mostly used by the Win32 API.
0 0 0 1 True if ordered and equal
LLVM Value Representation.
mop_iterator operands_begin()
1 0 1 1 True if unordered, greater than, or equal
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...
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
unsigned constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II, const MachineOperand &RegMO, unsigned OpIdx)
Try to constrain Reg so that it is usable by argument OpIdx of the provided MCInstrDesc II...
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size...
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
X86AddressMode - This struct holds a generalized full x86 address mode.
unsigned getLocReg() const
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
0 0 1 1 True if ordered and greater than or equal
This represents the llvm.dbg.declare instruction.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Value * getPointerOperand()
unsigned AllocateStack(unsigned Size, unsigned Align)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
Value * getRawDest() const
static const MachineInstrBuilder & addFullAddress(const MachineInstrBuilder &MIB, const X86AddressMode &AM)
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
iterator_range< arg_iterator > args()
0 0 0 0 Always false (always folded)
bool isStructTy() const
True if this is an instance of StructType.
MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...
static unsigned computeBytesPoppedByCalleeForSRet(const X86Subtarget *Subtarget, CallingConv::ID CC, ImmutableCallSite *CS)
bool isArrayTy() const
True if this is an instance of ArrayType.
A wrapper class for inspecting calls to intrinsic functions.
const BasicBlock * getParent() const
static unsigned X86ChooseCmpOpcode(EVT VT, const X86Subtarget *Subtarget)
an instruction to allocate memory on the stack
gep_type_iterator gep_type_begin(const User *GEP)