24 #include "llvm/Config/llvm-config.h" 40 #define DEBUG_TYPE "x86-isel" 42 STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
45 cl::desc(
"Enable setting constant bits to reduce size of mask immediates"),
55 struct X86ISelAddressMode {
76 unsigned char SymbolFlags;
79 : BaseType(RegBase), Base_FrameIndex(0), Scale(1), IndexReg(), Disp(0),
80 Segment(), GV(nullptr), CP(nullptr), BlockAddr(nullptr), ES(nullptr),
81 MCSym(nullptr), JT(-1), Align(0), SymbolFlags(X86II::
MO_NO_FLAG) {}
83 bool hasSymbolicDisplacement()
const {
84 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr ||
85 MCSym !=
nullptr || JT != -1 || BlockAddr !=
nullptr;
88 bool hasBaseOrIndexReg()
const {
89 return BaseType == FrameIndexBase ||
94 bool isRIPRelative()
const {
95 if (BaseType != RegBase)
return false;
97 dyn_cast_or_null<RegisterSDNode>(Base_Reg.
getNode()))
98 return RegNode->getReg() == X86::RIP;
107 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 109 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
110 dbgs() <<
"Base_Reg ";
115 if (BaseType == FrameIndexBase)
116 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
117 dbgs() <<
" Scale " << Scale <<
'\n' 123 dbgs() <<
" Disp " << Disp <<
'\n' 145 dbgs() <<
" JT" << JT <<
" Align" << Align <<
'\n';
169 bool IndirectTlsSegRefs;
174 OptForMinSize(
false) {}
177 return "X86 DAG->DAG Instruction Selection";
184 "indirect-tls-seg-refs");
189 void EmitFunctionEntryCode()
override;
193 void PreprocessISelDAG()
override;
194 void PostprocessISelDAG()
override;
197 #include "X86GenDAGISel.inc" 202 bool foldOffsetIntoAddress(uint64_t
Offset, X86ISelAddressMode &AM);
203 bool matchLoadInAddress(
LoadSDNode *
N, X86ISelAddressMode &AM);
204 bool matchWrapper(
SDValue N, X86ISelAddressMode &AM);
205 bool matchAddress(
SDValue N, X86ISelAddressMode &AM);
206 bool matchVectorAddress(
SDValue N, X86ISelAddressMode &AM);
207 bool matchAdd(
SDValue N, X86ISelAddressMode &AM,
unsigned Depth);
208 bool matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
210 bool matchAddressBase(
SDValue N, X86ISelAddressMode &AM);
244 return tryFoldLoad(P, P, N, Base, Scale, Index, Disp, Segment);
248 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
249 unsigned ConstraintID,
250 std::vector<SDValue> &OutOps)
override;
252 void emitSpecialCodeForMain();
254 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &DL,
258 Base = (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
259 ? CurDAG->getTargetFrameIndex(
261 TLI->getPointerTy(CurDAG->getDataLayout()))
263 Scale = getI8Imm(AM.Scale, DL);
268 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(),
272 Disp = CurDAG->getTargetConstantPool(AM.CP,
MVT::i32,
273 AM.Align, AM.Disp, AM.SymbolFlags);
275 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
276 Disp = CurDAG->getTargetExternalSymbol(AM.ES,
MVT::i32, AM.SymbolFlags);
277 }
else if (AM.MCSym) {
278 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
279 assert(AM.SymbolFlags == 0 &&
"oo");
280 Disp = CurDAG->getMCSymbol(AM.MCSym,
MVT::i32);
281 }
else if (AM.JT != -1) {
282 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
283 Disp = CurDAG->getTargetJumpTable(AM.JT,
MVT::i32, AM.SymbolFlags);
284 }
else if (AM.BlockAddr)
285 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr,
MVT::i32, AM.Disp,
288 Disp = CurDAG->getTargetConstant(AM.Disp, DL,
MVT::i32);
290 if (AM.Segment.getNode())
291 Segment = AM.Segment;
293 Segment = CurDAG->getRegister(0,
MVT::i32);
302 bool shouldAvoidImmediateInstFormsForSize(
SDNode *
N)
const {
313 UE = N->
use_end(); (UI != UE) && (UseCount < 2); ++UI) {
357 (RegNode = dyn_cast_or_null<RegisterSDNode>(
359 if ((RegNode->getReg() ==
X86::ESP) ||
360 (RegNode->getReg() == X86::RSP))
369 return (UseCount > 1);
373 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &DL) {
374 return CurDAG->getTargetConstant(Imm, DL,
MVT::i8);
378 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &DL) {
379 return CurDAG->getTargetConstant(Imm, DL,
MVT::i32);
383 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &DL) {
384 return CurDAG->getTargetConstant(Imm, DL,
MVT::i64);
387 SDValue getExtractVEXTRACTImmediate(
SDNode *N,
unsigned VecWidth,
389 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
395 SDValue getInsertVINSERTImmediate(
SDNode *N,
unsigned VecWidth,
397 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
406 SDNode *getGlobalBaseReg();
417 return Subtarget->getInstrInfo();
423 bool ComplexPatternFuncMutatesDAG()
const override {
427 bool isSExtAbsoluteSymbolRef(
unsigned Width,
SDNode *N)
const;
431 template <
unsigned W
idth>
bool isSExtRelocImm(
SDNode *N)
const {
432 if (
auto *CN = dyn_cast<ConstantSDNode>(N))
433 return isInt<Width>(CN->getSExtValue());
434 return isSExtAbsoluteSymbolRef(Width, N);
438 bool useNonTemporalLoad(
LoadSDNode *N)
const {
453 return Subtarget->hasSSE41();
455 return Subtarget->hasAVX2();
457 return Subtarget->hasAVX512();
461 bool foldLoadStoreIntoMemOperand(
SDNode *Node);
463 bool matchBitExtract(
SDNode *Node);
464 bool shrinkAndImmediate(
SDNode *N);
465 bool isMaskZeroExtended(
SDNode *N)
const;
466 bool tryShiftAmountMod(
SDNode *N);
474 bool tryOptimizeRem8Extend(
SDNode *N);
476 bool onlyUsesZeroFlag(
SDValue Flags)
const;
477 bool hasNoSignFlagUses(
SDValue Flags)
const;
478 bool hasNoCarryFlagUses(
SDValue Flags)
const;
494 return Subtarget->
hasVLX();
508 bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *N)
const {
530 if (useNonTemporalLoad(cast<LoadSDNode>(N)))
562 if (Imm->getAPIntValue().isSignedIntN(8))
571 Imm->getAPIntValue().getBitWidth() == 64 &&
572 Imm->getAPIntValue().isIntN(32))
610 if (
C &&
C->getSExtValue() == -2)
616 if (
C &&
C->getSExtValue() == -2)
658 "Unexpected chain operand");
710 if (isa<MemSDNode>(Chain.
getNode()) &&
711 cast<MemSDNode>(Chain.
getNode())->writeMem())
722 void X86DAGToDAGISel::PreprocessISelDAG() {
726 assert((!OptForMinSize || OptForSize) &&
"OptForMinSize implies OptForSize");
729 E = CurDAG->allnodes_end();
I !=
E; ) {
738 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(N, 0), Res);
740 CurDAG->DeleteNode(N);
747 !Subtarget->useRetpolineIndirectCalls() &&
750 (Subtarget->is64Bit() ||
751 !getTargetMachine().isPositionIndependent())))) {
805 if (SrcIsSSE && DstIsSSE)
808 if (!SrcIsSSE && !DstIsSSE) {
824 MemVT = SrcIsSSE ? SrcVT : DstVT;
826 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
831 CurDAG->getTruncStore(CurDAG->getEntryNode(), dl, N->
getOperand(0),
841 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(N, 0), Result);
846 CurDAG->DeleteNode(N);
851 bool X86DAGToDAGISel::tryOptimizeRem8Extend(
SDNode *N) {
853 if (Opc != X86::MOVZX32rr8 && Opc != X86::MOVSX32rr8 &&
854 Opc != X86::MOVSX64rr8)
866 unsigned ExpectedOpc = Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
867 : X86::MOVSX32rr8_NOREX;
872 if (Opc == X86::MOVSX64rr8) {
877 ReplaceUses(N, Extend);
886 void X86DAGToDAGISel::PostprocessISelDAG() {
893 bool MadeChange =
false;
894 while (Position != CurDAG->allnodes_begin()) {
900 if (tryOptimizeRem8Extend(N)) {
908 if ((Opc == X86::TEST8rr || Opc == X86::TEST16rr ||
909 Opc == X86::TEST32rr || Opc == X86::TEST64rr) &&
915 if (N0Opc == X86::AND8rr || N0Opc == X86::AND16rr ||
916 N0Opc == X86::AND32rr || N0Opc == X86::AND64rr) {
921 ReplaceUses(N, Test);
925 if (N0Opc == X86::AND8rm || N0Opc == X86::AND16rm ||
926 N0Opc == X86::AND32rm || N0Opc == X86::AND64rm) {
929 case X86::AND8rm: NewOpc = X86::TEST8mr;
break;
930 case X86::AND16rm: NewOpc = X86::TEST16mr;
break;
931 case X86::AND32rm: NewOpc = X86::TEST32mr;
break;
932 case X86::AND64rm: NewOpc = X86::TEST64mr;
break;
945 ReplaceUses(N, Test);
955 if ((Opc == X86::KORTESTBrr || Opc == X86::KORTESTWrr ||
956 Opc == X86::KORTESTDrr || Opc == X86::KORTESTQrr) &&
960 onlyUsesZeroFlag(
SDValue(N, 0))) {
965 if (N0Opc == X86::KANDBrr ||
966 (N0Opc == X86::KANDWrr && Subtarget->hasDQI()) ||
967 N0Opc == X86::KANDDrr || N0Opc == X86::KANDQrr) {
971 case X86::KORTESTBrr: NewOpc = X86::KTESTBrr;
break;
972 case X86::KORTESTWrr: NewOpc = X86::KTESTWrr;
break;
973 case X86::KORTESTDrr: NewOpc = X86::KTESTDrr;
break;
974 case X86::KORTESTQrr: NewOpc = X86::KTESTQrr;
break;
980 ReplaceUses(N, KTest);
987 if (Opc != TargetOpcode::SUBREG_TO_REG)
991 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1002 case X86::VMOVAPDrr:
case X86::VMOVUPDrr:
1003 case X86::VMOVAPSrr:
case X86::VMOVUPSrr:
1004 case X86::VMOVDQArr:
case X86::VMOVDQUrr:
1005 case X86::VMOVAPDYrr:
case X86::VMOVUPDYrr:
1006 case X86::VMOVAPSYrr:
case X86::VMOVUPSYrr:
1007 case X86::VMOVDQAYrr:
case X86::VMOVDQUYrr:
1008 case X86::VMOVAPDZ128rr:
case X86::VMOVUPDZ128rr:
1009 case X86::VMOVAPSZ128rr:
case X86::VMOVUPSZ128rr:
1010 case X86::VMOVDQA32Z128rr:
case X86::VMOVDQU32Z128rr:
1011 case X86::VMOVDQA64Z128rr:
case X86::VMOVDQU64Z128rr:
1012 case X86::VMOVAPDZ256rr:
case X86::VMOVUPDZ256rr:
1013 case X86::VMOVAPSZ256rr:
case X86::VMOVUPSZ256rr:
1014 case X86::VMOVDQA32Z256rr:
case X86::VMOVDQU32Z256rr:
1015 case X86::VMOVDQA64Z256rr:
case X86::VMOVDQU64Z256rr:
1029 (TSFlags & X86II::EncodingMask) !=
X86II::XOP)
1039 CurDAG->RemoveDeadNodes();
1044 void X86DAGToDAGISel::emitSpecialCodeForMain() {
1045 if (Subtarget->isTargetCygMing()) {
1047 auto &DL = CurDAG->getDataLayout();
1052 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(DL)),
1055 std::pair<SDValue, SDValue> Result = TLI.
LowerCallTo(CLI);
1056 CurDAG->setRoot(Result.second);
1060 void X86DAGToDAGISel::EmitFunctionEntryCode() {
1064 emitSpecialCodeForMain();
1074 return isInt<31>(Val);
1077 bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t
Offset,
1078 X86ISelAddressMode &AM) {
1084 if (AM.ES || AM.MCSym)
1087 int64_t Val = AM.Disp +
Offset;
1089 if (Subtarget->is64Bit()) {
1091 AM.hasSymbolicDisplacement()))
1095 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1104 bool X86DAGToDAGISel::matchLoadInAddress(
LoadSDNode *N, X86ISelAddressMode &AM){
1114 if (
C->getSExtValue() == 0 && AM.Segment.getNode() ==
nullptr &&
1115 !IndirectTlsSegRefs &&
1116 (Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() ||
1117 Subtarget->isTargetFuchsia()))
1120 AM.Segment = CurDAG->getRegister(X86::GS,
MVT::i16);
1123 AM.Segment = CurDAG->getRegister(X86::FS,
MVT::i16);
1135 bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1138 if (AM.hasSymbolicDisplacement())
1141 bool IsRIPRelTLS =
false;
1155 if (Subtarget->is64Bit() &&
1161 if (IsRIPRel && AM.hasBaseOrIndexReg())
1165 X86ISelAddressMode Backup = AM;
1170 AM.GV =
G->getGlobal();
1171 AM.SymbolFlags =
G->getTargetFlags();
1172 Offset =
G->getOffset();
1174 AM.CP = CP->getConstVal();
1175 AM.Align = CP->getAlignment();
1176 AM.SymbolFlags = CP->getTargetFlags();
1177 Offset = CP->getOffset();
1179 AM.ES = S->getSymbol();
1180 AM.SymbolFlags = S->getTargetFlags();
1181 }
else if (
auto *S = dyn_cast<MCSymbolSDNode>(N0)) {
1182 AM.MCSym = S->getMCSymbol();
1184 AM.JT = J->getIndex();
1185 AM.SymbolFlags = J->getTargetFlags();
1187 AM.BlockAddr = BA->getBlockAddress();
1188 AM.SymbolFlags = BA->getTargetFlags();
1189 Offset = BA->getOffset();
1193 if (foldOffsetIntoAddress(Offset, AM)) {
1199 AM.setBaseReg(CurDAG->getRegister(X86::RIP,
MVT::i64));
1207 bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
1208 if (matchAddressRecursively(N, AM, 0))
1213 if (AM.Scale == 2 &&
1214 AM.BaseType == X86ISelAddressMode::RegBase &&
1215 AM.Base_Reg.getNode() ==
nullptr) {
1216 AM.Base_Reg = AM.IndexReg;
1224 Subtarget->is64Bit() &&
1226 AM.BaseType == X86ISelAddressMode::RegBase &&
1227 AM.Base_Reg.getNode() ==
nullptr &&
1228 AM.IndexReg.getNode() ==
nullptr &&
1230 AM.hasSymbolicDisplacement())
1231 AM.Base_Reg = CurDAG->getRegister(X86::RIP,
MVT::i64);
1236 bool X86DAGToDAGISel::matchAdd(
SDValue N, X86ISelAddressMode &AM,
1242 X86ISelAddressMode Backup = AM;
1243 if (!matchAddressRecursively(N.
getOperand(0), AM, Depth+1) &&
1257 if (AM.BaseType == X86ISelAddressMode::RegBase &&
1258 !AM.Base_Reg.getNode() &&
1259 !AM.IndexReg.getNode()) {
1296 X86ISelAddressMode &AM) {
1303 if (ScaleLog <= 0 || ScaleLog >= 4 ||
1304 Mask != (0xffu << ScaleLog))
1329 AM.Scale = (1 << ScaleLog);
1339 X86ISelAddressMode &AM) {
1352 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
1371 AM.Scale = 1 << ShiftAmt;
1372 AM.IndexReg = NewAnd;
1406 X86ISelAddressMode &AM) {
1417 unsigned AMShiftAmt = MaskTZ;
1421 if (AMShiftAmt <= 0 || AMShiftAmt > 3)
return true;
1429 if (MaskLZ < ScaleDown)
1431 MaskLZ -= ScaleDown;
1439 bool ReplacingAnyExtend =
false;
1446 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
1447 ReplacingAnyExtend =
true;
1449 APInt MaskedHighBits =
1452 if (MaskedHighBits != Known.Zero)
return true;
1457 if (ReplacingAnyExtend) {
1481 AM.Scale = 1 << AMShiftAmt;
1482 AM.IndexReg = NewSRL;
1492 X86ISelAddressMode &AM,
1500 if (!Subtarget.
hasTBM() &&
1515 if (AMShiftAmt <= 0 || AMShiftAmt > 3)
return true;
1539 AM.Scale = 1 << AMShiftAmt;
1540 AM.IndexReg = NewAnd;
1544 bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
1548 dbgs() <<
"MatchAddress: ";
1553 return matchAddressBase(N, AM);
1558 if (AM.isRIPRelative()) {
1562 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
1566 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
1574 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
1575 if (
const auto *ESNode = dyn_cast<MCSymbolSDNode>(N.
getOperand(0))) {
1577 AM.MCSym = ESNode->getMCSymbol();
1583 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
1584 if (!foldOffsetIntoAddress(Val, AM))
1591 if (!matchWrapper(N, AM))
1596 if (!matchLoadInAddress(cast<LoadSDNode>(N), AM))
1601 if (AM.BaseType == X86ISelAddressMode::RegBase &&
1602 AM.Base_Reg.getNode() ==
nullptr &&
1604 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
1605 AM.Base_FrameIndex = cast<FrameIndexSDNode>(
N)->getIndex();
1611 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
1615 unsigned Val = CN->getZExtValue();
1620 if (Val == 1 || Val == 2 || Val == 3) {
1621 AM.Scale = 1 << Val;
1627 if (CurDAG->isBaseWithConstantOffset(ShVal)) {
1630 uint64_t Disp = (uint64_t)AddVal->
getSExtValue() << Val;
1631 if (!foldOffsetIntoAddress(Disp, AM))
1635 AM.IndexReg = ShVal;
1643 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
break;
1676 if (AM.BaseType == X86ISelAddressMode::RegBase &&
1677 AM.Base_Reg.getNode() ==
nullptr &&
1678 AM.IndexReg.getNode() ==
nullptr) {
1680 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
1681 CN->getZExtValue() == 9) {
1682 AM.Scale =
unsigned(CN->getZExtValue())-1;
1690 if (MulVal.getNode()->getOpcode() ==
ISD::ADD && MulVal.hasOneUse() &&
1691 isa<ConstantSDNode>(MulVal.getOperand(1))) {
1694 cast<ConstantSDNode>(MulVal.getOperand(1));
1695 uint64_t Disp = AddVal->
getSExtValue() * CN->getZExtValue();
1696 if (foldOffsetIntoAddress(Disp, AM))
1702 AM.IndexReg = AM.Base_Reg =
Reg;
1721 X86ISelAddressMode Backup = AM;
1722 if (matchAddressRecursively(N.
getOperand(0), AM, Depth+1)) {
1727 if (AM.IndexReg.getNode() || AM.isRIPRelative()) {
1747 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.getNode() &&
1749 !AM.Base_Reg.getNode()->hasOneUse()) ||
1750 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
1754 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
1755 ((AM.Disp != 0) && (Backup.Disp == 0)) +
1756 (AM.Segment.getNode() && !Backup.Segment.getNode()) >= 2)
1777 if (!matchAdd(N, AM, Depth))
1789 !matchAdd(N, AM, Depth))
1798 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
break;
1833 return matchAddressBase(N, AM);
1838 bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
1840 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.getNode()) {
1842 if (!AM.IndexReg.getNode()) {
1853 AM.BaseType = X86ISelAddressMode::RegBase;
1861 bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
1865 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
1866 if (!foldOffsetIntoAddress(Val, AM))
1871 if (!matchWrapper(N, AM))
1876 return matchAddressBase(N, AM);
1882 X86ISelAddressMode AM;
1883 auto *Mgs = cast<X86MaskedGatherScatterSDNode>(Parent);
1884 AM.IndexReg = Mgs->getIndex();
1885 AM.Scale = cast<ConstantSDNode>(Mgs->getScale())->getZExtValue();
1887 unsigned AddrSpace = cast<MemSDNode>(Parent)->getPointerInfo().getAddrSpace();
1889 if (AddrSpace == 256)
1890 AM.Segment = CurDAG->getRegister(X86::GS,
MVT::i16);
1891 if (AddrSpace == 257)
1892 AM.Segment = CurDAG->getRegister(X86::FS,
MVT::i16);
1893 if (AddrSpace == 258)
1894 AM.Segment = CurDAG->getRegister(X86::SS,
MVT::i16);
1897 if (matchVectorAddress(N, AM))
1901 if (AM.BaseType == X86ISelAddressMode::RegBase) {
1902 if (!AM.Base_Reg.getNode())
1903 AM.Base_Reg = CurDAG->getRegister(0, VT);
1906 getAddressOperands(AM,
SDLoc(N), Base, Scale, Index, Disp, Segment);
1920 X86ISelAddressMode AM;
1930 unsigned AddrSpace =
1931 cast<MemSDNode>(Parent)->getPointerInfo().getAddrSpace();
1933 if (AddrSpace == 256)
1934 AM.Segment = CurDAG->getRegister(X86::GS,
MVT::i16);
1935 if (AddrSpace == 257)
1936 AM.Segment = CurDAG->getRegister(X86::FS,
MVT::i16);
1937 if (AddrSpace == 258)
1938 AM.Segment = CurDAG->getRegister(X86::SS,
MVT::i16);
1941 if (matchAddress(N, AM))
1945 if (AM.BaseType == X86ISelAddressMode::RegBase) {
1946 if (!AM.Base_Reg.getNode())
1947 AM.Base_Reg = CurDAG->getRegister(0, VT);
1950 if (!AM.IndexReg.getNode())
1951 AM.IndexReg = CurDAG->getRegister(0, VT);
1953 getAddressOperands(AM,
SDLoc(N), Base, Scale, Index, Disp, Segment);
1961 while (User != Root) {
1977 bool X86DAGToDAGISel::selectScalarSSELoad(
SDNode *Root,
SDNode *Parent,
1981 SDValue &PatternNodeWithChain) {
1987 PatternNodeWithChain =
N;
1988 if (IsProfitableToFold(PatternNodeWithChain, N.
getNode(), Root) &&
1989 IsLegalToFold(PatternNodeWithChain, Parent, Root, OptLevel)) {
1990 LoadSDNode *
LD = cast<LoadSDNode>(PatternNodeWithChain);
1998 PatternNodeWithChain =
N;
1999 if (IsProfitableToFold(PatternNodeWithChain, N.
getNode(), Root) &&
2000 IsLegalToFold(PatternNodeWithChain, Parent, Root, OptLevel)) {
2001 auto *
MI = cast<MemIntrinsicSDNode>(PatternNodeWithChain);
2002 return selectAddr(
MI,
MI->getBasePtr(), Base, Scale,
Index, Disp,
2013 IsProfitableToFold(PatternNodeWithChain, N.
getNode(), Root) &&
2014 IsLegalToFold(PatternNodeWithChain, N.
getNode(), Root, OptLevel)) {
2015 LoadSDNode *
LD = cast<LoadSDNode>(PatternNodeWithChain);
2029 IsProfitableToFold(PatternNodeWithChain, N.
getNode(), Root) &&
2030 IsLegalToFold(PatternNodeWithChain, N.
getNode(), Root, OptLevel)) {
2032 LoadSDNode *
LD = cast<LoadSDNode>(PatternNodeWithChain);
2042 bool X86DAGToDAGISel::selectMOV64Imm32(
SDValue N,
SDValue &Imm) {
2044 uint64_t ImmVal = CN->getZExtValue();
2048 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(N),
MVT::i64);
2069 cast<GlobalAddressSDNode>(
N)->getGlobal()->getAbsoluteSymbolRange();
2076 bool X86DAGToDAGISel::selectLEA64_32Addr(
SDValue N,
SDValue &Base,
2082 if (!selectLEAAddr(N, Base, Scale, Index, Disp, Segment))
2086 if (RN && RN->
getReg() == 0)
2087 Base = CurDAG->getRegister(0,
MVT::i64);
2090 Base =
SDValue(CurDAG->getMachineNode(
2091 TargetOpcode::SUBREG_TO_REG, DL,
MVT::i64,
2092 CurDAG->getTargetConstant(0, DL,
MVT::i64),
2094 CurDAG->getTargetConstant(X86::sub_32bit, DL,
MVT::i32)),
2099 if (RN && RN->
getReg() == 0)
2100 Index = CurDAG->getRegister(0,
MVT::i64);
2103 "Expect to be extending 32-bit registers for use in LEA");
2104 Index =
SDValue(CurDAG->getMachineNode(
2105 TargetOpcode::SUBREG_TO_REG, DL,
MVT::i64,
2106 CurDAG->getTargetConstant(0, DL,
MVT::i64),
2108 CurDAG->getTargetConstant(X86::sub_32bit, DL,
2118 bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
2122 X86ISelAddressMode AM;
2133 if (matchAddress(N, AM))
2135 assert (T == AM.Segment);
2138 unsigned Complexity = 0;
2139 if (AM.BaseType == X86ISelAddressMode::RegBase)
2140 if (AM.Base_Reg.getNode())
2143 AM.Base_Reg = CurDAG->getRegister(0, VT);
2144 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2147 if (AM.IndexReg.getNode())
2150 AM.IndexReg = CurDAG->getRegister(0, VT);
2162 if (AM.hasSymbolicDisplacement()) {
2164 if (Subtarget->is64Bit())
2170 if (AM.Disp && (AM.Base_Reg.getNode() || AM.IndexReg.getNode()))
2174 if (Complexity <= 2)
2177 getAddressOperands(AM, DL, Base, Scale, Index, Disp, Segment);
2182 bool X86DAGToDAGISel::selectTLSADDRAddr(
SDValue N,
SDValue &Base,
2188 X86ISelAddressMode AM;
2189 AM.GV = GA->getGlobal();
2190 AM.Disp += GA->getOffset();
2191 AM.Base_Reg = CurDAG->getRegister(0, N.
getValueType());
2192 AM.SymbolFlags = GA->getTargetFlags();
2198 AM.IndexReg = CurDAG->getRegister(0,
MVT::i64);
2201 getAddressOperands(AM,
SDLoc(N), Base, Scale, Index, Disp, Segment);
2206 if (
auto *CN = dyn_cast<ConstantSDNode>(N)) {
2207 Op = CurDAG->getTargetConstant(CN->getAPIntValue(),
SDLoc(CN),
2216 bool WasTruncated =
false;
2218 WasTruncated =
true;
2233 return !WasTruncated;
2237 auto *GA = cast<GlobalAddressSDNode>(N.
getOperand(0));
2239 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
2243 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
SDLoc(N), VT,
2244 GA->getOffset(), GA->getTargetFlags());
2253 !IsProfitableToFold(N, P, Root) ||
2254 !IsLegalToFold(N, P, Root, OptLevel))
2257 return selectAddr(N.
getNode(),
2264 SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
2265 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
2267 return CurDAG->getRegister(GlobalBaseReg, TLI->getPointerTy(DL)).getNode();
2270 bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width,
SDNode *N)
const {
2299 bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
2304 if (UI.getUse().getResNo() != Flags.
getResNo())
2308 cast<RegisterSDNode>(UI->getOperand(1))->
getReg() != X86::EFLAGS)
2312 FlagUE = UI->
use_end(); FlagUI != FlagUE; ++FlagUI) {
2314 if (FlagUI.getUse().getResNo() != 1)
continue;
2316 if (!FlagUI->isMachineOpcode())
return false;
2335 bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
2340 if (UI.getUse().getResNo() != Flags.
getResNo())
2344 cast<RegisterSDNode>(UI->getOperand(1))->
getReg() != X86::EFLAGS)
2348 FlagUE = UI->
use_end(); FlagUI != FlagUE; ++FlagUI) {
2350 if (FlagUI.getUse().getResNo() != 1)
continue;
2352 if (!FlagUI->isMachineOpcode())
return false;
2391 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
2396 if (UI.getUse().getResNo() != Flags.
getResNo())
2399 unsigned UIOpc = UI->getOpcode();
2403 if (cast<RegisterSDNode>(UI->getOperand(1))->
getReg() != X86::EFLAGS)
2407 FlagUI != FlagUE; ++FlagUI) {
2409 if (FlagUI.getUse().getResNo() != 1)
2412 if (!FlagUI->isMachineOpcode())
2453 if (StoredVal.
getResNo() != 0)
return false;
2467 LoadNode = cast<LoadSDNode>(
Load);
2478 bool FoundLoad =
false;
2482 const unsigned int Max = 1024;
2579 bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(
SDNode *Node) {
2592 bool IsCommutable =
false;
2604 IsCommutable =
true;
2608 unsigned LoadOpNo = 0;
2612 LoadNode, InputChain)) {
2619 LoadNode, InputChain))
2624 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(), Base, Scale,
Index, Disp,
2628 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
2649 if (!Subtarget->slowIncDec() ||
2650 CurDAG->getMachineFunction().getFunction().optForSize()) {
2654 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.getValue(1))) {
2657 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
2658 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
2659 const SDValue Ops[] = {Base, Scale,
Index, Disp, Segment, InputChain};
2660 Result = CurDAG->getMachineNode(NewOpc,
SDLoc(Node),
MVT::i32,
2671 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
2674 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
2677 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
2680 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
2683 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
2686 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
2689 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
2691 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
2697 auto SelectImm8Opcode = [SelectOpcode](
unsigned Opc) {
2700 return SelectOpcode(X86::ADD64mi8, X86::ADD32mi8, X86::ADD16mi8, 0);
2702 return SelectOpcode(X86::ADC64mi8, X86::ADC32mi8, X86::ADC16mi8, 0);
2704 return SelectOpcode(X86::SUB64mi8, X86::SUB32mi8, X86::SUB16mi8, 0);
2706 return SelectOpcode(X86::SBB64mi8, X86::SBB32mi8, X86::SBB16mi8, 0);
2708 return SelectOpcode(X86::AND64mi8, X86::AND32mi8, X86::AND16mi8, 0);
2710 return SelectOpcode(X86::OR64mi8, X86::OR32mi8, X86::OR16mi8, 0);
2712 return SelectOpcode(X86::XOR64mi8, X86::XOR32mi8, X86::XOR16mi8, 0);
2717 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
2720 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
2723 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
2726 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
2729 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
2732 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
2735 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
2738 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
2745 unsigned NewOpc = SelectRegOpcode(Opc);
2750 if (
auto *OperandC = dyn_cast<ConstantSDNode>(Operand)) {
2751 auto OperandV = OperandC->getAPIntValue();
2757 ((MemVT !=
MVT::i8 && OperandV.getMinSignedBits() > 8 &&
2758 (-OperandV).getMinSignedBits() <= 8) ||
2759 (MemVT ==
MVT::i64 && OperandV.getMinSignedBits() > 32 &&
2760 (-OperandV).getMinSignedBits() <= 32)) &&
2761 hasNoCarryFlagUses(StoredVal.getValue(1))) {
2762 OperandV = -OperandV;
2768 if (MemVT !=
MVT::i8 && OperandV.getMinSignedBits() <= 8) {
2769 Operand = CurDAG->getTargetConstant(OperandV,
SDLoc(Node), MemVT);
2770 NewOpc = SelectImm8Opcode(Opc);
2771 }
else if (OperandV.getActiveBits() <= MemVT.
getSizeInBits() &&
2772 (MemVT !=
MVT::i64 || OperandV.getMinSignedBits() <= 32)) {
2773 Operand = CurDAG->getTargetConstant(OperandV,
SDLoc(Node), MemVT);
2774 NewOpc = SelectImmOpcode(Opc);
2780 CurDAG->getCopyToReg(InputChain,
SDLoc(Node), X86::EFLAGS,
2781 StoredVal.getOperand(2),
SDValue());
2784 Segment, Operand, CopyTo, CopyTo.getValue(1)};
2789 Segment, Operand, InputChain};
2801 CurDAG->setNodeMemRefs(Result, MemOps);
2806 ReplaceUses(
SDValue(StoredVal.getNode(), 1),
SDValue(Result, 0));
2807 CurDAG->RemoveDeadNode(Node);
2817 bool X86DAGToDAGISel::matchBitExtract(
SDNode *Node) {
2820 "Should be either an and-mask, or right-shift after clearing high bits.");
2823 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
2838 const bool CanHaveExtraUses = Subtarget->hasBMI2();
2839 auto checkUses = [CanHaveExtraUses](
SDValue Op,
unsigned NUses) {
2840 return CanHaveExtraUses ||
2843 auto checkOneUse = [checkUses](
SDValue Op) {
return checkUses(Op, 1); };
2844 auto checkTwoUse = [checkUses](
SDValue Op) {
return checkUses(Op, 2); };
2847 auto matchPatternA = [&checkOneUse, &NBits](
SDValue Mask) ->
bool {
2865 auto matchPatternB = [&checkOneUse, &NBits](
SDValue Mask) ->
bool {
2880 auto matchShiftAmt = [checkOneUse,
Size, &NBits](
SDValue ShiftAmt) {
2885 if (!checkOneUse(ShiftAmt))
2889 if (ShiftAmt.getOpcode() !=
ISD::SUB)
2892 if (!V0 || V0->getZExtValue() !=
Size)
2899 auto matchPatternC = [&checkOneUse, matchShiftAmt](
SDValue Mask) ->
bool {
2908 if (!checkOneUse(M1))
2910 return matchShiftAmt(M1);
2916 auto matchPatternD = [&checkOneUse, &checkTwoUse, matchShiftAmt,
2927 if (N1 != N01 || !checkTwoUse(N1))
2929 if (!matchShiftAmt(N1))
2935 auto matchLowBitMask = [&matchPatternA, &matchPatternB,
2938 return matchPatternA(
Mask) || matchPatternB(
Mask) || matchPatternC(
Mask);
2945 if (matchLowBitMask(Mask)) {
2949 if (!matchLowBitMask(Mask))
2952 }
else if (!matchPatternD(Node))
2963 assert(NVT ==
MVT::i32 &&
"Expected target valuetype to be i32");
2978 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, XVT), 0);
2981 CurDAG->getTargetInsertSubreg(X86::sub_8bit, DL, XVT, ImplDef, NBits);
2985 if (Subtarget->hasBMI2()) {
2988 ReplaceNode(Node, Extract.
getNode());
2989 SelectCode(Extract.
getNode());
3011 "Expected shift amount to be i8");
3014 SDValue OrigShiftAmt = ShiftAmt;
3019 Control = CurDAG->getNode(
ISD::OR, DL, XVT, Control, ShiftAmt);
3032 ReplaceNode(Node, Extract.
getNode());
3033 SelectCode(Extract.
getNode());
3052 if (!Subtarget->hasTBM() &&
3053 !(Subtarget->hasBMI() && Subtarget->hasFastBEXTR()))
3071 if (!MaskCst || !ShiftCst)
3079 uint64_t Shift = ShiftCst->getZExtValue();
3084 if (Shift == 8 && MaskSize == 8)
3092 SDValue New = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
3093 unsigned ROpc = NVT ==
MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
3094 unsigned MOpc = NVT ==
MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
3097 if (!Subtarget->hasTBM()) {
3098 ROpc = NVT ==
MVT::i64 ? X86::BEXTR64rr : X86::BEXTR32rr;
3099 MOpc = NVT ==
MVT::i64 ? X86::BEXTR64rm : X86::BEXTR32rm;
3100 unsigned NewOpc = NVT ==
MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
3101 New =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, New), 0);
3106 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
3107 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
3110 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
3114 CurDAG->setNodeMemRefs(NewNode, {cast<LoadSDNode>(Input)->getMemOperand()});
3116 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, Input, New);
3123 MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
3129 const ConstantInt *Val = cast<ConstantSDNode>(Imm)->getConstantIntValue();
3133 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
3134 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
3135 SDValue Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Imm,
3138 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
3142 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
3146 SDValue Ops[] = { N0, N1, Imm };
3148 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs, Ops);
3155 MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
3156 bool MayFoldLoad,
const SDLoc &dl,
3162 const ConstantInt *Val = cast<ConstantSDNode>(Imm)->getConstantIntValue();
3166 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
3167 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
3168 SDValue Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Imm,
3171 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
3176 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N2)->getMemOperand()});
3180 SDValue Ops[] = { N0, N2, Imm, InFlag };
3182 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs, Ops);
3187 bool X86DAGToDAGISel::tryShiftAmountMod(
SDNode *N) {
3198 SDValue ShiftAmt = OrigShiftAmt;
3214 if (isa<ConstantSDNode>(Add1) &&
3215 cast<ConstantSDNode>(Add1)->getZExtValue() % Size == 0) {
3220 isa<ConstantSDNode>(Add0) &&
3221 cast<ConstantSDNode>(Add0)->getZExtValue() != 0 &&
3222 cast<ConstantSDNode>(Add0)->getZExtValue() % Size == 0) {
3227 SDValue Zero = CurDAG->getConstant(0, DL, SubVT);
3250 CurDAG->getConstant(Size - 1, DL,
MVT::i8));
3256 if (UpdatedNode != N) {
3259 ReplaceNode(N, UpdatedNode);
3266 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
3281 bool X86DAGToDAGISel::shrinkAndImmediate(
SDNode *And) {
3297 APInt MaskVal = And1C->getAPIntValue();
3299 if (!MaskLZ || (VT ==
MVT::i64 && MaskLZ == 32))
3303 if (VT ==
MVT::i64 && MaskLZ >= 32) {
3305 MaskVal = MaskVal.
trunc(32);
3310 APInt NegMaskVal = MaskVal | HighZeros;
3320 NegMaskVal = NegMaskVal.zext(64);
3321 HighZeros = HighZeros.
zext(64);
3326 if (!CurDAG->MaskedValueIsZero(And0, HighZeros))
3331 if (NegMaskVal.isAllOnesValue()) {
3332 ReplaceNode(And, And0.
getNode());
3337 SDValue NewMask = CurDAG->getConstant(NegMaskVal,
SDLoc(And), VT);
3339 ReplaceNode(And, NewAnd.
getNode());
3358 if (Subtarget->isTargetNaCl())
3362 if (Subtarget->isTarget64BitILP32()) {
3371 ReplaceNode(Node, Brind.
getNode());
3372 SelectCode(ZextTarget.getNode());
3379 ReplaceNode(Node, getGlobalBaseReg());
3387 CurDAG->RemoveDeadNode(Node);
3394 SDValue VSelect = CurDAG->getNode(
3397 ReplaceNode(Node, VSelect.
getNode());
3398 SelectCode(VSelect.
getNode());
3404 if (matchBitExtract(Node))
3409 if (tryShiftAmountMod(Node))
3416 CurDAG->RemoveDeadNode(Node);
3419 if (matchBitExtract(Node))
3442 if (!Cst || !ShlCst)
3446 uint64_t ShlVal = ShlCst->getZExtValue();
3450 uint64_t RemovedBitsMask = (1ULL << ShlVal) - 1;
3451 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
3454 unsigned ShlOp, AddOp,
Op;
3474 ShlOp = X86::SHL32ri;
3475 AddOp = X86::ADD32rr;
3479 case ISD::AND: Op = X86::AND32ri8;
break;
3480 case ISD::OR: Op = X86::OR32ri8;
break;
3481 case ISD::XOR: Op = X86::XOR32ri8;
break;
3486 ShlOp = X86::SHL64ri;
3487 AddOp = X86::ADD64rr;
3491 case ISD::AND: Op = CstVT==
MVT::i8? X86::AND64ri8 : X86::AND64ri32;
break;
3492 case ISD::OR: Op = CstVT==
MVT::i8? X86::OR64ri8 : X86::OR64ri32;
break;
3493 case ISD::XOR: Op = CstVT==
MVT::i8? X86::XOR64ri8 : X86::XOR64ri32;
break;
3499 SDValue NewCst = CurDAG->getTargetConstant(Val >> ShlVal, dl, CstVT);
3500 SDNode *New = CurDAG->getMachineNode(Op, dl, NVT, N0->
getOperand(0),NewCst);
3502 CurDAG->SelectNodeTo(Node, AddOp, NVT,
SDValue(New, 0),
3505 CurDAG->SelectNodeTo(Node, ShlOp, NVT,
SDValue(New, 0),
3506 getI8Imm(ShlVal, dl));
3518 unsigned LoReg, ROpc, MOpc;
3523 ROpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
3524 MOpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
3543 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
3544 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
3547 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
3552 SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
3567 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
3572 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
3578 VTs = CurDAG->getVTList(NVT,
MVT::i32);
3580 VTs = CurDAG->getVTList(NVT, NVT,
MVT::i32);
3582 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InFlag});
3587 CurDAG->RemoveDeadNode(Node);
3601 case MVT::i32: Opc = X86::MUL32r; MOpc = X86::MUL32m;
break;
3602 case MVT::i64: Opc = X86::MUL64r; MOpc = X86::MUL64m;
break;
3607 case MVT::i32: Opc = X86::IMUL32r; MOpc = X86::IMUL32m;
break;
3608 case MVT::i64: Opc = X86::IMUL64r; MOpc = X86::IMUL64m;
break;
3612 unsigned SrcReg, LoReg, HiReg;
3621 SrcReg = LoReg = X86::RAX; HiReg = X86::RDX;
3625 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
3626 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
3629 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
3634 SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, SrcReg,
3642 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
3647 ReplaceUses(N1.
getValue(1), Chain);
3649 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
3651 SDValue Ops[] = { N1, InFlag };
3653 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
3658 if (!
SDValue(Node, 0).use_empty()) {
3659 assert(LoReg &&
"Register for low half is not defined!");
3660 SDValue ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
3663 ReplaceUses(
SDValue(Node, 0), ResLo);
3669 assert(HiReg &&
"Register for high half is not defined!");
3670 SDValue ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
3673 ReplaceUses(
SDValue(Node, 1), ResHi);
3678 CurDAG->RemoveDeadNode(Node);
3692 case MVT::i8: Opc = X86::DIV8r; MOpc = X86::DIV8m;
break;
3693 case MVT::i16: Opc = X86::DIV16r; MOpc = X86::DIV16m;
break;
3694 case MVT::i32: Opc = X86::DIV32r; MOpc = X86::DIV32m;
break;
3695 case MVT::i64: Opc = X86::DIV64r; MOpc = X86::DIV64m;
break;
3700 case MVT::i8: Opc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
3701 case MVT::i16: Opc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
3702 case MVT::i32: Opc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
3703 case MVT::i64: Opc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
3707 unsigned LoReg, HiReg, ClrReg;
3708 unsigned SExtOpcode;
3712 LoReg =
X86::AL; ClrReg = HiReg = X86::AH;
3713 SExtOpcode = X86::CBW;
3716 LoReg = X86::AX; HiReg = X86::DX;
3718 SExtOpcode = X86::CWD;
3722 SExtOpcode = X86::CDQ;
3725 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
3726 SExtOpcode = X86::CQO;
3730 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
3731 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
3732 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
3735 if (NVT ==
MVT::i8 && (!isSigned || signBitIsZero)) {
3738 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
3740 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
3742 Move = CurDAG->getMachineNode(X86::MOVZX32rm8, dl,
MVT::i32,
3745 ReplaceUses(N0.
getValue(1), Chain);
3747 CurDAG->setNodeMemRefs(Move, {cast<LoadSDNode>(N0)->getMemOperand()});
3749 Move = CurDAG->getMachineNode(X86::MOVZX32rr8, dl,
MVT::i32, N0);
3750 Chain = CurDAG->getEntryNode();
3757 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
3758 LoReg, N0,
SDValue()).getValue(1);
3759 if (isSigned && !signBitIsZero) {
3765 SDValue ClrNode =
SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, NVT), 0);
3769 SDValue(CurDAG->getMachineNode(
3770 TargetOpcode::EXTRACT_SUBREG, dl,
MVT::i16, ClrNode,
3771 CurDAG->getTargetConstant(X86::sub_16bit, dl,
3779 SDValue(CurDAG->getMachineNode(
3780 TargetOpcode::SUBREG_TO_REG, dl,
MVT::i64,
3781 CurDAG->getTargetConstant(0, dl,
MVT::i64), ClrNode,
3782 CurDAG->getTargetConstant(X86::sub_32bit, dl,
3790 InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
3791 ClrNode, InFlag).getValue(1);
3804 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
3819 unsigned AHExtOpcode =
3820 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
3822 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl,
MVT::i32,
3828 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl,
MVT::i8, Result);
3830 ReplaceUses(
SDValue(Node, 1), Result);
3836 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
3837 LoReg, NVT, InFlag);
3839 ReplaceUses(
SDValue(Node, 0), Result);
3845 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
3846 HiReg, NVT, InFlag);
3848 ReplaceUses(
SDValue(Node, 1), Result);
3852 CurDAG->RemoveDeadNode(Node);
3873 unsigned TestOpc = CmpVT ==
MVT::i64 ? X86::TEST64rr
3876 NewNode = CurDAG->getMachineNode(TestOpc, dl,
MVT::i32, BEXTR, BEXTR);
3878 CurDAG->RemoveDeadNode(Node);
3901 onlyUsesZeroFlag(
SDValue(Node, 0))) {
3908 MachineSDNode *Test = CurDAG->getMachineNode(X86::TEST64rr, dl,
3910 ReplaceNode(Node, Test);
3919 MachineSDNode *Test = CurDAG->getMachineNode(X86::TEST64rr, dl,
3921 ReplaceNode(Node, Test);
3928 unsigned ROpc, MOpc;
3936 (!(Mask & 0x80) || CmpVT ==
MVT::i8 ||
3937 hasNoSignFlagUses(
SDValue(Node, 0)))) {
3940 SubRegOp = X86::sub_8bit;
3941 ROpc = X86::TEST8ri;
3942 MOpc = X86::TEST8mi;
3943 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
3944 (!(Mask & 0x8000) || CmpVT ==
MVT::i16 ||
3945 hasNoSignFlagUses(
SDValue(Node, 0)))) {
3951 SubRegOp = X86::sub_16bit;
3952 ROpc = X86::TEST16ri;
3953 MOpc = X86::TEST16mi;
3955 ((!(Mask & 0x80000000) &&
3958 (CmpVT !=
MVT::i16 || !(Mask & 0x8000))) ||
3960 hasNoSignFlagUses(
SDValue(Node, 0)))) {
3967 SubRegOp = X86::sub_32bit;
3968 ROpc = X86::TEST32ri;
3969 MOpc = X86::TEST32mi;
3977 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
3982 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
3983 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
3984 SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Imm,
3990 CurDAG->setNodeMemRefs(NewNode,
3991 {cast<LoadSDNode>(
Reg)->getMemOperand()});
3995 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT, Reg);
3997 NewNode = CurDAG->getMachineNode(ROpc, dl,
MVT::i32, Reg, Imm);
4000 ReplaceNode(Node, NewNode);
4006 if (!Subtarget->hasSSE42())
4012 bool MayFoldLoad = !NeedIndex || !NeedMask;
4016 unsigned ROpc = Subtarget->hasAVX() ? X86::VPCMPISTRMrr : X86::PCMPISTRMrr;
4017 unsigned MOpc = Subtarget->hasAVX() ? X86::VPCMPISTRMrm : X86::PCMPISTRMrm;
4018 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl,
MVT::v16i8, Node);
4021 if (NeedIndex || !NeedMask) {
4022 unsigned ROpc = Subtarget->hasAVX() ? X86::VPCMPISTRIrr : X86::PCMPISTRIrr;
4023 unsigned MOpc = Subtarget->hasAVX() ? X86::VPCMPISTRIrm : X86::PCMPISTRIrm;
4024 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl,
MVT::i32, Node);
4030 CurDAG->RemoveDeadNode(Node);
4034 if (!Subtarget->hasSSE42())
4038 SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
X86::EAX,
4041 InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
X86::EDX,
4047 bool MayFoldLoad = !NeedIndex || !NeedMask;
4051 unsigned ROpc = Subtarget->hasAVX() ? X86::VPCMPESTRMrr : X86::PCMPESTRMrr;
4052 unsigned MOpc = Subtarget->hasAVX() ? X86::VPCMPESTRMrm : X86::PCMPESTRMrm;
4053 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl,
MVT::v16i8, Node,
4057 if (NeedIndex || !NeedMask) {
4058 unsigned ROpc = Subtarget->hasAVX() ? X86::VPCMPESTRIrr : X86::PCMPESTRIrr;
4059 unsigned MOpc = Subtarget->hasAVX() ? X86::VPCMPESTRIrm : X86::PCMPESTRIrm;
4060 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl,
MVT::i32, Node, InFlag);
4065 CurDAG->RemoveDeadNode(Node);
4070 if (foldLoadStoreIntoMemOperand(Node))
4078 bool X86DAGToDAGISel::
4079 SelectInlineAsmMemoryOperand(
const SDValue &Op,
unsigned ConstraintID,
4080 std::vector<SDValue> &OutOps) {
4081 SDValue Op0, Op1, Op2, Op3, Op4;
4082 switch (ConstraintID) {
4093 if (!selectAddr(
nullptr, Op, Op0, Op1, Op2, Op3, Op4))
4098 OutOps.push_back(Op0);
4099 OutOps.push_back(Op1);
4100 OutOps.push_back(Op2);
4101 OutOps.push_back(Op3);
4102 OutOps.push_back(Op4);
4110 return new X86DAGToDAGISel(TM, OptLevel);
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
constexpr bool isUInt< 32 >(uint64_t x)
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
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 ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
static bool isFusableLoadOpStorePattern(StoreSDNode *StoreNode, SDValue StoredVal, SelectionDAG *CurDAG, unsigned LoadOpNo, LoadSDNode *&LoadNode, SDValue &InputChain)
Check whether or not the chain ending in StoreNode is suitable for doing the {load; op; store} to mod...
EVT getValueType() const
Return the ValueType of the referenced return value.
Vector comparison generating mask bits for fp and integer signed and unsigned data types...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const SDValue & getOffset() const
C - The default llvm calling convention, compatible with C.
APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
DELETED_NODE - This is an illegal value that is used to catch errors.
This class represents lattice values for constants.
static void insertDAGNode(SelectionDAG &DAG, SDValue Pos, SDValue N)
static bool isLegalMaskCompare(SDNode *N, const X86Subtarget *Subtarget)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVector() const
Return true if this is a vector value type.
const SDValue & getBasePtr() const
CondCode getCondFromCMovOpc(unsigned Opc)
Return condition code of a CMov opcode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void push_back(const T &Elt)
APInt zext(unsigned width) const
Zero extend to a new width.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
bool slt(const APInt &RHS) const
Signed less than comparison.
CondCode getCondFromSETOpc(unsigned Opc)
Return condition code of a SET opcode.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool hasFastBEXTR() const
const SDValue & getChain() const
constexpr bool isInt< 8 >(int64_t x)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
unsigned getAlignment() const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isBitwiseNot(SDValue V)
Returns true if V is a bitwise not operation.
APInt trunc(unsigned width) const
Truncate to new width.
STATISTIC(NumFunctions, "Total number of functions")
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1 at the ...
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1...
static bool MayFoldLoad(SDValue Op)
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
unsigned getBitWidth() const
Return the number of bits in the APInt.
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
GlobalBaseReg - On Darwin, this node represents the result of the mflr at function entry...
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.
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
X86 compare and logical compare instructions.
void dump() const
Support for debugging, callable in GDB: V->dump()
The address of a basic block.
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)
bool hasOneUse() const
Return true if there is exactly one use of this node.
A description of a memory reference used in the backend.
Dynamic (non-constant condition) vector blend where only the sign bits of the condition elements are ...
Shift and rotation operations.
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef...
CallLoweringInfo & setChain(SDValue InChain)
CopyToReg - This node has three operands: a chain, a register number to set to this value...
op_iterator op_end() const
uint64_t getConstantOperandVal(unsigned i) const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
CondCode getCondFromBranchOpc(unsigned Opc)
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence, and carry arbitrary information that target might want to know.
Position
Position to insert a new instruction relative to an existing instruction.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
unsigned getSizeInBits() const
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
bool hasExternalLinkage() const
int64_t getSExtValue() const
static void InvalidateNodeId(SDNode *N)
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
X86 FP SETCC, similar to above, but with output as an i1 mask and with optional rounding mode...
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...
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Simple integer binary arithmetic operators.
op_iterator op_begin() const
static X86::CondCode getCondFromOpc(unsigned Opc)
ArrayRef< SDUse > ops() const
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
bool use_empty() const
Return true if there are no nodes using value ResNo of Node.
This class is used to represent ISD::STORE nodes.
bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
const SDValue & getBasePtr() const
initializer< Ty > init(const Ty &Val)
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
constexpr bool isUInt< 8 >(uint64_t x)
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static bool foldMaskedShiftToScaledMask(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
bool isMachineOpcode() const
static bool mayUseCarryFlag(X86::CondCode CC)
unsigned getScalarSizeInBits() const
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
const SDValue & getOperand(unsigned Num) const
X86 conditional branches.
bool isOperandOf(const SDNode *N) const
Return true if this node is an operand of N.
const SDValue & getOffset() const
APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
static Type * getVoidTy(LLVMContext &C)
This class provides iterator support for SDUse operands that use a specific SDNode.
unsigned getMachineOpcode() const
bool optForSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
void RepositionNode(allnodes_iterator Position, SDNode *N)
Move node N in the AllNodes list to be immediately before the given iterator Position.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
FunctionPass class - This class is used to implement most global optimizations.
On Darwin, this node represents the result of the popl at function entry, used for PIC code...
self_iterator getIterator()
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
static bool foldMaskAndShiftToExtract(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
std::vector< ArgListEntry > ArgListTy
This structure contains all information that is necessary for lowering calls.
APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
This class contains a discriminated union of information about pointers in memory operands...
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
unsigned getNumOperands() const
Return the number of values used by this operation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
bool use_empty() const
Return true if there are no uses of this node.
These operations represent an abstract X86 call instruction, which includes a bunch of information...
TokenFactor - This node takes multiple tokens as input and produces a single token result...
void dump() const
Dump this node, for debugging.
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
unsigned countPopulation(T Value)
Count the number of set bits in a value.
This is the shared class of boolean and integer constants.
static bool foldMaskedShiftToBEXTR(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM, const X86Subtarget &Subtarget)
constexpr bool isInt< 32 >(int64_t x)
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...
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
An SDNode that represents everything that will be needed to construct a MachineInstr.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static bool foldMaskAndShiftToScale(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
EVT getMemoryVT() const
Return the type of the in-memory value.
Target - Wrapper for Target specific information.
Class for arbitrary precision integers.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
static use_iterator use_end()
ZERO_EXTEND - Used for integer types, zeroing the new bits.
ANY_EXTEND - Used for integer types. The high bits are undefined.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
static bool hasSingleUsesFromRoot(SDNode *Root, SDNode *User)
bool is256BitVector() const
Return true if this is a 256-bit vector type.
int getNodeId() const
Return the unique node id.
static bool isDispSafeForFrameIndex(int64_t Val)
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
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...
bool isVector() const
Return true if this is a vector value type.
const SDValue & getValue() const
Bitwise operators - logical and, logical or, logical xor.
bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
bool is128BitVector() const
Return true if this is a 128-bit vector type.
A wrapper node for TargetConstantPool, TargetJumpTable, TargetExternalSymbol, TargetGlobalAddress, TargetGlobalTLSAddress, MCSymbol and TargetBlockAddress.
FunctionPass * createX86ISelDag(X86TargetMachine &TM, CodeGenOpt::Level OptLevel)
This pass converts a legalized DAG into a X86-specific DAG, ready for instruction scheduling...
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
StringRef getName() const
Return a constant reference to the value's name.
bool optForMinSize() const
Optimize this function for minimum size (-Oz).
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool is512BitVector() const
Return true if this is a 512-bit vector type.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
unsigned getOpcode() const
SDValue getValue(unsigned R) const
XOP - Opcode prefix used by XOP instructions.
constexpr bool isUInt< 16 >(uint64_t x)
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
const MachinePointerInfo & getPointerInfo() const
This class is used to form a handle around another node that is persistent and is updated across invo...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getMinSignedBits() const
Get the minimum bit size for this signed APInt.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
unsigned getResNo() const
get the index which selects a specific result in the SDNode
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
bool isNonTemporal() const
StringRef - Represent a constant reference to a string, i.e.
SetCC operator - This evaluates to a true value iff the condition is true.
unsigned countLeadingZeros() const
The APInt version of the countLeadingZeros functions in MathExtras.h.
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M, bool hasSymbolicDisplacement=true)
Returns true of the given offset can be fit into displacement field of the instruction.
unsigned getNumOperands() const
const SDValue & getOperand(unsigned i) const
uint64_t getZExtValue() const
TRUNCATE - Completely drop the high bits.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
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...
Carry-using nodes for multiple precision addition and subtraction.
Special wrapper used under X86-64 PIC mode for RIP relative displacements.
This class is used to represent ISD::LOAD nodes.
static int getUninvalidatedNodeId(SDNode *N)