15 #define DEBUG_TYPE "x86-isel"
39 STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
49 struct X86ISelAddressMode {
72 : BaseType(RegBase), Base_FrameIndex(0), Scale(1), IndexReg(), Disp(0),
73 Segment(), GV(0), CP(0), BlockAddr(0), ES(0), JT(-1),
Align(0),
77 bool hasSymbolicDisplacement()
const {
78 return GV != 0 || CP != 0 || ES != 0 || JT != -1 || BlockAddr != 0;
81 bool hasBaseOrIndexReg()
const {
82 return BaseType == FrameIndexBase ||
83 IndexReg.getNode() != 0 || Base_Reg.getNode() != 0;
88 bool isRIPRelative()
const {
89 if (BaseType != RegBase)
return false;
91 dyn_cast_or_null<RegisterSDNode>(Base_Reg.getNode()))
92 return RegNode->getReg() == X86::RIP;
101 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
103 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
104 dbgs() <<
"Base_Reg ";
105 if (Base_Reg.getNode() != 0)
106 Base_Reg.getNode()->dump();
109 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n'
110 <<
" Scale" << Scale <<
'\n'
112 if (IndexReg.getNode() != 0)
113 IndexReg.getNode()->dump();
116 dbgs() <<
" Disp " << Disp <<
'\n'
133 dbgs() <<
" JT" << JT <<
" Align" <<
Align <<
'\n';
159 virtual const char *getPassName()
const {
160 return "X86 DAG->DAG Instruction Selection";
163 virtual void EmitFunctionEntryCode();
167 virtual void PreprocessISelDAG();
169 inline bool immSext8(
SDNode *
N)
const {
170 return isInt<8>(cast<ConstantSDNode>(
N)->getSExtValue());
175 inline bool i64immSExt32(
SDNode *
N)
const {
176 uint64_t v = cast<ConstantSDNode>(
N)->getZExtValue();
177 return (int64_t)v == (int32_t)v;
181 #include "X86GenDAGISel.inc"
189 bool FoldOffsetIntoAddress(uint64_t Offset, X86ISelAddressMode &AM);
190 bool MatchLoadInAddress(
LoadSDNode *N, X86ISelAddressMode &AM);
191 bool MatchWrapper(
SDValue N, X86ISelAddressMode &AM);
192 bool MatchAddress(
SDValue N, X86ISelAddressMode &AM);
193 bool MatchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
195 bool MatchAddressBase(
SDValue N, X86ISelAddressMode &AM);
222 virtual bool SelectInlineAsmMemoryOperand(
const SDValue &Op,
224 std::vector<SDValue> &OutOps);
228 inline void getAddressOperands(X86ISelAddressMode &AM,
SDValue &Base,
231 Base = (AM.BaseType == X86ISelAddressMode::FrameIndexBase) ?
232 CurDAG->getTargetFrameIndex(AM.Base_FrameIndex,
233 getTargetLowering()->getPointerTy()) :
235 Scale = getI8Imm(AM.Scale);
240 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(),
244 Disp = CurDAG->getTargetConstantPool(AM.CP,
MVT::i32,
245 AM.Align, AM.Disp, AM.SymbolFlags);
247 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
248 Disp = CurDAG->getTargetExternalSymbol(AM.ES,
MVT::i32, AM.SymbolFlags);
249 }
else if (AM.JT != -1) {
250 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
251 Disp = CurDAG->getTargetJumpTable(AM.JT,
MVT::i32, AM.SymbolFlags);
252 }
else if (AM.BlockAddr)
253 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr,
MVT::i32, AM.Disp,
256 Disp = CurDAG->getTargetConstant(AM.Disp,
MVT::i32);
258 if (AM.Segment.getNode())
259 Segment = AM.Segment;
261 Segment = CurDAG->getRegister(0,
MVT::i32);
266 inline SDValue getI8Imm(
unsigned Imm) {
267 return CurDAG->getTargetConstant(Imm,
MVT::i8);
272 inline SDValue getI32Imm(
unsigned Imm) {
273 return CurDAG->getTargetConstant(Imm,
MVT::i32);
280 SDNode *getGlobalBaseReg();
291 return getTargetMachine().getInstrInfo();
335 if (Imm->getAPIntValue().isSignedIntN(8))
370 "Unexpected chain operand");
391 for (
unsigned i = 1, e = NumOps; i != e; ++i)
426 if (isa<MemSDNode>(Chain.
getNode()) &&
427 cast<MemSDNode>(Chain.
getNode())->writeMem())
438 void X86DAGToDAGISel::PreprocessISelDAG() {
440 OptForSize = MF->getFunction()->getAttributes().
444 E = CurDAG->allnodes_end();
I != E; ) {
453 (Subtarget->is64Bit() ||
454 getTargetMachine().getRelocationModel() !=
Reloc::PIC_)))) {
508 if (SrcIsSSE && DstIsSSE)
511 if (!SrcIsSSE && !DstIsSSE) {
527 MemVT = SrcIsSSE ? SrcVT : DstVT;
529 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
533 SDValue Store = CurDAG->getTruncStore(CurDAG->getEntryNode(), dl,
539 MemVT,
false,
false, 0);
546 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(N, 0), Result);
551 CurDAG->DeleteNode(N);
561 if (Subtarget->isTargetCygMing()) {
563 Subtarget->is64Bit() ? X86::CALL64pcrel32 : X86::CALLpcrel32;
565 TII->
get(CallOp)).addExternalSymbol(
"__main");
569 void X86DAGToDAGISel::EmitFunctionEntryCode() {
571 if (
const Function *Fn = MF->getFunction())
572 if (Fn->hasExternalLinkage() && Fn->getName() ==
"main")
573 EmitSpecialCodeForMain(MF->begin(), MF->getFrameInfo());
583 return isInt<31>(Val);
586 bool X86DAGToDAGISel::FoldOffsetIntoAddress(uint64_t Offset,
587 X86ISelAddressMode &AM) {
588 int64_t Val = AM.Disp + Offset;
590 if (Subtarget->is64Bit()) {
592 AM.hasSymbolicDisplacement()))
596 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
605 bool X86DAGToDAGISel::MatchLoadInAddress(
LoadSDNode *N, X86ISelAddressMode &AM){
615 if (
C->getSExtValue() == 0 && AM.Segment.getNode() == 0 &&
616 Subtarget->isTargetLinux())
633 bool X86DAGToDAGISel::MatchWrapper(
SDValue N, X86ISelAddressMode &AM) {
636 if (AM.hasSymbolicDisplacement())
650 if (AM.hasBaseOrIndexReg())
653 X86ISelAddressMode Backup = AM;
654 AM.GV =
G->getGlobal();
655 AM.SymbolFlags =
G->getTargetFlags();
656 if (FoldOffsetIntoAddress(
G->getOffset(), AM)) {
661 X86ISelAddressMode Backup = AM;
662 AM.CP = CP->getConstVal();
663 AM.Align = CP->getAlignment();
664 AM.SymbolFlags = CP->getTargetFlags();
665 if (FoldOffsetIntoAddress(CP->getOffset(), AM)) {
670 AM.ES = S->getSymbol();
671 AM.SymbolFlags = S->getTargetFlags();
673 AM.JT = J->getIndex();
674 AM.SymbolFlags = J->getTargetFlags();
676 X86ISelAddressMode Backup = AM;
677 AM.BlockAddr = BA->getBlockAddress();
678 AM.SymbolFlags = BA->getTargetFlags();
679 if (FoldOffsetIntoAddress(BA->getOffset(), AM)) {
687 AM.setBaseReg(CurDAG->getRegister(X86::RIP,
MVT::i64));
694 if (!Subtarget->is64Bit() ||
697 "RIP-relative addressing already handled");
699 AM.GV =
G->getGlobal();
700 AM.Disp +=
G->getOffset();
701 AM.SymbolFlags =
G->getTargetFlags();
703 AM.CP = CP->getConstVal();
704 AM.Align = CP->getAlignment();
705 AM.Disp += CP->getOffset();
706 AM.SymbolFlags = CP->getTargetFlags();
708 AM.ES = S->getSymbol();
709 AM.SymbolFlags = S->getTargetFlags();
711 AM.JT = J->getIndex();
712 AM.SymbolFlags = J->getTargetFlags();
714 AM.BlockAddr = BA->getBlockAddress();
715 AM.Disp += BA->getOffset();
716 AM.SymbolFlags = BA->getTargetFlags();
728 bool X86DAGToDAGISel::MatchAddress(
SDValue N, X86ISelAddressMode &AM) {
729 if (MatchAddressRecursively(N, AM, 0))
735 AM.BaseType == X86ISelAddressMode::RegBase &&
736 AM.Base_Reg.getNode() == 0) {
737 AM.Base_Reg = AM.IndexReg;
745 Subtarget->is64Bit() &&
747 AM.BaseType == X86ISelAddressMode::RegBase &&
748 AM.Base_Reg.getNode() == 0 &&
749 AM.IndexReg.getNode() == 0 &&
751 AM.hasSymbolicDisplacement())
752 AM.Base_Reg = CurDAG->getRegister(X86::RIP,
MVT::i64);
776 X86ISelAddressMode &AM) {
783 if (ScaleLog <= 0 || ScaleLog >= 4 ||
784 Mask != (0xffu << ScaleLog))
809 AM.Scale = (1 << ScaleLog);
819 X86ISelAddressMode &AM) {
832 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
851 AM.Scale = 1 << ShiftAmt;
852 AM.IndexReg = NewAnd;
886 X86ISelAddressMode &AM) {
897 unsigned AMShiftAmt = MaskTZ;
901 if (AMShiftAmt <= 0 || AMShiftAmt > 3)
return true;
916 bool ReplacingAnyExtend =
false;
923 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
924 ReplacingAnyExtend =
true;
926 APInt MaskedHighBits =
928 APInt KnownZero, KnownOne;
930 if (MaskedHighBits != KnownZero)
return true;
935 if (ReplacingAnyExtend) {
959 AM.Scale = 1 << AMShiftAmt;
960 AM.IndexReg = NewSRL;
964 bool X86DAGToDAGISel::MatchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
968 dbgs() <<
"MatchAddress: ";
973 return MatchAddressBase(N, AM);
978 if (AM.isRIPRelative()) {
982 if (!AM.ES && AM.JT != -1)
return true;
985 if (!FoldOffsetIntoAddress(Cst->getSExtValue(), AM))
993 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
994 if (!FoldOffsetIntoAddress(Val, AM))
1001 if (!MatchWrapper(N, AM))
1006 if (!MatchLoadInAddress(cast<LoadSDNode>(N), AM))
1011 if (AM.BaseType == X86ISelAddressMode::RegBase &&
1012 AM.Base_Reg.getNode() == 0 &&
1014 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
1015 AM.Base_FrameIndex = cast<FrameIndexSDNode>(
N)->getIndex();
1021 if (AM.IndexReg.getNode() != 0 || AM.Scale != 1)
1026 unsigned Val = CN->getZExtValue();
1031 if (Val == 1 || Val == 2 || Val == 3) {
1032 AM.Scale = 1 << Val;
1038 if (CurDAG->isBaseWithConstantOffset(ShVal)) {
1042 uint64_t Disp = (uint64_t)AddVal->
getSExtValue() << Val;
1043 if (!FoldOffsetIntoAddress(Disp, AM))
1047 AM.IndexReg = ShVal;
1055 if (AM.IndexReg.getNode() != 0 || AM.Scale != 1)
break;
1088 if (AM.BaseType == X86ISelAddressMode::RegBase &&
1089 AM.Base_Reg.getNode() == 0 &&
1090 AM.IndexReg.getNode() == 0) {
1093 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
1094 CN->getZExtValue() == 9) {
1095 AM.Scale =
unsigned(CN->getZExtValue())-1;
1103 if (MulVal.getNode()->getOpcode() ==
ISD::ADD && MulVal.hasOneUse() &&
1104 isa<ConstantSDNode>(MulVal.getNode()->getOperand(1))) {
1107 cast<ConstantSDNode>(MulVal.getNode()->getOperand(1));
1108 uint64_t Disp = AddVal->
getSExtValue() * CN->getZExtValue();
1109 if (FoldOffsetIntoAddress(Disp, AM))
1115 AM.IndexReg = AM.Base_Reg =
Reg;
1134 X86ISelAddressMode Backup = AM;
1140 if (AM.IndexReg.getNode() || AM.isRIPRelative()) {
1159 if ((AM.BaseType == X86ISelAddressMode::RegBase &&
1160 AM.Base_Reg.getNode() &&
1161 !AM.Base_Reg.getNode()->hasOneUse()) ||
1162 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
1166 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
1167 ((AM.Disp != 0) && (Backup.Disp == 0)) +
1168 (AM.Segment.getNode() && !Backup.Segment.getNode()) >= 2)
1193 X86ISelAddressMode Backup = AM;
1194 if (!MatchAddressRecursively(N.
getOperand(0), AM, Depth+1) &&
1195 !MatchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth+1))
1200 if (!MatchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth+1)&&
1201 !MatchAddressRecursively(Handle.getValue().getOperand(0), AM, Depth+1))
1208 if (AM.BaseType == X86ISelAddressMode::RegBase &&
1209 !AM.Base_Reg.getNode() &&
1210 !AM.IndexReg.getNode()) {
1223 if (CurDAG->isBaseWithConstantOffset(N)) {
1224 X86ISelAddressMode Backup = AM;
1228 if (!MatchAddressRecursively(N.
getOperand(0), AM, Depth+1) &&
1240 if (AM.IndexReg.getNode() != 0 || AM.Scale != 1)
break;
1270 return MatchAddressBase(N, AM);
1275 bool X86DAGToDAGISel::MatchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
1277 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.getNode()) {
1279 if (AM.IndexReg.getNode() == 0) {
1290 AM.BaseType = X86ISelAddressMode::RegBase;
1305 X86ISelAddressMode AM;
1315 unsigned AddrSpace =
1316 cast<MemSDNode>(Parent)->getPointerInfo().getAddrSpace();
1318 if (AddrSpace == 256)
1320 if (AddrSpace == 257)
1324 if (MatchAddress(N, AM))
1328 if (AM.BaseType == X86ISelAddressMode::RegBase) {
1329 if (!AM.Base_Reg.getNode())
1330 AM.Base_Reg = CurDAG->getRegister(0, VT);
1333 if (!AM.IndexReg.getNode())
1334 AM.IndexReg = CurDAG->getRegister(0, VT);
1336 getAddressOperands(AM, Base, Scale, Index, Disp, Segment);
1347 bool X86DAGToDAGISel::SelectScalarSSELoad(
SDNode *Root,
1351 SDValue &PatternNodeWithChain) {
1358 LoadSDNode *
LD = cast<LoadSDNode>(PatternNodeWithChain);
1359 if (!SelectAddr(LD, LD->
getBasePtr(), Base, Scale, Index, Disp, Segment))
1377 if (!SelectAddr(LD, LD->
getBasePtr(), Base, Scale, Index, Disp, Segment))
1379 PatternNodeWithChain =
SDValue(LD, 0);
1386 bool X86DAGToDAGISel::SelectMOV64Imm32(
SDValue N,
SDValue &Imm) {
1389 if ((uint32_t)ImmVal != (uint64_t)ImmVal)
1392 Imm = CurDAG->getTargetConstant(ImmVal,
MVT::i64);
1400 "Unexpected node type for MOV32ri64");
1414 bool X86DAGToDAGISel::SelectLEA64_32Addr(
SDValue N,
SDValue &Base,
1417 if (!SelectLEAAddr(N, Base, Scale, Index, Disp, Segment))
1422 if (RN && RN->
getReg() == 0)
1423 Base = CurDAG->getRegister(0,
MVT::i64);
1426 Base =
SDValue(CurDAG->getMachineNode(
1428 CurDAG->getTargetConstant(0,
MVT::i64),
1430 CurDAG->getTargetConstant(X86::sub_32bit,
MVT::i32)),
1435 if (RN && RN->
getReg() == 0)
1436 Index = CurDAG->getRegister(0,
MVT::i64);
1439 "Expect to be extending 32-bit registers for use in LEA");
1440 Index =
SDValue(CurDAG->getMachineNode(
1442 CurDAG->getTargetConstant(0,
MVT::i64),
1444 CurDAG->getTargetConstant(X86::sub_32bit,
MVT::i32)),
1453 bool X86DAGToDAGISel::SelectLEAAddr(
SDValue N,
1457 X86ISelAddressMode AM;
1464 if (MatchAddress(N, AM))
1466 assert (T == AM.Segment);
1470 unsigned Complexity = 0;
1471 if (AM.BaseType == X86ISelAddressMode::RegBase)
1472 if (AM.Base_Reg.getNode())
1475 AM.Base_Reg = CurDAG->getRegister(0, VT);
1476 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
1479 if (AM.IndexReg.getNode())
1482 AM.IndexReg = CurDAG->getRegister(0, VT);
1494 if (AM.hasSymbolicDisplacement()) {
1497 if (Subtarget->is64Bit())
1503 if (AM.Disp && (AM.Base_Reg.getNode() || AM.IndexReg.getNode()))
1507 if (Complexity <= 2)
1510 getAddressOperands(AM, Base, Scale, Index, Disp, Segment);
1515 bool X86DAGToDAGISel::SelectTLSADDRAddr(
SDValue N,
SDValue &Base,
1521 X86ISelAddressMode AM;
1522 AM.GV = GA->getGlobal();
1523 AM.Disp += GA->getOffset();
1524 AM.Base_Reg = CurDAG->getRegister(0, N.
getValueType());
1525 AM.SymbolFlags = GA->getTargetFlags();
1531 AM.IndexReg = CurDAG->getRegister(0,
MVT::i64);
1534 getAddressOperands(AM, Base, Scale, Index, Disp, Segment);
1544 !IsProfitableToFold(N, P, P) ||
1545 !IsLegalToFold(N, P, P, OptLevel))
1548 return SelectAddr(N.
getNode(),
1549 N.
getOperand(1), Base, Scale, Index, Disp, Segment);
1556 SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
1557 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
1558 return CurDAG->getRegister(GlobalBaseReg,
1559 getTargetLowering()->getPointerTy()).getNode();
1562 SDNode *X86DAGToDAGISel::SelectAtomic64(
SDNode *Node,
unsigned Opc) {
1568 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
1569 if (!SelectAddr(Node, In1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
1572 MemOp[0] = cast<MemSDNode>(Node)->getMemOperand();
1573 const SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, In2L, In2H, Chain};
1574 SDNode *ResNode = CurDAG->getMachineNode(Opc,
SDLoc(Node),
1576 cast<MachineSDNode>(ResNode)->setMemRefs(MemOp, MemOp + 1);
1619 X86::LOCK_ADD64mi32,
1632 X86::LOCK_SUB64mi32,
1684 X86::LOCK_AND64mi32,
1697 X86::LOCK_XOR64mi32,
1715 if ((int32_t)CNVal != CNVal)
1720 if ((CNVal == 1) || (CNVal == -1)) {
1721 Op = (CNVal == 1) ?
INC :
DEC;
1757 SDNode *X86DAGToDAGISel::SelectAtomicLoadArith(
SDNode *Node,
MVT NVT) {
1769 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
1770 if (!SelectAddr(Node, Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
1828 else if (i64immSExt32(Val.
getNode()))
1834 assert(Opc != 0 &&
"Invalid arith lock transform!");
1840 MemOp[0] = cast<MemSDNode>(Node)->getMemOperand();
1842 SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain };
1845 SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Val, Chain };
1848 cast<MachineSDNode>(
Ret)->setMemRefs(MemOp, MemOp + 1);
1850 return CurDAG->getMergeValues(RetVals, 2, dl).getNode();
1858 UE = N->
use_end(); UI != UE; ++UI) {
1863 if (cast<RegisterSDNode>(UI->getOperand(1))->
getReg() !=
1868 FlagUE = UI->
use_end(); FlagUI != FlagUE; ++FlagUI) {
1870 if (FlagUI.getUse().getResNo() != 1)
continue;
1872 if (!FlagUI->isMachineOpcode())
return false;
1874 switch (FlagUI->getMachineOpcode()) {
1876 case X86::SETAr:
case X86::SETAEr:
case X86::SETBr:
case X86::SETBEr:
1877 case X86::SETEr:
case X86::SETNEr:
case X86::SETPr:
case X86::SETNPr:
1878 case X86::SETAm:
case X86::SETAEm:
case X86::SETBm:
case X86::SETBEm:
1879 case X86::SETEm:
case X86::SETNEm:
case X86::SETPm:
case X86::SETNPm:
1880 case X86::JA_4:
case X86::JAE_4:
case X86::JB_4:
case X86::JBE_4:
1881 case X86::JE_4:
case X86::JNE_4:
case X86::JP_4:
case X86::JNP_4:
1882 case X86::CMOVA16rr:
case X86::CMOVA16rm:
1883 case X86::CMOVA32rr:
case X86::CMOVA32rm:
1884 case X86::CMOVA64rr:
case X86::CMOVA64rm:
1885 case X86::CMOVAE16rr:
case X86::CMOVAE16rm:
1886 case X86::CMOVAE32rr:
case X86::CMOVAE32rm:
1887 case X86::CMOVAE64rr:
case X86::CMOVAE64rm:
1888 case X86::CMOVB16rr:
case X86::CMOVB16rm:
1889 case X86::CMOVB32rr:
case X86::CMOVB32rm:
1890 case X86::CMOVB64rr:
case X86::CMOVB64rm:
1891 case X86::CMOVBE16rr:
case X86::CMOVBE16rm:
1892 case X86::CMOVBE32rr:
case X86::CMOVBE32rm:
1893 case X86::CMOVBE64rr:
case X86::CMOVBE64rm:
1894 case X86::CMOVE16rr:
case X86::CMOVE16rm:
1895 case X86::CMOVE32rr:
case X86::CMOVE32rm:
1896 case X86::CMOVE64rr:
case X86::CMOVE64rm:
1897 case X86::CMOVNE16rr:
case X86::CMOVNE16rm:
1898 case X86::CMOVNE32rr:
case X86::CMOVNE32rm:
1899 case X86::CMOVNE64rr:
case X86::CMOVNE64rm:
1900 case X86::CMOVNP16rr:
case X86::CMOVNP16rm:
1901 case X86::CMOVNP32rr:
case X86::CMOVNP32rm:
1902 case X86::CMOVNP64rr:
case X86::CMOVNP64rm:
1903 case X86::CMOVP16rr:
case X86::CMOVP16rm:
1904 case X86::CMOVP32rr:
case X86::CMOVP32rm:
1905 case X86::CMOVP64rr:
case X86::CMOVP64rm:
1908 default:
return false;
1926 if (StoredVal.
getResNo() != 0)
return false;
1940 LoadNode = cast<LoadSDNode>(
Load);
1960 bool ChainCheck =
false;
1979 UE = UI->
use_end(); UI != UE; ++UI) {
1980 if (UI.getUse().getResNo() != 0)
1982 if (UI->getNodeId() > LoadId)
2005 if (LdVT ==
MVT::i64)
return X86::DEC64m;
2006 if (LdVT ==
MVT::i32)
return X86::DEC32m;
2007 if (LdVT ==
MVT::i16)
return X86::DEC16m;
2008 if (LdVT ==
MVT::i8)
return X86::DEC8m;
2010 assert(Opc ==
X86ISD::INC &&
"unrecognized opcode");
2011 if (LdVT ==
MVT::i64)
return X86::INC64m;
2012 if (LdVT ==
MVT::i32)
return X86::INC32m;
2013 if (LdVT ==
MVT::i16)
return X86::INC16m;
2014 if (LdVT ==
MVT::i8)
return X86::INC8m;
2021 SDNode *X86DAGToDAGISel::SelectGather(
SDNode *Node,
unsigned Opc) {
2039 Disp, Segment, VMask, Chain};
2040 SDNode *ResNode = CurDAG->getMachineNode(Opc,
SDLoc(Node), VTs, Ops);
2067 unsigned IntNo = cast<ConstantSDNode>(Node->
getOperand(1))->getZExtValue();
2086 if (!Subtarget->hasAVX2())
2108 SDNode *RetVal = SelectGather(Node, Opc);
2118 return getGlobalBaseReg();
2147 SDNode *RetVal = SelectAtomic64(Node, Opc);
2157 SDNode *RetVal = SelectAtomicLoadArith(Node, NVT);
2179 if (!Cst || !ShlCst)
2183 uint64_t ShlVal = ShlCst->getZExtValue();
2187 uint64_t RemovedBitsMask = (1ULL << ShlVal) - 1;
2188 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
2211 ShlOp = X86::SHL32ri;
2215 case ISD::AND: Op = X86::AND32ri8;
break;
2216 case ISD::OR: Op = X86::OR32ri8;
break;
2217 case ISD::XOR: Op = X86::XOR32ri8;
break;
2222 ShlOp = X86::SHL64ri;
2226 case ISD::AND: Op = CstVT==
MVT::i8? X86::AND64ri8 : X86::AND64ri32;
break;
2227 case ISD::OR: Op = CstVT==
MVT::i8? X86::OR64ri8 : X86::OR64ri32;
break;
2228 case ISD::XOR: Op = CstVT==
MVT::i8? X86::XOR64ri8 : X86::XOR64ri32;
break;
2234 SDValue NewCst = CurDAG->getTargetConstant(Val >> ShlVal, CstVT);
2235 SDNode *New = CurDAG->getMachineNode(Op, dl, NVT, N0->
getOperand(0),NewCst);
2236 return CurDAG->SelectNodeTo(Node, ShlOp, NVT,
SDValue(New, 0),
2247 case MVT::i16: LoReg = X86::AX; Opc = X86::MUL16r;
break;
2249 case MVT::i64: LoReg = X86::RAX; Opc = X86::MUL64r;
break;
2252 SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
2257 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
2271 bool hasBMI2 = Subtarget->hasBMI2();
2275 case MVT::i8: Opc = X86::MUL8r; MOpc = X86::MUL8m;
break;
2276 case MVT::i16: Opc = X86::MUL16r; MOpc = X86::MUL16m;
break;
2277 case MVT::i32: Opc = hasBMI2 ? X86::MULX32rr : X86::MUL32r;
2278 MOpc = hasBMI2 ? X86::MULX32rm : X86::MUL32m;
break;
2279 case MVT::i64: Opc = hasBMI2 ? X86::MULX64rr : X86::MUL64r;
2280 MOpc = hasBMI2 ? X86::MULX64rm : X86::MUL64m;
break;
2285 case MVT::i8: Opc = X86::IMUL8r; MOpc = X86::IMUL8m;
break;
2286 case MVT::i16: Opc = X86::IMUL16r; MOpc = X86::IMUL16m;
break;
2287 case MVT::i32: Opc = X86::IMUL32r; MOpc = X86::IMUL32m;
break;
2288 case MVT::i64: Opc = X86::IMUL64r; MOpc = X86::IMUL64m;
break;
2292 unsigned SrcReg, LoReg, HiReg;
2297 SrcReg = LoReg =
X86::AL; HiReg = X86::AH;
2301 SrcReg = LoReg = X86::AX; HiReg = X86::DX;
2309 SrcReg = LoReg = X86::RAX; HiReg = X86::RDX;
2312 SrcReg =
X86::EDX; LoReg = HiReg = 0;
2315 SrcReg = X86::RDX; LoReg = HiReg = 0;
2319 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
2320 bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
2323 foldedLoad = TryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
2328 SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, SrcReg,
2336 if (MOpc == X86::MULX32rm || MOpc == X86::MULX64rm) {
2338 SDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
2345 SDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
2351 ReplaceUses(N1.
getValue(1), Chain);
2353 SDValue Ops[] = { N1, InFlag };
2354 if (Opc == X86::MULX32rr || Opc == X86::MULX64rr) {
2356 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
2362 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
2368 if (HiReg == X86::AH && Subtarget->is64Bit() &&
2370 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
2375 if (!
SDValue(Node, 0).use_empty())
2377 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl,
MVT::i8, Result));
2380 Result =
SDValue(CurDAG->getMachineNode(X86::SHR16ri, dl, MVT::i16,
2382 CurDAG->getTargetConstant(8,
MVT::i8)), 0);
2385 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl,
MVT::i8, Result));
2390 assert(LoReg &&
"Register for low half is not defined!");
2391 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg, NVT,
2395 ReplaceUses(
SDValue(Node, 0), ResLo);
2401 assert(HiReg &&
"Register for high half is not defined!");
2402 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg, NVT,
2406 ReplaceUses(
SDValue(Node, 1), ResHi);
2420 switch (NVT.SimpleTy) {
2422 case MVT::i8: Opc = X86::DIV8r; MOpc = X86::DIV8m;
break;
2423 case MVT::i16: Opc = X86::DIV16r; MOpc = X86::DIV16m;
break;
2424 case MVT::i32: Opc = X86::DIV32r; MOpc = X86::DIV32m;
break;
2425 case MVT::i64: Opc = X86::DIV64r; MOpc = X86::DIV64m;
break;
2428 switch (NVT.SimpleTy) {
2430 case MVT::i8: Opc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
2431 case MVT::i16: Opc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
2432 case MVT::i32: Opc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
2433 case MVT::i64: Opc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
2437 unsigned LoReg, HiReg, ClrReg;
2438 unsigned SExtOpcode;
2439 switch (NVT.SimpleTy) {
2442 LoReg =
X86::AL; ClrReg = HiReg = X86::AH;
2443 SExtOpcode = X86::CBW;
2446 LoReg = X86::AX; HiReg = X86::DX;
2448 SExtOpcode = X86::CWD;
2452 SExtOpcode = X86::CDQ;
2455 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
2456 SExtOpcode = X86::CQO;
2460 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
2461 bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
2462 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
2465 if (NVT ==
MVT::i8 && (!isSigned || signBitIsZero)) {
2468 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Move, Chain;
2469 if (TryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
2475 ReplaceUses(N0.
getValue(1), Chain);
2479 Chain = CurDAG->getEntryNode();
2485 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
2486 LoReg, N0,
SDValue()).getValue(1);
2487 if (isSigned && !signBitIsZero) {
2493 SDValue ClrNode =
SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, NVT), 0);
2494 switch (NVT.SimpleTy) {
2497 SDValue(CurDAG->getMachineNode(
2499 CurDAG->getTargetConstant(X86::sub_16bit,
MVT::i32)),
2506 SDValue(CurDAG->getMachineNode(
2508 CurDAG->getTargetConstant(0,
MVT::i64), ClrNode,
2509 CurDAG->getTargetConstant(X86::sub_32bit,
MVT::i32)),
2516 InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
2517 ClrNode, InFlag).getValue(1);
2541 if (HiReg == X86::AH && Subtarget->is64Bit() &&
2543 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
2550 if (!
SDValue(Node, 0).use_empty())
2552 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl,
MVT::i8, Result));
2555 Result =
SDValue(CurDAG->getMachineNode(X86::SHR16ri, dl, MVT::i16,
2557 CurDAG->getTargetConstant(8,
MVT::i8)),
2560 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl,
MVT::i8, Result));
2564 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
2565 LoReg, NVT, InFlag);
2567 ReplaceUses(
SDValue(Node, 0), Result);
2572 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
2573 HiReg, NVT, InFlag);
2575 ReplaceUses(
SDValue(Node, 1), Result);
2612 if (!Subtarget->is64Bit()) {
2615 case MVT::i32: TRC = &X86::GR32_ABCDRegClass;
break;
2616 case MVT::i16: TRC = &X86::GR16_ABCDRegClass;
break;
2625 SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl,
2629 SDNode *NewNode = CurDAG->getMachineNode(X86::TEST8ri, dl,
MVT::i32,
2650 case MVT::i64: TRC = &X86::GR64_ABCDRegClass;
break;
2651 case MVT::i32: TRC = &X86::GR32_ABCDRegClass;
break;
2652 case MVT::i16: TRC = &X86::GR16_ABCDRegClass;
break;
2660 SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl,
2666 SDNode *NewNode = CurDAG->getMachineNode(X86::TEST8ri_NOREX, dl,
2684 SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::sub_16bit, dl,
2688 SDNode *NewNode = CurDAG->getMachineNode(X86::TEST16ri, dl,
MVT::i32,
2698 if ((C->
getZExtValue() & ~UINT64_C(0xffffffff)) == 0 &&
2706 SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::sub_32bit, dl,
2710 SDNode *NewNode = CurDAG->getMachineNode(X86::TEST32ri, dl,
MVT::i32,
2741 unsigned Opc = StoredVal->getOpcode();
2746 LoadNode, InputChain))
2749 SDValue Base, Scale, Index, Disp, Segment;
2750 if (!SelectAddr(LoadNode, LoadNode->
getBasePtr(),
2751 Base, Scale, Index, Disp, Segment))
2757 const SDValue Ops[] = { Base, Scale, Index, Disp, Segment, InputChain };
2766 ReplaceUses(
SDValue(StoredVal.getNode(), 1),
SDValue(Result, 0));
2772 SDNode *ResNode = SelectCode(Node);
2775 if (ResNode == NULL || ResNode == Node)
2778 ResNode->
dump(CurDAG);
2784 bool X86DAGToDAGISel::
2785 SelectInlineAsmMemoryOperand(
const SDValue &Op,
char ConstraintCode,
2786 std::vector<SDValue> &OutOps) {
2787 SDValue Op0, Op1, Op2, Op3, Op4;
2788 switch (ConstraintCode) {
2791 default:
return true;
2793 if (!SelectAddr(0, Op, Op0, Op1, Op2, Op3, Op4))
2798 OutOps.push_back(Op0);
2799 OutOps.push_back(Op1);
2800 OutOps.push_back(Op2);
2801 OutOps.push_back(Op3);
2802 OutOps.push_back(Op4);
2811 return new X86DAGToDAGISel(TM, OptLevel);
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
bool isInt< 32 >(int64_t x)
static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq)
void push_back(const T &Elt)
SDValue getConstant(uint64_t Val, EVT VT, bool isTarget=false)
SDValue getValue(unsigned R) const
void dump() const
dump - Dump this node, for debugging.
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd)
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
static bool FoldMaskAndShiftToScale(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getOpcode() const
unsigned getSizeInBits() const
unsigned getNumOperands() const
unsigned getNumOperands() const
const SDValue & getOperand(unsigned Num) const
void setNodeId(int Id)
setNodeId - Set unique node id.
void ComputeMaskedBits(SDValue Op, APInt &KnownZero, APInt &KnownOne, unsigned Depth=0) const
const SDValue & getBasePtr() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
unsigned CountTrailingOnes_64(uint64_t Value)
const HexagonInstrInfo * TII
bool isNormalStore(const SDNode *N)
#define llvm_unreachable(msg)
bool isInt< 8 >(int64_t x)
static bool HasNoSignedComparisonUses(SDNode *N)
static SDValue getAtomicLoadArithTargetConstant(SelectionDAG *CurDAG, SDLoc dl, enum AtomicOpc &Op, MVT NVT, SDValue Val)
Abstract Stack Frame Information.
enable_if_c< std::numeric_limits< T >::is_integer &&!std::numeric_limits< T >::is_signed, std::size_t >::type 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...
X86 compare and logical compare instructions.
static bool FoldMaskAndShiftToExtract(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static bool isLoadIncOrDecStore(StoreSDNode *StoreNode, unsigned Opc, SDValue StoredVal, SelectionDAG *CurDAG, LoadSDNode *&LoadNode, SDValue &InputChain)
enable_if_c< std::numeric_limits< T >::is_integer &&!std::numeric_limits< T >::is_signed, std::size_t >::type 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...
Simple integer binary arithmetic operators.
const SDValue & getBasePtr() const
static const uint16_t AtomicOpcTbl[AtomicOpcEnd][AtomicSzEnd]
EVT getMemoryVT() const
getMemoryVT - Return the type of the in-memory value.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
SDNode * getNode() const
get the SDNode which holds the desired result
bool isNormalLoad(const SDNode *N)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
const SDValue & getOperand(unsigned i) const
bool isNonTemporal() const
LLVM Constant Representation.
bool isVector() const
isVector - Return true if this is a vector value type.
void RepositionNode(allnodes_iterator Position, SDNode *N)
unsigned getOpcode() const
use_iterator use_begin() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
ISD::MemIndexedMode getAddressingMode() const
uint64_t getConstantOperandVal(unsigned Num) const
const MCInstrDesc & get(unsigned Opcode) const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getOffset() const
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
const SDValue & getChain() const
MachineMemOperand * getMemOperand() const
unsigned getAddrSpace() const
static void InsertDAGNode(SelectionDAG &DAG, SDValue Pos, SDValue N)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
ISD::LoadExtType getExtensionType() const
Class for arbitrary precision integers.
int64_t getSExtValue() const
static use_iterator use_end()
ZERO_EXTEND - Used for integer types, zeroing the new bits.
SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT)
ANY_EXTEND - Used for integer types. The high bits are undefined.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
static bool isDispSafeForFrameIndex(int64_t Val)
uint64_t getConstantOperandVal(unsigned i) const
static unsigned getFusedLdStOpcode(EVT &LdVT, unsigned Opc)
Bitwise operators - logical and, logical or, logical xor.
bool hasAnyUseOfValue(unsigned Value) const
FunctionPass * createX86ISelDag(X86TargetMachine &TM, CodeGenOpt::Level OptLevel)
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
void ReplaceAllUsesWith(SDValue From, SDValue Op)
STATISTIC(NumLoadMoved,"Number of loads moved below TokenFactor")
static bool FoldMaskedShiftToScaledMask(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static void MoveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load, SDValue Call, SDValue OrigChain)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const SDValue & getOffset() const
bool isNON_EXTLoad(const SDNode *N)
SDValue getTargetExtractSubreg(int SRIdx, SDLoc DL, EVT VT, SDValue Operand)
bool isZeroNode(SDValue Elt)
SDValue getTargetConstant(uint64_t Val, EVT VT)
bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M, bool hasSymbolicDisplacement=true)
TRUNCATE - Completely drop the high bits.
MVT getSimpleValueType(unsigned ResNo) const
bool isScalarFPTypeInSSEReg(EVT VT) const
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
bool isOperandOf(SDNode *N) const
bool isMachineOpcode() const
uint64_t getZExtValue() const