22#include "llvm/Config/llvm-config.h"
27#include "llvm/IR/IntrinsicsX86.h"
38#define DEBUG_TYPE "x86-isel"
39#define PASS_NAME "X86 DAG->DAG Instruction Selection"
41STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
44 cl::desc(
"Enable setting constant bits to reduce size of mask immediates"),
48 "x86-promote-anyext-load",
cl::init(
true),
60 struct X86ISelAddressMode {
68 int Base_FrameIndex = 0;
74 const GlobalValue *GV =
nullptr;
77 const char *ES =
nullptr;
82 bool NegateIndex =
false;
84 X86ISelAddressMode() =
default;
86 bool hasSymbolicDisplacement()
const {
87 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr ||
88 MCSym !=
nullptr || JT != -1 || BlockAddr !=
nullptr;
91 bool hasBaseOrIndexReg()
const {
92 return BaseType == FrameIndexBase ||
93 IndexReg.getNode() !=
nullptr || Base_Reg.getNode() !=
nullptr;
98 if (BaseType != RegBase)
return false;
99 if (RegisterSDNode *RegNode =
101 return RegNode->getReg() == X86::RIP;
110#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
111 void dump(SelectionDAG *DAG =
nullptr) {
112 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
113 dbgs() <<
"Base_Reg ";
114 if (Base_Reg.getNode())
115 Base_Reg.getNode()->dump(DAG);
118 if (BaseType == FrameIndexBase)
119 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
120 dbgs() <<
" Scale " << Scale <<
'\n'
124 if (IndexReg.getNode())
125 IndexReg.getNode()->dump(DAG);
128 dbgs() <<
" Disp " << Disp <<
'\n'
150 dbgs() <<
" JT" << JT <<
" Align" << Alignment.value() <<
'\n';
164 const X86Subtarget *Subtarget;
170 bool IndirectTlsSegRefs;
173 X86DAGToDAGISel() =
delete;
175 explicit X86DAGToDAGISel(X86TargetMachine &tm,
CodeGenOptLevel OptLevel)
176 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr),
177 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
179 bool runOnMachineFunction(MachineFunction &MF)
override {
183 "indirect-tls-seg-refs");
190 void emitFunctionEntryCode()
override;
192 bool IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const override;
194 void PreprocessISelDAG()
override;
195 void PostprocessISelDAG()
override;
198#include "X86GenDAGISel.inc"
201 void Select(SDNode *
N)
override;
203 bool foldOffsetIntoAddress(uint64_t
Offset, X86ISelAddressMode &AM);
204 bool matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
205 bool AllowSegmentRegForX32 =
false);
206 bool matchWrapper(
SDValue N, X86ISelAddressMode &AM);
207 bool matchAddress(
SDValue N, X86ISelAddressMode &AM);
208 bool matchVectorAddress(
SDValue N, X86ISelAddressMode &AM);
209 bool matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
212 bool matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
214 bool matchVectorAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
216 bool matchAddressBase(
SDValue N, X86ISelAddressMode &AM);
220 bool selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
SDValue IndexOp,
234 bool tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
244 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
247 bool tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
252 bool isProfitableToFormMaskedOp(SDNode *
N)
const;
255 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
257 std::vector<SDValue> &OutOps)
override;
259 void emitSpecialCodeForMain();
261 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
265 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
266 Base = CurDAG->getTargetFrameIndex(
267 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
268 else if (AM.Base_Reg.
getNode())
271 Base = CurDAG->getRegister(0, VT);
273 Scale = getI8Imm(AM.Scale,
DL);
275#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
277 if (AM.NegateIndex) {
303 Index = CurDAG->getRegister(0, VT);
308 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(),
312 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
313 AM.Disp, AM.SymbolFlags);
315 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
316 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
317 }
else if (AM.MCSym) {
318 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
319 assert(AM.SymbolFlags == 0 &&
"oo");
320 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
321 }
else if (AM.JT != -1) {
322 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
323 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
324 }
else if (AM.BlockAddr)
325 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
328 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
331 Segment = AM.Segment;
333 Segment = CurDAG->getRegister(0, MVT::i16);
338 bool isAMXSDNode(SDNode *
N)
const {
342 for (
unsigned Idx = 0,
E =
N->getNumValues(); Idx !=
E; ++Idx) {
343 if (
N->getValueType(Idx) == MVT::x86amx)
346 for (
unsigned Idx = 0,
E =
N->getNumOperands(); Idx !=
E; ++Idx) {
348 if (
Op.getValueType() == MVT::x86amx)
360 bool shouldAvoidImmediateInstFormsForSize(SDNode *
N)
const {
361 uint32_t UseCount = 0;
366 if (!CurDAG->shouldOptForSize())
370 for (
const SDNode *User :
N->users()) {
376 if (
User->isMachineOpcode()) {
382 if (
User->getOpcode() == ISD::STORE &&
383 User->getOperand(1).getNode() ==
N) {
394 if (
User->getNumOperands() != 2)
415 OtherOp =
User->getOperand(1);
418 RegisterSDNode *RegNode;
422 if ((RegNode->
getReg() == X86::ESP) ||
423 (RegNode->
getReg() == X86::RSP))
432 return (UseCount > 1);
436 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &
DL) {
437 return CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
441 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &
DL) {
442 return CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
446 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &
DL) {
447 return CurDAG->getTargetConstant(Imm,
DL, MVT::i64);
450 SDValue getExtractVEXTRACTImmediate(SDNode *
N,
unsigned VecWidth,
452 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
453 uint64_t
Index =
N->getConstantOperandVal(1);
454 MVT VecVT =
N->getOperand(0).getSimpleValueType();
458 SDValue getInsertVINSERTImmediate(SDNode *
N,
unsigned VecWidth,
460 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
461 uint64_t
Index =
N->getConstantOperandVal(2);
462 MVT VecVT =
N->getSimpleValueType(0);
466 SDValue getPermuteVINSERTCommutedImmediate(SDNode *
N,
unsigned VecWidth,
468 assert(VecWidth == 128 &&
"Unexpected vector width");
469 uint64_t
Index =
N->getConstantOperandVal(2);
470 MVT VecVT =
N->getSimpleValueType(0);
472 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
475 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
480 MVT VT =
N->getSimpleValueType(0);
483 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
485 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
486 if (VT == MVT::i64) {
488 CurDAG->getMachineNode(
489 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
490 CurDAG->getTargetConstant(0, dl, MVT::i64), Zero,
491 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
496 unsigned Opcode =
N->getOpcode();
498 "Unexpected opcode for SBB materialization");
499 unsigned FlagOpIndex = Opcode ==
X86ISD::SBB ? 2 : 1;
501 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
502 N->getOperand(FlagOpIndex),
SDValue());
506 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
507 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
508 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
510 CurDAG->getMachineNode(
Opc, dl, VTs,
511 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
517 bool isUnneededShiftMask(SDNode *
N,
unsigned Width)
const {
519 const APInt &Val =
N->getConstantOperandAPInt(1);
524 APInt
Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
525 return Mask.countr_one() >= Width;
531 SDNode *getGlobalBaseReg();
535 const X86TargetMachine &getTargetMachine()
const {
536 return static_cast<const X86TargetMachine &
>(TM);
541 const X86InstrInfo *getInstrInfo()
const {
542 return Subtarget->getInstrInfo();
551 bool ComplexPatternFuncMutatesDAG()
const override {
555 bool isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const;
558 bool useNonTemporalLoad(LoadSDNode *
N)
const {
559 if (!
N->isNonTemporal())
562 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
564 if (
N->getAlign().value() < StoreSize)
573 return Subtarget->hasSSE41();
575 return Subtarget->hasAVX2();
577 return Subtarget->hasAVX512();
581 bool foldLoadStoreIntoMemOperand(SDNode *Node);
582 MachineSDNode *matchBEXTRFromAndImm(SDNode *Node);
583 bool matchBitExtract(SDNode *Node);
584 bool shrinkAndImmediate(SDNode *
N);
585 bool isMaskZeroExtended(SDNode *
N)
const;
586 bool tryShiftAmountMod(SDNode *
N);
587 bool tryShrinkShlLogicImm(SDNode *
N);
588 bool tryVPTERNLOG(SDNode *
N);
589 bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentB,
593 bool tryMatchBitSelect(SDNode *
N);
595 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
596 const SDLoc &dl, MVT VT, SDNode *Node);
597 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
598 const SDLoc &dl, MVT VT, SDNode *Node,
601 bool tryOptimizeRem8Extend(SDNode *
N);
603 bool onlyUsesZeroFlag(
SDValue Flags)
const;
604 bool hasNoSignFlagUses(
SDValue Flags)
const;
605 bool hasNoCarryFlagUses(
SDValue Flags)
const;
611 explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm,
613 : SelectionDAGISelLegacy(
614 ID, std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
618char X86DAGToDAGISelLegacy::ID = 0;
625 unsigned Opcode =
N->getOpcode();
632 EVT OpVT =
N->getOperand(0).getValueType();
636 OpVT =
N->getOperand(1).getValueType();
638 return Subtarget->hasVLX();
652bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
664X86DAGToDAGISel::IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const {
665 if (OptLevel == CodeGenOptLevel::None)
671 if (
N.getOpcode() != ISD::LOAD)
680 switch (
U->getOpcode()) {
707 if (
Imm->getAPIntValue().isSignedIntN(8))
716 Imm->getAPIntValue().getBitWidth() == 64 &&
717 Imm->getAPIntValue().isIntN(32))
724 (
Imm->getAPIntValue() == UINT8_MAX ||
725 Imm->getAPIntValue() == UINT16_MAX ||
726 Imm->getAPIntValue() == UINT32_MAX))
732 (-
Imm->getAPIntValue()).isSignedIntN(8))
736 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
737 hasNoCarryFlagUses(
SDValue(U, 1)))
762 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
766 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
775 if (
C &&
C->getSExtValue() == -2)
781 if (
C &&
C->getSExtValue() == -2)
816bool X86DAGToDAGISel::isProfitableToFormMaskedOp(SDNode *
N)
const {
819 "Unexpected opcode!");
824 return N->getOperand(1).hasOneUse();
833 if (Chain.
getNode() == Load.getNode())
834 Ops.push_back(Load.getOperand(0));
837 "Unexpected chain operand");
840 Ops.push_back(Load.getOperand(0));
846 Ops.push_back(NewChain);
851 Load.getOperand(1), Load.getOperand(2));
869 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
879 while (HasCallSeq && Chain.
getOpcode() != ISD::CALLSEQ_START) {
896 Callee.getValue(1).hasOneUse())
904 if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
907 uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
908 0x65, 0x66, 0x67, 0xf0, 0xf2};
911 uint8_t Byte = (Imm >> i) & 0xFF;
923 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
926void X86DAGToDAGISel::PreprocessISelDAG() {
927 bool MadeChange =
false;
929 E = CurDAG->allnodes_end();
I !=
E; ) {
948 MVT VT =
N->getSimpleValueType(0);
950 int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
955 "cf-protection-branch");
958 SDValue Complement = CurDAG->getConstant(~Imm, dl, VT,
false,
true);
959 Complement = CurDAG->getNOT(dl, Complement, VT);
961 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Complement);
971 if (
N->getOpcode() ==
X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
973 N->getOperand(0),
N->getOperand(1));
975 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
999 auto mayPreventLoadFold = [&]() {
1001 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1002 !
N->getOperand(1).hasOneUse();
1005 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1013 MVT VT =
N->getSimpleValueType(0);
1021 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1023 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1030 switch (
N->getOpcode()) {
1032 MVT VT =
N->getSimpleValueType(0);
1034 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1041 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1044 CurDAG->getIntPtrConstant(Index, dl));
1047 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1056 MVT VT =
N->getSimpleValueType(0);
1058 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1062 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1063 SDValue Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1064 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1066 MemNode->getMemOperand());
1069 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1072 CurDAG->getIntPtrConstant(Index, dl));
1076 CurDAG->ReplaceAllUsesWith(
N, To);
1088 MVT VT =
N->getSimpleValueType(0);
1094 SDNode *MaxLd =
nullptr;
1095 SDValue Ptr = Ld->getBasePtr();
1096 SDValue Chain = Ld->getChain();
1097 for (SDNode *User : Ptr->
users()) {
1099 MVT UserVT =
User->getSimpleValueType(0);
1101 UserLd->getBasePtr() == Ptr && UserLd->getChain() == Chain &&
1102 !
User->hasAnyUseOfValue(1) &&
1116 CurDAG->getIntPtrConstant(0, dl));
1117 SDValue Res = CurDAG->getBitcast(VT, Extract);
1121 CurDAG->ReplaceAllUsesWith(
N, To);
1130 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1131 if (EleVT == MVT::i1)
1134 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1135 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1136 "We can't replace VSELECT with BLENDV in vXi16!");
1138 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1141 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1142 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1145 N->getOperand(0),
N->getOperand(1),
1149 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1162 if (!
N->getSimpleValueType(0).isVector())
1166 switch (
N->getOpcode()) {
1176 if (
N->isStrictFPOpcode())
1178 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1179 {
N->getOperand(0),
N->getOperand(1)});
1182 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1185 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1195 if (!
N->getValueType(0).isVector())
1199 switch (
N->getOpcode()) {
1205 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1206 N->getOperand(0),
N->getOperand(1));
1208 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1217 if (!
N->getValueType(0).isVector())
1221 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1223 "Unexpected opcode for mask vector!");
1231 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1234 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1245 case ISD::FROUNDEVEN:
1247 case ISD::FNEARBYINT:
1254 switch (
N->getOpcode()) {
1257 case ISD::FCEIL:
Imm = 0xA;
break;
1259 case ISD::FFLOOR:
Imm = 0x9;
break;
1261 case ISD::FTRUNC:
Imm = 0xB;
break;
1263 case ISD::FROUNDEVEN:
Imm = 0x8;
break;
1265 case ISD::FNEARBYINT:
Imm = 0xC;
break;
1267 case ISD::FRINT:
Imm = 0x4;
break;
1270 bool IsStrict =
N->isStrictFPOpcode();
1274 {
N->getValueType(0), MVT::Other},
1275 {
N->getOperand(0),
N->getOperand(1),
1276 CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
1280 CurDAG->getTargetConstant(Imm, dl, MVT::i32));
1282 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1293 MVT VT =
N->getSimpleValueType(0);
1294 if (VT.
isVector() || VT == MVT::f128)
1297 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1298 : VT == MVT::f32 ? MVT::v4f32
1308 if (Subtarget->hasSSE2()) {
1309 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1310 Op0 = CurDAG->getNode(ISD::BITCAST, dl, IntVT, Op0);
1311 Op1 = CurDAG->getNode(ISD::BITCAST, dl, IntVT, Op1);
1313 switch (
N->getOpcode()) {
1320 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1321 Res = CurDAG->getNode(ISD::BITCAST, dl, VecVT, Res);
1323 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1326 CurDAG->getIntPtrConstant(0, dl));
1328 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1335 if (OptLevel != CodeGenOptLevel::None &&
1338 !Subtarget->useIndirectThunkCalls() &&
1339 ((
N->getOpcode() ==
X86ISD::CALL && !Subtarget->slowTwoMemOps()) ||
1341 (Subtarget->is64Bit() ||
1342 !getTargetMachine().isPositionIndependent())))) {
1381 switch (
N->getOpcode()) {
1384 case ISD::FP_EXTEND:
1386 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1387 MVT DstVT =
N->getSimpleValueType(0);
1395 const X86TargetLowering *X86Lowering =
1396 static_cast<const X86TargetLowering *
>(TLI);
1399 if (SrcIsSSE && DstIsSSE)
1402 if (!SrcIsSSE && !DstIsSSE) {
1404 if (
N->getOpcode() == ISD::FP_EXTEND)
1407 if (
N->getConstantOperandVal(1))
1415 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1417 MachinePointerInfo MPI =
1424 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1426 MemTmp, MPI, MemVT);
1433 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1442 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1443 MVT DstVT =
N->getSimpleValueType(0);
1451 const X86TargetLowering *X86Lowering =
1452 static_cast<const X86TargetLowering *
>(TLI);
1455 if (SrcIsSSE && DstIsSSE)
1458 if (!SrcIsSSE && !DstIsSSE) {
1463 if (
N->getConstantOperandVal(2))
1471 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1473 MachinePointerInfo MPI =
1482 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1483 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1487 if (
N->getFlags().hasNoFPExcept()) {
1489 Flags.setNoFPExcept(
true);
1490 Store->setFlags(Flags);
1493 assert(SrcVT == MemVT &&
"Unexpected VT!");
1494 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1499 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1501 Result = CurDAG->getMemIntrinsicNode(
1504 if (
N->getFlags().hasNoFPExcept()) {
1506 Flags.setNoFPExcept(
true);
1510 assert(DstVT == MemVT &&
"Unexpected VT!");
1511 Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
1519 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1533 CurDAG->RemoveDeadNodes();
1537bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1538 unsigned Opc =
N->getMachineOpcode();
1539 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1540 Opc != X86::MOVSX64rr8)
1552 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1553 : X86::MOVSX32rr8_NOREX;
1558 if (
Opc == X86::MOVSX64rr8) {
1561 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1563 ReplaceUses(
N, Extend);
1572void X86DAGToDAGISel::PostprocessISelDAG() {
1574 if (TM.getOptLevel() == CodeGenOptLevel::None)
1579 bool MadeChange =
false;
1580 while (Position != CurDAG->allnodes_begin()) {
1581 SDNode *
N = &*--Position;
1583 if (
N->use_empty() || !
N->isMachineOpcode())
1586 if (tryOptimizeRem8Extend(
N)) {
1591 unsigned Opc =
N->getMachineOpcode();
1602 case X86::CTEST16rr:
1603 case X86::CTEST32rr:
1604 case X86::CTEST64rr: {
1610#define CASE_ND(OP) \
1613 switch (
And.getMachineOpcode()) {
1620 if (
And->hasAnyUseOfValue(1))
1623 Ops[0] =
And.getOperand(0);
1624 Ops[1] =
And.getOperand(1);
1625 MachineSDNode *
Test =
1626 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1627 ReplaceUses(
N,
Test);
1635 if (
And->hasAnyUseOfValue(1))
1638 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1639#define FROM_TO(A, B) \
1640 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1642 switch (
And.getMachineOpcode()) {
1652 And.getOperand(3),
And.getOperand(4),
1653 And.getOperand(5),
And.getOperand(0)};
1656 Ops.push_back(
N->getOperand(2));
1657 Ops.push_back(
N->getOperand(3));
1660 Ops.push_back(
And.getOperand(6));
1663 Ops.push_back(
N->getOperand(4));
1665 MachineSDNode *
Test = CurDAG->getMachineNode(
1666 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1667 CurDAG->setNodeMemRefs(
1680 case X86::KORTESTBkk:
1681 case X86::KORTESTWkk:
1682 case X86::KORTESTDkk:
1683 case X86::KORTESTQkk: {
1685 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1700#define FROM_TO(A, B) \
1712 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1715 MachineSDNode *KTest = CurDAG->getMachineNode(
1717 ReplaceUses(
N, KTest);
1722 case TargetOpcode::SUBREG_TO_REG: {
1723 unsigned SubRegIdx =
N->getConstantOperandVal(2);
1724 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1741 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1742 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1743 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1744 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1745 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1746 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1747 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1748 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1753 if (!
In.isMachineOpcode() ||
1754 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1759 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1767 CurDAG->UpdateNodeOperands(
N,
N->getOperand(0), In,
N->getOperand(2));
1774 CurDAG->RemoveDeadNodes();
1779void X86DAGToDAGISel::emitSpecialCodeForMain() {
1780 if (Subtarget->isTargetCygMing()) {
1781 TargetLowering::ArgListTy
Args;
1782 auto &
DL = CurDAG->getDataLayout();
1784 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1785 CLI.setChain(CurDAG->getRoot())
1786 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1787 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1789 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1791 CurDAG->setRoot(
Result.second);
1795void X86DAGToDAGISel::emitFunctionEntryCode() {
1798 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1799 emitSpecialCodeForMain();
1812bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t
Offset,
1813 X86ISelAddressMode &AM) {
1818 int64_t Val = AM.Disp +
Offset;
1821 if (Val != 0 && (AM.ES || AM.MCSym))
1825 if (Subtarget->is64Bit()) {
1828 AM.hasSymbolicDisplacement()))
1832 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1851 if (Subtarget->isTarget64BitILP32() &&
1853 !AM.hasBaseOrIndexReg())
1863bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1864 bool AllowSegmentRegForX32) {
1877 !IndirectTlsSegRefs &&
1878 (Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() ||
1879 Subtarget->isTargetFuchsia())) {
1880 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1882 switch (
N->getPointerInfo().getAddrSpace()) {
1884 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1887 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1900bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1903 if (AM.hasSymbolicDisplacement())
1906 bool IsRIPRelTLS =
false;
1924 if (IsRIPRel && AM.hasBaseOrIndexReg())
1928 X86ISelAddressMode Backup = AM;
1933 AM.GV =
G->getGlobal();
1934 AM.SymbolFlags =
G->getTargetFlags();
1937 AM.CP =
CP->getConstVal();
1938 AM.Alignment =
CP->getAlign();
1939 AM.SymbolFlags =
CP->getTargetFlags();
1942 AM.ES = S->getSymbol();
1943 AM.SymbolFlags = S->getTargetFlags();
1945 AM.MCSym = S->getMCSymbol();
1947 AM.JT = J->getIndex();
1948 AM.SymbolFlags = J->getTargetFlags();
1950 AM.BlockAddr = BA->getBlockAddress();
1951 AM.SymbolFlags = BA->getTargetFlags();
1952 Offset = BA->getOffset();
1957 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1958 TM.isLargeGlobalValue(AM.GV)) {
1963 if (foldOffsetIntoAddress(
Offset, AM)) {
1969 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
1977bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
1978 if (matchAddressRecursively(
N, AM, 0))
1985 if (Subtarget->isTarget64BitILP32() &&
1986 AM.BaseType == X86ISelAddressMode::RegBase &&
1987 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
1988 SDValue Save_Base_Reg = AM.Base_Reg;
1991 if (matchLoadInAddress(LoadN, AM,
true))
1992 AM.Base_Reg = Save_Base_Reg;
1998 if (AM.Scale == 2 &&
1999 AM.BaseType == X86ISelAddressMode::RegBase &&
2000 AM.Base_Reg.
getNode() ==
nullptr) {
2001 AM.Base_Reg = AM.IndexReg;
2008 (!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2009 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2010 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2022 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2028bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
2032 HandleSDNode Handle(
N);
2034 X86ISelAddressMode Backup = AM;
2035 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
2036 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
2041 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
2043 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2050 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2053 N = Handle.getValue();
2059 N = Handle.getValue();
2069 if (
N->getNodeId() == -1 ||
2089 X86ISelAddressMode &AM) {
2096 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2097 Mask != (0xffu << ScaleLog))
2100 MVT XVT =
X.getSimpleValueType();
2101 MVT VT =
N.getSimpleValueType();
2126 AM.Scale = (1 << ScaleLog);
2134 X86ISelAddressMode &AM) {
2145 bool FoundAnyExtend =
false;
2149 FoundAnyExtend =
true;
2167 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2170 MVT VT =
N.getSimpleValueType();
2172 if (FoundAnyExtend) {
2193 AM.Scale = 1 << ShiftAmt;
2194 AM.IndexReg = NewAnd;
2228 X86ISelAddressMode &AM) {
2234 unsigned MaskIdx, MaskLen;
2237 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2243 unsigned AMShiftAmt = MaskIdx;
2247 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2251 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2252 if (MaskLZ < ScaleDown)
2254 MaskLZ -= ScaleDown;
2262 bool ReplacingAnyExtend =
false;
2264 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2265 X.getOperand(0).getSimpleValueType().getSizeInBits();
2268 X =
X.getOperand(0);
2269 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2270 ReplacingAnyExtend =
true;
2272 APInt MaskedHighBits =
2279 MVT VT =
N.getSimpleValueType();
2280 if (ReplacingAnyExtend) {
2281 assert(
X.getValueType() != VT);
2288 MVT XVT =
X.getSimpleValueType();
2309 AM.Scale = 1 << AMShiftAmt;
2310 AM.IndexReg = NewExt;
2320 X86ISelAddressMode &AM,
2328 if (!Subtarget.hasTBM() &&
2329 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2333 unsigned MaskIdx, MaskLen;
2341 unsigned AMShiftAmt = MaskIdx;
2345 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2347 MVT XVT =
X.getSimpleValueType();
2348 MVT VT =
N.getSimpleValueType();
2373 AM.Scale = 1 << AMShiftAmt;
2374 AM.IndexReg = NewExt;
2381 X86ISelAddressMode &AM,
2383 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2384 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2385 "Illegal index scale");
2391 EVT VT =
N.getValueType();
2392 unsigned Opc =
N.getOpcode();
2395 if (CurDAG->isBaseWithConstantOffset(
N)) {
2397 uint64_t
Offset = (uint64_t)AddVal->getSExtValue() * AM.Scale;
2398 if (!foldOffsetIntoAddress(
Offset, AM))
2399 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2403 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2404 if (AM.Scale <= 4) {
2406 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2412 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2413 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2414 if ((AM.Scale * ScaleAmt) <= 8) {
2415 AM.Scale *= ScaleAmt;
2416 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2424 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2426 if (CurDAG->isBaseWithConstantOffset(Src)) {
2427 SDValue AddSrc = Src.getOperand(0);
2429 int64_t
Offset = AddVal->getSExtValue();
2430 if (!foldOffsetIntoAddress((uint64_t)
Offset * AM.Scale, AM)) {
2438 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2439 CurDAG->RemoveDeadNode(
N.getNode());
2451 unsigned SrcOpc = Src.getOpcode();
2452 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2453 CurDAG->isADDLike(Src,
true)) &&
2455 if (CurDAG->isBaseWithConstantOffset(Src)) {
2456 SDValue AddSrc = Src.getOperand(0);
2457 uint64_t
Offset = Src.getConstantOperandVal(1);
2458 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2468 uint64_t ScaleAmt = 1ULL << ShAmt;
2469 if ((AM.Scale * ScaleAmt) <= 8 &&
2471 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2472 AM.Scale *= ScaleAmt;
2473 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2484 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2488 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2489 CurDAG->RemoveDeadNode(
N.getNode());
2490 return Res ? Res : ExtSrc;
2500bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2503 dbgs() <<
"MatchAddress: ";
2508 return matchAddressBase(
N, AM);
2513 if (AM.isRIPRelative()) {
2517 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2521 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2526 switch (
N.getOpcode()) {
2529 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2532 AM.MCSym = ESNode->getMCSymbol();
2539 if (!foldOffsetIntoAddress(Val, AM))
2546 if (!matchWrapper(
N, AM))
2556 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2557 AM.Base_Reg.
getNode() ==
nullptr &&
2559 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2566 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2570 unsigned Val = CN->getZExtValue();
2575 if (Val == 1 || Val == 2 || Val == 3) {
2577 AM.Scale = 1 << Val;
2578 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2586 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2590 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2591 "Unexpected value size!");
2603 uint64_t
Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2615 if (
N.getResNo() != 0)
break;
2620 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2621 AM.Base_Reg.
getNode() ==
nullptr &&
2622 AM.IndexReg.
getNode() ==
nullptr) {
2624 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2625 CN->getZExtValue() == 9) {
2626 AM.Scale = unsigned(CN->getZExtValue())-1;
2638 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2639 if (foldOffsetIntoAddress(Disp, AM))
2640 Reg =
N.getOperand(0);
2642 Reg =
N.getOperand(0);
2645 AM.IndexReg = AM.Base_Reg =
Reg;
2661 HandleSDNode Handle(
N);
2664 X86ISelAddressMode Backup = AM;
2665 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2666 N = Handle.getValue();
2670 N = Handle.getValue();
2672 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2687 RHS.getOperand(0).getValueType() == MVT::i32))
2691 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2693 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2697 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2698 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2711 AM.NegateIndex =
true;
2719 if (!CurDAG->isADDLike(
N))
2723 if (!matchAdd(
N, AM,
Depth))
2732 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2736 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2737 "Unexpected value size!");
2742 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2746 uint64_t
Mask =
N.getConstantOperandVal(1);
2771 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2779 if (
SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2781 AM.IndexReg =
Index;
2787 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2789 Mask = MaskC->getAPIntValue();
2790 Src = Src.getOperand(0);
2793 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2795 SDValue ShlSrc = Src.getOperand(0);
2796 SDValue ShlAmt = Src.getOperand(1);
2800 unsigned ShAmtV = ShAmtC->getZExtValue();
2808 if (!Src->getFlags().hasNoUnsignedWrap() &&
2809 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2817 MVT VT =
N.getSimpleValueType();
2821 if (!
Mask.isAllOnes()) {
2822 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2824 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2831 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2832 CurDAG->RemoveDeadNode(
N.getNode());
2835 AM.Scale = 1 << ShAmtV;
2839 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2843 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2846 Src.getOperand(0), AM))
2851 Src.getOperand(0), AM))
2856 Src.getOperand(0), AM, *Subtarget))
2864 return matchAddressBase(
N, AM);
2869bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2871 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
2884 AM.BaseType = X86ISelAddressMode::RegBase;
2889bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2890 X86ISelAddressMode &AM,
2893 dbgs() <<
"MatchVectorAddress: ";
2898 return matchAddressBase(
N, AM);
2901 switch (
N.getOpcode()) {
2904 if (!foldOffsetIntoAddress(Val, AM))
2909 if (!matchWrapper(
N, AM))
2915 HandleSDNode Handle(
N);
2917 X86ISelAddressMode Backup = AM;
2918 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2919 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2925 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2927 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2932 N = Handle.getValue();
2937 return matchAddressBase(
N, AM);
2943bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2944 return matchVectorAddressRecursively(
N, AM, 0);
2947bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
2952 X86ISelAddressMode AM;
2958 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2960 AM.IndexReg = IndexOp;
2964 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
2966 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
2968 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
2971 MVT VT =
BasePtr.getSimpleValueType();
2974 if (matchVectorAddress(BasePtr, AM))
2977 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
2991 X86ISelAddressMode AM;
3003 unsigned AddrSpace =
3006 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3008 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3010 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3015 MVT VT =
N.getSimpleValueType();
3017 if (matchAddress(
N, AM))
3020 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3036 N =
N.getOperand(0);
3053 return CR->getUnsignedMax().ult(1ull << 32);
3055 return !TM.isLargeGlobalValue(GV);
3064 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3077 if (RN &&
RN->getReg() == 0)
3078 Base = CurDAG->getRegister(0, MVT::i64);
3088 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3090 if (RN &&
RN->getReg() == 0)
3091 Index = CurDAG->getRegister(0, MVT::i64);
3094 "Expect to be extending 8/16/32-bit registers for use in LEA");
3097 Index = CurDAG->getTargetInsertSubreg(
SubReg,
DL, MVT::i64, ImplDef, Index);
3105bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3109 X86ISelAddressMode AM;
3113 MVT VT =
N.getSimpleValueType();
3118 SDValue T = CurDAG->getRegister(0, MVT::i32);
3120 if (matchAddress(
N, AM))
3125 unsigned Complexity = 0;
3126 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3128 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3144 if (AM.hasSymbolicDisplacement()) {
3146 if (Subtarget->is64Bit())
3156 auto isMathWithFlags = [](
SDValue V) {
3157 switch (
V.getOpcode()) {
3171 return !
SDValue(
V.getNode(), 1).use_empty();
3178 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3186 if (Complexity <= 2)
3189 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3200 X86ISelAddressMode AM;
3202 AM.GV = GA->getGlobal();
3203 AM.Disp += GA->getOffset();
3204 AM.SymbolFlags = GA->getTargetFlags();
3207 AM.ES = SA->getSymbol();
3208 AM.SymbolFlags = SA->getTargetFlags();
3211 if (Subtarget->is32Bit()) {
3213 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3216 MVT VT =
N.getSimpleValueType();
3217 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3225 EVT VT =
N.getValueType();
3226 bool WasTruncated =
false;
3228 WasTruncated =
true;
3229 N =
N.getOperand(0);
3238 unsigned Opc =
N.getOperand(0)->getOpcode();
3240 Op =
N.getOperand(0);
3243 return !WasTruncated;
3248 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3249 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3253 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3254 GA->getOffset(), GA->getTargetFlags());
3258bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
3262 assert(Root &&
P &&
"Unknown root/parent nodes");
3264 !IsProfitableToFold(
N,
P, Root) ||
3265 !IsLegalToFold(
N,
P, Root, OptLevel))
3268 return selectAddr(
N.getNode(),
3269 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3272bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
3276 assert(Root &&
P &&
"Unknown root/parent nodes");
3278 !IsProfitableToFold(
N,
P, Root) ||
3279 !IsLegalToFold(
N,
P, Root, OptLevel))
3282 return selectAddr(
N.getNode(),
3283 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3289SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3292 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3295bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3297 N =
N->getOperand(0).getNode();
3305 auto *GV = GA->getGlobal();
3308 return CR->getSignedMin().sge(-1ull << Width) &&
3309 CR->getSignedMax().slt(1ull << Width);
3314 return Width == 32 && !TM.isLargeGlobalValue(GV);
3318 assert(
N->isMachineOpcode() &&
"Unexpected node");
3319 unsigned Opc =
N->getMachineOpcode();
3320 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3325 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3330bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3332 for (SDUse &Use :
Flags->uses()) {
3334 if (
Use.getResNo() !=
Flags.getResNo())
3342 for (SDUse &FlagUse :
User->uses()) {
3344 if (FlagUse.getResNo() != 1)
3347 if (!FlagUse.getUser()->isMachineOpcode())
3367bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3369 for (SDUse &Use :
Flags->uses()) {
3371 if (
Use.getResNo() !=
Flags.getResNo())
3379 for (SDUse &FlagUse :
User->uses()) {
3381 if (FlagUse.getResNo() != 1)
3384 if (!FlagUse.getUser()->isMachineOpcode())
3424 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3426 for (SDUse &Use :
Flags->uses()) {
3428 if (
Use.getResNo() !=
Flags.getResNo())
3432 unsigned UserOpc =
User->getOpcode();
3439 for (SDUse &FlagUse :
User->uses()) {
3441 if (FlagUse.getResNo() != 1)
3444 if (!FlagUse.getUser()->isMachineOpcode())
3485 if (StoredVal.
getResNo() != 0)
return false;
3502 if (!Load.hasOneUse())
3510 bool FoundLoad =
false;
3514 const unsigned int Max = 1024;
3556 if (Chain == Load.getValue(1)) {
3562 if (
Op == Load.getValue(1)) {
3578 if (
Op.getNode() != LoadNode)
3610bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3612 SDValue StoredVal = StoreNode->getOperand(1);
3618 EVT MemVT = StoreNode->getMemoryVT();
3619 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3623 bool IsCommutable =
false;
3624 bool IsNegate =
false;
3638 IsCommutable =
true;
3642 unsigned LoadOpNo = IsNegate ? 1 : 0;
3643 LoadSDNode *LoadNode =
nullptr;
3646 LoadNode, InputChain)) {
3653 LoadNode, InputChain))
3658 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3662 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3683 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3686 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3693 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
3697 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3700 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
3701 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
3703 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3714 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
3717 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
3720 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
3723 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
3726 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
3729 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
3732 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
3734 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
3740 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
3743 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
3746 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
3749 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
3752 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
3755 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
3758 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
3761 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
3768 unsigned NewOpc = SelectRegOpcode(
Opc);
3774 int64_t OperandV = OperandC->getSExtValue();
3781 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
3783 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3784 OperandV = -OperandV;
3788 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
3789 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
3790 NewOpc = SelectImmOpcode(
Opc);
3796 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
3800 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
3801 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3805 Segment, Operand, InputChain};
3806 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3815 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
3817 CurDAG->setNodeMemRefs(Result, MemOps);
3823 CurDAG->RemoveDeadNode(Node);
3834bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
3838 "Should be either an and-mask, or right-shift after clearing high bits.");
3841 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
3844 MVT NVT =
Node->getSimpleValueType(0);
3847 if (NVT != MVT::i32 && NVT != MVT::i64)
3855 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
3856 auto checkUses = [AllowExtraUsesByDefault](
3858 std::optional<bool> AllowExtraUses) {
3859 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
3860 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
3862 auto checkOneUse = [checkUses](
SDValue Op,
3863 std::optional<bool> AllowExtraUses =
3865 return checkUses(
Op, 1, AllowExtraUses);
3867 auto checkTwoUse = [checkUses](
SDValue Op,
3868 std::optional<bool> AllowExtraUses =
3870 return checkUses(
Op, 2, AllowExtraUses);
3873 auto peekThroughOneUseTruncation = [checkOneUse](
SDValue V) {
3875 assert(
V.getSimpleValueType() == MVT::i32 &&
3876 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
3877 "Expected i64 -> i32 truncation");
3878 V =
V.getOperand(0);
3884 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
3887 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
3893 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3898 NBits =
M0->getOperand(1);
3899 NegateNBits =
false;
3903 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](
SDValue V) {
3904 V = peekThroughOneUseTruncation(V);
3905 return CurDAG->MaskedValueIsAllOnes(
3911 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
3914 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
3917 if (!isAllOnes(
Mask->getOperand(1)))
3920 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3924 if (!isAllOnes(
M0->getOperand(0)))
3926 NBits =
M0->getOperand(1);
3927 NegateNBits =
false;
3933 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](
SDValue ShiftAmt,
3934 unsigned Bitwidth) {
3939 NBits = NBits.getOperand(0);
3945 if (!V0 || V0->getZExtValue() != Bitwidth)
3947 NBits = NBits.getOperand(1);
3948 NegateNBits =
false;
3954 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
3957 Mask = peekThroughOneUseTruncation(Mask);
3958 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
3960 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
3967 if (!checkOneUse(
M1))
3969 canonicalizeShiftAmt(
M1, Bitwidth);
3974 return !NegateNBits;
3982 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
3983 AllowExtraUsesByDefault, &NegateNBits,
3984 &
X](SDNode *
Node) ->
bool {
3996 canonicalizeShiftAmt(N1, Bitwidth);
4000 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
4001 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4007 auto matchLowBitMask = [matchPatternA, matchPatternB,
4009 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4013 X =
Node->getOperand(0);
4016 if (matchLowBitMask(Mask)) {
4020 if (!matchLowBitMask(Mask))
4023 }
else if (matchLowBitMask(
SDValue(Node, 0))) {
4024 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4025 }
else if (!matchPatternD(Node))
4030 if (NegateNBits && !Subtarget->hasBMI2())
4042 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4045 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4047 NBits =
SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4048 MVT::i32, ImplDef, NBits, SRIdxVal),
4058 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4062 if (Subtarget->hasBMI2()) {
4064 if (NVT != MVT::i32) {
4071 ReplaceNode(Node, Extract.
getNode());
4072 SelectCode(Extract.
getNode());
4081 SDValue RealX = peekThroughOneUseTruncation(
X);
4087 MVT XVT =
X.getSimpleValueType();
4097 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4105 SDValue ShiftAmt =
X.getOperand(1);
4106 X =
X.getOperand(0);
4109 "Expected shift amount to be i8");
4113 SDValue OrigShiftAmt = ShiftAmt;
4118 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4123 if (XVT != MVT::i32) {
4137 ReplaceNode(Node, Extract.
getNode());
4138 SelectCode(Extract.
getNode());
4144MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4145 MVT NVT =
Node->getSimpleValueType(0);
4158 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4159 if (!PreferBEXTR && !Subtarget->hasBMI2())
4171 if (NVT != MVT::i32 && NVT != MVT::i64)
4177 if (!MaskCst || !ShiftCst)
4181 uint64_t
Mask = MaskCst->getZExtValue();
4185 uint64_t Shift = ShiftCst->getZExtValue();
4190 if (Shift == 8 && MaskSize == 8)
4201 if (!PreferBEXTR && MaskSize <= 32)
4205 unsigned ROpc, MOpc;
4207#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4209 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4213 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4218 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4219 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4225 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4226 if (Subtarget->hasTBM()) {
4227 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4228 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4230 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4236 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4237 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4241 MachineSDNode *NewNode;
4243 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4244 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4246 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4247 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4248 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4252 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4254 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4259 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4263 CurDAG->getMachineNode(NewOpc, dl, NVT,
SDValue(NewNode, 0), ShAmt);
4270MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4271 bool MayFoldLoad,
const SDLoc &dl,
4272 MVT VT, SDNode *Node) {
4277 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4280 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4281 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4284 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4285 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4294 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4295 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4302MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4303 bool MayFoldLoad,
const SDLoc &dl,
4304 MVT VT, SDNode *Node,
4310 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4313 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4314 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4317 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4318 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4328 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4329 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4334bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4335 EVT VT =
N->getValueType(0);
4342 unsigned Size = VT == MVT::i64 ? 64 : 32;
4345 SDValue ShiftAmt = OrigShiftAmt;
4364 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4368 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4369 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4373 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4382 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4383 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4389 Add0C->getZExtValue() != 0) {
4392 if (Add0C->getZExtValue() %
Size == 0)
4395 Add0C->getZExtValue() % 32 == 0) {
4403 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4407 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4429 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4436 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4437 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4441 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4443 if (UpdatedNode !=
N) {
4446 ReplaceNode(
N, UpdatedNode);
4453 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4461bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4462 MVT NVT =
N->getSimpleValueType(0);
4463 unsigned Opcode =
N->getOpcode();
4475 int64_t Val = Cst->getSExtValue();
4480 bool FoundAnyExtend =
false;
4484 FoundAnyExtend =
true;
4492 if (NVT != MVT::i32 && NVT != MVT::i64)
4499 uint64_t ShAmt = ShlCst->getZExtValue();
4503 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4504 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4509 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4513 ShiftedVal = (uint64_t)Val >> ShAmt;
4517 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4520 ShiftedVal = Val >> ShAmt;
4526 ShiftedVal = (uint64_t)Val >> ShAmt;
4534 if (!CanShrinkImmediate(ShiftedVal))
4544 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4550 NeededMask &= ~Cst->getAPIntValue();
4552 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4557 if (FoundAnyExtend) {
4563 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4565 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4574bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4575 SDNode *ParentB, SDNode *ParentC,
4578 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4579 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4581 auto tryFoldLoadOrBCast =
4584 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4588 if (
L.getOpcode() == ISD::BITCAST &&
L.hasOneUse()) {
4590 L =
L.getOperand(0);
4598 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4602 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4605 bool FoldedLoad =
false;
4606 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4607 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4609 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4614 uint8_t OldImm =
Imm;
4615 Imm = OldImm & 0xa5;
4616 if (OldImm & 0x02)
Imm |= 0x10;
4617 if (OldImm & 0x10)
Imm |= 0x02;
4618 if (OldImm & 0x08)
Imm |= 0x40;
4619 if (OldImm & 0x40)
Imm |= 0x08;
4620 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4625 uint8_t OldImm =
Imm;
4626 Imm = OldImm & 0x99;
4627 if (OldImm & 0x02)
Imm |= 0x04;
4628 if (OldImm & 0x04)
Imm |= 0x02;
4629 if (OldImm & 0x20)
Imm |= 0x40;
4630 if (OldImm & 0x40)
Imm |= 0x20;
4635 SDValue TImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
4639 MachineSDNode *MNode;
4641 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4646 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4647 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4649 bool UseD = EltSize == 32;
4651 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4653 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4655 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4661 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4663 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4665 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4671 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
4674 ReplaceUses(
C.getValue(1),
SDValue(MNode, 1));
4681 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
4683 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
4685 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
4689 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
4693 CurDAG->RemoveDeadNode(Root);
4699bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
4700 MVT NVT =
N->getSimpleValueType(0);
4703 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
4711 auto getFoldableLogicOp = [](
SDValue Op) {
4713 if (
Op.getOpcode() == ISD::BITCAST &&
Op.hasOneUse())
4714 Op =
Op.getOperand(0);
4716 if (!
Op.hasOneUse())
4719 unsigned Opc =
Op.getOpcode();
4730 auto tryPeelOuterNotWrappingLogic = [&](SDNode *
Op) {
4733 SDValue InnerOp = getFoldableLogicOp(
Op->getOperand(0));
4740 if ((FoldableOp = getFoldableLogicOp(N1))) {
4744 if ((FoldableOp = getFoldableLogicOp(N0))) {
4752 bool PeeledOuterNot =
false;
4754 if (
SDValue InnerOp = tryPeelOuterNotWrappingLogic(
N)) {
4755 PeeledOuterNot =
true;
4761 if ((FoldableOp = getFoldableLogicOp(N1)))
4763 else if ((FoldableOp = getFoldableLogicOp(N0)))
4771 SDNode *ParentA =
N;
4772 SDNode *ParentB = FoldableOp.
getNode();
4773 SDNode *ParentC = FoldableOp.
getNode();
4777 uint8_t TernlogMagicA = 0xf0;
4778 uint8_t TernlogMagicB = 0xcc;
4779 uint8_t TernlogMagicC = 0xaa;
4784 auto PeekThroughNot = [](
SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
4788 Parent =
Op.getNode();
4789 Op =
Op.getOperand(0);
4793 PeekThroughNot(
A, ParentA, TernlogMagicA);
4794 PeekThroughNot(
B, ParentB, TernlogMagicB);
4795 PeekThroughNot(
C, ParentC, TernlogMagicC);
4800 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
4801 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
4802 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
4806 switch (
N->getOpcode()) {
4810 Imm &= ~TernlogMagicA;
4812 Imm = ~(
Imm) & TernlogMagicA;
4822 return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC,
A,
B,
C, Imm);
4832bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
4835 MVT VT =
And->getSimpleValueType(0);
4836 if (VT != MVT::i32 && VT != MVT::i64)
4848 APInt MaskVal = And1C->getAPIntValue();
4850 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
4854 if (VT == MVT::i64 && MaskLZ >= 32) {
4856 MaskVal = MaskVal.
trunc(32);
4861 APInt NegMaskVal = MaskVal | HighZeros;
4870 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
4871 NegMaskVal = NegMaskVal.
zext(64);
4872 HighZeros = HighZeros.
zext(64);
4878 KnownBits Known0 = CurDAG->computeKnownBits(And0);
4890 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
4899 bool FoldedBCast,
bool Masked) {
4900#define VPTESTM_CASE(VT, SUFFIX) \
4903 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
4904 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
4907#define VPTESTM_BROADCAST_CASES(SUFFIX) \
4908default: llvm_unreachable("Unexpected VT!"); \
4909VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
4910VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
4911VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
4912VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
4913VPTESTM_CASE(v16i32, DZ##SUFFIX) \
4914VPTESTM_CASE(v8i64, QZ##SUFFIX)
4916#define VPTESTM_FULL_CASES(SUFFIX) \
4917VPTESTM_BROADCAST_CASES(SUFFIX) \
4918VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
4919VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
4920VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
4921VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
4922VPTESTM_CASE(v64i8, BZ##SUFFIX) \
4923VPTESTM_CASE(v32i16, WZ##SUFFIX)
4941#undef VPTESTM_FULL_CASES
4942#undef VPTESTM_BROADCAST_CASES
4948bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root,
SDValue Setcc,
4950 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
4995 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P,
SDValue &
L,
5000 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
5005 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
5009 if (
L.getOpcode() == ISD::BITCAST &&
L.hasOneUse()) {
5011 L =
L.getOperand(0);
5018 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5021 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5025 bool CanFoldLoads = Src0 != Src1;
5027 bool FoldedLoad =
false;
5028 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5030 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5034 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5043 bool IsMasked = InMask.
getNode() !=
nullptr;
5056 SDValue ImplDef =
SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5058 Src0 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src0);
5061 Src1 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src1);
5066 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5067 InMask =
SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5068 dl, MaskVT, InMask, RC), 0);
5076 MachineSDNode *CNode;
5078 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5081 SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5083 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5085 SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5087 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5093 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5096 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5098 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5104 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5105 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5106 dl, ResVT,
SDValue(CNode, 0), RC);
5110 CurDAG->RemoveDeadNode(Root);
5116bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5119 MVT NVT =
N->getSimpleValueType(0);
5122 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5156 SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5164void X86DAGToDAGISel::Select(SDNode *Node) {
5165 MVT NVT =
Node->getSimpleValueType(0);
5166 unsigned Opcode =
Node->getOpcode();
5169 if (
Node->isMachineOpcode()) {
5171 Node->setNodeId(-1);
5178 unsigned IntNo =
Node->getConstantOperandVal(1);
5181 case Intrinsic::x86_encodekey128:
5182 case Intrinsic::x86_encodekey256: {
5183 if (!Subtarget->hasKL())
5189 case Intrinsic::x86_encodekey128:
5190 Opcode = X86::ENCODEKEY128;
5192 case Intrinsic::x86_encodekey256:
5193 Opcode = X86::ENCODEKEY256;
5198 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5200 if (Opcode == X86::ENCODEKEY256)
5201 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5204 MachineSDNode *Res = CurDAG->getMachineNode(
5205 Opcode, dl,
Node->getVTList(),
5206 {Node->getOperand(2), Chain, Chain.getValue(1)});
5207 ReplaceNode(Node, Res);
5210 case Intrinsic::x86_tileloaddrs64_internal:
5211 case Intrinsic::x86_tileloaddrst164_internal:
5212 if (!Subtarget->hasAMXMOVRS())
5215 case Intrinsic::x86_tileloadd64_internal:
5216 case Intrinsic::x86_tileloaddt164_internal: {
5217 if (!Subtarget->hasAMXTILE())
5220 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5221 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5226 case Intrinsic::x86_tileloaddrs64_internal:
5227 Opc = X86::PTILELOADDRSV;
5229 case Intrinsic::x86_tileloaddrst164_internal:
5230 Opc = X86::PTILELOADDRST1V;
5232 case Intrinsic::x86_tileloadd64_internal:
5233 Opc = X86::PTILELOADDV;
5235 case Intrinsic::x86_tileloaddt164_internal:
5236 Opc = X86::PTILELOADDT1V;
5241 SDValue Scale = getI8Imm(1, dl);
5243 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5244 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5246 MachineSDNode *CNode;
5248 Node->getOperand(3),
5255 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5256 ReplaceNode(Node, CNode);
5263 unsigned IntNo =
Node->getConstantOperandVal(1);
5266 case Intrinsic::x86_sse3_monitor:
5267 case Intrinsic::x86_monitorx:
5268 case Intrinsic::x86_clzero: {
5269 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5274 case Intrinsic::x86_sse3_monitor:
5275 if (!Subtarget->hasSSE3())
5277 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5279 case Intrinsic::x86_monitorx:
5280 if (!Subtarget->hasMWAITX())
5282 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5284 case Intrinsic::x86_clzero:
5285 if (!Subtarget->hasCLZERO())
5287 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5292 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5293 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5297 if (IntNo == Intrinsic::x86_sse3_monitor ||
5298 IntNo == Intrinsic::x86_monitorx) {
5300 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5303 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5308 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5310 ReplaceNode(Node, CNode);
5316 case Intrinsic::x86_tilestored64_internal: {
5318 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5319 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5320 unsigned Opc = X86::PTILESTOREDV;
5323 SDValue Scale = getI8Imm(1, dl);
5325 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5326 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5328 MachineSDNode *CNode;
5330 Node->getOperand(3),
5336 Node->getOperand(6),
5338 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5339 ReplaceNode(Node, CNode);
5342 case Intrinsic::x86_tileloaddrs64:
5343 case Intrinsic::x86_tileloaddrst164:
5344 if (!Subtarget->hasAMXMOVRS())
5347 case Intrinsic::x86_tileloadd64:
5348 case Intrinsic::x86_tileloaddt164:
5349 case Intrinsic::x86_tilestored64: {
5350 if (!Subtarget->hasAMXTILE())
5353 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5354 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5358 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5359 case Intrinsic::x86_tileloaddrs64:
5360 Opc = X86::PTILELOADDRS;
5362 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5363 case Intrinsic::x86_tileloaddrst164:
5364 Opc = X86::PTILELOADDRST1;
5366 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5369 unsigned TIndex =
Node->getConstantOperandVal(2);
5372 SDValue Scale = getI8Imm(1, dl);
5374 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5375 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5377 MachineSDNode *CNode;
5378 if (
Opc == X86::PTILESTORED) {
5380 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5383 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5385 ReplaceNode(Node, CNode);
5393 if (Subtarget->isTarget64BitILP32()) {
5398 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5399 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5400 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5401 Node->getOperand(0), ZextTarget);
5402 ReplaceNode(Node, Brind.
getNode());
5403 SelectCode(ZextTarget.
getNode());
5410 ReplaceNode(Node, getGlobalBaseReg());
5417 ReplaceUses(
SDValue(Node, 0),
Node->getOperand(0));
5418 CurDAG->RemoveDeadNode(Node);
5424 if (matchBitExtract(Node))
5429 if (tryShiftAmountMod(Node))
5434 uint8_t
Imm =
Node->getConstantOperandVal(3);
5435 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5436 Node->getOperand(1),
Node->getOperand(2), Imm))
5442 if (tryVPTERNLOG(Node))
5452 tryVPTESTM(Node, N0, N1))
5455 tryVPTESTM(Node, N1, N0))
5459 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5461 CurDAG->RemoveDeadNode(Node);
5464 if (matchBitExtract(Node))
5472 if (tryShrinkShlLogicImm(Node))
5474 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5476 if (tryVPTERNLOG(Node))
5481 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5491 if (!CurDAG->shouldOptForSize())
5495 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5505 int64_t Val = Cst->getSExtValue();
5513 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5517 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5521 unsigned ROpc, MOpc;
5630 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5631 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5633 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5634 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5640 CurDAG->RemoveDeadNode(Node);
5645 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
5658 unsigned LoReg, ROpc, MOpc;
5663 ROpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
5664 MOpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
5683 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5684 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5687 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5692 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5695 MachineSDNode *CNode;
5701 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5703 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
5707 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5718 VTs = CurDAG->getVTList(NVT, MVT::i32);
5720 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
5722 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
5726 ReplaceUses(
SDValue(Node, 1),
SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
5727 CurDAG->RemoveDeadNode(Node);
5737 unsigned LoReg, HiReg;
5739 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
5740 bool UseMULXHi = UseMULX &&
SDValue(Node, 0).use_empty();
5744 Opc = UseMULXHi ? X86::MULX32Hrr
5746 : IsSigned ?
X86::IMUL32r
5748 MOpc = UseMULXHi ? X86::MULX32Hrm
5750 : IsSigned ?
X86::IMUL32m
5752 LoReg = UseMULX ? X86::EDX : X86::EAX;
5756 Opc = UseMULXHi ? X86::MULX64Hrr
5758 : IsSigned ?
X86::IMUL64r
5760 MOpc = UseMULXHi ? X86::MULX64Hrm
5762 : IsSigned ?
X86::IMUL64m
5764 LoReg = UseMULX ? X86::RDX : X86::RAX;
5769 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5770 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5773 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5778 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5783 MachineSDNode *CNode =
nullptr;
5787 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5788 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5791 }
else if (UseMULX) {
5792 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
5793 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5798 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5799 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5805 ReplaceUses(N1.
getValue(1), Chain);
5811 SDVTList VTs = CurDAG->getVTList(NVT);
5812 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5814 }
else if (UseMULX) {
5815 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
5816 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5820 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
5821 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5827 if (!
SDValue(Node, 0).use_empty()) {
5829 assert(LoReg &&
"Register for low half is not defined!");
5830 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
5834 ReplaceUses(
SDValue(Node, 0), ResLo);
5839 if (!
SDValue(Node, 1).use_empty()) {
5841 assert(HiReg &&
"Register for high half is not defined!");
5842 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
5846 ReplaceUses(
SDValue(Node, 1), ResHi);
5851 CurDAG->RemoveDeadNode(Node);
5860 unsigned ROpc, MOpc;
5865 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
5866 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
5867 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
5868 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
5873 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
5874 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
5875 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
5876 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
5880 unsigned LoReg, HiReg, ClrReg;
5881 unsigned SExtOpcode;
5885 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
5889 LoReg = X86::AX; HiReg = X86::DX;
5891 SExtOpcode = X86::CWD;
5894 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
5895 SExtOpcode = X86::CDQ;
5898 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
5899 SExtOpcode = X86::CQO;
5903 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5904 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5905 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
5908 if (NVT == MVT::i8) {
5911 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
5912 MachineSDNode *Move;
5913 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5915 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rm8
5917 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
5919 ReplaceUses(N0.
getValue(1), Chain);
5923 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rr8
5925 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
5926 Chain = CurDAG->getEntryNode();
5928 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX,
SDValue(Move, 0),
5933 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
5934 LoReg, N0,
SDValue()).getValue(1);
5938 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
5941 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
5943 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
5947 SDValue(CurDAG->getMachineNode(
5948 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
5949 CurDAG->getTargetConstant(X86::sub_16bit, dl,
5957 SDValue(CurDAG->getMachineNode(
5958 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
5959 CurDAG->getTargetConstant(0, dl, MVT::i64), ClrNode,
5960 CurDAG->getTargetConstant(X86::sub_32bit, dl,
5968 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
5969 ClrNode, InGlue).getValue(1);
5976 MachineSDNode *CNode =
5977 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
5985 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
5995 if (HiReg == X86::AH && !
SDValue(Node, 1).use_empty()) {
5996 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
5997 unsigned AHExtOpcode =
5998 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6000 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6001 MVT::Glue, AHCopy, InGlue);
6006 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6008 ReplaceUses(
SDValue(Node, 1), Result);
6013 if (!
SDValue(Node, 0).use_empty()) {
6014 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6015 LoReg, NVT, InGlue);
6016 InGlue =
Result.getValue(2);
6017 ReplaceUses(
SDValue(Node, 0), Result);
6022 if (!
SDValue(Node, 1).use_empty()) {
6023 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6024 HiReg, NVT, InGlue);
6025 InGlue =
Result.getValue(2);
6026 ReplaceUses(
SDValue(Node, 1), Result);
6030 CurDAG->RemoveDeadNode(Node);
6039 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6040 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6046 if (Subtarget->canUseCMOV())
6055 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6058 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6061 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6066 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6069 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6070 Chain =
SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6073 Glue =
SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6078 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6082 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6086 assert(Subtarget->canUseLAHFSAHF() &&
6087 "Target doesn't support SAHF or FCOMI?");
6088 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract,
SDValue());
6091 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6094 ReplaceUses(
SDValue(Node, 1), Chain);
6096 ReplaceUses(
SDValue(Node, 0), SAHF);
6097 CurDAG->RemoveDeadNode(Node);
6117 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6118 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6121 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6123 CurDAG->RemoveDeadNode(Node);
6143 uint64_t
Mask = MaskC->getZExtValue();
6150 onlyUsesZeroFlag(
SDValue(Node, 0))) {
6155 unsigned TestOpcode;
6163 if (LeadingZeros == 0 && SavesBytes) {
6168 ShiftAmt = TrailingZeros;
6170 TestOpcode = X86::TEST64rr;
6171 }
else if (TrailingZeros == 0 && SavesBytes) {
6176 ShiftAmt = LeadingZeros;
6178 TestOpcode = X86::TEST64rr;
6179 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6182 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6183 if (PopCount == 8) {
6185 ShiftAmt = TrailingZeros;
6186 SubRegIdx = X86::sub_8bit;
6188 TestOpcode = X86::TEST8rr;
6189 }
else if (PopCount == 16) {
6191 ShiftAmt = TrailingZeros;
6192 SubRegIdx = X86::sub_16bit;
6193 SubRegVT = MVT::i16;
6194 TestOpcode = X86::TEST16rr;
6195 }
else if (PopCount == 32) {
6197 ShiftAmt = TrailingZeros;
6198 SubRegIdx = X86::sub_32bit;
6199 SubRegVT = MVT::i32;
6200 TestOpcode = X86::TEST32rr;
6204 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6206 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6209 if (SubRegIdx != 0) {
6211 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6213 MachineSDNode *
Test =
6214 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6215 ReplaceNode(Node,
Test);
6222 unsigned ROpc, MOpc;
6230 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6231 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6234 SubRegOp = X86::sub_8bit;
6235 ROpc = X86::TEST8ri;
6236 MOpc = X86::TEST8mi;
6237 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6238 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6239 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6245 SubRegOp = X86::sub_16bit;
6246 ROpc = X86::TEST16ri;
6247 MOpc = X86::TEST16mi;
6249 ((!(Mask & 0x80000000) &&
6252 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6253 CmpVT == MVT::i32 ||
6254 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6261 SubRegOp = X86::sub_32bit;
6262 ROpc = X86::TEST32ri;
6263 MOpc = X86::TEST32mi;
6269 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6273 MachineSDNode *NewNode;
6274 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6275 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6277 if (!LoadN->isSimple()) {
6278 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6279 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6280 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6281 (MOpc == X86::TEST32mi && NumVolBits != 32))
6286 Reg.getOperand(0) };
6287 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6289 ReplaceUses(
Reg.getValue(1),
SDValue(NewNode, 1));
6291 CurDAG->setNodeMemRefs(NewNode,
6296 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6298 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg, Imm);
6301 ReplaceNode(Node, NewNode);
6307 if (!Subtarget->hasSSE42())
6310 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6311 bool NeedMask = !
SDValue(Node, 1).use_empty();
6313 bool MayFoldLoad = !NeedIndex || !NeedMask;
6315 MachineSDNode *CNode;
6318 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6320 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6321 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6324 if (NeedIndex || !NeedMask) {
6326 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6328 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6329 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6335 CurDAG->RemoveDeadNode(Node);
6339 if (!Subtarget->hasSSE42())
6343 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6344 Node->getOperand(1),
6346 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6347 Node->getOperand(3), InGlue).getValue(1);
6349 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6350 bool NeedMask = !
SDValue(Node, 1).use_empty();
6352 bool MayFoldLoad = !NeedIndex || !NeedMask;
6354 MachineSDNode *CNode;
6357 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6359 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6361 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6364 if (NeedIndex || !NeedMask) {
6366 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6368 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6369 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6374 CurDAG->RemoveDeadNode(Node);
6386 if (foldLoadStoreIntoMemOperand(Node))
6391 MVT VT =
Node->getSimpleValueType(0);
6393 if (Subtarget->hasSBBDepBreaking()) {
6398 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6403 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6404 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6406 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6411 Result = getSBBZero(Node);
6415 if (VT == MVT::i8 || VT == MVT::i16) {
6416 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6417 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6420 ReplaceUses(
SDValue(Node, 0), Result);
6421 CurDAG->RemoveDeadNode(Node);
6433 if (!
SDValue(Node, 0).use_empty()) {
6435 MVT VT =
Node->getSimpleValueType(0);
6436 if (VT == MVT::i8 || VT == MVT::i16) {
6437 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6438 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6440 ReplaceUses(
SDValue(Node, 0), Result);
6443 CurDAG->RemoveDeadNode(Node);
6450 SDValue IndexOp = Mgt->getIndex();
6453 MVT ValueVT =
Node->getSimpleValueType(0);
6454 MVT MaskVT =
Mask.getSimpleValueType();
6471 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6472 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6473 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6474 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6475 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6476 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6477 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6478 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6479 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6480 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6481 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6482 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6483 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6484 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6485 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6486 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6487 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6488 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6489 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6490 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6491 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6492 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6493 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6494 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6496 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6497 "Unexpected mask VT!");
6498 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6499 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6500 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6501 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6502 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6503 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6504 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6505 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6506 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6507 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6508 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6509 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6510 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6511 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6512 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6513 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6520 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6521 Base, Scale, Index, Disp, Segment))
6524 SDValue PassThru = Mgt->getPassThru();
6525 SDValue Chain = Mgt->getChain();
6527 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6529 MachineSDNode *NewNode;
6532 Index, Disp, Segment, Chain};
6533 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6536 Disp, Segment,
Mask, Chain};
6537 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6539 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6542 CurDAG->RemoveDeadNode(Node);
6548 SDValue IndexOp = Sc->getIndex();
6550 MVT ValueVT =
Value.getSimpleValueType();
6565 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6566 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6567 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6568 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6569 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6570 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6571 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6572 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6573 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6574 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6575 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6576 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6577 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6578 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6579 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6580 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6581 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6582 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6583 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6584 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6585 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6586 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6587 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6588 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6593 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6594 Base, Scale, Index, Disp, Segment))
6598 SDValue Chain = Sc->getChain();
6600 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6603 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6604 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6606 CurDAG->RemoveDeadNode(Node);
6609 case ISD::PREALLOCATED_SETUP: {
6610 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6611 auto CallId = MFI->getPreallocatedIdForCallSite(
6614 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6615 MachineSDNode *
New = CurDAG->getMachineNode(
6616 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6618 CurDAG->RemoveDeadNode(Node);
6621 case ISD::PREALLOCATED_ARG: {
6622 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6626 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6629 Ops[0] = CallIdValue;
6632 MachineSDNode *
New = CurDAG->getMachineNode(
6633 TargetOpcode::PREALLOCATED_ARG, dl,
6634 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
6639 CurDAG->RemoveDeadNode(Node);
6646 if (!Subtarget->hasWIDEKL())
6650 switch (
Node->getOpcode()) {
6654 Opcode = X86::AESENCWIDE128KL;
6657 Opcode = X86::AESDECWIDE128KL;
6660 Opcode = X86::AESENCWIDE256KL;
6663 Opcode = X86::AESDECWIDE256KL;
6671 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
6674 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
6676 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
6678 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
6680 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
6682 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
6684 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
6686 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
6688 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
6691 MachineSDNode *Res = CurDAG->getMachineNode(
6692 Opcode, dl,
Node->getVTList(),
6693 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
6695 ReplaceNode(Node, Res);
6702 if (
Node->getNumValues() == 3)
6703 Glue =
Node->getOperand(2);
6705 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
6706 ReplaceNode(Node,
Copy.getNode());
6714bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
6716 std::vector<SDValue> &OutOps) {
6717 SDValue Op0, Op1, Op2, Op3, Op4;
6718 switch (ConstraintID) {
6721 case InlineAsm::ConstraintCode::o:
6722 case InlineAsm::ConstraintCode::v:
6723 case InlineAsm::ConstraintCode::m:
6724 case InlineAsm::ConstraintCode::X:
6725 case InlineAsm::ConstraintCode::p:
6726 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
6731 OutOps.push_back(Op0);
6732 OutOps.push_back(Op1);
6733 OutOps.push_back(Op2);
6734 OutOps.push_back(Op3);
6735 OutOps.push_back(Op4);
6741 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
6747 return new X86DAGToDAGISelLegacy(TM, OptLevel);
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
#define CASE(ATTRNAME, AANAME,...)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isSigned(unsigned int Opcode)
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static bool isFusableLoadOpStorePattern(StoreSDNode *StoreNode, SDValue StoredVal, SelectionDAG *CurDAG, LoadSDNode *&LoadNode, SDValue &InputChain)
static void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII)
Check if the instruction uses RIP relative addressing.
#define FROM_TO(FROM, TO)
#define GET_EGPR_IF_ENABLED(OPC)
static bool isLegalMaskCompare(SDNode *N, const X86Subtarget *Subtarget)
static bool foldMaskAndShiftToScale(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static bool foldMaskAndShiftToExtract(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static bool needBWI(MVT VT)
static unsigned getVPTESTMOpc(MVT TestVT, bool IsTestN, bool FoldedLoad, bool FoldedBCast, bool Masked)
static bool foldMaskedShiftToBEXTR(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM, const X86Subtarget &Subtarget)
static bool mayUseCarryFlag(X86::CondCode CC)
static cl::opt< bool > EnablePromoteAnyextLoad("x86-promote-anyext-load", cl::init(true), cl::desc("Enable promoting aligned anyext load to wider load"), cl::Hidden)
static void moveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load, SDValue Call, SDValue OrigChain)
Replace the original chain operand of the call with load's chain operand and move load below the call...
#define GET_ND_IF_ENABLED(OPC)
#define VPTESTM_BROADCAST_CASES(SUFFIX)
static cl::opt< bool > AndImmShrink("x86-and-imm-shrink", cl::init(true), cl::desc("Enable setting constant bits to reduce size of mask immediates"), cl::Hidden)
static bool foldMaskedShiftToScaledMask(SelectionDAG &DAG, SDValue N, X86ISelAddressMode &AM)
#define VPTESTM_FULL_CASES(SUFFIX)
static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq)
Return true if call address is a load and it can be moved below CALLSEQ_START and the chains leading ...
static bool isDispSafeForFrameIndexOrRegBase(int64_t Val)
static bool isEndbrImm64(uint64_t Imm)
cl::opt< bool > IndirectBranchTracking("x86-indirect-branch-tracking", cl::init(false), cl::Hidden, cl::desc("Enable X86 indirect branch tracking pass."))
#define GET_ND_IF_ENABLED(OPC)
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countl_zero() const
The APInt version of std::countl_zero.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
bool isOne() const
Determine if this is a value of 1.
unsigned countr_one() const
Count the number of trailing one bits.
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI std::optional< ConstantRange > getAbsoluteSymbolRange() const
If this is an absolute symbol reference, returns the range of the symbol, otherwise returns std::null...
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
bool is128BitVector() const
Return true if this is a 128-bit vector type.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool is512BitVector() const
Return true if this is a 512-bit vector type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MVT getHalfNumVectorElementsVT() const
Return a VT for a vector type with the same element type but half the number of elements.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
bool isNonTemporal() const
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
int getNodeId() const
Return the unique node id.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
SDNodeFlags getFlags() const
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
iterator_range< user_iterator > users()
op_iterator op_end() const
op_iterator op_begin() const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISelPass(std::unique_ptr< SelectionDAGISel > Selector)
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
static int getUninvalidatedNodeId(SDNode *N)
virtual bool runOnMachineFunction(MachineFunction &mf)
static void InvalidateNodeId(SDNode *N)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
void RepositionNode(allnodes_iterator Position, SDNode *N)
Move node N in the AllNodes list to be immediately before the given iterator Position.
ilist< SDNode >::iterator allnodes_iterator
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
unsigned getID() const
Return the register class ID number.
bool hasOneUse() const
Return true if there is exactly one use of this value.
X86ISelDAGToDAGPass(X86TargetMachine &TM)
size_t getPreallocatedIdForCallSite(const Value *CS)
bool isScalarFPTypeInSSEReg(EVT VT) const
Return true if the specified scalar FP type is computed in an SSE register, not on the X87 floating p...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ 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...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ LOCAL_RECOVER
LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ X86
Windows x64, Windows Itanium (IA-64)
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ FST
This instruction implements a truncating store from FP stack slots.
@ CMPM
Vector comparison generating mask bits for fp and integer signed and unsigned data types.
@ CMP
X86 compare and logical compare instructions.
@ BLENDV
Dynamic (non-constant condition) vector blend where only the sign bits of the condition elements are ...
@ STRICT_CMPM
Vector comparison generating mask bits for fp and integer signed and unsigned data types.
@ NT_BRIND
BRIND node with NoTrack prefix.
@ FSETCCM
X86 FP SETCC, similar to above, but with output as an i1 mask and and a version with SAE.
@ FXOR
Bitwise logical XOR of floating point values.
@ BRCOND
X86 conditional branches.
@ CALL
These operations represent an abstract X86 call instruction, which includes a bunch of information.
@ FANDN
Bitwise logical ANDNOT of floating point values.
@ GlobalBaseReg
On Darwin, this node represents the result of the popl at function entry, used for PIC code.
@ FLD
This instruction implements an extending load to FP stack slots.
@ TC_RETURN
Tail call return.
@ FOR
Bitwise logical OR of floating point values.
@ Wrapper
A wrapper node for TargetConstantPool, TargetJumpTable, TargetExternalSymbol, TargetGlobalAddress,...
@ ANDNP
Bitwise Logical AND NOT of Packed FP values.
@ POP_FROM_X87_REG
The same as ISD::CopyFromReg except that this node makes it explicit that it may lower to an x87 FPU ...
@ FAND
Bitwise logical AND of floating point values.
@ CMOV
X86 conditional moves.
@ WrapperRIP
Special wrapper used under X86-64 PIC mode for RIP relative displacements.
int getCondSrcNoFromDesc(const MCInstrDesc &MCID)
Return the source operand # for condition code by MCID.
bool mayFoldLoad(SDValue Op, const X86Subtarget &Subtarget, bool AssumeSingleUse=false)
Check if Op is a load operation that could be folded into some other x86 instruction as a memory oper...
bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M, bool hasSymbolicDisplacement)
Returns true of the given offset can be fit into displacement field of the instruction.
bool isConstantSplat(SDValue Op, APInt &SplatVal, bool AllowPartialUndefs)
If Op is a constant whose elements are all the same constant or undefined, return true and return the...
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isa_and_nonnull(const Y &Val)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
unsigned M1(unsigned Val)
auto dyn_cast_or_null(const Y &Val)
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
FunctionPass * createX86ISelDag(X86TargetMachine &TM, CodeGenOptLevel OptLevel)
This pass converts a legalized DAG into a X86-specific DAG, ready for instruction scheduling.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
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.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
bool isVector() const
Return true if this is a vector value type.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
bool isConstant() const
Returns true if we know the value of all bits.
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
bool hasNoUnsignedWrap() const