58#define DEBUG_TYPE "legalizedag"
64struct FloatSignAsInt {
87class SelectionDAGLegalize {
99 EVT getSetCCResultType(
EVT VT)
const {
110 LegalizedNodes(LegalizedNodes), UpdatedNodes(UpdatedNodes) {}
131 std::pair<SDValue, SDValue> ExpandLibCall(RTLIB::Libcall LC,
SDNode *
Node,
133 bool IsSigned,
EVT RetVT);
134 std::pair<SDValue, SDValue> ExpandLibCall(RTLIB::Libcall LC,
SDNode *
Node,
bool isSigned);
136 void ExpandFPLibCall(
SDNode *
Node, RTLIB::Libcall LC,
138 void ExpandFPLibCall(
SDNode *
Node, RTLIB::Libcall Call_F32,
139 RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80,
140 RTLIB::Libcall Call_F128,
141 RTLIB::Libcall Call_PPCF128,
145 ExpandFastFPLibCall(
SDNode *
Node,
bool IsFast,
146 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_F32,
147 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_F64,
148 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_F80,
149 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_F128,
150 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_PPCF128,
154 RTLIB::Libcall Call_I16, RTLIB::Libcall Call_I32,
155 RTLIB::Libcall Call_I64, RTLIB::Libcall Call_I128);
157 RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64,
158 RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128,
159 RTLIB::Libcall Call_PPCF128,
162 RTLIB::Libcall CallI64,
163 RTLIB::Libcall CallI128);
175 void getSignAsIntValue(FloatSignAsInt &State,
const SDLoc &
DL,
177 SDValue modifySignAsInt(
const FloatSignAsInt &State,
const SDLoc &
DL,
225 dbgs() <<
" with: "; New->dump(&DAG));
228 "Replacing one node with another that produces a different number "
232 UpdatedNodes->
insert(New);
238 dbgs() <<
" with: "; New->dump(&DAG));
242 UpdatedNodes->
insert(New.getNode());
243 ReplacedNode(Old.getNode());
250 for (
unsigned i = 0, e = Old->
getNumValues(); i != e; ++i) {
261 dbgs() <<
" with: "; New->dump(&DAG));
265 UpdatedNodes->
insert(New.getNode());
266 ReplacedNode(Old.getNode());
276 bool isObjectScalable) {
284 ObjectSize, MFI.getObjectAlign(FI));
291SDValue SelectionDAGLegalize::ShuffleWithNarrowerEltType(
296 unsigned NumEltsGrowth = NumDestElts / NumMaskElts;
298 assert(NumEltsGrowth &&
"Cannot promote to vector type with fewer elts!");
300 if (NumEltsGrowth == 1)
303 SmallVector<int, 8> NewMask;
304 for (
unsigned i = 0; i != NumMaskElts; ++i) {
306 for (
unsigned j = 0;
j != NumEltsGrowth; ++
j) {
310 NewMask.
push_back(Idx * NumEltsGrowth + j);
313 assert(NewMask.
size() == NumDestElts &&
"Non-integer NumEltsGrowth?");
321SelectionDAGLegalize::ExpandConstantFP(ConstantFPSDNode *CFP,
bool UseCP) {
334 assert((VT == MVT::f64 || VT == MVT::f32) &&
"Invalid type expansion");
336 (VT == MVT::f64) ? MVT::i64 : MVT::i32);
346 while (SVT != MVT::f32 && SVT != MVT::f16 && SVT != MVT::bf16) {
379SDValue SelectionDAGLegalize::ExpandConstant(ConstantSDNode *CP) {
381 EVT VT =
CP->getValueType(0);
411 SmallVector<int, 8> ShufOps;
412 for (
unsigned i = 0; i != NumElts; ++i)
413 ShufOps.
push_back(i != InsertPos->getZExtValue() ? i : NumElts);
418 return ExpandInsertToVectorThroughStack(
Op);
421SDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) {
436 AAMDNodes AAInfo =
ST->getAAInfo();
447 bitcastToAPInt().zextOrTrunc(32),
448 SDLoc(CFP), MVT::i32);
449 return DAG.
getStore(Chain, dl, Con,
Ptr,
ST->getPointerInfo(),
450 ST->getBaseAlign(), MMOFlags, AAInfo);
458 zextOrTrunc(64), SDLoc(CFP), MVT::i64);
459 return DAG.
getStore(Chain, dl, Con,
Ptr,
ST->getPointerInfo(),
460 ST->getBaseAlign(), MMOFlags, AAInfo);
474 ST->getBaseAlign(), MMOFlags, AAInfo);
477 ST->getPointerInfo().getWithOffset(4),
478 ST->getBaseAlign(), MMOFlags, AAInfo);
487void SelectionDAGLegalize::LegalizeStoreOps(SDNode *Node) {
494 AAMDNodes AAInfo =
ST->getAAInfo();
496 if (!
ST->isTruncatingStore()) {
498 if (SDNode *OptStore = OptimizeFloatStore(ST).
getNode()) {
499 ReplaceNode(ST, OptStore);
504 MVT VT =
Value.getSimpleValueType();
507 case TargetLowering::Legal: {
510 EVT MemVT =
ST->getMemoryVT();
513 *
ST->getMemOperand())) {
516 ReplaceNode(
SDValue(ST, 0), Result);
521 case TargetLowering::Custom: {
524 if (Res && Res !=
SDValue(Node, 0))
525 ReplaceNode(
SDValue(Node, 0), Res);
528 case TargetLowering::Promote: {
531 "Can only promote stores to same size type");
534 ST->getBaseAlign(), MMOFlags, AAInfo);
535 ReplaceNode(
SDValue(Node, 0), Result);
544 EVT StVT =
ST->getMemoryVT();
549 if (StWidth != StSize) {
557 ST->getBaseAlign(), MMOFlags, AAInfo);
558 ReplaceNode(
SDValue(Node, 0), Result);
563 unsigned LogStWidth =
Log2_32(StWidthBits);
565 unsigned RoundWidth = 1 << LogStWidth;
566 assert(RoundWidth < StWidthBits);
567 unsigned ExtraWidth = StWidthBits - RoundWidth;
568 assert(ExtraWidth < RoundWidth);
569 assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
570 "Store size not an integral number of bytes!");
574 unsigned IncrementSize;
576 if (
DL.isLittleEndian()) {
580 RoundVT,
ST->getBaseAlign(), MMOFlags, AAInfo);
583 IncrementSize = RoundWidth / 8;
590 ST->getPointerInfo().getWithOffset(IncrementSize),
591 ExtraVT,
ST->getBaseAlign(), MMOFlags, AAInfo);
600 ST->getBaseAlign(), MMOFlags, AAInfo);
603 IncrementSize = RoundWidth / 8;
606 Ptr.getValueType()));
608 ST->getPointerInfo().getWithOffset(IncrementSize),
609 ExtraVT,
ST->getBaseAlign(), MMOFlags, AAInfo);
614 ReplaceNode(
SDValue(Node, 0), Result);
618 case TargetLowering::Legal: {
619 EVT MemVT =
ST->getMemoryVT();
623 *
ST->getMemOperand())) {
625 ReplaceNode(
SDValue(ST, 0), Result);
629 case TargetLowering::Custom: {
631 if (Res && Res !=
SDValue(Node, 0))
632 ReplaceNode(
SDValue(Node, 0), Res);
635 case TargetLowering::Expand:
637 "Vector Stores are handled in LegalizeVectorOps");
645 ST->getBaseAlign(), MMOFlags, AAInfo);
653 StVT,
ST->getBaseAlign(), MMOFlags, AAInfo);
656 ReplaceNode(
SDValue(Node, 0), Result);
662void SelectionDAGLegalize::LegalizeLoadOps(SDNode *Node) {
671 LLVM_DEBUG(
dbgs() <<
"Legalizing non-extending load operation\n");
672 MVT VT =
Node->getSimpleValueType(0);
678 case TargetLowering::Legal: {
679 EVT MemVT =
LD->getMemoryVT();
684 *
LD->getMemOperand())) {
689 case TargetLowering::Custom:
696 case TargetLowering::Promote: {
699 "Can only promote loads to same size type");
703 if (
const MDNode *MD =
LD->getRanges()) {
707 LD->getMemOperand()->clearRanges();
710 RVal = DAG.
getNode(ISD::BITCAST, dl, VT, Res);
715 if (RChain.
getNode() != Node) {
716 assert(RVal.
getNode() != Node &&
"Load must be completely replaced");
720 UpdatedNodes->insert(RVal.
getNode());
721 UpdatedNodes->insert(RChain.
getNode());
729 EVT SrcVT =
LD->getMemoryVT();
732 AAMDNodes AAInfo =
LD->getAAInfo();
744 TargetLowering::Promote)) {
758 Chain,
Ptr,
LD->getPointerInfo(), NVT,
759 LD->getBaseAlign(), MMOFlags, AAInfo);
771 Result.getValueType(), Result,
780 unsigned LogSrcWidth =
Log2_32(SrcWidthBits);
782 unsigned RoundWidth = 1 << LogSrcWidth;
783 assert(RoundWidth < SrcWidthBits);
784 unsigned ExtraWidth = SrcWidthBits - RoundWidth;
785 assert(ExtraWidth < RoundWidth);
786 assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
787 "Load size not an integral number of bytes!");
791 unsigned IncrementSize;
794 if (
DL.isLittleEndian()) {
798 LD->getPointerInfo(), RoundVT,
LD->getBaseAlign(),
802 IncrementSize = RoundWidth / 8;
806 LD->getPointerInfo().getWithOffset(IncrementSize),
807 ExtraVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
826 LD->getPointerInfo(), RoundVT,
LD->getBaseAlign(),
830 IncrementSize = RoundWidth / 8;
834 LD->getPointerInfo().getWithOffset(IncrementSize),
835 ExtraVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
853 bool isCustom =
false;
857 case TargetLowering::Custom:
860 case TargetLowering::Legal:
872 EVT MemVT =
LD->getMemoryVT();
875 *
LD->getMemOperand())) {
881 case TargetLowering::Expand: {
882 EVT DestVT =
Node->getValueType(0);
896 SrcVT,
LD->getMemOperand());
900 Chain =
Load.getValue(1);
909 if (SVT == MVT::f16 || SVT == MVT::bf16) {
915 Ptr, ISrcVT,
LD->getMemOperand());
917 DAG.
getNode(SVT == MVT::f16 ? ISD::FP16_TO_FP : ISD::BF16_TO_FP,
919 Chain =
Result.getValue(1);
925 "Vector Loads are handled in LegalizeVectorOps");
932 "EXTLOAD should always be supported!");
936 Node->getValueType(0),
938 LD->getMemOperand());
947 Chain =
Result.getValue(1);
956 assert(
Value.getNode() != Node &&
"Load must be completely replaced");
960 UpdatedNodes->insert(
Value.getNode());
961 UpdatedNodes->insert(Chain.
getNode());
968void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
977 for (
unsigned i = 0, e =
Node->getNumValues(); i != e; ++i)
979 TargetLowering::TypeLegal &&
980 "Unexpected illegal type!");
984 TargetLowering::TypeLegal ||
987 "Unexpected illegal type!");
991 TargetLowering::LegalizeAction Action = TargetLowering::Legal;
992 bool SimpleFinishLegalizing =
true;
993 switch (
Node->getOpcode()) {
1004 ReplaceNode(Node, UndefNode.
getNode());
1010 case ISD::STACKSAVE:
1013 case ISD::GET_DYNAMIC_AREA_OFFSET:
1015 Node->getValueType(0));
1019 Node->getValueType(0));
1020 if (Action != TargetLowering::Promote)
1023 case ISD::SET_FPENV:
1024 case ISD::SET_FPMODE:
1026 Node->getOperand(1).getValueType());
1028 case ISD::FP_TO_FP16:
1029 case ISD::FP_TO_BF16:
1038 Node->getOperand(0).getValueType());
1040 case ISD::STRICT_FP_TO_FP16:
1041 case ISD::STRICT_FP_TO_BF16:
1052 Node->getOperand(1).getValueType());
1059 case ISD::ATOMIC_STORE:
1061 Node->getOperand(1).getValueType());
1070 unsigned Opc =
Node->getOpcode();
1077 unsigned CompareOperand =
Opc == ISD::BR_CC ? 2
1081 MVT OpVT =
Node->getOperand(CompareOperand).getSimpleValueType();
1085 if (Action == TargetLowering::Legal) {
1088 Node->getValueType(0));
1098 SimpleFinishLegalizing =
false;
1100 case ISD::CALLSEQ_START:
1101 case ISD::CALLSEQ_END:
1105 SimpleFinishLegalizing =
false;
1119 if (Action == TargetLowering::Legal)
1120 Action = TargetLowering::Expand;
1122 case ISD::INIT_TRAMPOLINE:
1123 case ISD::ADJUST_TRAMPOLINE:
1131 if (Action == TargetLowering::Legal)
1132 Action = TargetLowering::Custom;
1139 case ISD::READCYCLECOUNTER:
1140 case ISD::READSTEADYCOUNTER:
1150 Action = TargetLowering::Legal;
1152 case ISD::UBSANTRAP:
1154 if (Action == TargetLowering::Expand) {
1157 NewVal = DAG.
getNode(ISD::TRAP, SDLoc(Node),
Node->getVTList(),
1158 Node->getOperand(0));
1159 ReplaceNode(Node, NewVal.
getNode());
1164 case ISD::DEBUGTRAP:
1166 if (Action == TargetLowering::Expand) {
1169 NewVal = DAG.
getNode(ISD::TRAP, SDLoc(Node),
Node->getVTList(),
1170 Node->getOperand(0));
1171 ReplaceNode(Node, NewVal.
getNode());
1196 unsigned Scale =
Node->getConstantOperandVal(2);
1198 Node->getValueType(0), Scale);
1209 case ISD::VP_SCATTER:
1219 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1224 case ISD::VECREDUCE_FADD:
1225 case ISD::VECREDUCE_FMUL:
1226 case ISD::VECREDUCE_ADD:
1227 case ISD::VECREDUCE_MUL:
1228 case ISD::VECREDUCE_AND:
1229 case ISD::VECREDUCE_OR:
1230 case ISD::VECREDUCE_XOR:
1231 case ISD::VECREDUCE_SMAX:
1232 case ISD::VECREDUCE_SMIN:
1233 case ISD::VECREDUCE_UMAX:
1234 case ISD::VECREDUCE_UMIN:
1235 case ISD::VECREDUCE_FMAX:
1236 case ISD::VECREDUCE_FMIN:
1237 case ISD::VECREDUCE_FMAXIMUM:
1238 case ISD::VECREDUCE_FMINIMUM:
1241 Node->getOpcode(),
Node->getOperand(0).getValueType());
1243 case ISD::VECREDUCE_SEQ_FADD:
1244 case ISD::VECREDUCE_SEQ_FMUL:
1245 case ISD::VP_REDUCE_FADD:
1246 case ISD::VP_REDUCE_FMUL:
1247 case ISD::VP_REDUCE_ADD:
1248 case ISD::VP_REDUCE_MUL:
1249 case ISD::VP_REDUCE_AND:
1250 case ISD::VP_REDUCE_OR:
1251 case ISD::VP_REDUCE_XOR:
1252 case ISD::VP_REDUCE_SMAX:
1253 case ISD::VP_REDUCE_SMIN:
1254 case ISD::VP_REDUCE_UMAX:
1255 case ISD::VP_REDUCE_UMIN:
1256 case ISD::VP_REDUCE_FMAX:
1257 case ISD::VP_REDUCE_FMIN:
1258 case ISD::VP_REDUCE_FMAXIMUM:
1259 case ISD::VP_REDUCE_FMINIMUM:
1260 case ISD::VP_REDUCE_SEQ_FADD:
1261 case ISD::VP_REDUCE_SEQ_FMUL:
1263 Node->getOpcode(),
Node->getOperand(1).getValueType());
1265 case ISD::VP_CTTZ_ELTS:
1266 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
1268 Node->getOperand(0).getValueType());
1270 case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
1284 if (SimpleFinishLegalizing) {
1285 SDNode *NewNode =
Node;
1286 switch (
Node->getOpcode()) {
1331 if (NewNode != Node) {
1332 ReplaceNode(Node, NewNode);
1336 case TargetLowering::Legal:
1339 case TargetLowering::Custom:
1347 if (
Node->getNumValues() == 1) {
1351 Node->getValueType(0) == MVT::Glue) &&
1352 "Type mismatch for custom legalized operation");
1355 ReplaceNode(
SDValue(Node, 0), Res);
1360 for (
unsigned i = 0, e =
Node->getNumValues(); i != e; ++i) {
1364 Node->getValueType(i) == MVT::Glue) &&
1365 "Type mismatch for custom legalized operation");
1369 ReplaceNode(Node, ResultVals.
data());
1374 case TargetLowering::Expand:
1375 if (ExpandNode(Node))
1378 case TargetLowering::LibCall:
1379 ConvertNodeToLibcall(Node);
1381 case TargetLowering::Promote:
1387 switch (
Node->getOpcode()) {
1396 case ISD::CALLSEQ_START:
1397 case ISD::CALLSEQ_END:
1400 return LegalizeLoadOps(Node);
1402 return LegalizeStoreOps(Node);
1406SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(
SDValue Op) {
1419 SmallPtrSet<const SDNode *, 32> Visited;
1426 if (
ST->isIndexed() ||
ST->isTruncatingStore() ||
1427 ST->getValue() != Vec)
1432 if (!
ST->getChain().reachesChainWithoutSideEffects(DAG.
getEntryNode()))
1441 ST->hasPredecessor(
Op.getNode()))
1461 Align ElementAlignment =
1466 if (
Op.getValueType().isVector()) {
1468 Op.getValueType(), Idx);
1469 NewLoad = DAG.
getLoad(
Op.getValueType(), dl, Ch, StackPtr,
1470 MachinePointerInfo(), ElementAlignment);
1484 NewLoadOperands[0] = Ch;
1490SDValue SelectionDAGLegalize::ExpandInsertToVectorThroughStack(
SDValue Op) {
1491 assert(
Op.getValueType().isVector() &&
"Non-vector insert subvector!");
1503 MachinePointerInfo PtrInfo =
1507 Align BaseVecAlignment =
1525 Ch, dl, Part, SubStackPtr,
1534 Ch, dl, Part, SubStackPtr,
1540 "ElementAlignment does not match!");
1543 return DAG.
getLoad(
Op.getValueType(), dl, Ch, StackPtr, PtrInfo,
1547SDValue SelectionDAGLegalize::ExpandConcatVectors(SDNode *Node) {
1551 unsigned NumOperands =
Node->getNumOperands();
1553 EVT VectorValueType =
Node->getOperand(0).getValueType();
1557 for (
unsigned I = 0;
I < NumOperands; ++
I) {
1559 for (
unsigned Idx = 0; Idx < NumSubElem; ++Idx) {
1568SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
1571 "Unexpected opcode!");
1577 EVT VT =
Node->getValueType(0);
1579 :
Node->getOperand(0).getValueType();
1583 MachinePointerInfo PtrInfo =
1589 assert(TypeByteSize > 0 &&
"Vector element type too small for stack store!");
1594 MemVT.
bitsLT(
Node->getOperand(0).getValueType());
1597 for (
unsigned i = 0, e =
Node->getNumOperands(); i != e; ++i) {
1599 if (
Node->getOperand(i).isUndef())
continue;
1601 unsigned Offset = TypeByteSize*i;
1608 Node->getOperand(i), Idx,
1616 if (!Stores.
empty())
1622 return DAG.
getLoad(VT, dl, StoreChain, FIPtr, PtrInfo);
1628void SelectionDAGLegalize::getSignAsIntValue(FloatSignAsInt &State,
1631 EVT FloatVT =
Value.getValueType();
1633 State.FloatVT = FloatVT;
1639 State.SignBit = NumBits - 1;
1654 State.FloatPointerInfo);
1657 if (DataLayout.isBigEndian()) {
1661 State.IntPointerInfo = State.FloatPointerInfo;
1664 unsigned ByteOffset = (NumBits / 8) - 1;
1671 State.IntPtr = IntPtr;
1673 State.IntPointerInfo, MVT::i8);
1680SDValue SelectionDAGLegalize::modifySignAsInt(
const FloatSignAsInt &State,
1684 return DAG.
getNode(ISD::BITCAST,
DL, State.FloatVT, NewIntValue);
1688 State.IntPointerInfo, MVT::i8);
1689 return DAG.
getLoad(State.FloatVT,
DL, Chain, State.FloatPtr,
1690 State.FloatPointerInfo);
1693SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node)
const {
1699 FloatSignAsInt SignAsInt;
1700 getSignAsIntValue(SignAsInt,
DL, Sign);
1720 FloatSignAsInt MagAsInt;
1721 getSignAsIntValue(MagAsInt,
DL, Mag);
1728 int ShiftAmount = SignAsInt.SignBit - MagAsInt.SignBit;
1729 EVT ShiftVT = IntVT;
1735 if (ShiftAmount > 0) {
1738 }
else if (ShiftAmount < 0) {
1751 return modifySignAsInt(MagAsInt,
DL, CopiedSign);
1754SDValue SelectionDAGLegalize::ExpandFNEG(SDNode *Node)
const {
1757 FloatSignAsInt SignAsInt;
1758 getSignAsIntValue(SignAsInt,
DL,
Node->getOperand(0));
1767 return modifySignAsInt(SignAsInt,
DL, SignFlip);
1770SDValue SelectionDAGLegalize::ExpandFABS(SDNode *Node)
const {
1775 EVT FloatVT =
Value.getValueType();
1782 FloatSignAsInt ValueAsInt;
1783 getSignAsIntValue(ValueAsInt,
DL,
Value);
1788 return modifySignAsInt(ValueAsInt,
DL, ClearedSign);
1791void SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(SDNode* Node,
1792 SmallVectorImpl<SDValue> &
Results) {
1794 assert(
SPReg &&
"Target cannot require DYNAMIC_STACKALLOC expansion and"
1795 " not tell us which reg is the stack pointer!");
1797 EVT VT =
Node->getValueType(0);
1809 Chain =
SP.getValue(1);
1818 if (Alignment > StackAlign)
1833SDValue SelectionDAGLegalize::EmitStackConvert(
SDValue SrcOp, EVT SlotVT,
1834 EVT DestVT,
const SDLoc &dl) {
1835 return EmitStackConvert(SrcOp, SlotVT, DestVT, dl, DAG.
getEntryNode());
1838SDValue SelectionDAGLegalize::EmitStackConvert(
SDValue SrcOp, EVT SlotVT,
1839 EVT DestVT,
const SDLoc &dl,
1846 if ((SrcVT.
bitsGT(SlotVT) &&
1848 (SlotVT.
bitsLT(DestVT) &&
1859 MachinePointerInfo PtrInfo =
1866 if (SrcVT.
bitsGT(SlotVT))
1871 Store = DAG.
getStore(Chain, dl, SrcOp, FIPtr, PtrInfo, SrcAlign);
1875 if (SlotVT.
bitsEq(DestVT))
1876 return DAG.
getLoad(DestVT, dl, Store, FIPtr, PtrInfo, DestAlign);
1883SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
1895 Node->getValueType(0).getVectorElementType());
1897 Node->getValueType(0), dl, Ch, StackPtr,
1904 unsigned NumElems =
Node->getNumOperands();
1906 EVT VT =
Node->getValueType(0);
1918 for (
unsigned i = 0; i < NumElems; ++i) {
1929 while (IntermedVals.
size() > 2) {
1930 NewIntermedVals.
clear();
1931 for (
unsigned i = 0, e = (IntermedVals.
size() & ~1u); i < e; i += 2) {
1937 FinalIndices.
reserve(IntermedVals[i].second.
size() +
1938 IntermedVals[i+1].second.
size());
1941 for (
unsigned j = 0, f = IntermedVals[i].second.
size(); j != f;
1944 FinalIndices.
push_back(IntermedVals[i].second[j]);
1946 for (
unsigned j = 0, f = IntermedVals[i+1].second.
size(); j != f;
1948 ShuffleVec[k] = NumElems + j;
1949 FinalIndices.
push_back(IntermedVals[i+1].second[j]);
1955 IntermedVals[i+1].first,
1960 std::make_pair(Shuffle, std::move(FinalIndices)));
1965 if ((IntermedVals.
size() & 1) != 0)
1968 IntermedVals.
swap(NewIntermedVals);
1972 "Invalid number of intermediate vectors");
1973 SDValue Vec1 = IntermedVals[0].first;
1975 if (IntermedVals.
size() > 1)
1976 Vec2 = IntermedVals[1].first;
1981 for (
unsigned i = 0, e = IntermedVals[0].second.
size(); i != e; ++i)
1982 ShuffleVec[IntermedVals[0].second[i]] = i;
1983 for (
unsigned i = 0, e = IntermedVals[1].second.
size(); i != e; ++i)
1984 ShuffleVec[IntermedVals[1].second[i]] = NumElems + i;
1997SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
1998 unsigned NumElems =
Node->getNumOperands();
2001 EVT VT =
Node->getValueType(0);
2002 EVT OpVT =
Node->getOperand(0).getValueType();
2007 bool isOnlyLowElement =
true;
2008 bool MoreThanTwoValues =
false;
2010 for (
unsigned i = 0; i < NumElems; ++i) {
2015 isOnlyLowElement =
false;
2021 }
else if (!Value2.
getNode()) {
2024 }
else if (V != Value1 && V != Value2) {
2025 MoreThanTwoValues =
true;
2032 if (isOnlyLowElement)
2038 for (
unsigned i = 0, e = NumElems; i !=
e; ++i) {
2039 if (ConstantFPSDNode *V =
2042 }
else if (ConstantSDNode *V =
2045 CV.
push_back(
const_cast<ConstantInt *
>(
V->getConstantIntValue()));
2050 const ConstantInt *CI =
V->getConstantIntValue();
2070 SmallSet<SDValue, 16> DefinedValues;
2071 for (
unsigned i = 0; i < NumElems; ++i) {
2072 if (
Node->getOperand(i).isUndef())
2078 if (!MoreThanTwoValues) {
2079 SmallVector<int, 8> ShuffleVec(NumElems, -1);
2080 for (
unsigned i = 0; i < NumElems; ++i) {
2084 ShuffleVec[i] =
V == Value1 ? 0 : NumElems;
2106 return ExpandVectorBuildThroughStack(Node);
2109SDValue SelectionDAGLegalize::ExpandSPLAT_VECTOR(SDNode *Node) {
2111 EVT VT =
Node->getValueType(0);
2122std::pair<SDValue, SDValue>
2123SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
2124 TargetLowering::ArgListTy &&Args,
2125 bool IsSigned, EVT RetVT) {
2133 Node->getOperationName(&DAG));
2150 (RetTy ==
F.getReturnType() ||
F.getReturnType()->
isVoidTy());
2154 TargetLowering::CallLoweringInfo CLI(DAG);
2156 CLI.setDebugLoc(SDLoc(Node))
2160 .setTailCall(isTailCall)
2161 .setSExtResult(signExtend)
2162 .setZExtResult(!signExtend)
2163 .setIsPostTypeLegalization(
true);
2165 std::pair<SDValue, SDValue> CallInfo = TLI.
LowerCallTo(CLI);
2167 if (!CallInfo.second.getNode()) {
2173 LLVM_DEBUG(
dbgs() <<
"Created libcall: "; CallInfo.first.dump(&DAG));
2177std::pair<SDValue, SDValue> SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
2179 TargetLowering::ArgListTy
Args;
2181 EVT ArgVT =
Op.getValueType();
2183 TargetLowering::ArgListEntry
Entry(
Op, ArgTy);
2186 Args.push_back(Entry);
2189 return ExpandLibCall(LC, Node, std::move(Args),
isSigned,
2190 Node->getValueType(0));
2193void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node,
2195 SmallVectorImpl<SDValue> &
Results) {
2196 if (LC == RTLIB::UNKNOWN_LIBCALL)
2199 if (
Node->isStrictFPOpcode()) {
2200 EVT RetVT =
Node->getValueType(0);
2202 TargetLowering::MakeLibCallOptions CallOptions;
2205 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, RetVT,
2208 Node->getOperand(0));
2210 Results.push_back(Tmp.second);
2212 bool IsSignedArgument =
Node->getOpcode() == ISD::FLDEXP;
2213 SDValue Tmp = ExpandLibCall(LC, Node, IsSignedArgument).first;
2219void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node,
2220 RTLIB::Libcall Call_F32,
2221 RTLIB::Libcall Call_F64,
2222 RTLIB::Libcall Call_F80,
2223 RTLIB::Libcall Call_F128,
2224 RTLIB::Libcall Call_PPCF128,
2225 SmallVectorImpl<SDValue> &
Results) {
2227 Call_F32, Call_F64, Call_F80,
2228 Call_F128, Call_PPCF128);
2229 ExpandFPLibCall(Node, LC,
Results);
2232void SelectionDAGLegalize::ExpandFastFPLibCall(
2233 SDNode *Node,
bool IsFast,
2234 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_F32,
2235 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_F64,
2236 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_F80,
2237 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_F128,
2238 std::pair<RTLIB::Libcall, RTLIB::Libcall> Call_PPCF128,
2239 SmallVectorImpl<SDValue> &
Results) {
2241 EVT VT =
Node->getSimpleValueType(0);
2250 Call_F128.first, Call_PPCF128.first);
2256 Call_F80.second, Call_F128.second,
2257 Call_PPCF128.second);
2260 ExpandFPLibCall(Node, LC,
Results);
2263SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node,
bool isSigned,
2264 RTLIB::Libcall Call_I8,
2265 RTLIB::Libcall Call_I16,
2266 RTLIB::Libcall Call_I32,
2267 RTLIB::Libcall Call_I64,
2268 RTLIB::Libcall Call_I128) {
2270 switch (
Node->getSimpleValueType(0).SimpleTy) {
2272 case MVT::i8: LC = Call_I8;
break;
2273 case MVT::i16: LC = Call_I16;
break;
2274 case MVT::i32: LC = Call_I32;
break;
2275 case MVT::i64: LC = Call_I64;
break;
2276 case MVT::i128: LC = Call_I128;
break;
2278 return ExpandLibCall(LC, Node,
isSigned).first;
2283void SelectionDAGLegalize::ExpandArgFPLibCall(SDNode* Node,
2284 RTLIB::Libcall Call_F32,
2285 RTLIB::Libcall Call_F64,
2286 RTLIB::Libcall Call_F80,
2287 RTLIB::Libcall Call_F128,
2288 RTLIB::Libcall Call_PPCF128,
2289 SmallVectorImpl<SDValue> &
Results) {
2290 EVT InVT =
Node->getOperand(
Node->isStrictFPOpcode() ? 1 : 0).getValueType();
2292 Call_F32, Call_F64, Call_F80,
2293 Call_F128, Call_PPCF128);
2294 ExpandFPLibCall(Node, LC,
Results);
2297SDValue SelectionDAGLegalize::ExpandBitCountingLibCall(
2298 SDNode *Node, RTLIB::Libcall CallI32, RTLIB::Libcall CallI64,
2299 RTLIB::Libcall CallI128) {
2301 switch (
Node->getSimpleValueType(0).SimpleTy) {
2322 EVT ArgVT =
Op.getValueType();
2324 TargetLowering::ArgListEntry Arg(
Op, ArgTy);
2326 Arg.IsZExt = !Arg.IsSExt;
2328 SDValue Res = ExpandLibCall(LC, Node, TargetLowering::ArgListTy{Arg},
2341SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node,
2342 SmallVectorImpl<SDValue> &
Results) {
2343 unsigned Opcode =
Node->getOpcode();
2347 switch (
Node->getSimpleValueType(0).SimpleTy) {
2349 case MVT::i8: LC=
isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
break;
2350 case MVT::i16: LC=
isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
break;
2351 case MVT::i32: LC=
isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
2352 case MVT::i64: LC=
isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
break;
2353 case MVT::i128: LC=
isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128;
break;
2361 EVT RetVT =
Node->getValueType(0);
2364 TargetLowering::ArgListTy
Args;
2366 EVT ArgVT =
Op.getValueType();
2368 TargetLowering::ArgListEntry
Entry(
Op, ArgTy);
2371 Args.push_back(Entry);
2376 TargetLowering::ArgListEntry
Entry(
2377 FIPtr, PointerType::getUnqual(RetTy->
getContext()));
2380 Args.push_back(Entry);
2386 TargetLowering::CallLoweringInfo CLI(DAG);
2394 std::pair<SDValue, SDValue> CallInfo = TLI.
LowerCallTo(CLI);
2398 DAG.
getLoad(RetVT, dl, CallInfo.second, FIPtr, MachinePointerInfo());
2399 Results.push_back(CallInfo.first);
2411 unsigned OtherOpcode =
Node->getOpcode() == ISD::FSIN
2412 ? ISD::FCOS : ISD::FSIN;
2419 if (
User->getOpcode() == OtherOpcode ||
User->getOpcode() == ISD::FSINCOS)
2425SDValue SelectionDAGLegalize::expandLdexp(SDNode *Node)
const {
2427 EVT VT =
Node->getValueType(0);
2430 EVT ExpVT =
N.getValueType();
2432 if (AsIntVT == EVT())
2440 SDNodeFlags NUW_NSW;
2448 const APFloat::ExponentType MaxExpVal = APFloat::semanticsMaxExponent(FltSem);
2449 const APFloat::ExponentType MinExpVal = APFloat::semanticsMinExponent(FltSem);
2450 const int Precision = APFloat::semanticsPrecision(FltSem);
2457 const APFloat One(FltSem,
"1.0");
2458 APFloat ScaleUpK =
scalbn(One, MaxExpVal, APFloat::rmNearestTiesToEven);
2462 scalbn(One, MinExpVal + Precision, APFloat::rmNearestTiesToEven);
2532 ExponentShiftAmt, NUW_NSW);
2537SDValue SelectionDAGLegalize::expandFrexp(SDNode *Node)
const {
2541 EVT ExpVT =
Node->getValueType(1);
2543 if (AsIntVT == EVT())
2547 const APFloat::ExponentType MinExpVal = APFloat::semanticsMinExponent(FltSem);
2548 const unsigned Precision = APFloat::semanticsPrecision(FltSem);
2581 FractSignMaskVal.
setBit(BitSize - 1);
2588 const APFloat One(FltSem,
"1.0");
2592 scalbn(One, Precision + 1, APFloat::rmNearestTiesToEven);
2604 SDValue AddNegSmallestNormal =
2606 SDValue DenormOrZero = DAG.
getSetCC(dl, SetCCVT, AddNegSmallestNormal,
2615 SDValue ScaledAsInt = DAG.
getNode(ISD::BITCAST, dl, AsIntVT, ScaleUp);
2639 const APFloat Half(FltSem,
"0.5");
2660SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(SDNode *Node,
2664 EVT DestVT =
Node->getValueType(0);
2666 unsigned OpNo =
Node->isStrictFPOpcode() ? 1 : 0;
2672 if (SrcVT == MVT::i32 && TLI.
isTypeLegal(MVT::f64) &&
2673 (DestVT.
bitsLE(MVT::f64) ||
2677 LLVM_DEBUG(
dbgs() <<
"32-bit [signed|unsigned] integer to float/double "
2701 MachinePointerInfo());
2706 DAG.
getStore(MemChain, dl,
Hi, HiPtr, MachinePointerInfo());
2711 DAG.
getLoad(MVT::f64, dl, MemChain, StackSlot, MachinePointerInfo());
2720 if (
Node->isStrictFPOpcode()) {
2722 {
Node->getOperand(0),
Load, Bias});
2724 if (DestVT !=
Sub.getValueType()) {
2725 std::pair<SDValue, SDValue> ResultPair;
2728 Result = ResultPair.first;
2729 Chain = ResultPair.second;
2744 if (((SrcVT == MVT::i32 || SrcVT == MVT::i64) && DestVT == MVT::f32) ||
2745 (SrcVT == MVT::i64 && DestVT == MVT::f64)) {
2746 LLVM_DEBUG(
dbgs() <<
"Converting unsigned i32/i64 to f32/f64\n");
2761 EVT SetCCVT = getSetCCResultType(SrcVT);
2773 if (
Node->isStrictFPOpcode()) {
2781 Flags.setNoFPExcept(
Node->getFlags().hasNoFPExcept());
2784 Flags.setNoFPExcept(
true);
2807 "Cannot perform lossless SINT_TO_FP!");
2810 if (
Node->isStrictFPOpcode()) {
2812 {
Node->getOperand(0), Op0 });
2821 SignSet, Four, Zero);
2830 case MVT::i8 : FF = 0x43800000ULL;
break;
2831 case MVT::i16: FF = 0x47800000ULL;
break;
2832 case MVT::i32: FF = 0x4F800000ULL;
break;
2833 case MVT::i64: FF = 0x5F800000ULL;
break;
2837 Constant *FudgeFactor = ConstantInt::get(
2846 if (DestVT == MVT::f32)
2856 HandleSDNode Handle(Load);
2857 LegalizeOp(
Load.getNode());
2861 if (
Node->isStrictFPOpcode()) {
2863 { Tmp1.
getValue(1), Tmp1, FudgeInReg });
2864 Chain =
Result.getValue(1);
2876void SelectionDAGLegalize::PromoteLegalINT_TO_FP(
2877 SDNode *
N,
const SDLoc &dl, SmallVectorImpl<SDValue> &
Results) {
2881 EVT DestVT =
N->getValueType(0);
2882 SDValue LegalOp =
N->getOperand(IsStrict ? 1 : 0);
2889 unsigned OpToUse = 0;
2917 DAG.
getNode(OpToUse, dl, {DestVT, MVT::Other},
2920 dl, NewInTy, LegalOp)});
2927 DAG.
getNode(OpToUse, dl, DestVT,
2929 dl, NewInTy, LegalOp)));
2937void SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDNode *
N,
const SDLoc &dl,
2938 SmallVectorImpl<SDValue> &
Results) {
2939 bool IsStrict =
N->isStrictFPOpcode();
2942 EVT DestVT =
N->getValueType(0);
2945 EVT NewOutTy = DestVT;
2947 unsigned OpToUse = 0;
2971 SDVTList VTs = DAG.
getVTList(NewOutTy, MVT::Other);
2987SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT_SAT(SDNode *Node,
2989 unsigned Opcode =
Node->getOpcode();
2992 EVT NewOutTy =
Node->getValueType(0);
3004 Node->getOperand(1));
3010 EVT VT =
Op.getValueType();
3030SDValue SelectionDAGLegalize::PromoteReduction(SDNode *Node) {
3032 MVT VecVT = IsVPOpcode ?
Node->getOperand(1).getSimpleValueType()
3033 :
Node->getOperand(0).getSimpleValueType();
3035 MVT ScalarVT =
Node->getSimpleValueType(0);
3042 assert(
Node->getOperand(0).getValueType().isFloatingPoint() &&
3043 "Only FP promotion is supported");
3045 for (
unsigned j = 0;
j !=
Node->getNumOperands(); ++
j)
3046 if (
Node->getOperand(j).getValueType().isVector() &&
3051 assert(
Node->getOperand(j).getValueType().isFloatingPoint() &&
3052 "Only FP promotion is supported");
3054 DAG.
getNode(ISD::FP_EXTEND,
DL, NewVecVT,
Node->getOperand(j));
3055 }
else if (
Node->getOperand(j).getValueType().isFloatingPoint()) {
3058 DAG.
getNode(ISD::FP_EXTEND,
DL, NewScalarVT,
Node->getOperand(j));
3071bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
3075 SDValue Tmp1, Tmp2, Tmp3, Tmp4;
3077 switch (
Node->getOpcode()) {
3117 Results.push_back(ExpandPARITY(
Node->getOperand(0), dl));
3152 case ISD::READCYCLECOUNTER:
3153 case ISD::READSTEADYCOUNTER:
3166 case ISD::ATOMIC_LOAD: {
3169 SDVTList VTs = DAG.
getVTList(
Node->getValueType(0), MVT::Other);
3172 Node->getOperand(0),
Node->getOperand(1), Zero, Zero,
3178 case ISD::ATOMIC_STORE: {
3182 Node->getOperand(0),
Node->getOperand(2),
Node->getOperand(1),
3187 case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: {
3191 SDVTList VTs = DAG.
getVTList(
Node->getValueType(0), MVT::Other);
3194 Node->getOperand(0),
Node->getOperand(1),
Node->getOperand(2),
3202 EVT OuterType =
Node->getValueType(0);
3233 case ISD::ATOMIC_LOAD_SUB: {
3235 EVT VT =
Node->getValueType(0);
3240 RHS =
RHS->getOperand(0);
3244 Node->getOperand(0),
Node->getOperand(1),
3250 case ISD::DYNAMIC_STACKALLOC:
3251 ExpandDYNAMIC_STACKALLOC(Node,
Results);
3254 for (
unsigned i = 0; i <
Node->getNumValues(); i++)
3259 EVT VT =
Node->getValueType(0);
3276 Node->getValueType(0))
3277 == TargetLowering::Legal)
3281 if ((Tmp1 = EmitStackConvert(
Node->getOperand(1),
Node->getValueType(0),
3282 Node->getValueType(0), dl,
3283 Node->getOperand(0)))) {
3284 ReplaceNode(Node, Tmp1.
getNode());
3285 LLVM_DEBUG(
dbgs() <<
"Successfully expanded STRICT_FP_ROUND node\n");
3298 if ((Tmp1 = EmitStackConvert(
Node->getOperand(0),
Node->getValueType(0),
3299 Node->getValueType(0), dl)))
3310 Node->getValueType(0))
3311 == TargetLowering::Legal)
3315 if ((Tmp1 = EmitStackConvert(
3316 Node->getOperand(1),
Node->getOperand(1).getValueType(),
3317 Node->getValueType(0), dl,
Node->getOperand(0)))) {
3318 ReplaceNode(Node, Tmp1.
getNode());
3319 LLVM_DEBUG(
dbgs() <<
"Successfully expanded STRICT_FP_EXTEND node\n");
3323 case ISD::FP_EXTEND: {
3325 EVT SrcVT =
Op.getValueType();
3326 EVT DstVT =
Node->getValueType(0);
3332 if ((Tmp1 = EmitStackConvert(
Op, SrcVT, DstVT, dl)))
3336 case ISD::BF16_TO_FP: {
3342 if (
Op.getValueType() == MVT::bf16) {
3344 DAG.
getNode(ISD::BITCAST, dl, MVT::i16,
Op));
3352 if (
Node->getValueType(0) != MVT::f32)
3357 case ISD::FP_TO_BF16: {
3359 if (
Op.getValueType() != MVT::f32)
3367 DAG.
getNode(ISD::BITCAST, dl, MVT::i32,
Op),
3371 if (
Node->getValueType(0) == MVT::bf16) {
3372 Op = DAG.
getNode(ISD::BITCAST, dl, MVT::bf16,
3396 SDNodeFlags CanonicalizeFlags =
Node->getFlags();
3399 {Chain, Operand, One}, CanonicalizeFlags);
3406 EVT VT =
Node->getValueType(0);
3438 if (
Node->isStrictFPOpcode())
3445 if ((Tmp1 = ExpandLegalINT_TO_FP(Node, Tmp2))) {
3447 if (
Node->isStrictFPOpcode())
3457 ReplaceNode(Node, Tmp1.
getNode());
3458 LLVM_DEBUG(
dbgs() <<
"Successfully expanded STRICT_FP_TO_SINT node\n");
3471 ReplaceNodeWithValue(
SDValue(Node, 0), Tmp1);
3472 LLVM_DEBUG(
dbgs() <<
"Successfully expanded STRICT_FP_TO_UINT node\n");
3481 case ISD::LLROUND: {
3484 EVT ResVT =
Node->getValueType(0);
3498 if (
Node->getOperand(0).getValueType().getVectorElementCount().isScalar())
3500 Tmp1 = DAG.
getNode(ISD::BITCAST, dl,
Node->getValueType(0),
3501 Node->getOperand(0));
3503 Tmp1 = ExpandExtractFromVectorThroughStack(
SDValue(Node, 0));
3507 Results.push_back(ExpandExtractFromVectorThroughStack(
SDValue(Node, 0)));
3510 Results.push_back(ExpandInsertToVectorThroughStack(
SDValue(Node, 0)));
3513 if (EVT VectorValueType =
Node->getOperand(0).getValueType();
3516 Results.push_back(ExpandVectorBuildThroughStack(Node));
3518 Results.push_back(ExpandConcatVectors(Node));
3521 Results.push_back(ExpandSCALAR_TO_VECTOR(Node));
3530 EVT VT =
Node->getValueType(0);
3540 if (NewEltVT.
bitsLT(EltVT)) {
3552 Op0 = DAG.
getNode(ISD::BITCAST, dl, NewVT, Op0);
3553 Op1 = DAG.
getNode(ISD::BITCAST, dl, NewVT, Op1);
3556 unsigned int factor =
3564 for (
unsigned fi = 0; fi < factor; ++fi)
3568 for (
unsigned fi = 0; fi < factor; ++fi)
3579 for (
unsigned i = 0; i != NumElems; ++i) {
3584 unsigned Idx =
Mask[i];
3596 Tmp1 = DAG.
getNode(ISD::BITCAST, dl,
Node->getValueType(0), Tmp1);
3605 unsigned Factor =
Node->getNumOperands();
3609 EVT VecVT =
Node->getValueType(0);
3620 for (
unsigned I = 0;
I < Factor / 2;
I++) {
3623 {
L.getValue(
I),
R.getValue(
I)});
3630 unsigned Factor =
Node->getNumOperands();
3633 EVT VecVT =
Node->getValueType(0);
3638 for (
unsigned I = 0;
I < Factor / 2;
I++) {
3641 {
Node->getOperand(
I),
Node->getOperand(
I + Factor / 2)});
3649 for (
unsigned I = 0;
I < Factor / 2;
I++)
3651 for (
unsigned I = 0;
I < Factor / 2;
I++)
3656 EVT OpTy =
Node->getOperand(0).getValueType();
3657 if (
Node->getConstantOperandVal(1)) {
3666 Node->getOperand(0));
3671 case ISD::STACKSAVE:
3676 Node->getValueType(0)));
3683 case ISD::STACKRESTORE:
3688 Node->getOperand(1)));
3693 case ISD::GET_DYNAMIC_AREA_OFFSET:
3698 Results.push_back(ExpandFCOPYSIGN(Node));
3701 Results.push_back(ExpandFNEG(Node));
3704 Results.push_back(ExpandFABS(Node));
3710 Test,
Node->getFlags(), SDLoc(Node), DAG))
3720 switch (
Node->getOpcode()) {
3727 Tmp1 =
Node->getOperand(0);
3728 Tmp2 =
Node->getOperand(1);
3729 Tmp1 = DAG.
getSelectCC(dl, Tmp1, Tmp2, Tmp1, Tmp2, Pred);
3734 case ISD::FMAXNUM: {
3740 case ISD::FMAXIMUM: {
3745 case ISD::FMINIMUMNUM:
3746 case ISD::FMAXIMUMNUM: {
3752 EVT VT =
Node->getValueType(0);
3759 Tmp1 = DAG.
getNode(ISD::FSINCOS, dl, VTs,
Node->getOperand(0));
3760 if (
Node->getOpcode() == ISD::FCOS)
3768 EVT VT =
Node->getValueType(0);
3775 if (
SDValue Expanded = expandLdexp(Node)) {
3778 Results.push_back(Expanded.getValue(1));
3790 if (
SDValue Expanded = expandFrexp(Node)) {
3792 Results.push_back(Expanded.getValue(1));
3796 case ISD::FSINCOS: {
3799 EVT VT =
Node->getValueType(0);
3802 Tmp1 = DAG.
getNode(ISD::FSIN, dl, VT,
Op, Flags);
3803 Tmp2 = DAG.
getNode(ISD::FCOS, dl, VT,
Op, Flags);
3810 case ISD::FP16_TO_FP:
3811 if (
Node->getValueType(0) != MVT::f32) {
3816 DAG.
getNode(ISD::FP16_TO_FP, dl, MVT::f32,
Node->getOperand(0));
3818 DAG.
getNode(ISD::FP_EXTEND, dl,
Node->getValueType(0), Res));
3821 case ISD::STRICT_BF16_TO_FP:
3822 case ISD::STRICT_FP16_TO_FP:
3823 if (
Node->getValueType(0) != MVT::f32) {
3828 {Node->getOperand(0), Node->getOperand(1)});
3830 {
Node->getValueType(0), MVT::Other},
3836 case ISD::FP_TO_FP16:
3840 MVT SVT =
Op.getSimpleValueType();
3841 if ((SVT == MVT::f64 || SVT == MVT::f80) &&
3849 DAG.
getNode(ISD::FP_TO_FP16, dl,
Node->getValueType(0), FloatVal));
3859 Results.push_back(ExpandConstantFP(CFP,
true));
3864 Results.push_back(ExpandConstant(CP));
3868 EVT VT =
Node->getValueType(0);
3871 const SDNodeFlags
Flags =
Node->getFlags();
3872 Tmp1 = DAG.
getNode(ISD::FNEG, dl, VT,
Node->getOperand(1));
3879 EVT VT =
Node->getValueType(0);
3882 "Don't know how to expand this subtraction!");
3883 Tmp1 = DAG.
getNOT(dl,
Node->getOperand(1), VT);
3897 EVT VT =
Node->getValueType(0);
3900 Tmp1 = DAG.
getNode(DivRemOpc, dl, VTs,
Node->getOperand(0),
3901 Node->getOperand(1));
3908 unsigned ExpandOpcode =
3910 EVT VT =
Node->getValueType(0);
3913 Tmp1 = DAG.
getNode(ExpandOpcode, dl, VTs,
Node->getOperand(0),
3914 Node->getOperand(1));
3922 MVT VT =
LHS.getSimpleValueType();
3923 unsigned MULHOpcode =
3933 EVT HalfType = EVT(VT).getHalfSizedIntegerVT(*DAG.
getContext());
3937 TargetLowering::MulExpansionKind::Always)) {
3938 for (
unsigned i = 0; i < 2; ++i) {
3951 EVT VT =
Node->getValueType(0);
3962 unsigned OpToUse = 0;
3963 if (HasSMUL_LOHI && !HasMULHS) {
3965 }
else if (HasUMUL_LOHI && !HasMULHU) {
3967 }
else if (HasSMUL_LOHI) {
3969 }
else if (HasUMUL_LOHI) {
3974 Node->getOperand(1)));
3985 TargetLowering::MulExpansionKind::OnlyLegalOrCustom)) {
4030 Node->getOperand(0),
4031 Node->getOperand(1),
4032 Node->getConstantOperandVal(2),
4055 EVT VT =
LHS.getValueType();
4059 EVT CarryType =
Node->getValueType(1);
4060 EVT SetCCType = getSetCCResultType(
Node->getValueType(0));
4107 if (TLI.
expandMULO(Node, Result, Overflow, DAG)) {
4124 Tmp1 =
Node->getOperand(0);
4125 Tmp2 =
Node->getOperand(1);
4126 Tmp3 =
Node->getOperand(2);
4147 unsigned EntrySize =
4183 Tmp1 =
Node->getOperand(0);
4184 Tmp2 =
Node->getOperand(1);
4190 Node->getOperand(2));
4199 Tmp1 = DAG.
getNode(ISD::BR_CC, dl, MVT::Other, Tmp1,
4202 Node->getOperand(2));
4210 bool IsVP =
Node->getOpcode() == ISD::VP_SETCC;
4215 unsigned Offset = IsStrict ? 1 : 0;
4225 DAG,
Node->getValueType(0), Tmp1, Tmp2, Tmp3, Mask, EVL, NeedInvert, dl,
4226 Chain, IsSignaling);
4234 {Chain, Tmp1, Tmp2, Tmp3},
Node->getFlags());
4238 {Tmp1, Tmp2, Tmp3, Mask, EVL},
Node->getFlags());
4240 Tmp1 = DAG.
getNode(
Node->getOpcode(), dl,
Node->getValueType(0), Tmp1,
4241 Tmp2, Tmp3,
Node->getFlags());
4264 assert(!IsStrict &&
"Don't know how to expand for strict nodes.");
4269 EVT VT =
Node->getValueType(0);
4280 Tmp1 =
Node->getOperand(0);
4281 Tmp2 =
Node->getOperand(1);
4282 Tmp3 =
Node->getOperand(2);
4283 Tmp4 =
Node->getOperand(3);
4284 EVT VT =
Node->getValueType(0);
4294 "Cannot expand ISD::SELECT_CC when ISD::SELECT also needs to be "
4296 EVT CCVT = getSetCCResultType(CmpVT);
4304 bool Legalized =
false;
4322 Tmp1 = DAG.
getSelectCC(dl, Tmp2, Tmp1, Tmp4, Tmp3, SwapInvCC,
4329 DAG, getSetCCResultType(Tmp1.
getValueType()), Tmp1, Tmp2, CC,
4332 assert(Legalized &&
"Can't legalize SELECT_CC with legal condition!");
4343 Tmp2, Tmp3, Tmp4, CC,
Node->getFlags());
4348 Tmp2, Tmp3, Tmp4, CC,
Node->getFlags());
4357 Tmp1 =
Node->getOperand(0);
4358 Tmp2 =
Node->getOperand(2);
4359 Tmp3 =
Node->getOperand(3);
4360 Tmp4 =
Node->getOperand(1);
4363 DAG, getSetCCResultType(Tmp2.
getValueType()), Tmp2, Tmp3, Tmp4,
4366 assert(Legalized &&
"Can't legalize BR_CC with legal condition!");
4371 assert(!NeedInvert &&
"Don't know how to invert BR_CC!");
4373 Tmp1 = DAG.
getNode(ISD::BR_CC, dl,
Node->getValueType(0), Tmp1,
4374 Tmp4, Tmp2, Tmp3,
Node->getOperand(4));
4378 Tmp1 = DAG.
getNode(ISD::BR_CC, dl,
Node->getValueType(0), Tmp1, Tmp4,
4379 Tmp2, Tmp3,
Node->getOperand(4));
4385 Results.push_back(ExpandBUILD_VECTOR(Node));
4388 Results.push_back(ExpandSPLAT_VECTOR(Node));
4394 EVT VT =
Node->getValueType(0);
4400 for (
unsigned Idx = 0; Idx < NumElem; Idx++) {
4415 case ISD::VECREDUCE_FADD:
4416 case ISD::VECREDUCE_FMUL:
4417 case ISD::VECREDUCE_ADD:
4418 case ISD::VECREDUCE_MUL:
4419 case ISD::VECREDUCE_AND:
4420 case ISD::VECREDUCE_OR:
4421 case ISD::VECREDUCE_XOR:
4422 case ISD::VECREDUCE_SMAX:
4423 case ISD::VECREDUCE_SMIN:
4424 case ISD::VECREDUCE_UMAX:
4425 case ISD::VECREDUCE_UMIN:
4426 case ISD::VECREDUCE_FMAX:
4427 case ISD::VECREDUCE_FMIN:
4428 case ISD::VECREDUCE_FMAXIMUM:
4429 case ISD::VECREDUCE_FMINIMUM:
4432 case ISD::VP_CTTZ_ELTS:
4433 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
4445 EVT ResVT =
Node->getValueType(0);
4451 case ISD::ADDRSPACECAST:
4475 switch (
Node->getOpcode()) {
4478 Node->getValueType(0))
4479 == TargetLowering::Legal)
4490 EVT VT =
Node->getValueType(0);
4491 const SDNodeFlags
Flags =
Node->getFlags();
4494 {Node->getOperand(0), Node->getOperand(1), Neg},
4510 Node->getOperand(1).getValueType())
4511 == TargetLowering::Legal)
4524 ReplaceNode(Node,
Results.data());
4536 return Flags.hasApproximateFuncs() && Flags.hasNoNaNs() &&
4537 Flags.hasNoInfs() && Flags.hasNoSignedZeros();
4540void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
4544 TargetLowering::MakeLibCallOptions CallOptions;
4547 unsigned Opc =
Node->getOpcode();
4549 case ISD::ATOMIC_FENCE: {
4552 TargetLowering::ArgListTy
Args;
4554 TargetLowering::CallLoweringInfo CLI(DAG);
4556 .setChain(
Node->getOperand(0))
4558 CallingConv::C, Type::getVoidTy(*DAG.
getContext()),
4563 std::pair<SDValue, SDValue> CallResult = TLI.
LowerCallTo(CLI);
4565 Results.push_back(CallResult.second);
4571 case ISD::ATOMIC_SWAP:
4572 case ISD::ATOMIC_LOAD_ADD:
4573 case ISD::ATOMIC_LOAD_SUB:
4574 case ISD::ATOMIC_LOAD_AND:
4575 case ISD::ATOMIC_LOAD_CLR:
4576 case ISD::ATOMIC_LOAD_OR:
4577 case ISD::ATOMIC_LOAD_XOR:
4578 case ISD::ATOMIC_LOAD_NAND:
4579 case ISD::ATOMIC_LOAD_MIN:
4580 case ISD::ATOMIC_LOAD_MAX:
4581 case ISD::ATOMIC_LOAD_UMIN:
4582 case ISD::ATOMIC_LOAD_UMAX:
4583 case ISD::ATOMIC_CMP_SWAP: {
4587 EVT RetVT =
Node->getValueType(0);
4592 Ops.push_back(
Node->getOperand(1));
4596 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
4597 "Unexpected atomic op or value type!");
4601 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, RetVT,
4604 Node->getOperand(0));
4606 Results.push_back(Tmp.second);
4611 TargetLowering::ArgListTy
Args;
4612 TargetLowering::CallLoweringInfo CLI(DAG);
4614 .setChain(
Node->getOperand(0))
4615 .setLibCallee(CallingConv::C, Type::getVoidTy(*DAG.
getContext()),
4619 std::pair<SDValue, SDValue> CallResult = TLI.
LowerCallTo(CLI);
4621 Results.push_back(CallResult.second);
4628 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(
4629 DAG, RTLIB::CLEAR_CACHE, MVT::isVoid, {StartVal, EndVal}, CallOptions,
4630 SDLoc(Node), InputChain);
4631 Results.push_back(Tmp.second);
4636 ExpandFPLibCall(Node, RTLIB::FMIN_F32, RTLIB::FMIN_F64,
4637 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
4638 RTLIB::FMIN_PPCF128,
Results);
4645 ExpandFPLibCall(Node, RTLIB::FMAX_F32, RTLIB::FMAX_F64,
4646 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
4647 RTLIB::FMAX_PPCF128,
Results);
4649 case ISD::FMINIMUMNUM:
4650 ExpandFPLibCall(Node, RTLIB::FMINIMUM_NUM_F32, RTLIB::FMINIMUM_NUM_F64,
4651 RTLIB::FMINIMUM_NUM_F80, RTLIB::FMINIMUM_NUM_F128,
4652 RTLIB::FMINIMUM_NUM_PPCF128,
Results);
4654 case ISD::FMAXIMUMNUM:
4655 ExpandFPLibCall(Node, RTLIB::FMAXIMUM_NUM_F32, RTLIB::FMAXIMUM_NUM_F64,
4656 RTLIB::FMAXIMUM_NUM_F80, RTLIB::FMAXIMUM_NUM_F128,
4657 RTLIB::FMAXIMUM_NUM_PPCF128,
Results);
4664 {RTLIB::FAST_SQRT_F32, RTLIB::SQRT_F32},
4665 {RTLIB::FAST_SQRT_F64, RTLIB::SQRT_F64},
4666 {RTLIB::FAST_SQRT_F80, RTLIB::SQRT_F80},
4667 {RTLIB::FAST_SQRT_F128, RTLIB::SQRT_F128},
4668 {RTLIB::FAST_SQRT_PPCF128, RTLIB::SQRT_PPCF128},
4673 ExpandFPLibCall(Node, RTLIB::CBRT_F32, RTLIB::CBRT_F64,
4674 RTLIB::CBRT_F80, RTLIB::CBRT_F128,
4675 RTLIB::CBRT_PPCF128,
Results);
4679 ExpandFPLibCall(Node, RTLIB::SIN_F32, RTLIB::SIN_F64,
4680 RTLIB::SIN_F80, RTLIB::SIN_F128,
4685 ExpandFPLibCall(Node, RTLIB::COS_F32, RTLIB::COS_F64,
4686 RTLIB::COS_F80, RTLIB::COS_F128,
4691 ExpandFPLibCall(Node, RTLIB::TAN_F32, RTLIB::TAN_F64, RTLIB::TAN_F80,
4692 RTLIB::TAN_F128, RTLIB::TAN_PPCF128,
Results);
4696 ExpandFPLibCall(Node, RTLIB::ASIN_F32, RTLIB::ASIN_F64, RTLIB::ASIN_F80,
4697 RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128,
Results);
4701 ExpandFPLibCall(Node, RTLIB::ACOS_F32, RTLIB::ACOS_F64, RTLIB::ACOS_F80,
4702 RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128,
Results);
4706 ExpandFPLibCall(Node, RTLIB::ATAN_F32, RTLIB::ATAN_F64, RTLIB::ATAN_F80,
4707 RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128,
Results);
4711 ExpandFPLibCall(Node, RTLIB::ATAN2_F32, RTLIB::ATAN2_F64, RTLIB::ATAN2_F80,
4712 RTLIB::ATAN2_F128, RTLIB::ATAN2_PPCF128,
Results);
4716 ExpandFPLibCall(Node, RTLIB::SINH_F32, RTLIB::SINH_F64, RTLIB::SINH_F80,
4717 RTLIB::SINH_F128, RTLIB::SINH_PPCF128,
Results);
4721 ExpandFPLibCall(Node, RTLIB::COSH_F32, RTLIB::COSH_F64, RTLIB::COSH_F80,
4722 RTLIB::COSH_F128, RTLIB::COSH_PPCF128,
Results);
4726 ExpandFPLibCall(Node, RTLIB::TANH_F32, RTLIB::TANH_F64, RTLIB::TANH_F80,
4727 RTLIB::TANH_F128, RTLIB::TANH_PPCF128,
Results);
4730 case ISD::FSINCOSPI: {
4731 EVT VT =
Node->getValueType(0);
4732 RTLIB::Libcall LC =
Node->getOpcode() == ISD::FSINCOS
4742 ExpandFPLibCall(Node, RTLIB::LOG_F32, RTLIB::LOG_F64, RTLIB::LOG_F80,
4743 RTLIB::LOG_F128, RTLIB::LOG_PPCF128,
Results);
4747 ExpandFPLibCall(Node, RTLIB::LOG2_F32, RTLIB::LOG2_F64, RTLIB::LOG2_F80,
4748 RTLIB::LOG2_F128, RTLIB::LOG2_PPCF128,
Results);
4752 ExpandFPLibCall(Node, RTLIB::LOG10_F32, RTLIB::LOG10_F64, RTLIB::LOG10_F80,
4753 RTLIB::LOG10_F128, RTLIB::LOG10_PPCF128,
Results);
4757 ExpandFPLibCall(Node, RTLIB::EXP_F32, RTLIB::EXP_F64, RTLIB::EXP_F80,
4758 RTLIB::EXP_F128, RTLIB::EXP_PPCF128,
Results);
4762 ExpandFPLibCall(Node, RTLIB::EXP2_F32, RTLIB::EXP2_F64, RTLIB::EXP2_F80,
4763 RTLIB::EXP2_F128, RTLIB::EXP2_PPCF128,
Results);
4766 ExpandFPLibCall(Node, RTLIB::EXP10_F32, RTLIB::EXP10_F64, RTLIB::EXP10_F80,
4767 RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128,
Results);
4771 ExpandFPLibCall(Node, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
4772 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
4773 RTLIB::TRUNC_PPCF128,
Results);
4777 ExpandFPLibCall(Node, RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
4778 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
4779 RTLIB::FLOOR_PPCF128,
Results);
4783 ExpandFPLibCall(Node, RTLIB::CEIL_F32, RTLIB::CEIL_F64,
4784 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
4785 RTLIB::CEIL_PPCF128,
Results);
4789 ExpandFPLibCall(Node, RTLIB::RINT_F32, RTLIB::RINT_F64,
4790 RTLIB::RINT_F80, RTLIB::RINT_F128,
4791 RTLIB::RINT_PPCF128,
Results);
4793 case ISD::FNEARBYINT:
4795 ExpandFPLibCall(Node, RTLIB::NEARBYINT_F32,
4796 RTLIB::NEARBYINT_F64,
4797 RTLIB::NEARBYINT_F80,
4798 RTLIB::NEARBYINT_F128,
4799 RTLIB::NEARBYINT_PPCF128,
Results);
4803 ExpandFPLibCall(Node, RTLIB::ROUND_F32,
4807 RTLIB::ROUND_PPCF128,
Results);
4809 case ISD::FROUNDEVEN:
4811 ExpandFPLibCall(Node, RTLIB::ROUNDEVEN_F32,
4812 RTLIB::ROUNDEVEN_F64,
4813 RTLIB::ROUNDEVEN_F80,
4814 RTLIB::ROUNDEVEN_F128,
4815 RTLIB::ROUNDEVEN_PPCF128,
Results);
4819 ExpandFPLibCall(Node, RTLIB::LDEXP_F32, RTLIB::LDEXP_F64, RTLIB::LDEXP_F80,
4820 RTLIB::LDEXP_F128, RTLIB::LDEXP_PPCF128,
Results);
4824 EVT VT =
Node->getValueType(0);
4836 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
4839 if (
Node->isStrictFPOpcode()) {
4842 {
Node->getValueType(0),
Node->getValueType(1)},
4843 {
Node->getOperand(0),
Node->getOperand(2)});
4846 {
Node->getValueType(0),
Node->getValueType(1)},
4853 Node->getOperand(1));
4855 Node->getValueType(0),
4860 unsigned Offset =
Node->isStrictFPOpcode() ? 1 : 0;
4861 bool ExponentHasSizeOfInt =
4863 Node->getOperand(1 +
Offset).getValueType().getSizeInBits();
4864 if (!ExponentHasSizeOfInt) {
4871 ExpandFPLibCall(Node, LC,
Results);
4876 ExpandFPLibCall(Node, RTLIB::POW_F32, RTLIB::POW_F64, RTLIB::POW_F80,
4877 RTLIB::POW_F128, RTLIB::POW_PPCF128,
Results);
4881 ExpandArgFPLibCall(Node, RTLIB::LROUND_F32,
4882 RTLIB::LROUND_F64, RTLIB::LROUND_F80,
4884 RTLIB::LROUND_PPCF128,
Results);
4888 ExpandArgFPLibCall(Node, RTLIB::LLROUND_F32,
4889 RTLIB::LLROUND_F64, RTLIB::LLROUND_F80,
4890 RTLIB::LLROUND_F128,
4891 RTLIB::LLROUND_PPCF128,
Results);
4895 ExpandArgFPLibCall(Node, RTLIB::LRINT_F32,
4896 RTLIB::LRINT_F64, RTLIB::LRINT_F80,
4898 RTLIB::LRINT_PPCF128,
Results);
4902 ExpandArgFPLibCall(Node, RTLIB::LLRINT_F32,
4903 RTLIB::LLRINT_F64, RTLIB::LLRINT_F80,
4905 RTLIB::LLRINT_PPCF128,
Results);
4910 {RTLIB::FAST_DIV_F32, RTLIB::DIV_F32},
4911 {RTLIB::FAST_DIV_F64, RTLIB::DIV_F64},
4912 {RTLIB::FAST_DIV_F80, RTLIB::DIV_F80},
4913 {RTLIB::FAST_DIV_F128, RTLIB::DIV_F128},
4914 {RTLIB::FAST_DIV_PPCF128, RTLIB::DIV_PPCF128},
Results);
4919 ExpandFPLibCall(Node, RTLIB::REM_F32, RTLIB::REM_F64,
4920 RTLIB::REM_F80, RTLIB::REM_F128,
4925 ExpandFPLibCall(Node, RTLIB::FMA_F32, RTLIB::FMA_F64,
4926 RTLIB::FMA_F80, RTLIB::FMA_F128,
4932 {RTLIB::FAST_ADD_F32, RTLIB::ADD_F32},
4933 {RTLIB::FAST_ADD_F64, RTLIB::ADD_F64},
4934 {RTLIB::FAST_ADD_F80, RTLIB::ADD_F80},
4935 {RTLIB::FAST_ADD_F128, RTLIB::ADD_F128},
4936 {RTLIB::FAST_ADD_PPCF128, RTLIB::ADD_PPCF128},
Results);
4942 {RTLIB::FAST_MUL_F32, RTLIB::MUL_F32},
4943 {RTLIB::FAST_MUL_F64, RTLIB::MUL_F64},
4944 {RTLIB::FAST_MUL_F80, RTLIB::MUL_F80},
4945 {RTLIB::FAST_MUL_F128, RTLIB::MUL_F128},
4946 {RTLIB::FAST_MUL_PPCF128, RTLIB::MUL_PPCF128},
Results);
4949 case ISD::FP16_TO_FP:
4950 if (
Node->getValueType(0) == MVT::f32) {
4951 Results.push_back(ExpandLibCall(RTLIB::FPEXT_F16_F32, Node,
false).first);
4954 case ISD::STRICT_BF16_TO_FP:
4955 if (
Node->getValueType(0) == MVT::f32) {
4956 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(
4957 DAG, RTLIB::FPEXT_BF16_F32, MVT::f32,
Node->getOperand(1),
4958 CallOptions, SDLoc(Node),
Node->getOperand(0));
4960 Results.push_back(Tmp.second);
4963 case ISD::STRICT_FP16_TO_FP: {
4964 if (
Node->getValueType(0) == MVT::f32) {
4965 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(
4966 DAG, RTLIB::FPEXT_F16_F32, MVT::f32,
Node->getOperand(1), CallOptions,
4967 SDLoc(Node),
Node->getOperand(0));
4969 Results.push_back(Tmp.second);
4973 case ISD::FP_TO_FP16: {
4976 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to expand fp_to_fp16");
4977 Results.push_back(ExpandLibCall(LC, Node,
false).first);
4980 case ISD::FP_TO_BF16: {
4983 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to expand fp_to_bf16");
4984 Results.push_back(ExpandLibCall(LC, Node,
false).first);
4992 bool IsStrict =
Node->isStrictFPOpcode();
4995 EVT SVT =
Node->getOperand(IsStrict ? 1 : 0).getValueType();
4996 EVT RVT =
Node->getValueType(0);
5003 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
5004 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
5005 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
5013 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to legalize as libcall");
5018 NVT,
Node->getOperand(IsStrict ? 1 : 0));
5020 std::pair<SDValue, SDValue> Tmp =
5024 Results.push_back(Tmp.second);
5032 bool IsStrict =
Node->isStrictFPOpcode();
5037 EVT SVT =
Op.getValueType();
5038 EVT RVT =
Node->getValueType(0);
5045 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
5046 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
5047 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
5055 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to legalize as libcall");
5058 std::pair<SDValue, SDValue> Tmp =
5064 Results.push_back(Tmp.second);
5075 bool IsStrict =
Node->isStrictFPOpcode();
5078 EVT VT =
Node->getValueType(0);
5080 "Unable to expand as libcall if it is not normal rounding");
5083 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to legalize as libcall");
5085 std::pair<SDValue, SDValue> Tmp =
5086 TLI.
makeLibCall(DAG, LC, VT,
Op, CallOptions, SDLoc(Node), Chain);
5089 Results.push_back(Tmp.second);
5092 case ISD::FP_EXTEND: {
5095 Node->getValueType(0)),
5096 Node,
false).first);
5100 case ISD::STRICT_FP_TO_FP16:
5101 case ISD::STRICT_FP_TO_BF16: {
5102 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
5103 if (
Node->getOpcode() == ISD::STRICT_FP_TO_FP16)
5105 else if (
Node->getOpcode() == ISD::STRICT_FP_TO_BF16)
5109 Node->getValueType(0));
5111 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unable to legalize as libcall");
5113 std::pair<SDValue, SDValue> Tmp =
5115 CallOptions, SDLoc(Node),
Node->getOperand(0));
5117 Results.push_back(Tmp.second);
5123 {RTLIB::FAST_SUB_F32, RTLIB::SUB_F32},
5124 {RTLIB::FAST_SUB_F64, RTLIB::SUB_F64},
5125 {RTLIB::FAST_SUB_F80, RTLIB::SUB_F80},
5126 {RTLIB::FAST_SUB_F128, RTLIB::SUB_F128},
5127 {RTLIB::FAST_SUB_PPCF128, RTLIB::SUB_PPCF128},
Results);
5131 Results.push_back(ExpandIntLibCall(Node,
true,
5133 RTLIB::SREM_I16, RTLIB::SREM_I32,
5134 RTLIB::SREM_I64, RTLIB::SREM_I128));
5137 Results.push_back(ExpandIntLibCall(Node,
false,
5139 RTLIB::UREM_I16, RTLIB::UREM_I32,
5140 RTLIB::UREM_I64, RTLIB::UREM_I128));
5143 Results.push_back(ExpandIntLibCall(Node,
true,
5145 RTLIB::SDIV_I16, RTLIB::SDIV_I32,
5146 RTLIB::SDIV_I64, RTLIB::SDIV_I128));
5149 Results.push_back(ExpandIntLibCall(Node,
false,
5151 RTLIB::UDIV_I16, RTLIB::UDIV_I32,
5152 RTLIB::UDIV_I64, RTLIB::UDIV_I128));
5157 ExpandDivRemLibCall(Node,
Results);
5160 Results.push_back(ExpandIntLibCall(Node,
false,
5162 RTLIB::MUL_I16, RTLIB::MUL_I32,
5163 RTLIB::MUL_I64, RTLIB::MUL_I128));
5166 Results.push_back(ExpandBitCountingLibCall(
5167 Node, RTLIB::CTLZ_I32, RTLIB::CTLZ_I64, RTLIB::CTLZ_I128));
5170 Results.push_back(ExpandBitCountingLibCall(
5171 Node, RTLIB::CTPOP_I32, RTLIB::CTPOP_I64, RTLIB::CTPOP_I128));
5173 case ISD::RESET_FPENV: {
5183 case ISD::GET_FPENV_MEM: {
5190 case ISD::SET_FPENV_MEM: {
5197 case ISD::GET_FPMODE: {
5200 EVT ModeVT =
Node->getValueType(0);
5204 Node->getOperand(0), dl);
5206 ModeVT, dl, Chain, StackPtr,
5212 case ISD::SET_FPMODE: {
5216 EVT ModeVT =
Mode.getValueType();
5220 Node->getOperand(0), dl,
Mode, StackPtr,
5226 case ISD::RESET_FPMODE: {
5234 Node->getOperand(0), dl));
5241 LLVM_DEBUG(
dbgs() <<
"Successfully converted node to libcall\n");
5242 ReplaceNode(Node,
Results.data());
5250 MVT EltVT,
MVT NewEltVT) {
5252 MVT MidVT = OldEltsPerNewElt == 1
5259void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
5262 MVT OVT =
Node->getSimpleValueType(0);
5268 Node->getOpcode() == ISD::VECREDUCE_FMAX ||
5269 Node->getOpcode() == ISD::VECREDUCE_FMIN ||
5270 Node->getOpcode() == ISD::VECREDUCE_FMAXIMUM ||
5271 Node->getOpcode() == ISD::VECREDUCE_FMINIMUM) {
5272 OVT =
Node->getOperand(0).getSimpleValueType();
5274 if (
Node->getOpcode() == ISD::ATOMIC_STORE ||
5279 Node->getOpcode() == ISD::VP_REDUCE_FADD ||
5280 Node->getOpcode() == ISD::VP_REDUCE_FMUL ||
5281 Node->getOpcode() == ISD::VP_REDUCE_FMAX ||
5282 Node->getOpcode() == ISD::VP_REDUCE_FMIN ||
5283 Node->getOpcode() == ISD::VP_REDUCE_FMAXIMUM ||
5284 Node->getOpcode() == ISD::VP_REDUCE_FMINIMUM ||
5285 Node->getOpcode() == ISD::VP_REDUCE_SEQ_FADD)
5286 OVT =
Node->getOperand(1).getSimpleValueType();
5287 if (
Node->getOpcode() == ISD::BR_CC ||
5289 OVT =
Node->getOperand(2).getSimpleValueType();
5292 SelectionDAG::FlagInserter FlagsInserter(DAG, FastMathFlags);
5295 SDValue Tmp1, Tmp2, Tmp3, Tmp4;
5296 switch (
Node->getOpcode()) {
5308 unsigned NewOpc =
Node->getOpcode();
5321 Tmp1 = DAG.
getNode(NewOpc, dl, NVT, Tmp1);
5337 auto AnyExtendedNode =
5343 auto LeftShiftResult =
5347 auto CTLZResult = DAG.
getNode(
Node->getOpcode(), dl, NVT, LeftShiftResult);
5355 Tmp1 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1);
5366 PromoteLegalFP_TO_INT(Node, dl,
Results);
5370 Results.push_back(PromoteLegalFP_TO_INT_SAT(Node, dl));
5376 PromoteLegalINT_TO_FP(Node, dl,
Results);
5384 TruncOp = ISD::BITCAST;
5387 &&
"VAARG promotion is supported only for vectors or integer types");
5393 Node->getConstantOperandVal(3));
5396 Tmp2 = DAG.
getNode(TruncOp, dl, OVT, Tmp1);
5403 UpdatedNodes->insert(Tmp2.
getNode());
5404 UpdatedNodes->insert(Chain.
getNode());
5421 unsigned ExtOp, TruncOp;
5423 ExtOp = ISD::BITCAST;
5424 TruncOp = ISD::BITCAST;
5428 switch (
Node->getOpcode()) {
5453 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(0));
5454 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5456 Tmp1 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
5465 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(0));
5466 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5477 unsigned ExtOp, TruncOp;
5478 if (
Node->getValueType(0).isVector() ||
5480 ExtOp = ISD::BITCAST;
5481 TruncOp = ISD::BITCAST;
5482 }
else if (
Node->getValueType(0).isInteger()) {
5486 ExtOp = ISD::FP_EXTEND;
5489 Tmp1 =
Node->getOperand(0);
5491 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5492 Tmp3 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(2));
5494 Tmp1 = DAG.
getSelect(dl, NVT, Tmp1, Tmp2, Tmp3);
5496 Tmp1 = DAG.
getNode(TruncOp, dl,
Node->getValueType(0), Tmp1);
5498 Tmp1 = DAG.
getNode(TruncOp, dl,
Node->getValueType(0), Tmp1,
5507 Tmp1 = DAG.
getNode(ISD::BITCAST, dl, NVT,
Node->getOperand(0));
5508 Tmp2 = DAG.
getNode(ISD::BITCAST, dl, NVT,
Node->getOperand(1));
5511 Tmp1 = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask);
5512 Tmp1 = DAG.
getNode(ISD::BITCAST, dl, OVT, Tmp1);
5520 Node->getOperand(2));
5528 MVT CVT =
Node->getSimpleValueType(0);
5529 assert(CVT == OVT &&
"not handled");
5531 unsigned ExtOp = ISD::FP_EXTEND;
5538 Tmp1 =
Node->getOperand(0);
5539 Tmp2 =
Node->getOperand(1);
5541 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(0));
5542 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5545 Tmp3 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(2));
5546 Tmp4 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(3));
5552 if (ExtOp != ISD::FP_EXTEND)
5564 unsigned ExtOp = ISD::FP_EXTEND;
5573 if (
Node->isStrictFPOpcode()) {
5575 std::tie(Tmp1, std::ignore) =
5577 std::tie(Tmp2, std::ignore) =
5581 SDVTList VTs = DAG.
getVTList(
Node->getValueType(0), MVT::Other);
5583 {OutChain, Tmp1, Tmp2, Node->getOperand(3)},
5588 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(0));
5589 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(1));
5591 Tmp2,
Node->getOperand(2),
Node->getFlags()));
5595 unsigned ExtOp = ISD::FP_EXTEND;
5601 Tmp1 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(2));
5602 Tmp2 = DAG.
getNode(ExtOp, dl, NVT,
Node->getOperand(3));
5604 Node->getOperand(0),
Node->getOperand(1),
5605 Tmp1, Tmp2,
Node->getOperand(4)));
5617 case ISD::FMINIMUMNUM:
5618 case ISD::FMAXIMUMNUM:
5621 Tmp1 = DAG.
getNode(ISD::FP_EXTEND, dl, NVT,
Node->getOperand(0));
5622 Tmp2 = DAG.
getNode(ISD::FP_EXTEND, dl, NVT,
Node->getOperand(1));
5623 Tmp3 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
5632 SDVTList VTs = DAG.
getVTList(NVT, MVT::Other);
5634 Node->getOperand(1));
5636 Node->getOperand(2));
5657 {
Node->getOperand(0),
Node->getOperand(1)});
5659 {
Node->getOperand(0),
Node->getOperand(2)});
5662 Tmp1 = DAG.
getNode(
Node->getOpcode(), dl, {NVT, MVT::Other},
5663 {Tmp3, Tmp1, Tmp2});
5671 Tmp1 = DAG.
getNode(ISD::FP_EXTEND, dl, NVT,
Node->getOperand(0));
5672 Tmp2 = DAG.
getNode(ISD::FP_EXTEND, dl, NVT,
Node->getOperand(1));
5673 Tmp3 = DAG.
getNode(ISD::FP_EXTEND, dl, NVT,
Node->getOperand(2));
5676 DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1, Tmp2, Tmp3),
5681 {
Node->getOperand(0),
Node->getOperand(1)});
5683 {
Node->getOperand(0),
Node->getOperand(2)});
5685 {
Node->getOperand(0),
Node->getOperand(3)});
5688 Tmp4 = DAG.
getNode(
Node->getOpcode(), dl, {NVT, MVT::Other},
5689 {Tmp4, Tmp1, Tmp2, Tmp3});
5699 Tmp1 = DAG.
getNode(ISD::FP_EXTEND, dl, NVT,
Node->getOperand(0));
5700 Tmp2 =
Node->getOperand(1);
5701 Tmp3 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1, Tmp2);
5716 {
Node->getOperand(0),
Node->getOperand(1)});
5717 Tmp2 =
Node->getOperand(2);
5729 {
Node->getOperand(0),
Node->getOperand(1)});
5730 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, {NVT, MVT::Other},
5731 {Tmp1.getValue(1), Tmp1, Node->getOperand(2)});
5739 Tmp1 = DAG.
getNode(ISD::FP_EXTEND, dl, NVT,
Node->getOperand(0));
5740 Tmp2 = DAG.
getNode(ISD::FFREXP, dl, {NVT,
Node->getValueType(1)}, Tmp1);
5751 case ISD::FSINCOSPI: {
5752 Tmp1 = DAG.
getNode(ISD::FP_EXTEND, dl, NVT,
Node->getOperand(0));
5755 for (
unsigned ResNum = 0; ResNum <
Node->getNumValues(); ResNum++)
5763 case ISD::FNEARBYINT:
5765 case ISD::FROUNDEVEN:
5786 Tmp1 = DAG.
getNode(ISD::FP_EXTEND, dl, NVT,
Node->getOperand(0));
5787 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1);
5815 {
Node->getOperand(0),
Node->getOperand(1)});
5816 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, {NVT, MVT::Other},
5817 {Tmp1.getValue(1), Tmp1});
5835 "Invalid promote type for build_vector");
5868 "Invalid promote type for extract_vector_elt");
5883 for (
unsigned I = 0;
I < NewEltsPerOldElt; ++
I) {
5914 "Invalid promote type for insert_vector_elt");
5932 for (
unsigned I = 0;
I < NewEltsPerOldElt; ++
I) {
5937 CastVal, IdxOffset);
5940 NewVec, Elt, InEltIdx);
5974 case ISD::ATOMIC_SWAP:
5975 case ISD::ATOMIC_STORE: {
5980 "unexpected promotion type");
5982 "unexpected atomic_swap with illegal type");
5989 if (AM->
getOpcode() == ISD::ATOMIC_STORE)
5995 if (AM->
getOpcode() != ISD::ATOMIC_STORE) {
5996 Results.push_back(DAG.
getNode(ISD::BITCAST, SL, OVT, NewAtomic));
6002 case ISD::ATOMIC_LOAD: {
6006 "unexpected promotion type");
6008 "unexpected atomic_load with illegal type");
6013 Results.push_back(DAG.
getNode(ISD::BITCAST, SL, OVT, NewAtomic));
6019 MVT ScalarType =
Scalar.getSimpleValueType();
6023 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1);
6027 Tmp1 = DAG.
getNode(ISD::FP_EXTEND, dl, NewScalarType, Scalar);
6028 Tmp2 = DAG.
getNode(
Node->getOpcode(), dl, NVT, Tmp1);
6034 case ISD::VECREDUCE_FMAX:
6035 case ISD::VECREDUCE_FMIN:
6036 case ISD::VECREDUCE_FMAXIMUM:
6037 case ISD::VECREDUCE_FMINIMUM:
6038 case ISD::VP_REDUCE_FMAX:
6039 case ISD::VP_REDUCE_FMIN:
6040 case ISD::VP_REDUCE_FMAXIMUM:
6041 case ISD::VP_REDUCE_FMINIMUM:
6042 Results.push_back(PromoteReduction(Node));
6049 ReplaceNode(Node,
Results.data());
6067 SelectionDAGLegalize
Legalizer(*
this, LegalizedNodes);
6074 bool AnyLegalized =
false;
6085 if (LegalizedNodes.
insert(
N).second) {
6086 AnyLegalized =
true;
6107 SelectionDAGLegalize
Legalizer(*
this, LegalizedNodes, &UpdatedNodes);
6114 return LegalizedNodes.
count(
N);
aarch64 falkor hwpf fix Falkor HW Prefetch Fix Late Phase
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static bool isConstant(const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isSigned(unsigned int Opcode)
Utilities for dealing with flags related to floating point properties and mode controls.
static MaybeAlign getAlign(Value *Ptr)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool ExpandBVWithShuffles(SDNode *Node, SelectionDAG &DAG, const TargetLowering &TLI, SDValue &Res)
static bool isSinCosLibcallAvailable(SDNode *Node, const TargetLowering &TLI)
Return true if sincos libcall is available.
static bool useSinCos(SDNode *Node)
Only issue sincos libcall if both sin and cos are needed.
static bool canUseFastMathLibcall(const SDNode *Node)
Return if we can use the FAST_* variant of a math libcall for the node.
static MachineMemOperand * getStackAlignedMMO(SDValue StackPtr, MachineFunction &MF, bool isObjectScalable)
static MVT getPromotedVectorElementType(const TargetLowering &TLI, MVT EltVT, MVT NewEltVT)
mir Rename Register Operands
std::pair< MCSymbol *, MachineModuleInfoImpl::StubValueTy > PairTy
Promote Memory to Register
PowerPC Reduce CR logical Operation
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file describes how to lower LLVM code to machine code.
static constexpr int Concat[]
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
APInt bitcastToAPInt() const
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
Class for arbitrary precision integers.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const SDValue & getBasePtr() const
const SDValue & getVal() const
static LLVM_ABI bool isValueValidForType(EVT VT, const APFloat &Val)
const APFloat & getValueAPF() const
const ConstantFP * getConstantFPValue() const
const APFloat & getValueAPF() const
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
bool isLittleEndian() const
Layout endianness...
LLVM_ABI Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
const BasicBlock & back() const
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
static LocationSize precise(uint64_t Value)
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
uint64_t getScalarSizeInBits() const
bool bitsLE(MVT VT) const
Return true if this has no more bits than VT.
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
bool bitsLT(MVT VT) const
Return true if this has less bits than VT.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
LLVM_ABI unsigned getEntrySize(const DataLayout &TD) const
getEntrySize - Return the size of each entry in the jump table.
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOStore
The memory access writes data.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
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 getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op)
Return the specified value casted to the target's desired shift amount type.
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
bool isKnownNeverSNaN(SDValue Op, const APInt &DemandedElts, unsigned Depth=0) const
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL)
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
LLVM_ABI SDValue getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDVTList VTs, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, MachineMemOperand *MMO)
Gets a node for an atomic cmpxchg op.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
LLVM_ABI bool shouldOptForSize() const
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
LLVM_ABI SDValue expandVACopy(SDNode *Node)
Expand the specified ISD::VACOPY node as the Legalize pass would.
allnodes_const_iterator allnodes_begin() const
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
allnodes_const_iterator allnodes_end() const
LLVM_ABI void DeleteNode(SDNode *N)
Remove the specified node from the system.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
LLVM_ABI SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue expandVAArg(SDNode *Node)
Expand the specified ISD::VAARG node as the Legalize pass would.
LLVM_ABI void Legalize()
This transforms the SelectionDAG into a SelectionDAG that is compatible with the target instruction s...
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI 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 ...
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL, const SDNodeFlags Flags=SDNodeFlags())
Returns sum of the base pointer and offset.
LLVM_ABI SDValue getVAArg(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue SV, unsigned Align)
VAArg produces a result and token chain, and takes a pointer and a source value as input.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue makeStateFunctionCall(unsigned LibFunc, SDValue Ptr, SDValue InChain, const SDLoc &DLoc)
Helper used to make a call to a library function that has one argument of pointer type.
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI std::pair< SDValue, SDValue > getStrictFPExtendOrRound(SDValue Op, SDValue Chain, const SDLoc &DL, EVT VT)
Convert Op, which must be a STRICT operation of float type, to the float type VT, by either extending...
LLVM_ABI SDValue getVPLogicalNOT(const SDLoc &DL, SDValue Val, SDValue Mask, SDValue EVL, EVT VT)
Create a vector-predicated logical NOT operation as (VP_XOR Val, BooleanOne, Mask,...
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of float type, to the float type VT, by either extending or rounding (by tr...
LLVM_ABI unsigned AssignTopologicalOrder()
Topological-sort the AllNodes list and a assign a unique node id for each node in the DAG based on th...
const TargetLibraryInfo & getLibInfo() const
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool expandMultipleResultFPLibCall(RTLIB::Libcall LC, SDNode *Node, SmallVectorImpl< SDValue > &Results, std::optional< unsigned > CallRetResNo={})
Expands a node with multiple results to an FP or vector libcall.
LLVMContext * getContext() const
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
LLVM_ABI SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a logical NOT operation as (XOR Val, BooleanOne).
bool insert(const value_type &X)
Insert a new element into the SetVector.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void swap(SmallVectorImpl &RHS)
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
unsigned getIntSize() const
Get size of a C-level int or unsigned int, in bits.
bool isOperationExpand(unsigned Op, EVT VT) const
Return true if the specified operation is illegal on this target or unlikely to be made legal with cu...
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const
Get the CallingConv that should be used for the specified libcall.
virtual bool isSExtCheaperThanZExt(EVT FromTy, EVT ToTy) const
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
bool isOperationLegalOrPromote(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal using promotion.
LegalizeAction getCondCodeAction(ISD::CondCode CC, MVT VT) const
Return how the condition code should be treated: either it is legal, needs to be expanded to some oth...
virtual bool isFPImmLegal(const APFloat &, EVT, bool ForCodeSize=false) const
Returns true if the target can instruction select the specified FP immediate natively.
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
LegalizeAction getFixedPointOperationAction(unsigned Op, EVT VT, unsigned Scale) const
Some fixed point operations may be natively supported by the target but only for specific scales.
virtual ISD::NodeType getExtendForAtomicOps() const
Returns how the platform's atomic operations are extended (ZERO_EXTEND, SIGN_EXTEND,...
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
bool isStrictFPEnabled() const
Return true if the target support strict float operation.
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const
Return true if the specified condition code is legal for a comparison of the specified types on this ...
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual bool isJumpTableRelative() const
virtual bool ShouldShrinkFPConstant(EVT) const
If true, then instruction selection should seek to shrink the FP constant of the specified type to a ...
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const
Return how this store with truncation should be treated: either it is legal, needs to be promoted to ...
LegalizeAction getLoadExtAction(unsigned ExtType, EVT ValVT, EVT MemVT) const
Return how this load with extension should be treated: either it is legal, needs to be promoted to a ...
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
virtual bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
Return true if the target supports a memory access of this type for the given address space and align...
virtual LegalizeAction getCustomOperationAction(SDNode &Op) const
How to legalize this custom operation?
bool isLoadExtLegalOrCustom(unsigned ExtType, EVT ValVT, EVT MemVT) const
Return true if the specified load with extension is legal or custom on this target.
LegalizeAction getStrictFPOperationAction(unsigned Op, EVT VT) const
bool isLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const
Return true if the specified load with extension is legal on this target.
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Get the libcall impl routine name for the specified libcall.
virtual bool useSoftFloat() const
bool isTruncStoreLegalOrCustom(EVT ValVT, EVT MemVT) const
Return true if the specified store with truncation has solution on this target.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
std::vector< ArgListEntry > ArgListTy
bool allowsMemoryAccessForAlignment(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
This function returns true if the memory access is aligned or if the target allows this specific unal...
bool isCondCodeLegalOrCustom(ISD::CondCode CC, MVT VT) const
Return true if the specified condition code is legal or custom for a comparison of the specified type...
MVT getRegisterType(MVT VT) const
Return the type of registers that this ValueType will eventually require.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
MVT getTypeToPromoteTo(unsigned Op, MVT VT) const
If the action for this operation is to promote, this method returns the ValueType to promote to.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
SDValue expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US][ADD|SUB]SAT.
bool expandMULO(SDNode *Node, SDValue &Result, SDValue &Overflow, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]MULO.
bool expandMUL(SDNode *N, SDValue &Lo, SDValue &Hi, EVT HiLoVT, SelectionDAG &DAG, MulExpansionKind Kind, SDValue LL=SDValue(), SDValue LH=SDValue(), SDValue RL=SDValue(), SDValue RH=SDValue()) const
Expand a MUL into two nodes.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue expandCTLZ(SDNode *N, SelectionDAG &DAG) const
Expand CTLZ/CTLZ_ZERO_UNDEF nodes.
SDValue expandBITREVERSE(SDNode *N, SelectionDAG &DAG) const
Expand BITREVERSE nodes.
SDValue expandCTTZ(SDNode *N, SelectionDAG &DAG) const
Expand CTTZ/CTTZ_ZERO_UNDEF nodes.
virtual SDValue expandIndirectJTBranch(const SDLoc &dl, SDValue Value, SDValue Addr, int JTI, SelectionDAG &DAG) const
Expands target specific indirect branch for the case of JumpTable expansion.
SDValue expandABD(SDNode *N, SelectionDAG &DAG) const
Expand ABDS/ABDU nodes.
SDValue expandShlSat(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]SHLSAT.
SDValue expandIS_FPCLASS(EVT ResultVT, SDValue Op, FPClassTest Test, SDNodeFlags Flags, const SDLoc &DL, SelectionDAG &DAG) const
Expand check for floating point class.
SDValue expandFP_TO_INT_SAT(SDNode *N, SelectionDAG &DAG) const
Expand FP_TO_[US]INT_SAT into FP_TO_[US]INT and selects or min/max.
SDValue expandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG) const
Expands an unaligned store to 2 half-size stores for integer values, and possibly more for vectors.
void expandSADDSUBO(SDNode *Node, SDValue &Result, SDValue &Overflow, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::S(ADD|SUB)O.
SDValue expandABS(SDNode *N, SelectionDAG &DAG, bool IsNegative=false) const
Expand ABS nodes.
SDValue expandVecReduce(SDNode *Node, SelectionDAG &DAG) const
Expand a VECREDUCE_* into an explicit calculation.
SDValue expandVPCTTZElements(SDNode *N, SelectionDAG &DAG) const
Expand VP_CTTZ_ELTS/VP_CTTZ_ELTS_ZERO_UNDEF nodes.
bool expandFP_TO_UINT(SDNode *N, SDValue &Result, SDValue &Chain, SelectionDAG &DAG) const
Expand float to UINT conversion.
bool expandREM(SDNode *Node, SDValue &Result, SelectionDAG &DAG) const
Expand an SREM or UREM using SDIV/UDIV or SDIVREM/UDIVREM, if legal.
std::pair< SDValue, SDValue > expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const
Expands an unaligned load to 2 half-size loads for an integer, and possibly more for vectors.
SDValue expandFMINIMUMNUM_FMAXIMUMNUM(SDNode *N, SelectionDAG &DAG) const
Expand fminimumnum/fmaximumnum into multiple comparison with selects.
SDValue expandVectorSplice(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::VECTOR_SPLICE.
SDValue expandCTPOP(SDNode *N, SelectionDAG &DAG) const
Expand CTPOP nodes.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
SDValue expandBSWAP(SDNode *N, SelectionDAG &DAG) const
Expand BSWAP nodes.
SDValue expandFMINIMUM_FMAXIMUM(SDNode *N, SelectionDAG &DAG) const
Expand fminimum/fmaximum into multiple comparison with selects.
SDValue getVectorSubVecPointer(SelectionDAG &DAG, SDValue VecPtr, EVT VecVT, EVT SubVecVT, SDValue Index) const
Get a pointer to a sub-vector of type SubVecVT at index Idx located in memory for a vector of type Ve...
bool expandFP_TO_SINT(SDNode *N, SDValue &Result, SelectionDAG &DAG) const
Expand float(f32) to SINT(i64) conversion.
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
SDValue expandFunnelShift(SDNode *N, SelectionDAG &DAG) const
Expand funnel shift.
bool LegalizeSetCCCondCode(SelectionDAG &DAG, EVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, SDValue Mask, SDValue EVL, bool &NeedInvert, const SDLoc &dl, SDValue &Chain, bool IsSignaling=false) const
Legalize a SETCC or VP_SETCC with given LHS and RHS and condition code CC on the current target.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const
This callback is invoked for operations that are unsupported by the target, which are registered to u...
SDValue expandFixedPointDiv(unsigned Opcode, const SDLoc &dl, SDValue LHS, SDValue RHS, unsigned Scale, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]DIVFIX[SAT].
SDValue getVectorElementPointer(SelectionDAG &DAG, SDValue VecPtr, EVT VecVT, SDValue Index) const
Get a pointer to vector element Idx located in memory for a vector of type VecVT starting at a base a...
SDValue expandFP_ROUND(SDNode *Node, SelectionDAG &DAG) const
Expand round(fp) to fp conversion.
SDValue expandROT(SDNode *N, bool AllowVectorOps, SelectionDAG &DAG) const
Expand rotations.
SDValue expandFMINNUM_FMAXNUM(SDNode *N, SelectionDAG &DAG) const
Expand fminnum/fmaxnum into fminnum_ieee/fmaxnum_ieee with quieted inputs.
SDValue expandCMP(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[US]CMP.
SDValue expandFixedPointMul(SDNode *Node, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::[U|S]MULFIX[SAT].
void expandUADDSUBO(SDNode *Node, SDValue &Result, SDValue &Overflow, SelectionDAG &DAG) const
Method for building the DAG expansion of ISD::U(ADD|SUB)O.
bool expandUINT_TO_FP(SDNode *N, SDValue &Result, SDValue &Chain, SelectionDAG &DAG) const
Expand UINT(i64) to double(f64) conversion.
bool expandMUL_LOHI(unsigned Opcode, EVT VT, const SDLoc &dl, SDValue LHS, SDValue RHS, SmallVectorImpl< SDValue > &Result, EVT HiLoVT, SelectionDAG &DAG, MulExpansionKind Kind, SDValue LL=SDValue(), SDValue LH=SDValue(), SDValue RL=SDValue(), SDValue RH=SDValue()) const
Expand a MUL or [US]MUL_LOHI of n-bit values into two or four nodes, respectively,...
SDValue expandAVG(SDNode *N, SelectionDAG &DAG) const
Expand vector/scalar AVGCEILS/AVGCEILU/AVGFLOORS/AVGFLOORU nodes.
Primary interface to the complete machine description for the target machine.
virtual const TargetFrameLowering * getFrameLowering() const
static constexpr TypeSize getFixed(ScalarTy ExactSize)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isVoidTy() const
Return true if this is 'void'.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
LLVM Value Representation.
constexpr ScalarTy getFixedValue() const
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ FRAME_TO_ARGS_OFFSET
FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to first (possible) on-stack ar...
@ FMAD
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations.
@ ADD
Simple integer binary arithmetic operators.
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ EH_SJLJ_SETUP_DISPATCH
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ EH_RETURN
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin,...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ ADDROFRETURNADDR
ADDROFRETURNADDR - Represents the llvm.addressofreturnaddress intrinsic.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ SETCCCARRY
Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a boolean indicating ...
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ GLOBAL_OFFSET_TABLE
The address of the GOT.
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ VECTOR_SPLICE
VECTOR_SPLICE(VEC1, VEC2, IMM) - Returns a subvector of the same type as VEC1/VEC2 from CONCAT_VECTOR...
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ SPONENTRY
SPONENTRY - Represents the llvm.sponentry intrinsic.
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
LLVM_ABI NodeType getExtForLoadExtType(bool IsFP, LoadExtType)
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
LLVM_ABI std::optional< unsigned > getVPMaskIdx(unsigned Opcode)
The operand position of the vector mask.
LLVM_ABI CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
LLVM_ABI Libcall getPOWI(EVT RetVT)
getPOWI - Return the POWI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI 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.
LLVM_ABI Libcall getLDEXP(EVT RetVT)
getLDEXP - Return the LDEXP_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFREXP(EVT RetVT)
getFREXP - Return the FREXP_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINCOSPI(EVT RetVT)
getSINCOSPI - Return the SINCOSPI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getMODF(EVT RetVT)
getMODF - Return the MODF_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPLibCall(EVT VT, Libcall Call_F32, Libcall Call_F64, Libcall Call_F80, Libcall Call_F128, Libcall Call_PPCF128)
GetFPLibCall - Helper to return the right libcall for the given floating point type,...
LLVM_ABI Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order, MVT VT)
Return the outline atomics value for the given opcode, atomic ordering and type, or UNKNOWN_LIBCALL i...
LLVM_ABI Libcall getFPEXT(EVT OpVT, EVT RetVT)
getFPEXT - Return the FPEXT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINCOS(EVT RetVT)
getSINCOS - Return the SINCOS_* value for the given types, or UNKNOWN_LIBCALL if there is none.
@ Undef
Value of the register doesn't matter.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
Returns: X * 2^Exp for integral exponents.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
AtomicOrdering
Atomic ordering for LLVM's memory model.
To bit_cast(const From &from) noexcept
@ Or
Bitwise or logical OR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
uint64_t value() const
This is a hole in the type system and should not be abused.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
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 changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
uint64_t getScalarSizeInBits() const
EVT getHalfSizedIntegerVT(LLVMContext &Context) const
Finds the smallest simple value type that is greater than or equal to half the width of this EVT.
TypeSize getStoreSizeInBits() const
Return the number of bits overwritten by a store of the specified value type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
LLVM_ABI const fltSemantics & getFltSemantics() const
Returns an APFloat semantics tag appropriate for the value type.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
void setNoUnsignedWrap(bool b)
void setNoSignedWrap(bool b)
bool IsPostTypeLegalization
MakeLibCallOptions & setIsSigned(bool Value=true)