40 #define DEBUG_TYPE "legalizedag"
44 struct FloatSignAsInt;
58 class SelectionDAGLegalize {
70 EVT getSetCCResultType(
EVT VT)
const {
71 return TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
81 LegalizedNodes(LegalizedNodes), UpdatedNodes(UpdatedNodes) {}
84 void LegalizeOp(
SDNode *Node);
89 void LegalizeLoadOps(
SDNode *Node);
90 void LegalizeStoreOps(
SDNode *Node);
110 bool &NeedInvert,
const SDLoc &dl);
114 unsigned NumOps,
bool isSigned,
const SDLoc &dl);
117 SDNode *Node,
bool isSigned);
135 void ExpandDYNAMIC_STACKALLOC(
SDNode *Node,
137 void getSignAsIntValue(FloatSignAsInt &State,
const SDLoc &DL,
139 SDValue modifySignAsInt(
const FloatSignAsInt &State,
const SDLoc &DL,
162 bool ExpandNode(
SDNode *Node);
163 void ConvertNodeToLibcall(
SDNode *Node);
164 void PromoteNode(
SDNode *Node);
169 LegalizedNodes.
erase(N);
171 UpdatedNodes->insert(N);
175 dbgs() <<
" with: "; New->
dump(&DAG));
178 "Replacing one node with another that produces a different number "
182 UpdatedNodes->insert(New);
187 dbgs() <<
" with: "; New->
dump(&DAG));
191 UpdatedNodes->insert(New.
getNode());
203 UpdatedNodes->insert(New[
i].getNode());
214 SDValue SelectionDAGLegalize::ShuffleWithNarrowerEltType(
219 unsigned NumEltsGrowth = NumDestElts / NumMaskElts;
221 assert(NumEltsGrowth &&
"Cannot promote to vector type with fewer elts!");
223 if (NumEltsGrowth == 1)
224 return DAG.getVectorShuffle(NVT, dl, N1, N2, Mask);
227 for (
unsigned i = 0;
i != NumMaskElts; ++
i) {
229 for (
unsigned j = 0; j != NumEltsGrowth; ++j) {
233 NewMask.
push_back(Idx * NumEltsGrowth + j);
236 assert(NewMask.
size() == NumDestElts &&
"Non-integer NumEltsGrowth?");
237 assert(TLI.isShuffleMaskLegal(NewMask, NVT) &&
"Shuffle not legal?");
238 return DAG.getVectorShuffle(NVT, dl, N1, N2, NewMask);
275 TLI.ShouldShrinkFPConstant(OrigVT)) {
285 DAG.getConstantPool(LLVMC, TLI.getPointerTy(DAG.getDataLayout()));
286 unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->
getAlignment();
288 SDValue Result = DAG.getExtLoad(
295 OrigVT, dl, DAG.getEntryNode(), CPIdx,
305 TLI.getPointerTy(DAG.getDataLayout()));
306 unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->
getAlignment();
308 VT, dl, DAG.getEntryNode(), CPIdx,
317 SDValue SelectionDAGLegalize::PerformInsertVectorEltInMemory(
SDValue Vec,
333 SDValue StackPtr = DAG.CreateStackTemporary(VT);
335 int SPFI = cast<FrameIndexSDNode>(StackPtr.
getNode())->getIndex();
339 DAG.getEntryNode(), dl, Tmp1, StackPtr,
342 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, Tmp3);
348 DAG.getMachineFunction(), SPFI));
369 for (
unsigned i = 0;
i != NumElts; ++
i)
370 ShufOps.
push_back(
i != InsertPos->getZExtValue() ?
i : NumElts);
372 return DAG.getVectorShuffle(Vec.
getValueType(), dl, Vec, ScVec, ShufOps);
375 return PerformInsertVectorEltInMemory(Vec, Val, Idx, dl);
396 bitcastToAPInt().zextOrTrunc(32),
398 return DAG.getStore(Chain, dl, Con, Ptr, ST->
getPointerInfo(), Alignment,
408 Alignment, MMOFlags, AAInfo);
418 if (DAG.getDataLayout().isBigEndian())
421 Lo = DAG.getStore(Chain, dl, Lo, Ptr, ST->
getPointerInfo(), Alignment,
425 Hi = DAG.getStore(Chain, dl, Hi, Ptr,
427 MinAlign(Alignment, 4U), MMOFlags, AAInfo);
436 void SelectionDAGLegalize::LegalizeStoreOps(
SDNode *Node) {
447 if (
SDNode *OptStore = OptimizeFloatStore(ST).getNode()) {
448 ReplaceNode(ST, OptStore);
455 switch (TLI.getOperationAction(
ISD::STORE, VT)) {
464 if (!TLI.allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Align)) {
465 SDValue Result = TLI.expandUnalignedStore(ST, DAG);
466 ReplaceNode(
SDValue(ST, 0), Result);
472 if (Res && Res !=
SDValue(Node, 0))
473 ReplaceNode(
SDValue(Node, 0), Res);
479 "Can only promote stores to same size type");
483 Alignment, MMOFlags, AAInfo);
484 ReplaceNode(
SDValue(Node, 0), Result);
495 auto &DL = DAG.getDataLayout();
503 Value = DAG.getZeroExtendInReg(Value, dl, StVT);
505 DAG.getTruncStore(Chain, dl, Value, Ptr, ST->
getPointerInfo(), NVT,
506 Alignment, MMOFlags, AAInfo);
507 ReplaceNode(
SDValue(Node, 0), Result);
508 }
else if (StWidth & (StWidth - 1)) {
511 unsigned RoundWidth = 1 <<
Log2_32(StWidth);
512 assert(RoundWidth < StWidth);
513 unsigned ExtraWidth = StWidth - RoundWidth;
514 assert(ExtraWidth < RoundWidth);
515 assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
516 "Store size not an integral number of bytes!");
520 unsigned IncrementSize;
525 Lo = DAG.getTruncStore(Chain, dl, Value, Ptr, ST->
getPointerInfo(),
526 RoundVT, Alignment, MMOFlags, AAInfo);
529 IncrementSize = RoundWidth / 8;
531 DAG.getConstant(IncrementSize, dl,
534 ISD::SRL, dl, Value.getValueType(), Value,
535 DAG.getConstant(RoundWidth, dl,
536 TLI.getShiftAmountTy(Value.getValueType(), DL)));
537 Hi = DAG.getTruncStore(
540 MinAlign(Alignment, IncrementSize), MMOFlags, AAInfo);
546 ISD::SRL, dl, Value.getValueType(), Value,
547 DAG.getConstant(ExtraWidth, dl,
548 TLI.getShiftAmountTy(Value.getValueType(), DL)));
550 RoundVT, Alignment, MMOFlags, AAInfo);
553 IncrementSize = RoundWidth / 8;
555 DAG.getConstant(IncrementSize, dl,
557 Lo = DAG.getTruncStore(
558 Chain, dl, Value, Ptr,
560 MinAlign(Alignment, IncrementSize), MMOFlags, AAInfo);
565 ReplaceNode(
SDValue(Node, 0), Result);
575 if (!TLI.allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Align)) {
576 SDValue Result = TLI.expandUnalignedStore(ST, DAG);
577 ReplaceNode(
SDValue(ST, 0), Result);
583 if (Res && Res !=
SDValue(Node, 0))
584 ReplaceNode(
SDValue(Node, 0), Res);
589 "Vector Stores are handled in LegalizeVectorOps");
592 assert(TLI.isTypeLegal(StVT) &&
593 "Do not know how to expand this store!");
597 Alignment, MMOFlags, AAInfo);
598 ReplaceNode(
SDValue(Node, 0), Result);
605 void SelectionDAGLegalize::LegalizeLoadOps(
SDNode *Node) {
618 switch (TLI.getOperationAction(Node->
getOpcode(), VT)) {
627 if (!TLI.allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Align)) {
628 std::tie(RVal, RChain) = TLI.expandUnalignedLoad(LD, DAG);
633 if (
SDValue Res = TLI.LowerOperation(RVal, DAG)) {
640 MVT NVT = TLI.getTypeToPromoteTo(Node->
getOpcode(), VT);
642 "Can only promote loads to same size type");
650 if (RChain.
getNode() != Node) {
651 assert(RVal.
getNode() != Node &&
"Load must be completely replaced");
652 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 0), RVal);
653 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 1), RChain);
655 UpdatedNodes->insert(RVal.
getNode());
656 UpdatedNodes->insert(RChain.
getNode());
711 }
else if (SrcWidth & (SrcWidth - 1)) {
714 unsigned RoundWidth = 1 <<
Log2_32(SrcWidth);
715 assert(RoundWidth < SrcWidth);
716 unsigned ExtraWidth = SrcWidth - RoundWidth;
717 assert(ExtraWidth < RoundWidth);
718 assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
719 "Load size not an integral number of bytes!");
723 unsigned IncrementSize;
724 auto &DL = DAG.getDataLayout();
734 IncrementSize = RoundWidth / 8;
735 Ptr = DAG.getNode(
ISD::ADD, dl, Ptr.getValueType(),
Ptr,
736 DAG.getConstant(IncrementSize, dl,
737 Ptr.getValueType()));
740 ExtraVT,
MinAlign(Alignment, IncrementSize), MMOFlags,
751 DAG.getConstant(RoundWidth, dl,
752 TLI.getShiftAmountTy(Hi.getValueType(), DL)));
765 IncrementSize = RoundWidth / 8;
766 Ptr = DAG.getNode(
ISD::ADD, dl, Ptr.getValueType(),
Ptr,
767 DAG.getConstant(IncrementSize, dl,
768 Ptr.getValueType()));
771 ExtraVT,
MinAlign(Alignment, IncrementSize), MMOFlags,
782 DAG.getConstant(ExtraWidth, dl,
783 TLI.getShiftAmountTy(Hi.getValueType(), DL)));
791 bool isCustom =
false;
792 switch (TLI.getLoadExtAction(ExtType, Node->
getValueType(0),
814 if (!TLI.allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS, Align)) {
815 std::tie(Value, Chain) = TLI.expandUnalignedLoad(LD, DAG);
826 if (TLI.isTypeLegal(SrcVT) ||
827 TLI.isLoadExtLegal(ExtType, LoadVT, SrcVT)) {
833 SDValue Load = DAG.getExtLoad(MidExtType, dl, LoadVT, Chain, Ptr,
861 "Vector Loads are handled in LegalizeVectorOps");
868 "EXTLOAD should always be supported!");
881 ValRes = DAG.getZeroExtendInReg(Result, dl, SrcVT.getScalarType());
890 if (Chain.getNode() != Node) {
891 assert(Value.getNode() != Node &&
"Load must be completely replaced");
892 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 0), Value);
893 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 1), Chain);
895 UpdatedNodes->insert(Value.getNode());
896 UpdatedNodes->insert(Chain.getNode());
903 void SelectionDAGLegalize::LegalizeOp(
SDNode *Node) {
914 "Unexpected illegal type!");
917 assert((TLI.getTypeAction(*DAG.getContext(),
Op.getValueType()) ==
919 TLI.isTypeLegal(
Op.getValueType()) ||
921 "Unexpected illegal type!");
926 bool SimpleFinishLegalizing =
true;
935 Action = TLI.getOperationAction(Node->
getOpcode(),
939 Action = TLI.getOperationAction(Node->
getOpcode(),
948 Action = TLI.getOperationAction(Node->
getOpcode(),
953 EVT InnerType = cast<VTSDNode>(Node->
getOperand(1))->getVT();
954 Action = TLI.getOperationAction(Node->
getOpcode(), InnerType);
958 Action = TLI.getOperationAction(Node->
getOpcode(),
971 cast<CondCodeSDNode>(Node->
getOperand(CCOperand))->
get();
972 Action = TLI.getCondCodeAction(CCCode, OpVT);
975 Action = TLI.getOperationAction(Node->
getOpcode(),
978 Action = TLI.getOperationAction(Node->
getOpcode(), OpVT);
986 SimpleFinishLegalizing =
false;
993 SimpleFinishLegalizing =
false;
1041 ReplaceNode(Node, NewVal.
getNode());
1056 if (SimpleFinishLegalizing) {
1077 NewNode = DAG.UpdateNodeOperands(Node, Op0, SAO);
1095 NewNode = DAG.UpdateNodeOperands(Node, Op0, Op1, SAO);
1101 if (NewNode != Node) {
1102 ReplaceNode(Node, NewNode);
1112 if (!(Res.getNode() != Node || Res.getResNo() != 0))
1117 ReplaceNode(
SDValue(Node, 0), Res);
1124 ReplaceNode(Node, ResultVals.
data());
1130 if (ExpandNode(Node))
1134 ConvertNodeToLibcall(Node);
1155 return LegalizeLoadOps(Node);
1158 return LegalizeStoreOps(Node);
1163 SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(
SDValue Op) {
1183 if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(User)) {
1209 StackPtr = DAG.CreateStackTemporary(VecVT);
1210 Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr,
1214 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
1227 DAG.ReplaceAllUsesOfValueWith(Ch,
SDValue(NewLoad.
getNode(), 1));
1233 NewLoadOperands[0] = Ch;
1235 SDValue(DAG.UpdateNodeOperands(NewLoad.
getNode(), NewLoadOperands), 0);
1239 SDValue SelectionDAGLegalize::ExpandInsertToVectorThroughStack(
SDValue Op) {
1248 EVT VecVT = Vec.getValueType();
1249 SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
1250 int FI = cast<FrameIndexSDNode>(StackPtr.
getNode())->getIndex();
1255 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo);
1258 SDValue SubStackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
1264 return DAG.getLoad(Op.
getValueType(), dl, Ch, StackPtr, PtrInfo);
1267 SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(
SDNode* Node) {
1275 SDValue FIPtr = DAG.CreateStackTemporary(VT);
1276 int FI = cast<FrameIndexSDNode>(FIPtr.
getNode())->getIndex();
1288 unsigned Offset = TypeByteSize*
i;
1296 Stores.push_back(DAG.getTruncStore(DAG.getEntryNode(), dl,
1300 Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl, Node->
getOperand(i),
1305 if (!Stores.empty())
1308 StoreChain = DAG.getEntryNode();
1311 return DAG.getLoad(VT, dl, StoreChain, FIPtr, PtrInfo);
1317 struct FloatSignAsInt {
1333 void SelectionDAGLegalize::getSignAsIntValue(FloatSignAsInt &State,
1338 State.FloatVT = FloatVT;
1341 if (TLI.isTypeLegal(IVT)) {
1342 State.IntValue = DAG.getNode(
ISD::BITCAST, DL, IVT, Value);
1344 State.SignBit = NumBits - 1;
1350 MVT LoadTy = TLI.getRegisterType(*DAG.getContext(),
MVT::i8);
1352 SDValue StackPtr = DAG.CreateStackTemporary(FloatVT, LoadTy);
1353 int FI = cast<FrameIndexSDNode>(StackPtr.
getNode())->getIndex();
1355 State.FloatPtr = StackPtr;
1358 State.Chain = DAG.getStore(DAG.getEntryNode(), DL, Value, State.FloatPtr,
1359 State.FloatPointerInfo);
1366 State.IntPointerInfo = State.FloatPointerInfo;
1371 DAG.getConstant(ByteOffset, DL, StackPtr.
getValueType()));
1376 State.IntPtr = IntPtr;
1377 State.IntValue = DAG.getExtLoad(
ISD::EXTLOAD, DL, LoadTy, State.Chain, IntPtr,
1378 State.IntPointerInfo,
MVT::i8);
1385 SDValue SelectionDAGLegalize::modifySignAsInt(
const FloatSignAsInt &State,
1392 SDValue Chain = DAG.getTruncStore(State.Chain, DL, NewIntValue, State.IntPtr,
1393 State.IntPointerInfo,
MVT::i8);
1394 return DAG.getLoad(State.FloatVT, DL, Chain, State.FloatPtr,
1395 State.FloatPointerInfo);
1398 SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(
SDNode *Node)
const {
1404 FloatSignAsInt SignAsInt;
1405 getSignAsIntValue(SignAsInt, DL, Sign);
1407 EVT IntVT = SignAsInt.IntValue.getValueType();
1408 SDValue SignMask = DAG.getConstant(SignAsInt.SignMask, DL, IntVT);
1414 if (TLI.isOperationLegalOrCustom(
ISD::FABS, FloatVT) &&
1415 TLI.isOperationLegalOrCustom(
ISD::FNEG, FloatVT)) {
1418 SDValue Cond = DAG.getSetCC(DL, getSetCCResultType(IntVT), SignBit,
1420 return DAG.getSelect(DL, FloatVT, Cond, NegValue, AbsValue);
1424 FloatSignAsInt MagAsInt;
1425 getSignAsIntValue(MagAsInt, DL, Mag);
1426 EVT MagVT = MagAsInt.IntValue.getValueType();
1427 SDValue ClearSignMask = DAG.getConstant(~MagAsInt.SignMask, DL, MagVT);
1432 int ShiftAmount = SignAsInt.SignBit - MagAsInt.SignBit;
1434 if (ShiftAmount > 0) {
1435 SDValue ShiftCnst = DAG.getConstant(ShiftAmount, DL, IntVT);
1437 }
else if (ShiftAmount < 0) {
1438 SDValue ShiftCnst = DAG.getConstant(-ShiftAmount, DL, IntVT);
1444 if (ShiftAmount > 0) {
1445 SDValue ShiftCnst = DAG.getConstant(ShiftAmount, DL, MagVT);
1447 }
else if (ShiftAmount < 0) {
1448 SDValue ShiftCnst = DAG.getConstant(-ShiftAmount, DL, MagVT);
1455 return modifySignAsInt(MagAsInt, DL, CopiedSign);
1458 SDValue SelectionDAGLegalize::ExpandFABS(
SDNode *Node)
const {
1465 SDValue Zero = DAG.getConstantFP(0.0, DL, FloatVT);
1470 FloatSignAsInt ValueAsInt;
1471 getSignAsIntValue(ValueAsInt, DL, Value);
1472 EVT IntVT = ValueAsInt.IntValue.getValueType();
1473 SDValue ClearSignMask = DAG.getConstant(~ValueAsInt.SignMask, DL, IntVT);
1476 return modifySignAsInt(ValueAsInt, DL, ClearedSign);
1479 void SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(
SDNode* Node,
1481 unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore();
1482 assert(SPReg &&
"Target cannot require DYNAMIC_STACKALLOC expansion and"
1483 " not tell us which reg is the stack pointer!");
1493 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, dl,
true), dl);
1496 SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
1498 unsigned Align = cast<ConstantSDNode>(Tmp3)->getZExtValue();
1499 unsigned StackAlign =
1500 DAG.getSubtarget().getFrameLowering()->getStackAlignment();
1502 if (Align > StackAlign)
1504 DAG.getConstant(-(uint64_t)Align, dl, VT));
1505 Chain = DAG.getCopyToReg(Chain, dl, SPReg, Tmp1);
1507 Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, dl,
true),
1508 DAG.getIntPtrConstant(0, dl,
true),
SDValue(), dl);
1532 bool SelectionDAGLegalize::LegalizeSetCCCondCode(
EVT VT,
SDValue &LHS,
1539 switch (TLI.getCondCodeAction(CCCode, OpVT)) {
1546 if (TLI.isCondCodeLegal(InvCC, OpVT)) {
1548 CC = DAG.getCondCode(InvCC);
1558 &&
"If SETO is expanded, SETOEQ must be legal!");
1563 &&
"If SETUO is expanded, SETUNE must be legal!");
1599 if (TLI.isCondCodeLegal(InvCC, OpVT)) {
1600 CC = DAG.getCondCode(InvCC);
1613 SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1);
1614 SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2);
1617 SetCC1 = DAG.getSetCC(dl, VT, LHS, LHS, CC1);
1618 SetCC2 = DAG.getSetCC(dl, VT, RHS, RHS, CC2);
1620 LHS = DAG.
getNode(Opc, dl, VT, SetCC1, SetCC2);
1636 unsigned SrcAlign = DAG.getDataLayout().getPrefTypeAlignment(
1638 SDValue FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign);
1649 unsigned DestAlign = DAG.getDataLayout().getPrefTypeAlignment(DestType);
1655 if (SrcSize > SlotSize)
1656 Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, PtrInfo,
1659 assert(SrcSize == SlotSize &&
"Invalid store");
1661 DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, PtrInfo, SrcAlign);
1665 if (SlotSize == DestSize)
1666 return DAG.getLoad(DestVT, dl, Store, FIPtr, PtrInfo, DestAlign);
1668 assert(SlotSize < DestSize &&
"Unknown extension!");
1669 return DAG.getExtLoad(
ISD::EXTLOAD, dl, DestVT, Store, FIPtr, PtrInfo, SlotVT,
1673 SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(
SDNode *Node) {
1682 SDValue Ch = DAG.getTruncStore(
1683 DAG.getEntryNode(), dl, Node->
getOperand(0), StackPtr,
1705 for (
int Phase = 0; Phase < 2; ++Phase) {
1708 for (
unsigned i = 0; i < NumElems; ++
i) {
1719 while (IntermedVals.
size() > 2) {
1720 NewIntermedVals.
clear();
1721 for (
unsigned i = 0, e = (IntermedVals.
size() & ~1u); i < e; i += 2) {
1727 FinalIndices.
reserve(IntermedVals[i].second.
size() +
1728 IntermedVals[i+1].second.
size());
1731 for (
unsigned j = 0, f = IntermedVals[i].second.
size(); j != f;
1734 FinalIndices.
push_back(IntermedVals[i].second[j]);
1736 for (
unsigned j = 0, f = IntermedVals[i+1].second.
size(); j != f;
1738 ShuffleVec[k] = NumElems + j;
1739 FinalIndices.
push_back(IntermedVals[i+1].second[j]);
1745 IntermedVals[i+1].first,
1750 std::make_pair(Shuffle, std::move(FinalIndices)));
1755 if ((IntermedVals.
size() & 1) != 0)
1758 IntermedVals.
swap(NewIntermedVals);
1762 "Invalid number of intermediate vectors");
1763 SDValue Vec1 = IntermedVals[0].first;
1765 if (IntermedVals.
size() > 1)
1766 Vec2 = IntermedVals[1].first;
1771 for (
unsigned i = 0, e = IntermedVals[0].second.
size(); i != e; ++
i)
1772 ShuffleVec[IntermedVals[0].second[i]] = i;
1773 for (
unsigned i = 0, e = IntermedVals[1].second.
size(); i != e; ++
i)
1774 ShuffleVec[IntermedVals[1].second[i]] = NumElems + i;
1787 SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(
SDNode *Node) {
1797 bool isOnlyLowElement =
true;
1798 bool MoreThanTwoValues =
false;
1799 bool isConstant =
true;
1800 for (
unsigned i = 0; i < NumElems; ++
i) {
1805 isOnlyLowElement =
false;
1806 if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V))
1811 }
else if (!Value2.
getNode()) {
1814 }
else if (V != Value1 && V != Value2) {
1815 MoreThanTwoValues =
true;
1820 return DAG.getUNDEF(VT);
1822 if (isOnlyLowElement)
1828 for (
unsigned i = 0, e = NumElems; i != e; ++
i) {
1830 dyn_cast<ConstantFPSDNode>(Node->
getOperand(i))) {
1831 CV.
push_back(const_cast<ConstantFP *>(V->getConstantFPValue()));
1833 dyn_cast<ConstantSDNode>(Node->
getOperand(i))) {
1835 CV.
push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
1852 DAG.getConstantPool(CP, TLI.getPointerTy(DAG.getDataLayout()));
1853 unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->
getAlignment();
1855 VT, dl, DAG.getEntryNode(), CPIdx,
1861 for (
unsigned i = 0; i < NumElems; ++
i) {
1867 if (TLI.shouldExpandBuildVectorWithShuffles(VT, DefinedValues.
size())) {
1868 if (!MoreThanTwoValues) {
1870 for (
unsigned i = 0; i < NumElems; ++
i) {
1874 ShuffleVec[
i] = V == Value1 ? 0 : NumElems;
1876 if (TLI.isShuffleMaskLegal(ShuffleVec, Node->
getValueType(0))) {
1883 Vec2 = DAG.getUNDEF(VT);
1886 return DAG.getVectorShuffle(VT, dl, Vec1, Vec2, ShuffleVec);
1896 return ExpandVectorBuildThroughStack(Node);
1913 Entry.
isZExt = !isSigned;
1914 Args.push_back(Entry);
1916 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
1917 TLI.getPointerTy(DAG.getDataLayout()));
1925 SDValue InChain = DAG.getEntryNode();
1930 const Function *
F = DAG.getMachineFunction().getFunction();
1932 TLI.isInTailCallPosition(DAG, Node, TCChain) &&
1938 CLI.setDebugLoc(
SDLoc(Node)).setChain(InChain)
1939 .setCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee, std::move(Args))
1940 .setTailCall(isTailCall).setSExtResult(isSigned).setZExtResult(!isSigned);
1942 std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
1944 if (!CallInfo.second.getNode())
1946 return DAG.getRoot();
1948 return CallInfo.first;
1954 const SDValue *Ops,
unsigned NumOps,
1955 bool isSigned,
const SDLoc &dl) {
1957 Args.reserve(NumOps);
1960 for (
unsigned i = 0; i != NumOps; ++
i) {
1961 Entry.
Node = Ops[
i];
1964 Entry.
isZExt = !isSigned;
1965 Args.push_back(Entry);
1967 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
1968 TLI.getPointerTy(DAG.getDataLayout()));
1973 CLI.setDebugLoc(dl).setChain(DAG.getEntryNode())
1974 .setCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee, std::move(Args))
1975 .setSExtResult(isSigned).setZExtResult(!isSigned);
1977 std::pair<SDValue,SDValue> CallInfo = TLI.LowerCallTo(CLI);
1979 return CallInfo.first;
1984 std::pair<SDValue, SDValue>
1998 Entry.
isZExt = !isSigned;
1999 Args.push_back(Entry);
2001 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2002 TLI.getPointerTy(DAG.getDataLayout()));
2007 CLI.setDebugLoc(
SDLoc(Node)).setChain(InChain)
2008 .setCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee, std::move(Args))
2009 .setSExtResult(isSigned).setZExtResult(!isSigned);
2011 std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
2025 case MVT::f32: LC = Call_F32;
break;
2026 case MVT::f64: LC = Call_F64;
break;
2027 case MVT::f80: LC = Call_F80;
break;
2031 return ExpandLibCall(LC, Node,
false);
2034 SDValue SelectionDAGLegalize::ExpandIntLibCall(
SDNode* Node,
bool isSigned,
2043 case MVT::i8: LC = Call_I8;
break;
2044 case MVT::i16: LC = Call_I16;
break;
2045 case MVT::i32: LC = Call_I32;
break;
2046 case MVT::i64: LC = Call_I64;
break;
2049 return ExpandLibCall(LC, Node, isSigned);
2054 SelectionDAGLegalize::ExpandDivRemLibCall(
SDNode *Node,
2072 SDValue InChain = DAG.getEntryNode();
2085 Entry.
isZExt = !isSigned;
2086 Args.push_back(Entry);
2090 SDValue FIPtr = DAG.CreateStackTemporary(RetVT);
2094 Entry.
isZExt = !isSigned;
2095 Args.push_back(Entry);
2097 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2098 TLI.getPointerTy(DAG.getDataLayout()));
2102 CLI.setDebugLoc(dl).setChain(InChain)
2103 .setCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee, std::move(Args))
2104 .setSExtResult(isSigned).setZExtResult(!isSigned);
2106 std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
2162 SelectionDAGLegalize::ExpandSinCosLibCall(
SDNode *Node,
2177 SDValue InChain = DAG.getEntryNode();
2190 Args.push_back(Entry);
2193 SDValue SinPtr = DAG.CreateStackTemporary(RetVT);
2194 Entry.
Node = SinPtr;
2198 Args.push_back(Entry);
2201 SDValue CosPtr = DAG.CreateStackTemporary(RetVT);
2202 Entry.
Node = CosPtr;
2206 Args.push_back(Entry);
2208 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2209 TLI.getPointerTy(DAG.getDataLayout()));
2213 CLI.setDebugLoc(dl).setChain(InChain)
2214 .setCallee(TLI.getLibcallCallingConv(LC),
2217 std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
2229 SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(
bool isSigned,
SDValue Op0,
2241 SDValue WordOff = DAG.getConstant(
sizeof(
int), dl,
2246 StackSlot, WordOff);
2247 if (DAG.getDataLayout().isLittleEndian())
2260 SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, Op0Mapped,
Lo,
2271 SDValue Bias = DAG.getConstantFP(isSigned ?
2285 DAG.getIntPtrConstant(0, dl));
2291 assert(!isSigned &&
"Legalize cannot Expand SINT_TO_FP for i64 yet");
2301 DAG.getConstant(UINT64_C(0x4330000000000000), dl,
MVT::i64);
2303 DAG.getConstantFP(
BitsToDouble(UINT64_C(0x4530000000100000)), dl,
2306 DAG.getConstant(UINT64_C(0x4530000000000000), dl,
MVT::i64);
2310 DAG.getConstant(32, dl,
MVT::i64));
2328 SDValue ShiftConst = DAG.getConstant(
2329 1, dl, TLI.getShiftAmountTy(Op0.
getValueType(), DAG.getDataLayout()));
2344 return DAG.getSelect(dl,
MVT::f32, SignBitTest, Slow, Fast);
2350 DAG.getConstant(UINT64_C(0xfffffffffffff800), dl,
MVT::i64));
2352 DAG.getConstant(UINT64_C(0x800), dl,
MVT::i64));
2354 DAG.getConstant(UINT64_C(0x7ff), dl,
MVT::i64));
2356 DAG.getConstant(UINT64_C(0), dl,
MVT::i64),
2360 DAG.getConstant(UINT64_C(0x0020000000000000), dl,
2364 EVT SHVT = TLI.getShiftAmountTy(Sel2.
getValueType(), DAG.getDataLayout());
2367 DAG.getConstant(32, dl, SHVT));
2371 DAG.getConstantFP(
BitsToDouble(UINT64_C(0x41f0000000000000)), dl,
2378 DAG.getIntPtrConstant(0, dl));
2387 SDValue Zero = DAG.getIntPtrConstant(0, dl),
2388 Four = DAG.getIntPtrConstant(4, dl);
2390 SignSet, Four,
Zero);
2398 case MVT::i8 : FF = 0x43800000ULL;
break;
2399 case MVT::i16: FF = 0x47800000ULL;
break;
2400 case MVT::i32: FF = 0x4F800000ULL;
break;
2401 case MVT::i64: FF = 0x5F800000ULL;
break;
2403 if (DAG.getDataLayout().isLittleEndian())
2409 DAG.getConstantPool(FudgeFactor, TLI.getPointerTy(DAG.getDataLayout()));
2410 unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->
getAlignment();
2412 Alignment =
std::min(Alignment, 4u);
2415 FudgeInReg = DAG.getLoad(
2416 MVT::f32, dl, DAG.getEntryNode(), CPIdx,
2420 SDValue Load = DAG.getExtLoad(
2437 SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(
SDValue LegalOp,
EVT DestVT,
2443 unsigned OpToUse = 0;
2455 if (isSigned)
continue;
2468 return DAG.getNode(OpToUse, dl, DestVT,
2470 dl, NewInTy, LegalOp));
2478 SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(
SDValue LegalOp,
EVT DestVT,
2482 EVT NewOutTy = DestVT;
2484 unsigned OpToUse = 0;
2499 if (!isSigned && TLI.isOperationLegalOrCustom(
ISD::FP_TO_UINT, NewOutTy)) {
2519 EVT SHVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
2529 APInt MaskHi4(Sz, 0), MaskHi2(Sz, 0), MaskHi1(Sz, 0);
2530 APInt MaskLo4(Sz, 0), MaskLo2(Sz, 0), MaskLo1(Sz, 0);
2531 for (
unsigned J = 0; J != Sz; J += 8) {
2532 MaskHi4 = MaskHi4.Or(
APInt(Sz, 0xF0ull << J));
2533 MaskLo4 = MaskLo4.Or(
APInt(Sz, 0x0Full << J));
2534 MaskHi2 = MaskHi2.Or(
APInt(Sz, 0xCCull << J));
2535 MaskLo2 = MaskLo2.Or(
APInt(Sz, 0x33ull << J));
2536 MaskHi1 = MaskHi1.Or(
APInt(Sz, 0xAAull << J));
2537 MaskLo1 = MaskLo1.Or(
APInt(Sz, 0x55ull << J));
2541 Tmp = (Sz > 8 ? DAG.getNode(
ISD::BSWAP, dl, VT, Op) :
Op);
2544 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskHi4, dl, VT));
2545 Tmp3 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskLo4, dl, VT));
2546 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Tmp2, DAG.getConstant(4, dl, VT));
2547 Tmp3 = DAG.
getNode(
ISD::SHL, dl, VT, Tmp3, DAG.getConstant(4, dl, VT));
2551 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskHi2, dl, VT));
2552 Tmp3 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskLo2, dl, VT));
2553 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Tmp2, DAG.getConstant(2, dl, VT));
2554 Tmp3 = DAG.
getNode(
ISD::SHL, dl, VT, Tmp3, DAG.getConstant(2, dl, VT));
2558 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskHi1, dl, VT));
2559 Tmp3 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskLo1, dl, VT));
2560 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Tmp2, DAG.getConstant(1, dl, VT));
2561 Tmp3 = DAG.
getNode(
ISD::SHL, dl, VT, Tmp3, DAG.getConstant(1, dl, VT));
2566 Tmp = DAG.getConstant(0, dl, VT);
2567 for (
unsigned I = 0, J = Sz-1;
I < Sz; ++
I, --J) {
2576 Shift = Shift.shl(J);
2577 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp2, DAG.getConstant(Shift, dl, VT));
2587 EVT SHVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
2588 SDValue Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8;
2592 Tmp2 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2593 Tmp1 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2594 return DAG.getNode(
ISD::OR, dl, VT, Tmp1, Tmp2);
2596 Tmp4 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(24, dl, SHVT));
2597 Tmp3 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2598 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2599 Tmp1 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(24, dl, SHVT));
2601 DAG.getConstant(0xFF0000, dl, VT));
2602 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp2, DAG.getConstant(0xFF00, dl, VT));
2605 return DAG.getNode(
ISD::OR, dl, VT, Tmp4, Tmp2);
2607 Tmp8 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(56, dl, SHVT));
2608 Tmp7 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(40, dl, SHVT));
2609 Tmp6 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(24, dl, SHVT));
2610 Tmp5 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2611 Tmp4 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2612 Tmp3 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(24, dl, SHVT));
2613 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(40, dl, SHVT));
2614 Tmp1 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(56, dl, SHVT));
2616 DAG.getConstant(255ULL<<48, dl, VT));
2618 DAG.getConstant(255ULL<<40, dl, VT));
2620 DAG.getConstant(255ULL<<32, dl, VT));
2622 DAG.getConstant(255ULL<<24, dl, VT));
2624 DAG.getConstant(255ULL<<16, dl, VT));
2626 DAG.getConstant(255ULL<<8 , dl, VT));
2633 return DAG.getNode(
ISD::OR, dl, VT, Tmp8, Tmp4);
2638 SDValue SelectionDAGLegalize::ExpandBitCount(
unsigned Opc,
SDValue Op,
2644 EVT ShVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
2648 "CTPOP not implemented for this type.");
2666 DAG.getConstant(1, dl, ShVT)),
2670 DAG.getNode(
ISD::AND, dl, VT, Op, Mask33),
2673 DAG.getConstant(2, dl, ShVT)),
2679 DAG.getConstant(4, dl, ShVT))),
2683 DAG.getNode(
ISD::MUL, dl, VT, Op, Mask01),
2684 DAG.getConstant(Len - 8, dl, ShVT));
2696 EVT SetCCVT = getSetCCResultType(VT);
2698 SDValue Zero = DAG.getConstant(0, dl, VT);
2701 DAG.getConstant(len, dl, VT),
CTLZ);
2713 EVT ShVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
2714 for (
unsigned i = 0; (1U <<
i) <= (len / 2); ++
i) {
2715 SDValue Tmp3 = DAG.getConstant(1ULL << i, dl, ShVT);
2719 Op = DAG.getNOT(dl, Op, VT);
2732 DAG.getNOT(dl, Op, VT),
2734 DAG.getConstant(1, dl, VT)));
2736 if (!TLI.isOperationLegalOrCustom(
ISD::CTPOP, VT) &&
2737 TLI.isOperationLegalOrCustom(
ISD::CTLZ, VT))
2738 return DAG.getNode(
ISD::SUB, dl, VT,
2741 return DAG.getNode(
ISD::CTPOP, dl, VT, Tmp3);
2746 bool SelectionDAGLegalize::ExpandNode(
SDNode *Node) {
2749 SDValue Tmp1, Tmp2, Tmp3, Tmp4;
2773 TLI.getPointerTy(DAG.getDataLayout()));
2781 DAG.getConstant(0, dl, TLI.getPointerTy(DAG.getDataLayout())));
2815 SDValue Swap = DAG.getAtomicCmpSwap(
2818 cast<AtomicSDNode>(Node)->getMemOperand());
2826 cast<AtomicSDNode>(Node)->getMemoryVT(),
2829 cast<AtomicSDNode>(Node)->getMemOperand());
2838 SDValue Res = DAG.getAtomicCmpSwap(
2841 Node->
getOperand(3), cast<MemSDNode>(Node)->getMemOperand());
2847 EVT AtomicType = cast<AtomicSDNode>(Node)->getMemoryVT();
2849 switch (TLI.getExtendForAtomicOps()) {
2864 LHS = DAG.getZeroExtendInReg(Res, dl, AtomicType);
2880 ExpandDYNAMIC_STACKALLOC(Node, Results);
2889 Results.
push_back(DAG.getConstant(0, dl, VT));
2892 Results.
push_back(DAG.getConstantFP(0, dl, VT));
2920 SDValue One = DAG.getConstant(1, dl, VT);
2922 SDValue Zero = DAG.getConstant(0, dl, VT);
2930 EVT ShiftAmountTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
2935 SDValue ShiftCst = DAG.getConstant(BitsDiff, dl, ShiftAmountTy);
2950 Tmp1 = EmitStackConvert(Node->
getOperand(0), ExtraVT,
2962 if (TLI.expandFP_TO_SINT(Node, Tmp1, DAG))
2969 APFloat apf(DAG.EVTToAPFloatSemantics(VT),
2973 Tmp1 = DAG.getConstantFP(apf, dl, VT);
2974 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(VT),
2983 DAG.getConstant(x, dl, NVT));
2984 Tmp1 = DAG.getSelect(dl, NVT, Tmp2, True, False);
2989 Results.
push_back(DAG.expandVAArg(Node));
2990 Results.
push_back(Results[0].getValue(1));
2993 Results.
push_back(DAG.expandVACopy(Node));
3001 Tmp1 = ExpandExtractFromVectorThroughStack(
SDValue(Node, 0));
3011 Results.
push_back(ExpandVectorBuildThroughStack(Node));
3015 Results.
push_back(ExpandSCALAR_TO_VECTOR(Node));
3024 ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Node)->getMask();
3030 if (!TLI.isTypeLegal(EltVT)) {
3032 EVT NewEltVT = TLI.getTypeToTransformTo(*DAG.getContext(), EltVT);
3037 if (NewEltVT.
bitsLT(EltVT)) {
3054 unsigned int factor =
3062 for (
unsigned fi = 0; fi < factor; ++fi)
3066 for (
unsigned fi = 0; fi < factor; ++fi)
3077 for (
unsigned i = 0; i != NumElems; ++
i) {
3082 unsigned Idx = Mask[
i];
3086 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))));
3090 DAG.getConstant(Idx - NumElems, dl,
3091 TLI.getVectorIdxTy(DAG.getDataLayout()))));
3102 if (cast<ConstantSDNode>(Node->
getOperand(1))->getZExtValue()) {
3106 TLI.getShiftAmountTy(
3108 DAG.getDataLayout())));
3121 if (
unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) {
3124 Results.
push_back(Results[0].getValue(1));
3133 if (
unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) {
3142 Results.
push_back(Results[0].getValue(0));
3145 Results.
push_back(ExpandFCOPYSIGN(Node));
3149 Tmp1 = DAG.getConstantFP(-0.0, dl, Node->
getValueType(0));
3173 Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp1, Tmp2, Pred);
3186 SDVTList VTs = DAG.getVTList(VT, VT);
3209 if (!TLI.useSoftFloat() &&
TM.Options.UnsafeFPMath) {
3217 DAG.getIntPtrConstant(0, dl));
3228 Results.
push_back(ExpandConstantFP(CFP,
true));
3238 if (TLI.isOperationLegalOrCustom(
ISD::FADD, VT) &&
3239 TLI.isOperationLegalOrCustom(
ISD::FNEG, VT)) {
3250 TLI.isOperationLegalOrCustom(
ISD::XOR, VT) &&
3251 "Don't know how to expand this subtraction!");
3255 Tmp1 = DAG.getNode(
ISD::ADD, dl, VT, Tmp1, DAG.getConstant(1, dl, VT));
3267 if (TLI.isOperationLegalOrCustom(DivRemOpc, VT)) {
3268 SDVTList VTs = DAG.getVTList(VT, VT);
3269 Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Tmp2, Tmp3).getValue(1);
3271 }
else if (TLI.isOperationLegalOrCustom(DivOpc, VT)) {
3273 Tmp1 = DAG.getNode(DivOpc, dl, VT, Tmp2, Tmp3);
3274 Tmp1 = DAG.getNode(
ISD::MUL, dl, VT, Tmp1, Tmp3);
3275 Tmp1 = DAG.getNode(
ISD::SUB, dl, VT, Tmp2, Tmp1);
3285 if (TLI.isOperationLegalOrCustom(DivRemOpc, VT)) {
3286 SDVTList VTs = DAG.getVTList(VT, VT);
3287 Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Node->
getOperand(0),
3295 unsigned ExpandOpcode =
3298 SDVTList VTs = DAG.getVTList(VT, VT);
3300 Tmp1 = DAG.getNode(ExpandOpcode, dl, VTs, Node->
getOperand(0),
3310 unsigned MULHOpcode =
3313 if (TLI.isOperationLegalOrCustom(MULHOpcode, VT)) {
3315 Results.
push_back(DAG.getNode(MULHOpcode, dl, VT, LHS, RHS));
3321 assert(TLI.isTypeLegal(HalfType));
3322 if (TLI.expandMUL_LOHI(Node->
getOpcode(), VT, Node, LHS, RHS, Halves,
3325 for (
unsigned i = 0; i < 2; ++
i) {
3328 SDValue Shift = DAG.getConstant(
3329 HalfType.getScalarSizeInBits(), dl,
3330 TLI.getShiftAmountTy(HalfType, DAG.getDataLayout()));
3339 EVT VT = Node->getValueType(0);
3340 SDVTList VTs = DAG.getVTList(VT, VT);
3346 bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(
ISD::SMUL_LOHI, VT);
3347 bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(
ISD::UMUL_LOHI, VT);
3348 bool HasMULHS = TLI.isOperationLegalOrCustom(
ISD::MULHS, VT);
3349 bool HasMULHU = TLI.isOperationLegalOrCustom(
ISD::MULHU, VT);
3350 unsigned OpToUse = 0;
3351 if (HasSMUL_LOHI && !HasMULHS) {
3353 }
else if (HasUMUL_LOHI && !HasMULHU) {
3355 }
else if (HasSMUL_LOHI) {
3357 }
else if (HasUMUL_LOHI) {
3361 Results.
push_back(DAG.getNode(OpToUse, dl, VTs, Node->getOperand(0),
3362 Node->getOperand(1)));
3370 TLI.isOperationLegalOrCustom(
ISD::SHL, VT) &&
3371 TLI.isOperationLegalOrCustom(
ISD::OR, VT) &&
3372 TLI.expandMUL(Node, Lo, Hi, HalfType, DAG,
3378 TLI.getShiftAmountTy(HalfType, DAG.getDataLayout()));
3392 EVT ResultType = Node->getValueType(1);
3393 EVT OType = getSetCCResultType(Node->getValueType(0));
3408 SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign,
3416 Results.
push_back(DAG.getBoolExtOrTrunc(Cmp, dl, ResultType, ResultType));
3428 EVT ResultType = Node->getValueType(1);
3429 EVT SetCCType = getSetCCResultType(Node->getValueType(0));
3432 SDValue SetCC = DAG.getSetCC(dl, SetCCType, Sum, LHS, CC);
3434 Results.
push_back(DAG.getBoolExtOrTrunc(SetCC, dl, ResultType, ResultType));
3439 EVT VT = Node->getValueType(0);
3445 static const unsigned Ops[2][3] =
3448 bool isSigned = Node->getOpcode() ==
ISD::SMULO;
3449 if (TLI.isOperationLegalOrCustom(Ops[isSigned][0], VT)) {
3451 TopHalf = DAG.
getNode(Ops[isSigned][0], dl, VT, LHS, RHS);
3452 }
else if (TLI.isOperationLegalOrCustom(Ops[isSigned][1], VT)) {
3453 BottomHalf = DAG.
getNode(Ops[isSigned][1], dl, DAG.getVTList(VT, VT), LHS,
3456 }
else if (TLI.isTypeLegal(WideVT)) {
3457 LHS = DAG.
getNode(Ops[isSigned][2], dl, WideVT, LHS);
3458 RHS = DAG.
getNode(Ops[isSigned][2], dl, WideVT, RHS);
3459 Tmp1 = DAG.getNode(
ISD::MUL, dl, WideVT, LHS, RHS);
3461 DAG.getIntPtrConstant(0, dl));
3463 DAG.getIntPtrConstant(1, dl));
3485 DAG.getConstant(LoSize - 1, dl,
3486 TLI.getPointerTy(DAG.getDataLayout())));
3489 DAG.getConstant(LoSize - 1, dl,
3490 TLI.getPointerTy(DAG.getDataLayout())));
3497 if(DAG.getDataLayout().isLittleEndian()) {
3502 SDValue Args[] = { LHS, HiLHS, RHS, HiRHS };
3503 Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
3505 SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
3506 Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
3509 DAG.getIntPtrConstant(0, dl));
3511 DAG.getIntPtrConstant(1, dl));
3517 "Unexpected uses of illegally type from expanded lib call.");
3521 Tmp1 = DAG.getConstant(
3523 TLI.getShiftAmountTy(BottomHalf.
getValueType(), DAG.getDataLayout()));
3524 Tmp1 = DAG.getNode(
ISD::SRA, dl, VT, BottomHalf, Tmp1);
3525 TopHalf = DAG.getSetCC(dl, getSetCCResultType(VT), TopHalf, Tmp1,
3528 TopHalf = DAG.getSetCC(dl, getSetCCResultType(VT), TopHalf,
3533 EVT RType = Node->getValueType(1);
3538 "Unexpected result type for S/UMULO legalization");
3545 EVT PairTy = Node->getValueType(0);
3551 TLI.getShiftAmountTy(PairTy, DAG.getDataLayout())));
3556 Tmp1 = Node->getOperand(0);
3560 Tmp1 = DAG.getSelectCC(dl, Tmp1.getOperand(0), Tmp1.getOperand(1),
3562 cast<CondCodeSDNode>(Tmp1.getOperand(2))->
get());
3564 Tmp1 = DAG.getSelectCC(dl, Tmp1,
3565 DAG.getConstant(0, dl, Tmp1.getValueType()),
3576 EVT PTy = TLI.getPointerTy(TD);
3578 unsigned EntrySize =
3579 DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD);
3591 if (TLI.isJumpTableRelative()) {
3596 TLI.getPICJumpTableRelocBase(Table, DAG));
3605 Tmp1 = Node->getOperand(0);
3614 Tmp3 = (Tmp2.
isUndef()) ? Tmp2 :
3619 DAG.getConstant(0, dl, Tmp3.getValueType()),
3620 Node->getOperand(2));
3625 Tmp1 = Node->getOperand(0);
3628 bool Legalized = LegalizeSetCCCondCode(Node->getValueType(0), Tmp1, Tmp2,
3629 Tmp3, NeedInvert, dl);
3641 Tmp1 = DAG.getLogicalNOT(dl, Tmp1, Tmp1->getValueType(0));
3649 EVT VT = Node->getValueType(0);
3651 switch (TLI.getBooleanContents(Tmp1->getValueType(0))) {
3661 DAG.getConstant(TrueValue, dl, VT),
3662 DAG.getConstant(0, dl, VT),
3668 Tmp1 = Node->getOperand(0);
3669 Tmp2 = Node->getOperand(1);
3670 Tmp3 = Node->getOperand(2);
3672 EVT VT = Node->getValueType(0);
3676 if (TLI.isCondCodeLegal(CCOp, Tmp1.getSimpleValueType())) {
3679 EVT CmpVT = Tmp1.getValueType();
3681 "Cannot expand ISD::SELECT_CC when ISD::SELECT also needs to be "
3684 TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), CmpVT);
3686 Results.
push_back(DAG.getSelect(dl, VT, Cond, Tmp3, Tmp4));
3691 bool Legalized =
false;
3696 Tmp1.getValueType().isInteger());
3697 if (TLI.isCondCodeLegal(InvCC, Tmp1.getSimpleValueType())) {
3700 Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp4, Tmp3, InvCC);
3705 if (TLI.isCondCodeLegal(SwapInvCC, Tmp1.getSimpleValueType())) {
3709 Tmp1 = DAG.getSelectCC(dl, Tmp2, Tmp1, Tmp4, Tmp3, SwapInvCC);
3714 Legalized = LegalizeSetCCCondCode(
3715 getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC, NeedInvert,
3718 assert(Legalized &&
"Can't legalize SELECT_CC with legal condition!");
3729 Tmp1, Tmp2, Tmp3, Tmp4, CC);
3731 Tmp2 = DAG.getConstant(0, dl, Tmp1.getValueType());
3734 Tmp2, Tmp3, Tmp4, CC);
3741 Tmp1 = Node->getOperand(0);
3742 Tmp2 = Node->getOperand(2);
3743 Tmp3 = Node->getOperand(3);
3746 bool Legalized = LegalizeSetCCCondCode(getSetCCResultType(
3747 Tmp2.getValueType()), Tmp2, Tmp3, Tmp4, NeedInvert, dl);
3749 assert(Legalized &&
"Can't legalize BR_CC with legal condition!");
3762 Tmp3 = DAG.getConstant(0, dl, Tmp2.getValueType());
3764 Tmp1 = DAG.getNode(
ISD::BR_CC, dl, Node->getValueType(0), Tmp1, Tmp4,
3765 Tmp2, Tmp3, Node->getOperand(4));
3771 Results.
push_back(ExpandBUILD_VECTOR(Node));
3777 EVT VT = Node->getValueType(0);
3783 for (
unsigned Idx = 0; Idx < NumElem; Idx++) {
3786 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3789 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3790 Scalars.
push_back(DAG.getNode(Node->getOpcode(), dl,
3795 ReplaceNode(
SDValue(Node, 0), Result);
3812 if (Results.
empty())
3815 ReplaceNode(Node, Results.
data());
3819 void SelectionDAGLegalize::ConvertNodeToLibcall(
SDNode *Node) {
3822 SDValue Tmp1, Tmp2, Tmp3, Tmp4;
3834 DAG.getExternalSymbol(
"__sync_synchronize",
3835 TLI.getPointerTy(DAG.getDataLayout())),
3838 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
3862 std::pair<SDValue, SDValue> Tmp = ExpandChainLibCall(LC, Node,
false);
3874 DAG.getExternalSymbol(
"abort",
3875 TLI.getPointerTy(DAG.getDataLayout())),
3877 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
3909 ExpandSinCosLibCall(Node, Results);
4014 Results.
push_back(ExpandLibCall(LC, Node,
false));
4023 Results.
push_back(ExpandIntLibCall(Node,
true,
4029 Results.
push_back(ExpandIntLibCall(Node,
false,
4035 Results.
push_back(ExpandIntLibCall(Node,
true,
4041 Results.
push_back(ExpandIntLibCall(Node,
false,
4049 ExpandDivRemLibCall(Node, Results);
4052 Results.
push_back(ExpandIntLibCall(Node,
false,
4060 if (!Results.
empty())
4061 ReplaceNode(Node, Results.
data());
4067 MVT EltVT,
MVT NewEltVT) {
4074 void SelectionDAGLegalize::PromoteNode(
SDNode *Node) {
4086 MVT NVT = TLI.getTypeToPromoteTo(Node->
getOpcode(), OVT);
4104 DAG.getConstant(TopBit, dl, NVT));
4108 Tmp1 = DAG.getNode(Node->
getOpcode(), dl, NVT, Tmp1);
4112 Tmp1 = DAG.getNode(
ISD::SUB, dl, NVT, Tmp1,
4113 DAG.getConstant(NVT.getSizeInBits() -
4120 unsigned DiffBits = NVT.getSizeInBits() - OVT.
getSizeInBits();
4122 Tmp1 = DAG.getNode(Node->
getOpcode(), dl, NVT, Tmp1);
4125 DAG.getConstant(DiffBits, dl,
4126 TLI.getShiftAmountTy(NVT, DAG.getDataLayout())));
4151 &&
"VAARG promotion is supported only for vectors or integer types");
4156 Tmp1 = DAG.getVAArg(NVT, dl, Chain, Ptr, Node->
getOperand(2),
4160 Tmp2 = DAG.
getNode(TruncOp, dl, OVT, Tmp1);
4164 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 0), Tmp2);
4165 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 1), Chain);
4167 UpdatedNodes->insert(Tmp2.
getNode());
4168 UpdatedNodes->insert(Chain.
getNode());
4180 unsigned ExtOp, TruncOp;
4203 Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->
getOperand(0));
4206 Tmp1 = DAG.getNode(Node->
getOpcode(), dl, NVT, Tmp1, Tmp2);
4207 Results.
push_back(DAG.getNode(TruncOp, dl, OVT, Tmp1));
4215 Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->
getOperand(0));
4217 Tmp1 = DAG.getNode(
ISD::MUL, dl, NVT, Tmp1, Tmp2);
4219 auto &DL = DAG.getDataLayout();
4223 DAG.getConstant(OriginalSize, dl, TLI.getScalarShiftAmountTy(DL, NVT)));
4229 unsigned ExtOp, TruncOp;
4246 Tmp1 = DAG.getSelect(dl, NVT, Tmp1, Tmp2, Tmp3);
4248 Tmp1 = DAG.getNode(TruncOp, dl, Node->
getValueType(0), Tmp1);
4250 Tmp1 = DAG.getNode(TruncOp, dl, Node->
getValueType(0), Tmp1,
4251 DAG.getIntPtrConstant(0, dl));
4256 ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Node)->getMask();
4263 Tmp1 = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask);
4270 if (NVT.isInteger()) {
4272 cast<CondCodeSDNode>(Node->
getOperand(2))->
get();
4275 Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->
getOperand(0));
4283 if (NVT.isInteger()) {
4285 cast<CondCodeSDNode>(Node->
getOperand(1))->
get();
4288 Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->
getOperand(2));
4289 Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->
getOperand(3));
4308 Tmp3, DAG.getIntPtrConstant(0, dl)));
4317 DAG.getNode(Node->
getOpcode(), dl, NVT, Tmp1, Tmp2, Tmp3),
4318 DAG.getIntPtrConstant(0, dl)));
4334 Tmp3, DAG.getIntPtrConstant(isTrunc, dl)));
4354 Tmp2 = DAG.getNode(Node->
getOpcode(), dl, NVT, Tmp1);
4356 Tmp2, DAG.getIntPtrConstant(0, dl)));
4370 "Invalid promote type for build_vector");
4403 "Invalid promote type for extract_vector_elt");
4407 unsigned NewEltsPerOldElt = MidVT.getVectorNumElements();
4412 SDValue Factor = DAG.getConstant(NewEltsPerOldElt, SL, IdxVT);
4418 for (
unsigned I = 0;
I < NewEltsPerOldElt; ++
I) {
4419 SDValue IdxOffset = DAG.getConstant(
I, SL, IdxVT);
4450 "Invalid promote type for insert_vector_elt");
4454 unsigned NewEltsPerOldElt = MidVT.getVectorNumElements();
4461 SDValue Factor = DAG.getConstant(NewEltsPerOldElt,
SDLoc(), IdxVT);
4468 for (
unsigned I = 0;
I < NewEltsPerOldElt; ++
I) {
4469 SDValue IdxOffset = DAG.getConstant(
I, SL, IdxVT);
4473 CastVal, IdxOffset);
4476 NewVec, Elt, InEltIdx);
4513 if (!Results.
empty())
4514 ReplaceNode(Node, Results.
data());
4522 SelectionDAGLegalize
Legalizer(*
this, LegalizedNodes);
4529 bool AnyLegalized =
false;
4540 if (LegalizedNodes.
insert(N).second) {
4541 AnyLegalized =
true;
4542 Legalizer.LegalizeOp(N);
4562 SelectionDAGLegalize
Legalizer(*
this, LegalizedNodes, &UpdatedNodes);
4566 LegalizedNodes.
insert(N);
4567 Legalizer.LegalizeOp(N);
4569 return LegalizedNodes.
count(N);
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
bool LegalizeOp(SDNode *N, SmallSetVector< SDNode *, 16 > &UpdatedNodes)
Transforms a SelectionDAG node and any operands to it into a node that is compatible with the target ...
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
static Constant * getFPTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
bool use_empty() const
Return true if there are no uses of this node.
void push_back(const T &Elt)
BUILTIN_OP_END - This must be the last enum value in this list.
A parsed version of the target data layout string in and methods for querying it. ...
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
SDValue getValue(unsigned R) const
static APInt getSignBit(unsigned BitWidth)
Get the SignBit for a specific bit width.
static MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant, which is required to be operand #1) half of the integer or float value specified as operand #0.
Flags getFlags() const
Return the raw flags of the source value,.
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
NodeType getExtForLoadExtType(bool IsFP, LoadExtType)
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an vector value) starting with the ...
BR_CC - Conditional branch.
static MVT getVectorVT(MVT VT, unsigned NumElements)
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
SDVTList getVTList() const
Libcall getSYNC(unsigned Opc, MVT VT)
Return the SYNC_FETCH_AND_* value for the given opcode and type, or UNKNOWN_LIBCALL if there is none...
const TargetMachine & getTarget() const
unsigned getScalarSizeInBits() const
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain...
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Function Alias Analysis Results
Type * getTypeForEVT(LLVMContext &Context) const
getTypeForEVT - This method returns an LLVM type corresponding to the specified EVT.
unsigned getSizeInBits() const
static MVT getPromotedVectorElementType(const TargetLowering &TLI, MVT EltVT, MVT NewEltVT)
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
unsigned getNumOperands() const
Return the number of values used by this operation.
Type * getReturnType() const
Returns the type of the ret val.
unsigned getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned Num) const
bool bitsLT(MVT VT) const
Return true if this has less bits than VT.
static IntegerType * getInt64Ty(LLVMContext &C)
[US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned integers.
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
void reserve(size_type N)
void DeleteNode(SDNode *N)
Remove the specified node from the system.
const SDValue & getBasePtr() const
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1 at the ...
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
bool bitsLT(EVT VT) const
bitsLT - Return true if this has less bits than VT.
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist)
Returns true if N is a predecessor of any node in Worklist.
const Triple & getTargetTriple() const
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic...
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations...
bool isVector() const
isVector - Return true if this is a vector value type.
struct fuzzer::@269 Flags
Shift and rotation operations.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static Constant * get(ArrayRef< Constant * > V)
FLT_ROUNDS_ - Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest 2 Round to ...
MachinePointerInfo getWithOffset(int64_t O) const
APInt bitcastToAPInt() const
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.
MVT getScalarType() const
getScalarType - If this is a vector type, return the element type, otherwise return this...
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA)...
EVT getScalarType() const
getScalarType - If this is a vector type, return the element type, otherwise return this...
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt) For double-word atomic operations: ValLo, ValHi, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amtLo, amtHi) ValLo, ValHi, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amtLo, amtHi) These correspond to the atomicrmw instruction.
allnodes_const_iterator allnodes_end() const
bool bitsGE(EVT VT) const
bitsGE - Return true if this has no less bits than VT.
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool isInteger() const
isInteger - Return true if this is an integer, or a vector integer type.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
LLVM_NODISCARD bool empty() const
STACKSAVE - STACKSAVE has one operand, an input chain.
FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to first (possible) on-stack ar...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
EVT getVectorElementType() const
getVectorElementType - Given a vector type, return the type of each element.
unsigned AssignTopologicalOrder()
Topological-sort the AllNodes list and a assign a unique node id for each node in the DAG based on th...
static unsigned getAlignment(GlobalVariable *GV)
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here...
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
Simple integer binary arithmetic operators.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
bool isLittleEndian() const
Layout endianness...
const SDValue & getBasePtr() const
EVT getHalfSizedIntegerVT(LLVMContext &Context) const
getHalfSizedIntegerVT - Finds the smallest simple value type that is greater than or equal to half th...
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification, or lowering of the constant.
EVT getMemoryVT() const
Return the type of the in-memory value.
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
static bool useSinCos(SDNode *Node)
Only issue sincos libcall if both sin and cos are needed.
const ConstantInt * getConstantIntValue() const
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
UNDEF - An undefined node.
This class is used to represent ISD::STORE nodes.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the specified, possibly variable...
SDNode * getNode() const
get the SDNode which holds the desired result
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
MinAlign - A and B are either alignments or offsets.
unsigned getScalarSizeInBits() const
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned getStoreSizeInBits() const
getStoreSizeInBits - Return the number of bits overwritten by a store of the specified value type...
bool isInteger() const
isInteger - Return true if this is an integer, or a vector integer type.
virtual bool isShuffleMaskLegal(const SmallVectorImpl< int > &, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations, those with specific masks.
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
unsigned getVectorNumElements() const
APInt trunc(unsigned width) const
Truncate to new width.
void Legalize()
This transforms the SelectionDAG into a SelectionDAG that is compatible with the target instruction s...
constexpr bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
MVT - Machine Value Type.
const SDValue & getOperand(unsigned i) const
The instances of the Type class are immutable: once they are created, they are never changed...
void swap(SmallVectorImpl &RHS)
Simple binary floating point operators.
C - The default llvm calling convention, compatible with C.
This is an important base class in LLVM.
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE...
bool isVector() const
isVector - Return true if this is a vector value type.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
ConstantFP - Floating Point Values [float, double].
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
static Type * getVoidTy(LLVMContext &C)
This class provides iterator support for SDUse operands that use a specific SDNode.
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
unsigned getOpcode() const
TRAP - Trapping instruction.
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
DEBUGTRAP - Trap intended to get the attention of a debugger.
CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y)...
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
const SDValue & getValue() const
static bool isValueValidForType(EVT VT, const APFloat &Val)
Bit counting operators with an undefined result for zero inputs.
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo...
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
EVT - Extended Value Type.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
std::vector< ArgListEntry > ArgListTy
const APFloat & getValueAPF() const
bool bitsEq(EVT VT) const
bitsEq - Return true if this has the same number of bits as VT.
const ConstantFP * getConstantFPValue() const
This structure contains all information that is necessary for lowering calls.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements)
getVectorVT - Returns the EVT that represents a vector NumElements in length, where each element is o...
This class contains a discriminated union of information about pointers in memory operands...
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
const MachinePointerInfo & getPointerInfo() const
bool bitsGT(EVT VT) const
bitsGT - Return true if this has more bits than VT.
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
TokenFactor - This node takes multiple tokens as input and produces a single token result...
A SetVector that performs no allocations if smaller than a certain size.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
void dump() const
Dump this node, for debugging.
allnodes_const_iterator allnodes_begin() const
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and rounds it to a floating point val...
BRCOND - Conditional branch.
const SDValue & getChain() const
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Byte Swap and Counting operators.
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Represents one node in the SelectionDAG.
CondCode getSetCCInverse(CondCode Operation, bool isInteger)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
double BitsToDouble(uint64_t Bits)
BitsToDouble - This function takes a 64-bit integer and returns the bit equivalent double...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Class for arbitrary precision integers.
Select(COND, TRUEVAL, FALSEVAL).
op_iterator op_begin() const
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.
bool isGNUEnvironment() const
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
iterator_range< value_op_iterator > op_values() const
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
Flags
Flags values. These may be or'd together.
unsigned getAddressSpace() const
Return the address space for the associated pointer.
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
BR_JT - Jumptable branch.
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the source.
These are IR-level optimization flags that may be propagated to SDNodes.
Bitwise operators - logical and, logical or, logical xor.
pointer data()
Return a pointer to the vector's buffer, even if empty().
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
void ReplaceAllUsesWith(SDValue From, SDValue Op)
Modify anything using 'From' to use 'To' instead.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
op_iterator op_end() const
bool reachesChainWithoutSideEffects(SDValue Dest, unsigned Depth=2) const
Return true if this operand (which must be a chain) reaches the specified operand without crossing an...
FSINCOS - Compute both fsin and fcos as a single operation.
static MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.setjmp intrinsic.
EVT getValueType() const
Return the ValueType of the referenced return value.
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin...
Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a carry value...
const APFloat & getValueAPF() const
bool isByteSized() const
isByteSized - Return true if the bit size is a multiple of 8.
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
bool isFloatingPoint() const
isFloatingPoint - Return true if this is a FP, or a vector FP type.
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())
static bool isSinCosLibcallAvailable(SDNode *Node, const TargetLowering &TLI)
Return true if sincos libcall is available.
LLVM Value Representation.
FMA - Perform a * b + c with no intermediate rounding step.
static bool ExpandBVWithShuffles(SDNode *Node, SelectionDAG &DAG, const TargetLowering &TLI, SDValue &Res)
EVT changeTypeToInteger()
Return the type converted to an equivalently sized integer or vector with integer element type...
bool isTruncatingStore() const
Return true if the op does a truncation before store.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
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.
PREFETCH - This corresponds to a prefetch intrinsic.
const TargetLowering & getTargetLoweringInfo() const
Primary interface to the complete machine description for the target machine.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations...
SetCC operator - This evaluates to a true value iff the condition is true.
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
MVT getVectorElementType() const
static APInt getNullValue(unsigned numBits)
Get the '0' value.
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
TRUNCATE - Completely drop the high bits.
unsigned getAlignment() const
static bool canCombineSinCosLibcall(SDNode *Node, const TargetLowering &TLI, const TargetMachine &TM)
Return true if sincos libcall is available and can be used to combine sin and cos.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, FLOG, FLOG2, FLOG10, FEXP, FEXP2, FCEIL, FTRUNC, FRINT, FNEARBYINT, FROUND, FFLOOR - Perform various unary floating point operations.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
getIntegerVT - Returns the EVT that represents an integer with the given number of bits...
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
MVT getSimpleVT() const
getSimpleVT - Return the SimpleValueType held in the specified simple EVT.
const SDNodeFlags * getFlags() const
This could be defined as a virtual function and implemented more simply and directly, but it is not to avoid creating a vtable for this class.
This file describes how to lower LLVM code to machine code.
bool isVoidTy() const
Return true if this is 'void'.
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
unsigned getVectorNumElements() const
getVectorNumElements - Given a vector type, return the number of elements it contains.
This class is used to represent ISD::LOAD nodes.
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary...