56 #define DEBUG_TYPE "legalizedag" 62 struct FloatSignAsInt {
85 class SelectionDAGLegalize {
97 EVT getSetCCResultType(
EVT VT)
const {
108 LegalizedNodes(LegalizedNodes), UpdatedNodes(UpdatedNodes) {}
111 void LegalizeOp(
SDNode *Node);
116 void LegalizeLoadOps(
SDNode *Node);
117 void LegalizeStoreOps(
SDNode *Node);
137 bool &NeedInvert,
const SDLoc &dl);
141 unsigned NumOps,
bool isSigned,
const SDLoc &dl);
144 SDNode *Node,
bool isSigned);
162 void ExpandDYNAMIC_STACKALLOC(
SDNode *Node,
164 void getSignAsIntValue(FloatSignAsInt &State,
const SDLoc &DL,
166 SDValue modifySignAsInt(
const FloatSignAsInt &State,
const SDLoc &DL,
188 bool ExpandNode(
SDNode *Node);
189 void ConvertNodeToLibcall(
SDNode *Node);
190 void PromoteNode(
SDNode *Node);
196 LegalizedNodes.
erase(N);
203 dbgs() <<
" with: "; New->
dump(&DAG));
206 "Replacing one node with another that produces a different number " 210 UpdatedNodes->
insert(New);
216 dbgs() <<
" with: "; New->
dump(&DAG));
228 for (
unsigned i = 0, e = Old->
getNumValues(); i != e; ++i) {
232 UpdatedNodes->
insert(New[i].getNode());
244 SDValue SelectionDAGLegalize::ShuffleWithNarrowerEltType(
249 unsigned NumEltsGrowth = NumDestElts / NumMaskElts;
251 assert(NumEltsGrowth &&
"Cannot promote to vector type with fewer elts!");
253 if (NumEltsGrowth == 1)
254 return DAG.getVectorShuffle(NVT, dl, N1, N2, Mask);
257 for (
unsigned i = 0; i != NumMaskElts; ++i) {
259 for (
unsigned j = 0; j != NumEltsGrowth; ++j) {
263 NewMask.
push_back(Idx * NumEltsGrowth + j);
266 assert(NewMask.
size() == NumDestElts &&
"Non-integer NumEltsGrowth?");
267 assert(TLI.isShuffleMaskLegal(NewMask, NVT) &&
"Shuffle not legal?");
268 return DAG.getVectorShuffle(NVT, dl, N1, N2, NewMask);
305 TLI.ShouldShrinkFPConstant(OrigVT)) {
315 DAG.getConstantPool(LLVMC, TLI.getPointerTy(DAG.getDataLayout()));
316 unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->
getAlignment();
318 SDValue Result = DAG.getExtLoad(
325 OrigVT, dl, DAG.getEntryNode(), CPIdx,
335 TLI.getPointerTy(DAG.getDataLayout()));
336 unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->
getAlignment();
338 VT, dl, DAG.getEntryNode(), CPIdx,
347 SDValue SelectionDAGLegalize::PerformInsertVectorEltInMemory(
SDValue Vec,
363 SDValue StackPtr = DAG.CreateStackTemporary(VT);
365 int SPFI = cast<FrameIndexSDNode>(StackPtr.
getNode())->getIndex();
369 DAG.getEntryNode(), dl, Tmp1, StackPtr,
372 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, Tmp3);
378 DAG.getMachineFunction(), SPFI));
399 for (
unsigned i = 0; i != NumElts; ++i)
400 ShufOps.
push_back(i != InsertPos->getZExtValue() ? i : NumElts);
402 return DAG.getVectorShuffle(Vec.
getValueType(), dl, Vec, ScVec, ShufOps);
405 return PerformInsertVectorEltInMemory(Vec, Val, Idx, dl);
427 bitcastToAPInt().zextOrTrunc(32),
429 return DAG.getStore(Chain, dl, Con, Ptr, ST->
getPointerInfo(), Alignment,
439 Alignment, MMOFlags, AAInfo);
449 if (DAG.getDataLayout().isBigEndian())
452 Lo = DAG.getStore(Chain, dl, Lo, Ptr, ST->
getPointerInfo(), Alignment,
456 Hi = DAG.getStore(Chain, dl, Hi, Ptr,
458 MinAlign(Alignment, 4U), MMOFlags, AAInfo);
467 void SelectionDAGLegalize::LegalizeStoreOps(
SDNode *Node) {
479 if (
SDNode *OptStore = OptimizeFloatStore(ST).getNode()) {
480 ReplaceNode(ST, OptStore);
486 switch (TLI.getOperationAction(
ISD::STORE, VT)) {
495 if (!TLI.allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS,
Align)) {
497 SDValue Result = TLI.expandUnalignedStore(ST, DAG);
498 ReplaceNode(
SDValue(ST, 0), Result);
506 if (Res && Res !=
SDValue(Node, 0))
507 ReplaceNode(
SDValue(Node, 0), Res);
513 "Can only promote stores to same size type");
517 Alignment, MMOFlags, AAInfo);
518 ReplaceNode(
SDValue(Node, 0), Result);
529 auto &DL = DAG.getDataLayout();
537 Value = DAG.getZeroExtendInReg(Value, dl, StVT);
539 DAG.getTruncStore(Chain, dl, Value, Ptr, ST->
getPointerInfo(), NVT,
540 Alignment, MMOFlags, AAInfo);
541 ReplaceNode(
SDValue(Node, 0), Result);
542 }
else if (StWidth & (StWidth - 1)) {
545 unsigned RoundWidth = 1 <<
Log2_32(StWidth);
546 assert(RoundWidth < StWidth);
547 unsigned ExtraWidth = StWidth - RoundWidth;
548 assert(ExtraWidth < RoundWidth);
549 assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
550 "Store size not an integral number of bytes!");
554 unsigned IncrementSize;
556 if (DL.isLittleEndian()) {
559 Lo = DAG.getTruncStore(Chain, dl, Value, Ptr, ST->
getPointerInfo(),
560 RoundVT, Alignment, MMOFlags, AAInfo);
563 IncrementSize = RoundWidth / 8;
565 DAG.getConstant(IncrementSize, dl,
569 DAG.getConstant(RoundWidth, dl,
571 Hi = DAG.getTruncStore(
574 MinAlign(Alignment, IncrementSize), MMOFlags, AAInfo);
581 DAG.getConstant(ExtraWidth, dl,
584 RoundVT, Alignment, MMOFlags, AAInfo);
587 IncrementSize = RoundWidth / 8;
589 DAG.getConstant(IncrementSize, dl,
591 Lo = DAG.getTruncStore(
592 Chain, dl, Value, Ptr,
594 MinAlign(Alignment, IncrementSize), MMOFlags, AAInfo);
599 ReplaceNode(
SDValue(Node, 0), Result);
609 if (!TLI.allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS,
Align)) {
610 SDValue Result = TLI.expandUnalignedStore(ST, DAG);
611 ReplaceNode(
SDValue(ST, 0), Result);
617 if (Res && Res !=
SDValue(Node, 0))
618 ReplaceNode(
SDValue(Node, 0), Res);
623 "Vector Stores are handled in LegalizeVectorOps");
628 if (TLI.isTypeLegal(StVT)) {
630 Result = DAG.getStore(Chain, dl, Value, Ptr, ST->
getPointerInfo(),
631 Alignment, MMOFlags, AAInfo);
636 TLI.getTypeToTransformTo(*DAG.getContext(), StVT),
638 Result = DAG.getTruncStore(Chain, dl, Value, Ptr, ST->
getPointerInfo(),
639 StVT, Alignment, MMOFlags, AAInfo);
642 ReplaceNode(
SDValue(Node, 0), Result);
648 void SelectionDAGLegalize::LegalizeLoadOps(
SDNode *Node) {
657 LLVM_DEBUG(
dbgs() <<
"Legalizing non-extending load operation\n");
662 switch (TLI.getOperationAction(Node->
getOpcode(), VT)) {
671 if (!TLI.allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS,
Align)) {
672 std::tie(RVal, RChain) = TLI.expandUnalignedLoad(LD, DAG);
677 if (
SDValue Res = TLI.LowerOperation(RVal, DAG)) {
684 MVT NVT = TLI.getTypeToPromoteTo(Node->
getOpcode(), VT);
686 "Can only promote loads to same size type");
694 if (RChain.
getNode() != Node) {
695 assert(RVal.
getNode() != Node &&
"Load must be completely replaced");
696 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 0), RVal);
697 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 1), RChain);
699 UpdatedNodes->insert(RVal.
getNode());
700 UpdatedNodes->insert(RChain.
getNode());
738 DAG.getExtLoad(NewExtType, dl, Node->
getValueType(0), Chain, Ptr,
756 }
else if (SrcWidth & (SrcWidth - 1)) {
759 unsigned RoundWidth = 1 <<
Log2_32(SrcWidth);
760 assert(RoundWidth < SrcWidth);
761 unsigned ExtraWidth = SrcWidth - RoundWidth;
762 assert(ExtraWidth < RoundWidth);
763 assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
764 "Load size not an integral number of bytes!");
768 unsigned IncrementSize;
769 auto &DL = DAG.getDataLayout();
771 if (DL.isLittleEndian()) {
779 IncrementSize = RoundWidth / 8;
780 Ptr = DAG.getNode(
ISD::ADD, dl, Ptr.getValueType(), Ptr,
781 DAG.getConstant(IncrementSize, dl,
782 Ptr.getValueType()));
783 Hi = DAG.getExtLoad(ExtType, dl, Node->
getValueType(0), Chain, Ptr,
785 ExtraVT,
MinAlign(Alignment, IncrementSize), MMOFlags,
796 DAG.getConstant(RoundWidth, dl,
797 TLI.getShiftAmountTy(Hi.getValueType(), DL)));
805 Hi = DAG.getExtLoad(ExtType, dl, Node->
getValueType(0), Chain, Ptr,
810 IncrementSize = RoundWidth / 8;
811 Ptr = DAG.getNode(
ISD::ADD, dl, Ptr.getValueType(), Ptr,
812 DAG.getConstant(IncrementSize, dl,
813 Ptr.getValueType()));
816 ExtraVT,
MinAlign(Alignment, IncrementSize), MMOFlags,
827 DAG.getConstant(ExtraWidth, dl,
828 TLI.getShiftAmountTy(Hi.getValueType(), DL)));
836 bool isCustom =
false;
837 switch (TLI.getLoadExtAction(ExtType, Node->
getValueType(0),
859 if (!TLI.allowsMemoryAccess(*DAG.getContext(), DL, MemVT, AS,
Align)) {
860 std::tie(Value, Chain) = TLI.expandUnalignedLoad(LD, DAG);
871 if (TLI.isTypeLegal(SrcVT) ||
872 TLI.isLoadExtLegal(ExtType, LoadVT, SrcVT)) {
878 SDValue Load = DAG.getExtLoad(MidExtType, dl, LoadVT, Chain, Ptr,
906 "Vector Loads are handled in LegalizeVectorOps");
913 "EXTLOAD should always be supported!");
926 ValRes = DAG.getZeroExtendInReg(Result, dl, SrcVT.getScalarType());
936 if (Chain.getNode() != Node) {
937 assert(Value.
getNode() != Node &&
"Load must be completely replaced");
938 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 0), Value);
939 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 1), Chain);
941 UpdatedNodes->insert(Value.
getNode());
942 UpdatedNodes->insert(Chain.getNode());
949 void SelectionDAGLegalize::LegalizeOp(
SDNode *Node) {
958 for (
unsigned i = 0, e = Node->
getNumValues(); i != e; ++i)
962 "Unexpected illegal type!");
965 assert((TLI.getTypeAction(*DAG.getContext(),
Op.getValueType()) ==
967 TLI.isTypeLegal(
Op.getValueType()) ||
970 "Unexpected illegal type!");
975 bool SimpleFinishLegalizing =
true;
984 Action = TLI.getOperationAction(Node->
getOpcode(),
988 Action = TLI.getOperationAction(Node->
getOpcode(),
997 Action = TLI.getOperationAction(Node->
getOpcode(),
1002 EVT InnerType = cast<VTSDNode>(Node->
getOperand(1))->getVT();
1003 Action = TLI.getOperationAction(Node->
getOpcode(), InnerType);
1007 Action = TLI.getOperationAction(Node->
getOpcode(),
1018 cast<CondCodeSDNode>(Node->
getOperand(CCOperand))->
get();
1019 Action = TLI.getCondCodeAction(CCCode, OpVT);
1022 Action = TLI.getOperationAction(Node->
getOpcode(),
1025 Action = TLI.getOperationAction(Node->
getOpcode(), OpVT);
1033 SimpleFinishLegalizing =
false;
1040 SimpleFinishLegalizing =
false;
1088 ReplaceNode(Node, NewVal.
getNode());
1121 Action = TLI.getStrictFPOperationAction(Node->
getOpcode(),
1133 Action = TLI.getFixedPointOperationAction(Node->
getOpcode(),
1138 Action = TLI.getOperationAction(Node->
getOpcode(),
1139 cast<MaskedScatterSDNode>(Node)->getValue().getValueType());
1142 Action = TLI.getOperationAction(Node->
getOpcode(),
1143 cast<MaskedStoreSDNode>(Node)->getValue().getValueType());
1154 if (SimpleFinishLegalizing) {
1175 NewNode = DAG.UpdateNodeOperands(Node, Op0, SAO);
1195 NewNode = DAG.UpdateNodeOperands(Node, Op0, Op1, SAO);
1201 if (NewNode != Node) {
1202 ReplaceNode(Node, NewNode);
1214 if (!(Res.getNode() != Node || Res.getResNo() != 0))
1220 ReplaceNode(
SDValue(Node, 0), Res);
1225 for (
unsigned i = 0, e = Node->
getNumValues(); i != e; ++i)
1228 ReplaceNode(Node, ResultVals.
data());
1234 if (ExpandNode(Node))
1238 ConvertNodeToLibcall(Node);
1259 return LegalizeLoadOps(Node);
1261 return LegalizeStoreOps(Node);
1265 SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(
SDValue Op) {
1286 if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(User)) {
1315 StackPtr = DAG.CreateStackTemporary(VecVT);
1316 Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr,
1320 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
1333 DAG.ReplaceAllUsesOfValueWith(Ch,
SDValue(NewLoad.
getNode(), 1));
1339 NewLoadOperands[0] = Ch;
1341 SDValue(DAG.UpdateNodeOperands(NewLoad.
getNode(), NewLoadOperands), 0);
1345 SDValue SelectionDAGLegalize::ExpandInsertToVectorThroughStack(
SDValue Op) {
1354 EVT VecVT = Vec.getValueType();
1355 SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
1356 int FI = cast<FrameIndexSDNode>(StackPtr.
getNode())->getIndex();
1361 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo);
1364 SDValue SubStackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
1370 return DAG.getLoad(Op.
getValueType(), dl, Ch, StackPtr, PtrInfo);
1373 SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(
SDNode* Node) {
1381 SDValue FIPtr = DAG.CreateStackTemporary(VT);
1382 int FI = cast<FrameIndexSDNode>(FIPtr.
getNode())->getIndex();
1394 unsigned Offset = TypeByteSize*i;
1402 Stores.push_back(DAG.getTruncStore(DAG.getEntryNode(), dl,
1406 Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl, Node->
getOperand(i),
1411 if (!Stores.empty())
1414 StoreChain = DAG.getEntryNode();
1417 return DAG.getLoad(VT, dl, StoreChain, FIPtr, PtrInfo);
1423 void SelectionDAGLegalize::getSignAsIntValue(FloatSignAsInt &State,
1428 State.FloatVT = FloatVT;
1431 if (TLI.isTypeLegal(IVT)) {
1432 State.IntValue = DAG.getNode(
ISD::BITCAST, DL, IVT, Value);
1434 State.SignBit = NumBits - 1;
1440 MVT LoadTy = TLI.getRegisterType(*DAG.getContext(),
MVT::i8);
1442 SDValue StackPtr = DAG.CreateStackTemporary(FloatVT, LoadTy);
1443 int FI = cast<FrameIndexSDNode>(StackPtr.
getNode())->getIndex();
1445 State.FloatPtr = StackPtr;
1448 State.Chain = DAG.getStore(DAG.getEntryNode(), DL, Value, State.FloatPtr,
1449 State.FloatPointerInfo);
1456 State.IntPointerInfo = State.FloatPointerInfo;
1461 DAG.getConstant(ByteOffset, DL, StackPtr.
getValueType()));
1466 State.IntPtr = IntPtr;
1467 State.IntValue = DAG.getExtLoad(
ISD::EXTLOAD, DL, LoadTy, State.Chain, IntPtr,
1468 State.IntPointerInfo,
MVT::i8);
1475 SDValue SelectionDAGLegalize::modifySignAsInt(
const FloatSignAsInt &State,
1482 SDValue Chain = DAG.getTruncStore(State.Chain, DL, NewIntValue, State.IntPtr,
1483 State.IntPointerInfo,
MVT::i8);
1484 return DAG.getLoad(State.FloatVT, DL, Chain, State.FloatPtr,
1485 State.FloatPointerInfo);
1488 SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(
SDNode *Node)
const {
1494 FloatSignAsInt SignAsInt;
1495 getSignAsIntValue(SignAsInt, DL, Sign);
1497 EVT IntVT = SignAsInt.IntValue.getValueType();
1498 SDValue SignMask = DAG.getConstant(SignAsInt.SignMask, DL, IntVT);
1504 if (TLI.isOperationLegalOrCustom(
ISD::FABS, FloatVT) &&
1505 TLI.isOperationLegalOrCustom(
ISD::FNEG, FloatVT)) {
1508 SDValue Cond = DAG.getSetCC(DL, getSetCCResultType(IntVT), SignBit,
1510 return DAG.getSelect(DL, FloatVT, Cond, NegValue, AbsValue);
1514 FloatSignAsInt MagAsInt;
1515 getSignAsIntValue(MagAsInt, DL, Mag);
1516 EVT MagVT = MagAsInt.IntValue.getValueType();
1517 SDValue ClearSignMask = DAG.getConstant(~MagAsInt.SignMask, DL, MagVT);
1522 int ShiftAmount = SignAsInt.SignBit - MagAsInt.SignBit;
1523 EVT ShiftVT = IntVT;
1528 if (ShiftAmount > 0) {
1529 SDValue ShiftCnst = DAG.getConstant(ShiftAmount, DL, ShiftVT);
1531 }
else if (ShiftAmount < 0) {
1532 SDValue ShiftCnst = DAG.getConstant(-ShiftAmount, DL, ShiftVT);
1541 return modifySignAsInt(MagAsInt, DL, CopiedSign);
1544 SDValue SelectionDAGLegalize::ExpandFABS(
SDNode *Node)
const {
1551 SDValue Zero = DAG.getConstantFP(0.0, DL, FloatVT);
1556 FloatSignAsInt ValueAsInt;
1557 getSignAsIntValue(ValueAsInt, DL, Value);
1558 EVT IntVT = ValueAsInt.IntValue.getValueType();
1559 SDValue ClearSignMask = DAG.getConstant(~ValueAsInt.SignMask, DL, IntVT);
1562 return modifySignAsInt(ValueAsInt, DL, ClearedSign);
1565 void SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(
SDNode* Node,
1567 unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore();
1568 assert(SPReg &&
"Target cannot require DYNAMIC_STACKALLOC expansion and" 1569 " not tell us which reg is the stack pointer!");
1579 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, dl);
1582 SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT);
1584 unsigned Align = cast<ConstantSDNode>(Tmp3)->getZExtValue();
1585 unsigned StackAlign =
1586 DAG.getSubtarget().getFrameLowering()->getStackAlignment();
1588 if (Align > StackAlign)
1590 DAG.getConstant(-(uint64_t)Align, dl, VT));
1591 Chain = DAG.getCopyToReg(Chain, dl, SPReg, Tmp1);
1593 Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, dl,
true),
1594 DAG.getIntPtrConstant(0, dl,
true),
SDValue(), dl);
1618 bool SelectionDAGLegalize::LegalizeSetCCCondCode(
EVT VT,
SDValue &LHS,
1625 bool NeedSwap =
false;
1626 switch (TLI.getCondCodeAction(CCCode, OpVT)) {
1633 if (TLI.isCondCodeLegalOrCustom(InvCC, OpVT)) {
1635 CC = DAG.getCondCode(InvCC);
1640 if (!TLI.isCondCodeLegalOrCustom(InvCC, OpVT)) {
1646 if (TLI.isCondCodeLegalOrCustom(InvCC, OpVT)) {
1647 CC = DAG.getCondCode(InvCC);
1660 &&
"If SETO is expanded, SETOEQ must be legal!");
1664 &&
"If SETUO is expanded, SETUNE must be legal!");
1704 SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1);
1705 SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2);
1708 SetCC1 = DAG.getSetCC(dl, VT, LHS, LHS, CC1);
1709 SetCC2 = DAG.getSetCC(dl, VT, RHS, RHS, CC2);
1711 LHS = DAG.
getNode(Opc, dl, VT, SetCC1, SetCC2);
1727 unsigned SrcAlign = DAG.getDataLayout().getPrefTypeAlignment(
1729 SDValue FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign);
1740 unsigned DestAlign = DAG.getDataLayout().getPrefTypeAlignment(DestType);
1746 if (SrcSize > SlotSize)
1747 Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, PtrInfo,
1750 assert(SrcSize == SlotSize &&
"Invalid store");
1752 DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, PtrInfo, SrcAlign);
1756 if (SlotSize == DestSize)
1757 return DAG.getLoad(DestVT, dl, Store, FIPtr, PtrInfo, DestAlign);
1759 assert(SlotSize < DestSize &&
"Unknown extension!");
1760 return DAG.getExtLoad(
ISD::EXTLOAD, dl, DestVT, Store, FIPtr, PtrInfo, SlotVT,
1764 SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(
SDNode *Node) {
1773 SDValue Ch = DAG.getTruncStore(
1774 DAG.getEntryNode(), dl, Node->
getOperand(0), StackPtr,
1799 for (
unsigned i = 0; i < NumElems; ++i) {
1810 while (IntermedVals.
size() > 2) {
1811 NewIntermedVals.
clear();
1812 for (
unsigned i = 0, e = (IntermedVals.
size() & ~1u); i < e; i += 2) {
1819 IntermedVals[i+1].second.
size());
1822 for (
unsigned j = 0, f = IntermedVals[i].
second.size(); j != f;
1827 for (
unsigned j = 0, f = IntermedVals[i+1].
second.size(); j != f;
1829 ShuffleVec[k] = NumElems + j;
1836 IntermedVals[i+1].first,
1841 std::make_pair(Shuffle, std::move(FinalIndices)));
1846 if ((IntermedVals.
size() & 1) != 0)
1849 IntermedVals.
swap(NewIntermedVals);
1853 "Invalid number of intermediate vectors");
1854 SDValue Vec1 = IntermedVals[0].first;
1856 if (IntermedVals.
size() > 1)
1857 Vec2 = IntermedVals[1].
first;
1862 for (
unsigned i = 0, e = IntermedVals[0].
second.size(); i != e; ++i)
1863 ShuffleVec[IntermedVals[0].
second[i]] = i;
1864 for (
unsigned i = 0, e = IntermedVals[1].
second.size(); i != e; ++i)
1865 ShuffleVec[IntermedVals[1].
second[i]] = NumElems + i;
1878 SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(
SDNode *Node) {
1888 bool isOnlyLowElement =
true;
1889 bool MoreThanTwoValues =
false;
1891 for (
unsigned i = 0; i < NumElems; ++i) {
1896 isOnlyLowElement =
false;
1897 if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V))
1902 }
else if (!Value2.
getNode()) {
1905 }
else if (V != Value1 && V != Value2) {
1906 MoreThanTwoValues =
true;
1911 return DAG.getUNDEF(VT);
1913 if (isOnlyLowElement)
1919 for (
unsigned i = 0, e = NumElems; i != e; ++i) {
1921 dyn_cast<ConstantFPSDNode>(Node->
getOperand(i))) {
1922 CV.
push_back(const_cast<ConstantFP *>(V->getConstantFPValue()));
1924 dyn_cast<ConstantSDNode>(Node->
getOperand(i))) {
1926 CV.
push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
1943 DAG.getConstantPool(CP, TLI.getPointerTy(DAG.getDataLayout()));
1944 unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->
getAlignment();
1946 VT, dl, DAG.getEntryNode(), CPIdx,
1952 for (
unsigned i = 0; i < NumElems; ++i) {
1958 if (TLI.shouldExpandBuildVectorWithShuffles(VT, DefinedValues.
size())) {
1959 if (!MoreThanTwoValues) {
1961 for (
unsigned i = 0; i < NumElems; ++i) {
1965 ShuffleVec[i] = V == Value1 ? 0 : NumElems;
1967 if (TLI.isShuffleMaskLegal(ShuffleVec, Node->
getValueType(0))) {
1974 Vec2 = DAG.getUNDEF(VT);
1977 return DAG.getVectorShuffle(VT, dl, Vec1, Vec2, ShuffleVec);
1987 return ExpandVectorBuildThroughStack(Node);
1997 TargetLowering::ArgListEntry Entry;
2003 Entry.IsSExt = TLI.shouldSignExtendTypeInLibCall(ArgVT, isSigned);
2004 Entry.IsZExt = !TLI.shouldSignExtendTypeInLibCall(ArgVT, isSigned);
2005 Args.push_back(Entry);
2007 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2008 TLI.getPointerTy(DAG.getDataLayout()));
2017 SDValue InChain = DAG.getEntryNode();
2022 const Function &
F = DAG.getMachineFunction().getFunction();
2024 TLI.isInTailCallPosition(DAG, Node, TCChain) &&
2030 bool signExtend = TLI.shouldSignExtendTypeInLibCall(RetVT, isSigned);
2033 .
setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee,
2035 .setTailCall(isTailCall)
2040 std::pair<SDValue, SDValue>
CallInfo = TLI.LowerCallTo(CLI);
2042 if (!CallInfo.second.getNode()) {
2043 LLVM_DEBUG(
dbgs() <<
"Created tailcall: "; DAG.getRoot().dump());
2045 return DAG.getRoot();
2048 LLVM_DEBUG(
dbgs() <<
"Created libcall: "; CallInfo.first.dump());
2049 return CallInfo.first;
2055 const SDValue *Ops,
unsigned NumOps,
2056 bool isSigned,
const SDLoc &dl) {
2058 Args.reserve(NumOps);
2060 TargetLowering::ArgListEntry Entry;
2061 for (
unsigned i = 0; i != NumOps; ++i) {
2062 Entry.Node = Ops[i];
2064 Entry.IsSExt = isSigned;
2065 Entry.IsZExt = !isSigned;
2066 Args.push_back(Entry);
2068 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2069 TLI.getPointerTy(DAG.getDataLayout()));
2076 .setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee,
2078 .setSExtResult(isSigned)
2082 std::pair<SDValue,SDValue>
CallInfo = TLI.LowerCallTo(CLI);
2084 return CallInfo.first;
2089 std::pair<SDValue, SDValue>
2096 TargetLowering::ArgListEntry Entry;
2102 Entry.IsSExt = isSigned;
2103 Entry.IsZExt = !isSigned;
2104 Args.push_back(Entry);
2106 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2107 TLI.getPointerTy(DAG.getDataLayout()));
2114 .
setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee,
2116 .setSExtResult(isSigned)
2119 std::pair<SDValue, SDValue>
CallInfo = TLI.LowerCallTo(CLI);
2131 Node = DAG.mutateStrictFPToFP(Node);
2136 case MVT::f32: LC = Call_F32;
break;
2137 case MVT::f64: LC = Call_F64;
break;
2138 case MVT::f80: LC = Call_F80;
break;
2142 return ExpandLibCall(LC, Node,
false);
2145 SDValue SelectionDAGLegalize::ExpandIntLibCall(
SDNode* Node,
bool isSigned,
2154 case MVT::i8: LC = Call_I8;
break;
2155 case MVT::i16: LC = Call_I16;
break;
2156 case MVT::i32: LC = Call_I32;
break;
2157 case MVT::i64: LC = Call_I64;
break;
2160 return ExpandLibCall(LC, Node, isSigned);
2165 SelectionDAGLegalize::ExpandDivRemLibCall(
SDNode *Node,
2173 case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
break;
2174 case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
break;
2175 case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
2176 case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
break;
2177 case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128;
break;
2183 SDValue InChain = DAG.getEntryNode();
2189 TargetLowering::ArgListEntry Entry;
2195 Entry.IsSExt = isSigned;
2196 Entry.IsZExt = !isSigned;
2197 Args.push_back(Entry);
2201 SDValue FIPtr = DAG.CreateStackTemporary(RetVT);
2204 Entry.IsSExt = isSigned;
2205 Entry.IsZExt = !isSigned;
2206 Args.push_back(Entry);
2208 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2209 TLI.getPointerTy(DAG.getDataLayout()));
2215 .
setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee,
2217 .setSExtResult(isSigned)
2220 std::pair<SDValue, SDValue>
CallInfo = TLI.LowerCallTo(CLI);
2234 case MVT::f32: LC = RTLIB::SINCOS_F32;
break;
2235 case MVT::f64: LC = RTLIB::SINCOS_F64;
break;
2236 case MVT::f80: LC = RTLIB::SINCOS_F80;
break;
2237 case MVT::f128: LC = RTLIB::SINCOS_F128;
break;
2263 SelectionDAGLegalize::ExpandSinCosLibCall(
SDNode *Node,
2268 case MVT::f32: LC = RTLIB::SINCOS_F32;
break;
2269 case MVT::f64: LC = RTLIB::SINCOS_F64;
break;
2270 case MVT::f80: LC = RTLIB::SINCOS_F80;
break;
2271 case MVT::f128: LC = RTLIB::SINCOS_F128;
break;
2278 SDValue InChain = DAG.getEntryNode();
2284 TargetLowering::ArgListEntry Entry;
2289 Entry.IsSExt =
false;
2290 Entry.IsZExt =
false;
2291 Args.push_back(Entry);
2294 SDValue SinPtr = DAG.CreateStackTemporary(RetVT);
2295 Entry.Node = SinPtr;
2297 Entry.IsSExt =
false;
2298 Entry.IsZExt =
false;
2299 Args.push_back(Entry);
2302 SDValue CosPtr = DAG.CreateStackTemporary(RetVT);
2303 Entry.Node = CosPtr;
2305 Entry.IsSExt =
false;
2306 Entry.IsZExt =
false;
2307 Args.push_back(Entry);
2309 SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
2310 TLI.getPointerTy(DAG.getDataLayout()));
2315 TLI.getLibcallCallingConv(LC),
Type::getVoidTy(*DAG.getContext()), Callee,
2318 std::pair<SDValue, SDValue>
CallInfo = TLI.LowerCallTo(CLI);
2330 SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(
bool isSigned,
SDValue Op0,
2338 LLVM_DEBUG(
dbgs() <<
"32-bit [signed|unsigned] integer to float/double " 2345 SDValue WordOff = DAG.getConstant(
sizeof(
int), dl,
2350 StackSlot, WordOff);
2351 if (DAG.getDataLayout().isLittleEndian())
2364 SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, Op0Mapped,
Lo,
2375 SDValue Bias = DAG.getConstantFP(isSigned ?
2382 SDValue Result = DAG.getFPExtendOrRound(Sub, dl, DestVT);
2385 assert(!isSigned &&
"Legalize cannot Expand SINT_TO_FP for i64 yet");
2390 SDValue SignSet = DAG.getSetCC(dl, getSetCCResultType(SrcVT), Op0,
2392 SDValue Zero = DAG.getIntPtrConstant(0, dl),
2393 Four = DAG.getIntPtrConstant(4, dl);
2395 SignSet, Four, Zero);
2403 case MVT::i8 : FF = 0x43800000ULL;
break;
2404 case MVT::i16: FF = 0x47800000ULL;
break;
2405 case MVT::i32: FF = 0x4F800000ULL;
break;
2406 case MVT::i64: FF = 0x5F800000ULL;
break;
2408 if (DAG.getDataLayout().isLittleEndian())
2414 DAG.getConstantPool(FudgeFactor, TLI.getPointerTy(DAG.getDataLayout()));
2415 unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->
getAlignment();
2417 Alignment = std::min(Alignment, 4u);
2420 FudgeInReg = DAG.getLoad(
2421 MVT::f32, dl, DAG.getEntryNode(), CPIdx,
2442 SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(
SDValue LegalOp,
EVT DestVT,
2448 unsigned OpToUse = 0;
2460 if (isSigned)
continue;
2473 return DAG.getNode(OpToUse, dl, DestVT,
2475 dl, NewInTy, LegalOp));
2483 SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(
SDValue LegalOp,
EVT DestVT,
2487 EVT NewOutTy = DestVT;
2489 unsigned OpToUse = 0;
2504 if (!isSigned && TLI.isOperationLegalOrCustom(
ISD::FP_TO_UINT, NewOutTy)) {
2523 EVT SHVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
2533 APInt MaskHi4(Sz, 0), MaskHi2(Sz, 0), MaskHi1(Sz, 0);
2534 APInt MaskLo4(Sz, 0), MaskLo2(Sz, 0), MaskLo1(Sz, 0);
2535 for (
unsigned J = 0; J != Sz; J += 8) {
2536 MaskHi4 = MaskHi4 | (0xF0ull << J);
2537 MaskLo4 = MaskLo4 | (0x0Full << J);
2538 MaskHi2 = MaskHi2 | (0xCCull << J);
2539 MaskLo2 = MaskLo2 | (0x33ull << J);
2540 MaskHi1 = MaskHi1 | (0xAAull << J);
2541 MaskLo1 = MaskLo1 | (0x55ull << J);
2545 Tmp = (Sz > 8 ? DAG.getNode(
ISD::BSWAP, dl, VT, Op) :
Op);
2548 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskHi4, dl, VT));
2549 Tmp3 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskLo4, dl, VT));
2550 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Tmp2, DAG.getConstant(4, dl, SHVT));
2551 Tmp3 = DAG.
getNode(
ISD::SHL, dl, VT, Tmp3, DAG.getConstant(4, dl, SHVT));
2555 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskHi2, dl, VT));
2556 Tmp3 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskLo2, dl, VT));
2557 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Tmp2, DAG.getConstant(2, dl, SHVT));
2558 Tmp3 = DAG.
getNode(
ISD::SHL, dl, VT, Tmp3, DAG.getConstant(2, dl, SHVT));
2562 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskHi1, dl, VT));
2563 Tmp3 = DAG.
getNode(
ISD::AND, dl, VT, Tmp, DAG.getConstant(MaskLo1, dl, VT));
2564 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Tmp2, DAG.getConstant(1, dl, SHVT));
2565 Tmp3 = DAG.
getNode(
ISD::SHL, dl, VT, Tmp3, DAG.getConstant(1, dl, SHVT));
2570 Tmp = DAG.getConstant(0, dl, VT);
2571 for (
unsigned I = 0, J = Sz-1;
I < Sz; ++
I, --J) {
2581 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp2, DAG.getConstant(Shift, dl, VT));
2591 EVT SHVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
2592 SDValue Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8;
2596 Tmp2 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2597 Tmp1 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2598 return DAG.getNode(
ISD::OR, dl, VT, Tmp1, Tmp2);
2600 Tmp4 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(24, dl, SHVT));
2601 Tmp3 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2602 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2603 Tmp1 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(24, dl, SHVT));
2605 DAG.getConstant(0xFF0000, dl, VT));
2606 Tmp2 = DAG.
getNode(
ISD::AND, dl, VT, Tmp2, DAG.getConstant(0xFF00, dl, VT));
2609 return DAG.getNode(
ISD::OR, dl, VT, Tmp4, Tmp2);
2611 Tmp8 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(56, dl, SHVT));
2612 Tmp7 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(40, dl, SHVT));
2613 Tmp6 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(24, dl, SHVT));
2614 Tmp5 = DAG.
getNode(
ISD::SHL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2615 Tmp4 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(8, dl, SHVT));
2616 Tmp3 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(24, dl, SHVT));
2617 Tmp2 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(40, dl, SHVT));
2618 Tmp1 = DAG.
getNode(
ISD::SRL, dl, VT, Op, DAG.getConstant(56, dl, SHVT));
2620 DAG.getConstant(255ULL<<48, dl, VT));
2622 DAG.getConstant(255ULL<<40, dl, VT));
2624 DAG.getConstant(255ULL<<32, dl, VT));
2626 DAG.getConstant(255ULL<<24, dl, VT));
2628 DAG.getConstant(255ULL<<16, dl, VT));
2630 DAG.getConstant(255ULL<<8 , dl, VT));
2637 return DAG.getNode(
ISD::OR, dl, VT, Tmp8, Tmp4);
2641 bool SelectionDAGLegalize::ExpandNode(
SDNode *Node) {
2645 SDValue Tmp1, Tmp2, Tmp3, Tmp4;
2649 if (TLI.expandABS(Node, Tmp1, DAG))
2653 if (TLI.expandCTPOP(Node, Tmp1, DAG))
2658 if (TLI.expandCTLZ(Node, Tmp1, DAG))
2663 if (TLI.expandCTTZ(Node, Tmp1, DAG))
2679 TLI.getPointerTy(DAG.getDataLayout()));
2687 DAG.getConstant(0, dl, TLI.getPointerTy(DAG.getDataLayout())));
2721 SDValue Swap = DAG.getAtomicCmpSwap(
2724 cast<AtomicSDNode>(Node)->getMemOperand());
2732 cast<AtomicSDNode>(Node)->getMemoryVT(),
2735 cast<AtomicSDNode>(Node)->getMemOperand());
2744 SDValue Res = DAG.getAtomicCmpSwap(
2747 Node->
getOperand(3), cast<MemSDNode>(Node)->getMemOperand());
2753 EVT AtomicType = cast<AtomicSDNode>(Node)->getMemoryVT();
2755 switch (TLI.getExtendForAtomicOps()) {
2766 RHS = DAG.getZeroExtendInReg(Node->
getOperand(2), dl, AtomicType);
2770 LHS = DAG.getZeroExtendInReg(Res, dl, AtomicType);
2771 RHS = DAG.getZeroExtendInReg(Node->
getOperand(2), dl, AtomicType);
2786 ExpandDYNAMIC_STACKALLOC(Node, Results);
2795 Results.
push_back(DAG.getConstant(0, dl, VT));
2798 Results.
push_back(DAG.getConstantFP(0, dl, VT));
2826 SDValue One = DAG.getConstant(1, dl, VT);
2828 SDValue Zero = DAG.getConstant(0, dl, VT);
2836 EVT ShiftAmountTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
2839 SDValue ShiftCst = DAG.getConstant(BitsDiff, dl, ShiftAmountTy);
2854 Tmp1 = EmitStackConvert(Node->
getOperand(0), ExtraVT,
2860 if (TLI.expandUINT_TO_FP(Node, Tmp1, DAG)) {
2871 if (TLI.expandFP_TO_SINT(Node, Tmp1, DAG))
2875 if (TLI.expandFP_TO_UINT(Node, Tmp1, DAG))
2879 Results.
push_back(DAG.expandVAArg(Node));
2880 Results.
push_back(Results[0].getValue(1));
2883 Results.
push_back(DAG.expandVACopy(Node));
2891 Tmp1 = ExpandExtractFromVectorThroughStack(
SDValue(Node, 0));
2901 Results.
push_back(ExpandVectorBuildThroughStack(Node));
2904 Results.
push_back(ExpandSCALAR_TO_VECTOR(Node));
2913 ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Node)->getMask();
2919 if (!TLI.isTypeLegal(EltVT)) {
2920 EVT NewEltVT = TLI.getTypeToTransformTo(*DAG.getContext(), EltVT);
2925 if (NewEltVT.
bitsLT(EltVT)) {
2941 unsigned int factor =
2949 for (
unsigned fi = 0; fi < factor; ++fi)
2953 for (
unsigned fi = 0; fi < factor; ++fi)
2964 for (
unsigned i = 0; i != NumElems; ++i) {
2969 unsigned Idx = Mask[i];
2973 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))));
2977 DAG.getConstant(Idx - NumElems, dl,
2978 TLI.getVectorIdxTy(DAG.getDataLayout()))));
2981 Tmp1 = DAG.getBuildVector(VT, dl, Ops);
2989 if (cast<ConstantSDNode>(Node->
getOperand(1))->getZExtValue()) {
2993 TLI.getShiftAmountTy(
2995 DAG.getDataLayout())));
3008 if (
unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) {
3011 Results.
push_back(Results[0].getValue(1));
3020 if (
unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) {
3029 Results.
push_back(Results[0].getValue(0));
3032 Results.
push_back(ExpandFCOPYSIGN(Node));
3036 Tmp1 = DAG.getConstantFP(-0.0, dl, Node->
getValueType(0));
3060 Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp1, Tmp2, Pred);
3066 if (
SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(Node, DAG))
3078 SDVTList VTs = DAG.getVTList(VT, VT);
3102 if (!TLI.useSoftFloat() &&
TM.Options.UnsafeFPMath) {
3110 DAG.getIntPtrConstant(0, dl));
3121 Results.
push_back(ExpandConstantFP(CFP,
true));
3131 if (TLI.isOperationLegalOrCustom(
ISD::FADD, VT) &&
3132 TLI.isOperationLegalOrCustom(
ISD::FNEG, VT)) {
3143 TLI.isOperationLegalOrCustom(
ISD::XOR, VT) &&
3144 "Don't know how to expand this subtraction!");
3148 Tmp1 = DAG.getNode(
ISD::ADD, dl, VT, Tmp1, DAG.getConstant(1, dl, VT));
3160 if (TLI.isOperationLegalOrCustom(DivRemOpc, VT)) {
3161 SDVTList VTs = DAG.getVTList(VT, VT);
3162 Tmp1 = DAG.
getNode(DivRemOpc, dl, VTs, Tmp2, Tmp3).getValue(1);
3164 }
else if (TLI.isOperationLegalOrCustom(DivOpc, VT)) {
3166 Tmp1 = DAG.
getNode(DivOpc, dl, VT, Tmp2, Tmp3);
3178 if (TLI.isOperationLegalOrCustom(DivRemOpc, VT)) {
3179 SDVTList VTs = DAG.getVTList(VT, VT);
3188 unsigned ExpandOpcode =
3191 SDVTList VTs = DAG.getVTList(VT, VT);
3203 unsigned MULHOpcode =
3206 if (TLI.isOperationLegalOrCustom(MULHOpcode, VT)) {
3208 Results.
push_back(DAG.getNode(MULHOpcode, dl, VT, LHS, RHS));
3214 assert(TLI.isTypeLegal(HalfType));
3215 if (TLI.expandMUL_LOHI(Node->
getOpcode(), VT, Node, LHS, RHS, Halves,
3218 for (
unsigned i = 0; i < 2; ++i) {
3221 SDValue Shift = DAG.getConstant(
3222 HalfType.getScalarSizeInBits(), dl,
3223 TLI.getShiftAmountTy(HalfType, DAG.getDataLayout()));
3233 SDVTList VTs = DAG.getVTList(VT, VT);
3239 bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(
ISD::SMUL_LOHI, VT);
3240 bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(
ISD::UMUL_LOHI, VT);
3241 bool HasMULHS = TLI.isOperationLegalOrCustom(
ISD::MULHS, VT);
3242 bool HasMULHU = TLI.isOperationLegalOrCustom(
ISD::MULHU, VT);
3243 unsigned OpToUse = 0;
3244 if (HasSMUL_LOHI && !HasMULHS) {
3246 }
else if (HasUMUL_LOHI && !HasMULHU) {
3248 }
else if (HasSMUL_LOHI) {
3250 }
else if (HasUMUL_LOHI) {
3263 TLI.isOperationLegalOrCustom(
ISD::SHL, VT) &&
3264 TLI.isOperationLegalOrCustom(
ISD::OR, VT) &&
3265 TLI.expandMUL(Node, Lo, Hi, HalfType, DAG,
3271 TLI.getShiftAmountTy(HalfType, DAG.getDataLayout()));
3279 if (TLI.expandFunnelShift(Node, Tmp1, DAG))
3284 if (TLI.expandROT(Node, Tmp1, DAG))
3291 Results.
push_back(TLI.expandAddSubSat(Node, DAG));
3294 Results.
push_back(TLI.getExpandedFixedPointMultiplication(Node, DAG));
3319 SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign,
3327 Results.
push_back(DAG.getBoolExtOrTrunc(Cmp, dl, ResultType, ResultType));
3337 if (TLI.isOperationLegalOrCustom(OpcCarry, Node->
getValueType(0))) {
3340 { LHS, RHS, CarryIn });
3353 SDValue SetCC = DAG.getSetCC(dl, SetCCType, Sum, LHS, CC);
3355 Results.
push_back(DAG.getBoolExtOrTrunc(SetCC, dl, ResultType, ResultType));
3366 static const unsigned Ops[2][3] =
3370 if (TLI.isOperationLegalOrCustom(Ops[isSigned][0], VT)) {
3372 TopHalf = DAG.
getNode(Ops[isSigned][0], dl, VT, LHS, RHS);
3373 }
else if (TLI.isOperationLegalOrCustom(Ops[isSigned][1], VT)) {
3374 BottomHalf = DAG.
getNode(Ops[isSigned][1], dl, DAG.getVTList(VT, VT), LHS,
3377 }
else if (TLI.isTypeLegal(WideVT)) {
3378 LHS = DAG.
getNode(Ops[isSigned][2], dl, WideVT, LHS);
3379 RHS = DAG.
getNode(Ops[isSigned][2], dl, WideVT, RHS);
3382 DAG.getIntPtrConstant(0, dl));
3384 DAG.getIntPtrConstant(1, dl));
3392 LC = RTLIB::MUL_I16;
3394 LC = RTLIB::MUL_I32;
3396 LC = RTLIB::MUL_I64;
3398 LC = RTLIB::MUL_I128;
3399 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Cannot expand this operation!");
3409 DAG.getConstant(LoSize - 1, dl,
3410 TLI.getPointerTy(DAG.getDataLayout())));
3413 DAG.getConstant(LoSize - 1, dl,
3414 TLI.getPointerTy(DAG.getDataLayout())));
3416 HiLHS = DAG.getConstant(0, dl, VT);
3417 HiRHS = DAG.getConstant(0, dl, VT);
3425 if(DAG.getDataLayout().isLittleEndian()) {
3431 Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
3434 Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
3437 "Ret value is a collection of constituent nodes holding result.");
3443 Tmp1 = DAG.getConstant(
3445 TLI.getShiftAmountTy(BottomHalf.
getValueType(), DAG.getDataLayout()));
3447 TopHalf = DAG.getSetCC(dl, getSetCCResultType(VT), TopHalf, Tmp1,
3450 TopHalf = DAG.getSetCC(dl, getSetCCResultType(VT), TopHalf,
3460 "Unexpected result type for S/UMULO legalization");
3473 TLI.getShiftAmountTy(PairTy, DAG.getDataLayout())));
3484 cast<CondCodeSDNode>(Tmp1.
getOperand(2))->
get());
3486 Tmp1 = DAG.getSelectCC(dl, Tmp1,
3498 EVT PTy = TLI.getPointerTy(TD);
3500 unsigned EntrySize =
3501 DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD);
3522 if (TLI.isJumpTableRelative()) {
3527 TLI.getPICJumpTableRelocBase(Table, DAG));
3530 Tmp1 = TLI.expandIndirectJTBranch(dl, LD.getValue(1), Addr, DAG);
3549 cast<ConstantSDNode>(Tmp2.
getOperand(1))->getZExtValue() == 1))
3565 bool Legalized = LegalizeSetCCCondCode(Node->
getValueType(0), Tmp1, Tmp2,
3566 Tmp3, NeedInvert, dl);
3578 Tmp1 = DAG.getLogicalNOT(dl, Tmp1, Tmp1->
getValueType(0));
3598 DAG.getConstant(TrueValue, dl, VT),
3599 DAG.getConstant(0, dl, VT),
3618 "Cannot expand ISD::SELECT_CC when ISD::SELECT also needs to be " 3621 TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), CmpVT);
3623 Results.
push_back(DAG.getSelect(dl, VT, Cond, Tmp3, Tmp4));
3628 bool Legalized =
false;
3637 Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp4, Tmp3, InvCC);
3646 Tmp1 = DAG.getSelectCC(dl, Tmp2, Tmp1, Tmp4, Tmp3, SwapInvCC);
3651 Legalized = LegalizeSetCCCondCode(
3652 getSetCCResultType(Tmp1.
getValueType()), Tmp1, Tmp2, CC, NeedInvert,
3655 assert(Legalized &&
"Can't legalize SELECT_CC with legal condition!");
3666 Tmp1, Tmp2, Tmp3, Tmp4, CC);
3671 Tmp2, Tmp3, Tmp4, CC);
3683 bool Legalized = LegalizeSetCCCondCode(getSetCCResultType(
3684 Tmp2.
getValueType()), Tmp2, Tmp3, Tmp4, NeedInvert, dl);
3686 assert(Legalized &&
"Can't legalize BR_CC with legal condition!");
3688 assert(!NeedInvert &&
"Don't know how to invert BR_CC!");
3705 Results.
push_back(ExpandBUILD_VECTOR(Node));
3717 for (
unsigned Idx = 0; Idx < NumElem; Idx++) {
3720 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3723 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3729 ReplaceNode(
SDValue(Node, 0), Result);
3746 if (Results.
empty()) {
3752 ReplaceNode(Node, Results.
data());
3756 void SelectionDAGLegalize::ConvertNodeToLibcall(
SDNode *Node) {
3761 bool CanUseFiniteLibCall =
TM.Options.NoInfsFPMath &&
TM.Options.NoNaNsFPMath;
3774 DAG.getExternalSymbol(
"__sync_synchronize",
3775 TLI.getPointerTy(DAG.getDataLayout())),
3778 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
3801 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected atomic op or value type!");
3803 std::pair<SDValue, SDValue> Tmp = ExpandChainLibCall(LC, Node,
false);
3815 DAG.getExternalSymbol(
3816 "abort", TLI.getPointerTy(DAG.getDataLayout())),
3818 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
3825 Results.
push_back(ExpandFPLibCall(Node, RTLIB::FMIN_F32, RTLIB::FMIN_F64,
3826 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
3827 RTLIB::FMIN_PPCF128));
3831 Results.
push_back(ExpandFPLibCall(Node, RTLIB::FMAX_F32, RTLIB::FMAX_F64,
3832 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
3833 RTLIB::FMAX_PPCF128));
3837 Results.
push_back(ExpandFPLibCall(Node, RTLIB::SQRT_F32, RTLIB::SQRT_F64,
3838 RTLIB::SQRT_F80, RTLIB::SQRT_F128,
3839 RTLIB::SQRT_PPCF128));
3842 Results.
push_back(ExpandFPLibCall(Node, RTLIB::CBRT_F32, RTLIB::CBRT_F64,
3843 RTLIB::CBRT_F80, RTLIB::CBRT_F128,
3844 RTLIB::CBRT_PPCF128));
3848 Results.
push_back(ExpandFPLibCall(Node, RTLIB::SIN_F32, RTLIB::SIN_F64,
3849 RTLIB::SIN_F80, RTLIB::SIN_F128,
3850 RTLIB::SIN_PPCF128));
3854 Results.
push_back(ExpandFPLibCall(Node, RTLIB::COS_F32, RTLIB::COS_F64,
3855 RTLIB::COS_F80, RTLIB::COS_F128,
3856 RTLIB::COS_PPCF128));
3860 ExpandSinCosLibCall(Node, Results);
3864 if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_log_finite))
3865 Results.
push_back(ExpandFPLibCall(Node, RTLIB::LOG_FINITE_F32,
3866 RTLIB::LOG_FINITE_F64,
3867 RTLIB::LOG_FINITE_F80,
3868 RTLIB::LOG_FINITE_F128,
3869 RTLIB::LOG_FINITE_PPCF128));
3871 Results.
push_back(ExpandFPLibCall(Node, RTLIB::LOG_F32, RTLIB::LOG_F64,
3872 RTLIB::LOG_F80, RTLIB::LOG_F128,
3873 RTLIB::LOG_PPCF128));
3877 if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_log2_finite))
3878 Results.
push_back(ExpandFPLibCall(Node, RTLIB::LOG2_FINITE_F32,
3879 RTLIB::LOG2_FINITE_F64,
3880 RTLIB::LOG2_FINITE_F80,
3881 RTLIB::LOG2_FINITE_F128,
3882 RTLIB::LOG2_FINITE_PPCF128));
3884 Results.
push_back(ExpandFPLibCall(Node, RTLIB::LOG2_F32, RTLIB::LOG2_F64,
3885 RTLIB::LOG2_F80, RTLIB::LOG2_F128,
3886 RTLIB::LOG2_PPCF128));
3890 if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_log10_finite))
3891 Results.
push_back(ExpandFPLibCall(Node, RTLIB::LOG10_FINITE_F32,
3892 RTLIB::LOG10_FINITE_F64,
3893 RTLIB::LOG10_FINITE_F80,
3894 RTLIB::LOG10_FINITE_F128,
3895 RTLIB::LOG10_FINITE_PPCF128));
3897 Results.
push_back(ExpandFPLibCall(Node, RTLIB::LOG10_F32, RTLIB::LOG10_F64,
3898 RTLIB::LOG10_F80, RTLIB::LOG10_F128,
3899 RTLIB::LOG10_PPCF128));
3903 if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_exp_finite))
3904 Results.
push_back(ExpandFPLibCall(Node, RTLIB::EXP_FINITE_F32,
3905 RTLIB::EXP_FINITE_F64,
3906 RTLIB::EXP_FINITE_F80,
3907 RTLIB::EXP_FINITE_F128,
3908 RTLIB::EXP_FINITE_PPCF128));
3910 Results.
push_back(ExpandFPLibCall(Node, RTLIB::EXP_F32, RTLIB::EXP_F64,
3911 RTLIB::EXP_F80, RTLIB::EXP_F128,
3912 RTLIB::EXP_PPCF128));
3916 if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_exp2_finite))
3917 Results.
push_back(ExpandFPLibCall(Node, RTLIB::EXP2_FINITE_F32,
3918 RTLIB::EXP2_FINITE_F64,
3919 RTLIB::EXP2_FINITE_F80,
3920 RTLIB::EXP2_FINITE_F128,
3921 RTLIB::EXP2_FINITE_PPCF128));
3923 Results.
push_back(ExpandFPLibCall(Node, RTLIB::EXP2_F32, RTLIB::EXP2_F64,
3924 RTLIB::EXP2_F80, RTLIB::EXP2_F128,
3925 RTLIB::EXP2_PPCF128));
3929 Results.
push_back(ExpandFPLibCall(Node, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
3930 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
3931 RTLIB::TRUNC_PPCF128));
3935 Results.
push_back(ExpandFPLibCall(Node, RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
3936 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
3937 RTLIB::FLOOR_PPCF128));
3941 Results.
push_back(ExpandFPLibCall(Node, RTLIB::CEIL_F32, RTLIB::CEIL_F64,
3942 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
3943 RTLIB::CEIL_PPCF128));
3947 Results.
push_back(ExpandFPLibCall(Node, RTLIB::RINT_F32, RTLIB::RINT_F64,
3948 RTLIB::RINT_F80, RTLIB::RINT_F128,
3949 RTLIB::RINT_PPCF128));
3953 Results.
push_back(ExpandFPLibCall(Node, RTLIB::NEARBYINT_F32,
3954 RTLIB::NEARBYINT_F64,
3955 RTLIB::NEARBYINT_F80,
3956 RTLIB::NEARBYINT_F128,
3957 RTLIB::NEARBYINT_PPCF128));
3961 Results.
push_back(ExpandFPLibCall(Node, RTLIB::ROUND_F32,
3965 RTLIB::ROUND_PPCF128));
3969 Results.
push_back(ExpandFPLibCall(Node, RTLIB::POWI_F32, RTLIB::POWI_F64,
3970 RTLIB::POWI_F80, RTLIB::POWI_F128,
3971 RTLIB::POWI_PPCF128));
3975 if (CanUseFiniteLibCall && DAG.getLibInfo().has(LibFunc_pow_finite))
3976 Results.
push_back(ExpandFPLibCall(Node, RTLIB::POW_FINITE_F32,
3977 RTLIB::POW_FINITE_F64,
3978 RTLIB::POW_FINITE_F80,
3979 RTLIB::POW_FINITE_F128,
3980 RTLIB::POW_FINITE_PPCF128));
3982 Results.
push_back(ExpandFPLibCall(Node, RTLIB::POW_F32, RTLIB::POW_F64,
3983 RTLIB::POW_F80, RTLIB::POW_F128,
3984 RTLIB::POW_PPCF128));
3987 Results.
push_back(ExpandFPLibCall(Node, RTLIB::DIV_F32, RTLIB::DIV_F64,
3988 RTLIB::DIV_F80, RTLIB::DIV_F128,
3989 RTLIB::DIV_PPCF128));
3993 Results.
push_back(ExpandFPLibCall(Node, RTLIB::REM_F32, RTLIB::REM_F64,
3994 RTLIB::REM_F80, RTLIB::REM_F128,
3995 RTLIB::REM_PPCF128));
3999 Results.
push_back(ExpandFPLibCall(Node, RTLIB::FMA_F32, RTLIB::FMA_F64,
4000 RTLIB::FMA_F80, RTLIB::FMA_F128,
4001 RTLIB::FMA_PPCF128));
4004 Results.
push_back(ExpandFPLibCall(Node, RTLIB::ADD_F32, RTLIB::ADD_F64,
4005 RTLIB::ADD_F80, RTLIB::ADD_F128,
4006 RTLIB::ADD_PPCF128));
4009 Results.
push_back(ExpandFPLibCall(Node, RTLIB::MUL_F32, RTLIB::MUL_F64,
4010 RTLIB::MUL_F80, RTLIB::MUL_F128,
4011 RTLIB::MUL_PPCF128));
4015 Results.
push_back(ExpandLibCall(RTLIB::FPEXT_F16_F32, Node,
false));
4021 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to expand fp_to_fp16");
4022 Results.
push_back(ExpandLibCall(LC, Node,
false));
4026 Results.
push_back(ExpandFPLibCall(Node, RTLIB::SUB_F32, RTLIB::SUB_F64,
4027 RTLIB::SUB_F80, RTLIB::SUB_F128,
4028 RTLIB::SUB_PPCF128));
4031 Results.
push_back(ExpandIntLibCall(Node,
true,
4033 RTLIB::SREM_I16, RTLIB::SREM_I32,
4034 RTLIB::SREM_I64, RTLIB::SREM_I128));
4037 Results.
push_back(ExpandIntLibCall(Node,
false,
4039 RTLIB::UREM_I16, RTLIB::UREM_I32,
4040 RTLIB::UREM_I64, RTLIB::UREM_I128));
4043 Results.
push_back(ExpandIntLibCall(Node,
true,
4045 RTLIB::SDIV_I16, RTLIB::SDIV_I32,
4046 RTLIB::SDIV_I64, RTLIB::SDIV_I128));
4049 Results.
push_back(ExpandIntLibCall(Node,
false,
4051 RTLIB::UDIV_I16, RTLIB::UDIV_I32,
4052 RTLIB::UDIV_I64, RTLIB::UDIV_I128));
4057 ExpandDivRemLibCall(Node, Results);
4060 Results.
push_back(ExpandIntLibCall(Node,
false,
4062 RTLIB::MUL_I16, RTLIB::MUL_I32,
4063 RTLIB::MUL_I64, RTLIB::MUL_I128));
4070 Results.
push_back(ExpandLibCall(RTLIB::CTLZ_I32, Node,
false));
4073 Results.
push_back(ExpandLibCall(RTLIB::CTLZ_I64, Node,
false));
4076 Results.
push_back(ExpandLibCall(RTLIB::CTLZ_I128, Node,
false));
4083 if (!Results.
empty()) {
4084 LLVM_DEBUG(
dbgs() <<
"Successfully converted node to libcall\n");
4085 ReplaceNode(Node, Results.
data());
4093 MVT EltVT,
MVT NewEltVT) {
4100 void SelectionDAGLegalize::PromoteNode(
SDNode *Node) {
4113 MVT NVT = TLI.getTypeToPromoteTo(Node->
getOpcode(), OVT);
4131 DAG.getConstant(TopBit, dl, NVT));
4140 DAG.getConstant(NVT.getSizeInBits() -
4147 unsigned DiffBits = NVT.getSizeInBits() - OVT.
getSizeInBits();
4152 DAG.getConstant(DiffBits, dl,
4153 TLI.getShiftAmountTy(NVT, DAG.getDataLayout())));
4179 &&
"VAARG promotion is supported only for vectors or integer types");
4184 Tmp1 = DAG.getVAArg(NVT, dl, Chain, Ptr, Node->
getOperand(2),
4188 Tmp2 = DAG.
getNode(TruncOp, dl, OVT, Tmp1);
4192 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 0), Tmp2);
4193 DAG.ReplaceAllUsesOfValueWith(
SDValue(Node, 1), Chain);
4195 UpdatedNodes->insert(Tmp2.
getNode());
4196 UpdatedNodes->insert(Chain.
getNode());
4209 unsigned ExtOp, TruncOp;
4236 Results.
push_back(DAG.getNode(TruncOp, dl, OVT, Tmp1));
4248 auto &DL = DAG.getDataLayout();
4252 DAG.getConstant(OriginalSize, dl, TLI.getScalarShiftAmountTy(DL, NVT)));
4258 unsigned ExtOp, TruncOp;
4275 Tmp1 = DAG.getSelect(dl, NVT, Tmp1, Tmp2, Tmp3);
4280 DAG.getIntPtrConstant(0, dl));
4285 ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Node)->getMask();
4292 Tmp1 = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask);
4299 if (NVT.isInteger()) {
4301 cast<CondCodeSDNode>(Node->
getOperand(2))->
get();
4312 if (NVT.isInteger()) {
4314 cast<CondCodeSDNode>(Node->
getOperand(1))->
get();
4337 Tmp3, DAG.getIntPtrConstant(0, dl)));
4345 DAG.getNode(Node->
getOpcode(), dl, NVT, Tmp1, Tmp2, Tmp3),
4346 DAG.getIntPtrConstant(0, dl)));
4361 Tmp3, DAG.getIntPtrConstant(isTrunc, dl)));
4381 Tmp2 = DAG.getNode(Node->
getOpcode(), dl, NVT, Tmp1);
4383 Tmp2, DAG.getIntPtrConstant(0, dl)));
4396 "Invalid promote type for build_vector");
4429 "Invalid promote type for extract_vector_elt");
4433 unsigned NewEltsPerOldElt = MidVT.getVectorNumElements();
4438 SDValue Factor = DAG.getConstant(NewEltsPerOldElt, SL, IdxVT);
4444 for (
unsigned I = 0;
I < NewEltsPerOldElt; ++
I) {
4445 SDValue IdxOffset = DAG.getConstant(
I, SL, IdxVT);
4453 SDValue NewVec = DAG.getBuildVector(MidVT, SL, NewOps);
4475 "Invalid promote type for insert_vector_elt");
4479 unsigned NewEltsPerOldElt = MidVT.getVectorNumElements();
4486 SDValue Factor = DAG.getConstant(NewEltsPerOldElt,
SDLoc(), IdxVT);
4493 for (
unsigned I = 0;
I < NewEltsPerOldElt; ++
I) {
4494 SDValue IdxOffset = DAG.getConstant(
I, SL, IdxVT);
4498 CastVal, IdxOffset);
4501 NewVec, Elt, InEltIdx);
4538 if (!Results.
empty()) {
4540 ReplaceNode(Node, Results.
data());
4547 AssignTopologicalOrder();
4558 SelectionDAGLegalize
Legalizer(*
this, LegalizedNodes);
4565 bool AnyLegalized =
false;
4566 for (
auto NI = allnodes_end(); NI != allnodes_begin();) {
4570 if (N->
use_empty() && N != getRoot().getNode()) {
4576 if (LegalizedNodes.
insert(N).second) {
4577 AnyLegalized =
true;
4578 Legalizer.LegalizeOp(N);
4580 if (N->
use_empty() && N != getRoot().getNode()) {
4598 SelectionDAGLegalize
Legalizer(*
this, LegalizedNodes, &UpdatedNodes);
4602 LegalizedNodes.
insert(N);
4603 Legalizer.LegalizeOp(N);
4605 return LegalizedNodes.
count(N);
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 ...
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. ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static bool isConstant(const MachineInstr &MI)
static MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
C - The default llvm calling convention, compatible with C.
Constrained versions of libm-equivalent floating point intrinsics.
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.
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
NodeType getExtForLoadExtType(bool IsFP, LoadExtType)
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an vector value) starting with the ...
BR_CC - Conditional branch.
This class represents lattice values for constants.
static MVT getVectorVT(MVT VT, unsigned NumElements)
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool isVector() const
Return true if this is a vector value type.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
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 SDValue & getBasePtr() const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void push_back(const T &Elt)
const SDValue & getValue() const
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain...
SDVTList getVTList() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
unsigned getVectorNumElements() const
const SDValue & getChain() const
Function Alias Analysis Results
static MVT getPromotedVectorElementType(const TargetLowering &TLI, MVT EltVT, MVT NewEltVT)
unsigned getAlignment() const
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
APInt trunc(unsigned width) const
Truncate to new width.
Constrained versions of the binary floating point operators.
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
static IntegerType * getInt64Ty(LLVMContext &C)
[US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned integers.
const SDNodeFlags getFlags() const
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
void reserve(size_type N)
bool isByteSized() const
Return true if the bit size is a multiple of 8.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1 at the ...
unsigned getValueSizeInBits() const
Returns the size of the value in bits.
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) ...
std::pair< MCSymbol *, MachineModuleInfoImpl::StubValueTy > PairTy
Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
const ConstantFP * getConstantFPValue() const
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
bool isTruncatingStore() const
Return true if the op does a truncation before store.
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode *> &Visited, SmallVectorImpl< const SDNode *> &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
unsigned getAddressSpace() const
Return the address space for the associated pointer.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations...
static uint32_t getAlignment(const MCSectionCOFF &Sec)
Shift and rotation operations.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth...
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
CallLoweringInfo & setChain(SDValue InChain)
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
RESULT = SMULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same wi...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
op_iterator op_end() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
FLT_ROUNDS_ - Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest 2 Round to ...
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.
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA)...
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.
const DataLayout & getDataLayout() const
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...
This file implements a class to represent arbitrary precision integral constant values and operations...
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
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...
unsigned getSizeInBits() const
unsigned getScalarSizeInBits() const
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
bool insert(const value_type &X)
Insert a new element into the SetVector.
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here...
falkor hwpf fix Falkor HW Prefetch Fix Late Phase
const TargetMachine & getTarget() const
Simple integer binary arithmetic operators.
bool bitsLT(MVT VT) const
Return true if this has less bits than VT.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
CallLoweringInfo & setZExtResult(bool Value=true)
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...
op_iterator op_begin() const
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification, or lowering of the constant.
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
static bool useSinCos(SDNode *Node)
Only issue sincos libcall if both sin and cos are needed.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
amdgpu Simplify well known AMD library false Value * Callee
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
MVT getVectorElementType() const
UNDEF - An undefined node.
This class is used to represent ISD::STORE nodes.
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...
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
bool isVoidTy() const
Return true if this is 'void'.
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getBasePtr() const
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
Type * getReturnType() const
Returns the type of the ret val.
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
void Legalize()
This transforms the SelectionDAG into a SelectionDAG that is compatible with the target instruction s...
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
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.
PowerPC Reduce CR logical Operation
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
unsigned getScalarSizeInBits() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE...
iterator_range< value_op_iterator > op_values() const
const SDValue & getOperand(unsigned Num) const
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...
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.
This file declares a class to represent arbitrary precision floating point values and provide a varie...
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.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
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.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
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.
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.
std::vector< ArgListEntry > ArgListTy
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
This structure contains all information that is necessary for lowering calls.
This class contains a discriminated union of information about pointers in memory operands...
unsigned getNumOperands() const
Return the number of values used by this operation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
const APFloat & getValueAPF() const
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
bool use_empty() const
Return true if there are no uses of this node.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
TokenFactor - This node takes multiple tokens as input and produces a single token result...
void dump() const
Dump this node, for debugging.
const TargetLowering & getTargetLoweringInfo() const
A SetVector that performs no allocations if smaller than a certain size.
unsigned getStoreSizeInBits() const
Return the number of bits overwritten by a store of the specified value type.
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.
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
EVT getVectorElementType() const
Given a vector type, return the type of each element.
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.
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...
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
CallLoweringInfo & setSExtResult(bool Value=true)
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.
double BitsToDouble(uint64_t Bits)
This function takes a 64-bit integer and returns the bit equivalent double.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachinePointerInfo getWithOffset(int64_t O) const
unsigned Log2_32(uint32_t Value)
Return 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 EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT...
EVT getMemoryVT() const
Return the type of the in-memory value.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
Class for arbitrary precision integers.
Select(COND, TRUEVAL, FALSEVAL).
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
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.
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Flags
Flags values. These may be or'd together.
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.
bool isVector() const
Return true if this is a vector value type.
const SDValue & getValue() const
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...
LLVM_NODISCARD bool empty() const
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...
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
const ConstantInt * getConstantIntValue() const
Flags getFlags() const
Return the raw flags of the source value,.
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
unsigned getOpcode() const
FSINCOS - Compute both fsin and fcos as a single operation.
SDValue getValue(unsigned R) const
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.
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...
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin...
const MachinePointerInfo & getPointerInfo() const
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
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.
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
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...
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.
Primary interface to the complete machine description for the target machine.
const APFloat & getValueAPF() const
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.
APInt bitcastToAPInt() const
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations, those with specific masks.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const SDValue & getOperand(unsigned i) const
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
TRUNCATE - Completely drop the high bits.
bool hasPredecessor(const SDNode *N) const
Return true if N is a predecessor of this node.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
Perform various unary floating-point operations inspired by libm.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
LLVMContext * getContext() const
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
static Constant * get(ArrayRef< Constant *> V)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
Carry-using nodes for multiple precision addition and subtraction.
EVT getHalfSizedIntegerVT(LLVMContext &Context) const
Finds the smallest simple value type that is greater than or equal to half the width of this EVT...
This file describes how to lower LLVM code to machine code.
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
This class is used to represent ISD::LOAD nodes.
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary...