29 #define DEBUG_TYPE "legalize-types" 35 void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
43 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
51 case ISD::BITCAST: R = ScalarizeVecRes_BITCAST(N);
break;
56 case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N);
break;
58 case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));
break;
61 case ISD::VSELECT: R = ScalarizeVecRes_VSELECT(N);
break;
62 case ISD::SELECT: R = ScalarizeVecRes_SELECT(N);
break;
64 case ISD::SETCC: R = ScalarizeVecRes_SETCC(N);
break;
65 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(N);
break;
70 R = ScalarizeVecRes_VecInregOp(N);
105 R = ScalarizeVecRes_UnaryOp(N);
144 R = ScalarizeVecRes_BinOp(N);
147 R = ScalarizeVecRes_TernaryOp(N);
173 R = ScalarizeVecRes_StrictFPOp(N);
176 R = ScalarizeVecRes_SMULFIX(N);
182 SetScalarizedVector(
SDValue(N, ResNo), R);
192 SDValue DAGTypeLegalizer::ScalarizeVecRes_TernaryOp(
SDNode *N) {
200 SDValue DAGTypeLegalizer::ScalarizeVecRes_SMULFIX(
SDNode *N) {
208 SDValue DAGTypeLegalizer::ScalarizeVecRes_StrictFPOp(
SDNode *N) {
221 for (
unsigned i = 1; i < NumOpers; ++i) {
225 Oper = GetScalarizedVector(Oper);
238 SDValue DAGTypeLegalizer::ScalarizeVecRes_MERGE_VALUES(
SDNode *N,
240 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
241 return GetScalarizedVector(Op);
244 SDValue DAGTypeLegalizer::ScalarizeVecRes_BITCAST(
SDNode *N) {
249 Op = GetScalarizedVector(Op);
255 SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *N) {
265 SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *N) {
271 SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_ROUND(
SDNode *N) {
284 SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *N) {
312 SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(
SDNode *N) {
326 Op = GetScalarizedVector(Op);
336 SDValue DAGTypeLegalizer::ScalarizeVecRes_InregOp(
SDNode *N) {
344 SDValue DAGTypeLegalizer::ScalarizeVecRes_VecInregOp(
SDNode *N) {
353 Op = GetScalarizedVector(Op);
372 SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *N) {
382 SDValue DAGTypeLegalizer::ScalarizeVecRes_VSELECT(
SDNode *N) {
390 Cond = GetScalarizedVector(Cond);
420 if (ScalarBool != VecBool) {
421 switch (ScalarBool) {
442 auto BoolVT = getSetCCResultType(CondVT);
443 if (BoolVT.bitsLT(CondVT))
451 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(
SDNode *N) {
458 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(
SDNode *N) {
470 SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *N) {
475 unsigned Op = !cast<ConstantSDNode>(
Arg)->isNullValue();
476 return GetScalarizedVector(N->
getOperand(Op));
482 "Operand types must be vectors");
485 EVT OpVT = LHS.getValueType();
491 LHS = GetScalarizedVector(LHS);
492 RHS = GetScalarizedVector(RHS);
510 return DAG.
getNode(ExtendCode, DL, NVT, Res);
518 bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *N,
unsigned OpNo) {
523 if (!Res.getNode()) {
527 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
534 Res = ScalarizeVecOp_BITCAST(N);
544 Res = ScalarizeVecOp_UnaryOp(N);
547 Res = ScalarizeVecOp_CONCAT_VECTORS(N);
550 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N);
553 Res = ScalarizeVecOp_VSELECT(N);
556 Res = ScalarizeVecOp_VSETCC(N);
559 Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo);
562 Res = ScalarizeVecOp_FP_ROUND(N, OpNo);
568 if (!Res.getNode())
return false;
572 if (Res.getNode() ==
N)
576 "Invalid operand expansion");
578 ReplaceValueWith(
SDValue(N, 0), Res);
584 SDValue DAGTypeLegalizer::ScalarizeVecOp_BITCAST(
SDNode *N) {
592 SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp(
SDNode *N) {
594 "Unexpected vector type!");
604 SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *N) {
607 Ops[i] = GetScalarizedVector(N->
getOperand(i));
613 SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *N) {
626 SDValue DAGTypeLegalizer::ScalarizeVecOp_VSELECT(
SDNode *N) {
640 "Operand types must be vectors");
659 Res = DAG.
getNode(ExtendCode, DL, NVT, Res);
668 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
686 SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *N,
unsigned OpNo) {
702 void DAGTypeLegalizer::SplitVectorResult(
SDNode *N,
unsigned ResNo) {
713 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
722 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi);
break;
724 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi);
break;
725 case ISD::BITCAST: SplitVecRes_BITCAST(N, Lo, Hi);
break;
731 case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi);
break;
737 SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi);
740 SplitVecRes_MLOAD(cast<MaskedLoadSDNode>(N), Lo, Hi);
743 SplitVecRes_MGATHER(cast<MaskedGatherSDNode>(N), Lo, Hi);
746 SplitVecRes_SETCC(N, Lo, Hi);
749 SplitVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N), Lo, Hi);
755 SplitVecRes_ExtVecInRegOp(N, Lo, Hi);
789 SplitVecRes_UnaryOp(N, Lo, Hi);
795 SplitVecRes_ExtendOp(N, Lo, Hi);
831 SplitVecRes_BinOp(N, Lo, Hi);
834 SplitVecRes_TernaryOp(N, Lo, Hi);
860 SplitVecRes_StrictFPOp(N, Lo, Hi);
863 SplitVecRes_SMULFIX(N, Lo, Hi);
875 GetSplitVector(N->
getOperand(0), LHSLo, LHSHi);
877 GetSplitVector(N->
getOperand(1), RHSLo, RHSHi);
886 void DAGTypeLegalizer::SplitVecRes_TernaryOp(
SDNode *N,
SDValue &Lo,
889 GetSplitVector(N->
getOperand(0), Op0Lo, Op0Hi);
891 GetSplitVector(N->
getOperand(1), Op1Lo, Op1Hi);
893 GetSplitVector(N->
getOperand(2), Op2Lo, Op2Hi);
897 Op0Lo, Op1Lo, Op2Lo);
899 Op0Hi, Op1Hi, Op2Hi);
902 void DAGTypeLegalizer::SplitVecRes_SMULFIX(
SDNode *N,
SDValue &Lo,
905 GetSplitVector(N->
getOperand(0), LHSLo, LHSHi);
907 GetSplitVector(N->
getOperand(1), RHSLo, RHSHi);
916 void DAGTypeLegalizer::SplitVecRes_BITCAST(
SDNode *N,
SDValue &Lo,
928 switch (getTypeAction(InVT)) {
942 GetExpandedOp(InOp, Lo, Hi);
953 GetSplitVector(InOp, Lo, Hi);
965 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT, Lo, Hi);
973 void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(
SDNode *N,
SDValue &Lo,
986 void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(
SDNode *N,
SDValue &Lo,
991 if (NumSubvectors == 1) {
1007 void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *N,
SDValue &Lo,
1017 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
1023 void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(
SDNode *N,
SDValue &Lo,
1029 GetSplitVector(Vec, Lo, Hi);
1042 unsigned IdxVal = ConstIdx->getZExtValue();
1043 if ((IdxVal == 0) && (IdxVal + SubElems <= VecElems / 2)) {
1070 DAG.
getConstant(IncrementSize, dl, StackPtr.getValueType()));
1074 MinAlign(Alignment, IncrementSize));
1077 void DAGTypeLegalizer::SplitVecRes_FPOWI(
SDNode *N,
SDValue &Lo,
1085 void DAGTypeLegalizer::SplitVecRes_FCOPYSIGN(
SDNode *N,
SDValue &Lo,
1088 GetSplitVector(N->
getOperand(0), LHSLo, LHSHi);
1095 GetSplitVector(RHS, RHSLo, RHSHi);
1104 void DAGTypeLegalizer::SplitVecRes_InregOp(
SDNode *N,
SDValue &Lo,
1107 GetSplitVector(N->
getOperand(0), LHSLo, LHSHi);
1111 std::tie(LoVT, HiVT) =
1120 void DAGTypeLegalizer::SplitVecRes_ExtVecInRegOp(
SDNode *N,
SDValue &Lo,
1129 GetSplitVector(N0, InLo, InHi);
1136 EVT OutLoVT, OutHiVT;
1139 assert((2 * OutNumElements) <= InNumElements &&
1140 "Illegal extend vector in reg split");
1150 for (
unsigned i = 0; i != OutNumElements; ++i)
1151 SplitHi[i] = i + OutNumElements;
1154 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1155 Hi = DAG.
getNode(Opcode, dl, OutHiVT, InHi);
1158 void DAGTypeLegalizer::SplitVecRes_StrictFPOp(
SDNode *N,
SDValue &Lo,
1174 for (
unsigned i = 1; i < NumOps; ++i) {
1184 GetSplitVector(Op, OpLo, OpHi);
1194 EVT HiValueVTs[] = {HiVT, MVT::Other};
1205 ReplaceValueWith(
SDValue(N, 1), Chain);
1208 void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *N,
SDValue &Lo,
1214 GetSplitVector(Vec, Lo, Hi);
1217 unsigned IdxVal = CIdx->getZExtValue();
1219 if (IdxVal < LoNumElts)
1266 Lo = DAG.
getLoad(LoVT, dl, Store, StackPtr, PtrInfo);
1270 StackPtr = DAG.
getNode(
ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
1272 StackPtr.getValueType()));
1275 Hi = DAG.
getLoad(HiVT, dl, Store, StackPtr,
1276 PtrInfo.getWithOffset(IncrementSize),
1277 MinAlign(Alignment, IncrementSize));
1287 void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(
SDNode *N,
SDValue &Lo,
1312 EVT LoMemVT, HiMemVT;
1322 Alignment, MMOFlags, AAInfo);
1331 ReplaceValueWith(
SDValue(LD, 1), Ch);
1349 unsigned SecondHalfAlignment =
1351 Alignment/2 : Alignment;
1356 GetSplitVector(Mask, MaskLo, MaskHi);
1358 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, dl);
1361 EVT LoMemVT, HiMemVT;
1364 SDValue PassThruLo, PassThruHi;
1366 GetSplitVector(PassThru, PassThruLo, PassThruHi);
1368 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, dl);
1375 Lo = DAG.
getMaskedLoad(LoVT, dl, Ch, Ptr, MaskLo, PassThruLo, LoMemVT, MMO,
1387 Hi = DAG.
getMaskedLoad(HiVT, dl, Ch, Ptr, MaskHi, PassThruHi, HiMemVT, MMO,
1397 ReplaceValueWith(
SDValue(MLD, 1), Ch);
1418 GetSplitVector(Mask, MaskLo, MaskHi);
1420 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, dl);
1423 EVT LoMemVT, HiMemVT;
1427 SDValue PassThruLo, PassThruHi;
1429 GetSplitVector(PassThru, PassThruLo, PassThruHi);
1431 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, dl);
1435 GetSplitVector(Index, IndexLo, IndexHi);
1437 std::tie(IndexLo, IndexHi) = DAG.
SplitVector(Index, dl);
1444 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo, Scale};
1448 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi, Scale};
1459 ReplaceValueWith(
SDValue(MGT, 1), Ch);
1466 "Operand types must be vectors");
1490 void DAGTypeLegalizer::SplitVecRes_UnaryOp(
SDNode *N,
SDValue &Lo,
1514 void DAGTypeLegalizer::SplitVecRes_ExtendOp(
SDNode *N,
SDValue &Lo,
1536 if ((NumElements & 1) == 0 &&
1542 EVT SplitLoVT, SplitHiVT;
1546 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
1560 SplitVecRes_UnaryOp(N, Lo, Hi);
1568 GetSplitVector(N->
getOperand(0), Inputs[0], Inputs[1]);
1569 GetSplitVector(N->
getOperand(1), Inputs[2], Inputs[3]);
1584 unsigned InputUsed[2] = { -1U, -1U };
1585 unsigned FirstMaskIdx =
High * NewElts;
1586 bool useBuildVector =
false;
1587 for (
unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
1589 int Idx = N->
getMaskElt(FirstMaskIdx + MaskOffset);
1592 unsigned Input = (
unsigned)Idx / NewElts;
1601 Idx -= Input * NewElts;
1606 if (InputUsed[OpNo] == Input) {
1609 }
else if (InputUsed[OpNo] == -1U) {
1611 InputUsed[OpNo] = Input;
1619 useBuildVector =
true;
1627 if (useBuildVector) {
1632 for (
unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
1634 int Idx = N->
getMaskElt(FirstMaskIdx + MaskOffset);
1637 unsigned Input = (
unsigned)Idx / NewElts;
1646 Idx -= Input * NewElts;
1656 }
else if (InputUsed[0] == -1U) {
1660 SDValue Op0 = Inputs[InputUsed[0]];
1662 SDValue Op1 = InputUsed[1] == -1U ?
1663 DAG.
getUNDEF(NewVT) : Inputs[InputUsed[1]];
1681 bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *N,
unsigned OpNo) {
1689 if (!Res.getNode()) {
1693 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
1700 case ISD::SETCC: Res = SplitVecOp_VSETCC(N);
break;
1706 Res = SplitVecOp_TruncateHelper(N);
1711 Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo);
1714 Res = SplitVecOp_MSTORE(cast<MaskedStoreSDNode>(N), OpNo);
1717 Res = SplitVecOp_MSCATTER(cast<MaskedScatterSDNode>(N), OpNo);
1720 Res = SplitVecOp_MGATHER(cast<MaskedGatherSDNode>(N), OpNo);
1723 Res = SplitVecOp_VSELECT(N, OpNo);
1728 Res = SplitVecOp_TruncateHelper(N);
1730 Res = SplitVecOp_UnaryOp(N);
1743 Res = SplitVecOp_UnaryOp(N);
1749 Res = SplitVecOp_ExtVecInRegOp(N);
1765 Res = SplitVecOp_VECREDUCE(N, OpNo);
1771 if (!Res.getNode())
return false;
1775 if (Res.getNode() ==
N)
1779 "Invalid operand expansion");
1781 ReplaceValueWith(
SDValue(N, 0), Res);
1785 SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *N,
unsigned OpNo) {
1788 assert(OpNo == 0 &&
"Illegal operand must be mask");
1799 assert(Lo.getValueType() == Hi.getValueType() &&
1800 "Lo and Hi have differing types");
1804 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
1806 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
1807 std::tie(LoOp0, HiOp0) = DAG.
SplitVector(Src0, DL);
1808 std::tie(LoOp1, HiOp1) = DAG.
SplitVector(Src1, DL);
1809 std::tie(LoMask, HiMask) = DAG.
SplitVector(Mask, DL);
1819 SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *N,
unsigned OpNo) {
1826 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
1827 GetSplitVector(VecOp, Lo, Hi);
1832 unsigned CombineOpc = 0;
1884 Lo = BitConvertToInteger(Lo);
1885 Hi = BitConvertToInteger(Hi);
1891 JoinIntegers(Lo, Hi));
1894 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *N) {
1903 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
1905 if (IdxVal < LoElts) {
1907 "Extracted subvector crosses vector split!");
1916 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *N) {
1921 if (isa<ConstantSDNode>(Idx)) {
1922 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
1926 GetSplitVector(Vec, Lo, Hi);
1928 uint64_t LoElts = Lo.getValueType().getVectorNumElements();
1930 if (IdxVal < LoElts)
1974 SDValue DAGTypeLegalizer::SplitVecOp_ExtVecInRegOp(
SDNode *N) {
1979 SplitVecRes_ExtVecInRegOp(N, Lo, Hi);
2001 GetSplitVector(Mask, MaskLo, MaskHi);
2003 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, dl);
2006 EVT LoMemVT, HiMemVT;
2009 SDValue PassThruLo, PassThruHi;
2011 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2013 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, dl);
2017 GetSplitVector(Index, IndexLo, IndexHi);
2019 std::tie(IndexLo, IndexHi) = DAG.
SplitVector(Index, dl);
2026 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo, Scale};
2036 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi, Scale};
2047 ReplaceValueWith(
SDValue(MGT, 1), Ch);
2051 ReplaceValueWith(
SDValue(MGT, 0), Res);
2065 EVT LoMemVT, HiMemVT;
2071 GetSplitVector(Data, DataLo, DataHi);
2073 std::tie(DataLo, DataHi) = DAG.
SplitVector(Data, DL);
2078 GetSplitVector(Mask, MaskLo, MaskHi);
2080 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, DL);
2084 unsigned SecondHalfAlignment =
2086 Alignment/2 : Alignment;
2094 Lo = DAG.
getMaskedStore(Ch, DL, DataLo, Ptr, MaskLo, LoMemVT, MMO,
2107 Hi = DAG.
getMaskedStore(Ch, DL, DataHi, Ptr, MaskHi, HiMemVT, MMO,
2128 EVT LoMemVT, HiMemVT;
2134 GetSplitVector(Data, DataLo, DataHi);
2136 std::tie(DataLo, DataHi) = DAG.
SplitVector(Data, DL);
2141 GetSplitVector(Mask, MaskLo, MaskHi);
2143 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, DL);
2147 GetSplitVector(Index, IndexLo, IndexHi);
2149 std::tie(IndexLo, IndexHi) = DAG.
SplitVector(Index, DL);
2157 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo, Scale};
2169 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi, Scale};
2176 assert(OpNo == 1 &&
"Can only split the stored value");
2189 EVT LoMemVT, HiMemVT;
2193 if (!LoMemVT.isByteSized() || !HiMemVT.isByteSized())
2196 unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
2200 Alignment, MMOFlags, AAInfo);
2211 HiMemVT, Alignment, MMOFlags, AAInfo);
2215 Alignment, MMOFlags, AAInfo);
2220 SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(
SDNode *N) {
2231 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
2242 SDValue DAGTypeLegalizer::SplitVecOp_TruncateHelper(
SDNode *N) {
2268 assert(!(NumElements & 1) &&
"Splitting vector, but not in half!");
2274 EVT LoOutVT, HiOutVT;
2276 assert(LoOutVT == HiOutVT &&
"Unequal split?");
2281 if (isTypeLegal(LoOutVT) ||
2282 InElementSize <= OutElementSize * 2)
2283 return SplitVecOp_UnaryOp(N);
2292 return SplitVecOp_UnaryOp(N);
2296 GetSplitVector(InVec, InLoVec, InHiVec);
2299 EVT HalfElementVT = IsFloat ?
2324 "Operand types must be vectors");
2326 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
2330 unsigned PartElements = Lo0.getValueType().getVectorNumElements();
2369 void DAGTypeLegalizer::WidenVectorResult(
SDNode *N,
unsigned ResNo) {
2381 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
2388 case ISD::BITCAST: Res = WidenVecRes_BITCAST(N);
break;
2394 case ISD::LOAD: Res = WidenVecRes_LOAD(N);
break;
2398 case ISD::SELECT: Res = WidenVecRes_SELECT(N);
break;
2400 case ISD::SETCC: Res = WidenVecRes_SETCC(N);
break;
2401 case ISD::UNDEF: Res = WidenVecRes_UNDEF(N);
break;
2403 Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N));
2406 Res = WidenVecRes_MLOAD(cast<MaskedLoadSDNode>(N));
2409 Res = WidenVecRes_MGATHER(cast<MaskedGatherSDNode>(N));
2432 Res = WidenVecRes_Binary(N);
2445 Res = WidenVecRes_BinaryCanTrap(N);
2472 Res = WidenVecRes_StrictFP(N);
2476 Res = WidenVecRes_FCOPYSIGN(N);
2480 Res = WidenVecRes_POWI(N);
2486 Res = WidenVecRes_Shift(N);
2492 Res = WidenVecRes_EXTEND_VECTOR_INREG(N);
2505 Res = WidenVecRes_Convert(N);
2532 "Target supports vector op, but scalar requires expansion?");
2549 Res = WidenVecRes_Unary(N);
2552 Res = WidenVecRes_Ternary(N);
2558 SetWidenedVector(
SDValue(N, ResNo), Res);
2585 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
2588 if (ConcatEnd == 1) {
2589 VT = ConcatOps[0].getValueType();
2591 return ConcatOps[0];
2594 SDLoc dl(ConcatOps[0]);
2602 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
2603 Idx = ConcatEnd - 1;
2604 VT = ConcatOps[Idx--].getValueType();
2605 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
2618 unsigned NumToInsert = ConcatEnd - Idx - 1;
2619 for (
unsigned i = 0, OpIdx = Idx+1; i < NumToInsert; i++, OpIdx++) {
2624 ConcatOps[Idx+1] = VecOp;
2625 ConcatEnd = Idx + 2;
2631 unsigned RealVals = ConcatEnd - Idx - 1;
2632 unsigned SubConcatEnd = 0;
2633 unsigned SubConcatIdx = Idx + 1;
2634 while (SubConcatEnd < RealVals)
2635 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
2636 while (SubConcatEnd < OpsToConcat)
2637 SubConcatOps[SubConcatEnd++] = undefVec;
2639 NextVT, SubConcatOps);
2640 ConcatEnd = SubConcatIdx + 1;
2645 if (ConcatEnd == 1) {
2646 VT = ConcatOps[0].getValueType();
2648 return ConcatOps[0];
2653 if (NumOps != ConcatEnd ) {
2655 for (
unsigned j = ConcatEnd; j < NumOps; ++j)
2656 ConcatOps[j] = UndefVal;
2662 SDValue DAGTypeLegalizer::WidenVecRes_BinaryCanTrap(
SDNode *N) {
2672 NumElts = NumElts / 2;
2694 unsigned ConcatEnd = 0;
2702 while (CurNumElts != 0) {
2703 while (CurNumElts >= NumElts) {
2710 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
2712 CurNumElts -= NumElts;
2715 NumElts = NumElts / 2;
2720 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
2727 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
2747 NumElts = NumElts / 2;
2762 unsigned ConcatEnd = 0;
2769 for (
unsigned i = 1; i < NumOpers; ++i) {
2774 "Invalid operand type to widen!");
2775 Oper = GetWidenedVector(Oper);
2786 while (CurNumElts != 0) {
2787 while (CurNumElts >= NumElts) {
2790 for (
unsigned i = 0; i < NumOpers; ++i) {
2803 ConcatOps[ConcatEnd++] = Oper;
2806 CurNumElts -= NumElts;
2809 NumElts = NumElts / 2;
2814 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
2817 for (
unsigned i = 0; i < NumOpers; ++i) {
2831 ConcatOps[ConcatEnd++] = Oper;
2840 if (Chains.
size() == 1)
2841 NewChain = Chains[0];
2844 ReplaceValueWith(
SDValue(N, 1), NewChain);
2866 InVTNumElts = InVT.getVectorNumElements();
2867 if (InVTNumElts == WidenNumElts) {
2869 return DAG.
getNode(Opcode, DL, WidenVT, InOp);
2891 if (WidenNumElts % InVTNumElts == 0) {
2893 unsigned NumConcat = WidenNumElts/InVTNumElts;
2898 return DAG.
getNode(Opcode, DL, WidenVT, InVec);
2902 if (InVTNumElts % WidenNumElts == 0) {
2908 return DAG.
getNode(Opcode, DL, WidenVT, InVal);
2919 for (
unsigned i=0; i < MinElts; ++i) {
2924 Ops[i] = DAG.
getNode(Opcode, DL, EltVT, Val);
2932 SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *N) {
2946 InOp = GetWidenedVector(InOp);
2953 return DAG.
getNode(Opcode, DL, WidenVT, InOp);
2960 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i != e; ++i) {
2979 while (Ops.
size() != WidenNumElts)
2985 SDValue DAGTypeLegalizer::WidenVecRes_FCOPYSIGN(
SDNode *N) {
2989 return WidenVecRes_BinaryCanTrap(N);
3008 EVT ShVT = ShOp.getValueType();
3010 ShOp = GetWidenedVector(ShOp);
3011 ShVT = ShOp.getValueType();
3016 if (ShVT != ShWidenVT)
3017 ShOp = ModifyToType(ShOp, ShWidenVT);
3033 .getVectorElementType(),
3040 SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *N,
unsigned ResNo) {
3041 SDValue WidenVec = DisintegrateMERGE_VALUES(N, ResNo);
3042 return GetWidenedVector(WidenVec);
3052 switch (getTypeAction(InVT)) {
3064 InOp = GetPromotedInteger(InOp);
3066 if (WidenVT.
bitsEq(InVT))
3079 InOp = GetWidenedVector(InOp);
3081 if (WidenVT.
bitsEq(InVT))
3090 if (WidenSize % InSize == 0 && InVT !=
MVT::x86mmx) {
3095 unsigned NewNumElts = WidenSize / InSize;
3123 return CreateStackStoreLoad(InOp, WidenVT);
3126 SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(
SDNode *N) {
3140 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
3141 NewOps.append(WidenNumElts - NumElts, DAG.
getUNDEF(EltVT));
3146 SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(
SDNode *N) {
3154 bool InputWidened =
false;
3162 for (
unsigned i=0; i < NumOperands; ++i)
3164 for (
unsigned i = NumOperands; i != NumConcat; ++i)
3169 InputWidened =
true;
3173 for (i=1; i < NumOperands; ++i)
3177 if (i == NumOperands)
3182 if (NumOperands == 2) {
3185 for (
unsigned i = 0; i < NumInElts; ++i) {
3187 MaskOps[i + NumInElts] = i + WidenNumElts;
3201 for (
unsigned i=0; i < NumOperands; ++i) {
3204 InOp = GetWidenedVector(InOp);
3205 for (
unsigned j=0; j < NumInElts; ++j)
3211 for (; Idx < WidenNumElts; ++Idx)
3212 Ops[Idx] = UndefVal;
3216 SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *N) {
3225 InOp = GetWidenedVector(InOp);
3230 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
3231 if (IdxVal == 0 && InVT == WidenVT)
3236 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
3245 for (i=0; i < NumElts; ++i)
3252 for (; i < WidenNumElts; ++i)
3257 SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *N) {
3271 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
3273 Result = GenWidenVectorLoads(LdChain, LD);
3279 if (LdChain.
size() == 1)
3280 NewChain = LdChain[0];
3286 ReplaceValueWith(
SDValue(N, 1), NewChain);
3304 Mask = ModifyToType(Mask, WideMaskVT,
true);
3330 Mask = ModifyToType(Mask, WideMaskVT,
true);
3337 Index = ModifyToType(Index, WideIndexVT);
3350 SDValue DAGTypeLegalizer::WidenVecRes_SCALAR_TO_VECTOR(
SDNode *N) {
3414 if (MaskScalarBits < ToMaskScalBits) {
3418 }
else if (MaskScalarBits > ToMaskScalBits) {
3426 "Mask should have the right element size by now.");
3444 "A mask of ToMaskVT should have been produced by now.");
3475 EVT FinalVT = VSelVT;
3487 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
3505 VSelOp1 = GetWidenedVector(VSelOp1);
3506 VSelOp2 = GetWidenedVector(VSelOp2);
3510 EVT ToMaskVT = VSelVT;
3517 Mask = convertMask(Cond, MaskVT, ToMaskVT);
3527 unsigned ScalarBits1 = VT1.getScalarSizeInBits();
3533 if (ScalarBits0 != ScalarBits1) {
3534 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
3535 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
3547 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
3548 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
3552 Mask = convertMask(Cond, MaskVT, ToMaskVT);
3566 if (
SDValue Res = WidenVSELECTAndMask(N))
3571 CondEltVT, WidenNumElts);
3573 Cond1 = GetWidenedVector(Cond1);
3581 SDValue SplitSelect = SplitVecOp_VSELECT(N, 0);
3582 SDValue Res = ModifyToType(SplitSelect, WidenVT);
3587 Cond1 = ModifyToType(Cond1, CondWidenVT);
3594 WidenVT, Cond1, InOp1, InOp2);
3597 SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(
SDNode *N) {
3623 for (
unsigned i = 0; i != NumElts; ++i) {
3625 if (Idx < (
int)NumElts)
3626 NewMask.push_back(Idx);
3628 NewMask.push_back(Idx - NumElts + WidenNumElts);
3630 for (
unsigned i = NumElts; i != WidenNumElts; ++i)
3631 NewMask.push_back(-1);
3638 "Operands must be vectors");
3652 SDValue SplitVSetCC = SplitVecOp_VSETCC(N);
3653 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
3657 InOp1 = GetWidenedVector(InOp1);
3664 "Input not widened to expected type!");
3674 bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *N,
unsigned OpNo) {
3686 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
3696 case ISD::STORE: Res = WidenVecOp_STORE(N);
break;
3697 case ISD::MSTORE: Res = WidenVecOp_MSTORE(N, OpNo);
break;
3698 case ISD::MGATHER: Res = WidenVecOp_MGATHER(N, OpNo);
break;
3699 case ISD::MSCATTER: Res = WidenVecOp_MSCATTER(N, OpNo);
break;
3700 case ISD::SETCC: Res = WidenVecOp_SETCC(N);
break;
3706 Res = WidenVecOp_EXTEND(N);
3715 Res = WidenVecOp_Convert(N);
3720 if (!Res.getNode())
return false;
3724 if (Res.getNode() ==
N)
3729 "Invalid operand expansion");
3731 ReplaceValueWith(
SDValue(N, 0), Res);
3742 "Unexpected type action");
3743 InOp = GetWidenedVector(InOp);
3746 "Input wasn't widened!");
3758 FixedEltVT == InEltVT) {
3760 "Not enough elements in the fixed type for the operand!");
3762 "We can't have the same type as we started with!");
3779 return WidenVecOp_Convert(N);
3812 "Unexpected type action");
3813 InOp = GetWidenedVector(InOp);
3831 for (
unsigned i=0; i < NumElts; ++i)
3848 unsigned InWidenSize = InWidenVT.getSizeInBits();
3852 unsigned NewNumElts = InWidenSize /
Size;
3862 return CreateStackStoreLoad(InOp, VT);
3865 SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(
SDNode *N) {
3876 for (i = 1; i < NumOperands; ++i)
3880 if (i == NumOperands)
3891 for (
unsigned i=0; i < NumOperands; ++i) {
3895 "Unexpected type action");
3896 InOp = GetWidenedVector(InOp);
3897 for (
unsigned j=0; j < NumInElts; ++j)
3905 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *N) {
3911 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *N) {
3927 GenWidenVectorTruncStores(StChain, ST);
3929 GenWidenVectorStores(StChain, ST);
3931 if (StChain.
size() == 1)
3937 SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *N,
unsigned OpNo) {
3938 assert((OpNo == 1 || OpNo == 3) &&
3939 "Can widen only data or mask operand of mstore");
3942 EVT MaskVT = Mask.getValueType();
3948 StVal = GetWidenedVector(StVal);
3955 Mask = ModifyToType(Mask, WideMaskVT,
true);
3959 Mask = ModifyToType(Mask, WideMaskVT,
true);
3965 StVal = ModifyToType(StVal, WideVT);
3968 assert(Mask.getValueType().getVectorNumElements() ==
3970 "Mask and data vectors should have the same number of elements");
3976 SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *N,
unsigned OpNo) {
3977 assert(OpNo == 4 &&
"Can widen only the index of mgather");
3978 auto *MG = cast<MaskedGatherSDNode>(
N);
3979 SDValue DataOp = MG->getPassThru();
3981 SDValue Scale = MG->getScale();
3990 MG->getMemOperand());
3996 SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *N,
unsigned OpNo) {
4005 DataOp = GetWidenedVector(DataOp);
4006 NumElts = DataOp.getValueType().getVectorNumElements();
4012 Index = ModifyToType(Index, WideIndexVT);
4018 Mask = ModifyToType(Mask, WideMaskVT,
true);
4019 }
else if (OpNo == 4) {
4021 Index = GetWidenedVector(Index);
4062 return PromoteTargetBoolean(CC, VT);
4078 unsigned Width,
EVT WidenVT,
4079 unsigned Align = 0,
unsigned WidenEx = 0) {
4083 unsigned AlignInBits =
Align*8;
4086 EVT RetVT = WidenEltVT;
4087 if (Width == WidenEltWidth)
4101 (WidenWidth % MemVTWidth) == 0 &&
4103 (MemVTWidth <= Width ||
4104 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
4117 (WidenWidth % MemVTWidth) == 0 &&
4119 (MemVTWidth <= Width ||
4120 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
4135 unsigned Start,
unsigned End) {
4137 SDLoc dl(LdOps[Start]);
4138 EVT LdTy = LdOps[Start].getValueType();
4146 for (
unsigned i = Start + 1; i != End; ++i) {
4147 EVT NewLdTy = LdOps[i].getValueType();
4148 if (NewLdTy != LdTy) {
4184 int WidthDiff = WidenWidth - LdWidth;
4188 EVT NewVT =
FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff);
4191 Align, MMOFlags, AAInfo);
4195 if (LdWidth <= NewVTWidth) {
4197 unsigned NumElts = WidenWidth / NewVTWidth;
4202 if (NewVT == WidenVT)
4205 assert(WidenWidth % NewVTWidth == 0);
4206 unsigned NumConcat = WidenWidth / NewVTWidth;
4209 ConcatOps[0] = LdOp;
4210 for (
unsigned i = 1; i != NumConcat; ++i)
4211 ConcatOps[i] = UndefVal;
4219 LdWidth -= NewVTWidth;
4222 while (LdWidth > 0) {
4223 unsigned Increment = NewVTWidth / 8;
4224 Offset += Increment;
4228 if (LdWidth < NewVTWidth) {
4230 NewVT =
FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff);
4232 L = DAG.
getLoad(NewVT, dl, Chain, BasePtr,
4234 MinAlign(Align, Increment), MMOFlags, AAInfo);
4243 while (size < LdOp->getValueSizeInBits(0)) {
4250 L = DAG.
getLoad(NewVT, dl, Chain, BasePtr,
4252 MinAlign(Align, Increment), MMOFlags, AAInfo);
4259 LdWidth -= NewVTWidth;
4263 unsigned End = LdOps.
size();
4264 if (!LdOps[0].getValueType().
isVector())
4274 EVT LdTy = LdOps[i].getValueType();
4277 for (--i; i >= 0; --i) {
4278 LdTy = LdOps[i].getValueType();
4284 ConcatOps[--Idx] = LdOps[i];
4285 for (--i; i >= 0; --i) {
4286 EVT NewLdTy = LdOps[i].getValueType();
4287 if (NewLdTy != LdTy) {
4294 ConcatOps[--Idx] = LdOps[i];
4307 for (; i != End-Idx; ++i)
4308 WidenOps[i] = ConcatOps[Idx+i];
4309 for (; i != NumOps; ++i)
4310 WidenOps[i] = UndefVal;
4343 LdEltVT,
Align, MMOFlags, AAInfo);
4345 unsigned i = 0,
Offset = Increment;
4346 for (i=1; i < NumElts; ++i,
Offset += Increment) {
4348 Ops[i] = DAG.
getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
4350 Align, MMOFlags, AAInfo);
4356 for (; i != WidenNumElts; ++i)
4385 while (StWidth != 0) {
4389 unsigned Increment = NewVTWidth / 8;
4398 MinAlign(Align, Offset), MMOFlags, AAInfo));
4399 StWidth -= NewVTWidth;
4400 Offset += Increment;
4404 }
while (StWidth != 0 && StWidth >= NewVTWidth);
4407 unsigned NumElts = ValWidth / NewVTWidth;
4411 Idx = Idx * ValEltWidth / NewVTWidth;
4419 MinAlign(Align, Offset), MMOFlags, AAInfo));
4420 StWidth -= NewVTWidth;
4421 Offset += Increment;
4423 }
while (StWidth != 0 && StWidth >= NewVTWidth);
4425 Idx = Idx * NewVTWidth / ValEltWidth;
4463 unsigned Offset = Increment;
4464 for (
unsigned i=1; i < NumElts; ++i, Offset += Increment) {
4471 StEltVT,
MinAlign(Align, Offset), MMOFlags, AAInfo));
4479 bool FillWithZeroes) {
4484 "input and widen element type must match");
4493 if (WidenNumElts > InNumElts && WidenNumElts % InNumElts == 0) {
4494 unsigned NumConcat = WidenNumElts / InNumElts;
4499 for (
unsigned i = 1; i != NumConcat; ++i)
4505 if (WidenNumElts < InNumElts && InNumElts % WidenNumElts)
4513 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
4515 for (Idx = 0; Idx < MinNumElts; ++Idx)
4522 for ( ; Idx < WidenNumElts; ++Idx)
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
virtual 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...
EVT getValueType() const
Return the ValueType of the referenced return value.
Constrained versions of libm-equivalent floating point intrinsics.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef...
SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an vector value) starting with the ...
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0...
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
SDValue scalarizeVectorStore(StoreSDNode *ST, SelectionDAG &DAG) const
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
const SDValue & getBasePtr() const
void push_back(const T &Elt)
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
const SDValue & getValue() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
static ISD::NodeType getExtendForContent(BooleanContent Content)
const SDValue & getChain() const
unsigned getAlignment() const
unsigned getValueSizeInBits(unsigned ResNo) const
Returns MVT::getSizeInBits(getValueType(ResNo)).
Constrained versions of the binary floating point operators.
bool isInteger() const
Return true if this is an integer or a vector integer type.
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
[US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned integers.
const SDNodeFlags getFlags() const
BooleanContent getBooleanContents(bool isVec, bool isFloat) const
For targets without i1 registers, this gives the nature of the high-bits of boolean values held in ty...
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
bool isOperationLegalOrCustom(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
bool isByteSized() const
Return true if the bit size is a multiple of 8.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1 at the ...
unsigned getValueSizeInBits() const
Returns the size of the value in bits.
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
bool isTruncatingStore() const
Return true if the op does a truncation before store.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
A description of a memory reference used in the backend.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Shift and rotation operations.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
This is used by foldAnyOrAllBitsSet() to capture a source value (Root) and the bit indexes (Mask) nee...
SDValue getMaskedScatter(SDVTList VTs, EVT VT, const SDLoc &dl, ArrayRef< SDValue > Ops, MachineMemOperand *MMO)
RESULT = SMULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same wi...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
const SDValue & getPassThru() const
op_iterator op_end() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
const SDValue & getValue() const
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
const DataLayout & getDataLayout() const
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned 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.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
This class is used to represent an MSTORE node.
unsigned getScalarSizeInBits() const
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
MachineFunction & getMachineFunction() const
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
SDValue getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl, ArrayRef< SDValue > Ops, MachineMemOperand *MMO)
const SDValue & getScale() const
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Simple integer binary arithmetic operators.
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getMaskedStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Mask, EVT MemVT, MachineMemOperand *MMO, bool IsTruncating=false, bool IsCompressing=false)
op_iterator op_begin() const
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
const SDValue & getMask() const
std::pair< EVT, EVT > GetSplitDestVTs(const EVT &VT) const
Compute the VTs needed for the low/hi parts of a type which is split (or expanded) into two not neces...
UNDEF - An undefined node.
This class is used to represent ISD::STORE nodes.
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the specified, possibly variable...
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getBasePtr() const
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
static MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
These reductions are non-strict, and have a single vector operand.
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...
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...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool isExpandingLoad() const
static EVT FindMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align=0, unsigned WidenEx=0)
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
Simple binary floating point operators.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
iterator_range< value_op_iterator > op_values() const
const SDValue & getOperand(unsigned Num) const
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL...
std::pair< SDValue, SDValue > SplitVectorOperand(const SDNode *N, unsigned OpNo)
Split the node's operand with EXTRACT_SUBVECTOR and return the low/high part.
unsigned getPrefTypeAlignment(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
unsigned getOriginalAlignment() const
Returns alignment and volatility of the memory access.
const SDValue & getValue() const
SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Mask, SDValue Src0, EVT MemVT, MachineMemOperand *MMO, ISD::LoadExtType, bool IsExpanding=false)
Bit counting operators with an undefined result for zero inputs.
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
const SDValue & getIndex() const
const SDValue & getBasePtr() const
This class contains a discriminated union of information about pointers in memory operands...
unsigned getNumOperands() const
Return the number of values used by this operation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, 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...
SDValue CreateStackTemporary(EVT VT, unsigned minAlign=1)
Create a stack temporary, suitable for holding the specified value type.
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
The memory access writes data.
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
TokenFactor - This node takes multiple tokens as input and produces a single token result...
void dump() const
Dump this node, for debugging.
const TargetLowering & getTargetLoweringInfo() const
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Returns platform specific canonical encoding of a floating point number.
virtual bool canOpTrap(unsigned Op, EVT VT) const
Returns true if the operation can trap for the value type.
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
EVT getVectorElementType() const
Given a vector type, return the type of each element.
std::pair< SDValue, SDValue > SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the vector with EXTRACT_SUBVECTOR using the provides VTs and return the low/high part...
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and rounds it to a floating point val...
const SDValue & getMask() const
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...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
bool isVector(MCInstrInfo const &MCII, MCInst const &MCI)
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on two values, following the IEEE-754 2008 definition.
const SDValue & getPassThru() const
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Byte Swap and Counting operators.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
SDValue IncrementMemoryAddress(SDValue Addr, SDValue Mask, const SDLoc &DL, EVT DataVT, SelectionDAG &DAG, bool IsCompressedMemory) const
Increments memory address Addr according to the type of the value DataVT that should be stored...
Represents one node in the SelectionDAG.
static bool isSETCCorConvertedSETCC(SDValue N)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachinePointerInfo getWithOffset(int64_t O) const
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT...
EVT getMemoryVT() const
Return the type of the in-memory value.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
Select(COND, TRUEVAL, FALSEVAL).
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
ZERO_EXTEND - Used for integer types, zeroing the new bits.
const SDValue & getBasePtr() const
ANY_EXTEND - Used for integer types. The high bits are undefined.
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
int getMaskElt(unsigned Idx) const
Flags
Flags values. These may be or'd together.
amdgpu Simplify well known AMD library false Value Value * Arg
The memory access reads data.
static 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.
bool isVector() const
Return true if this is a vector value type.
Bitwise operators - logical and, logical or, logical xor.
pointer data()
Return a pointer to the vector's buffer, even if empty().
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
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 ...
Flags getFlags() const
Return the raw flags of the source value,.
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
const SDValue & getBasePtr() const
unsigned getOpcode() const
SDValue getValue(unsigned R) const
This class is used to represent an MSCATTER node.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
const MachinePointerInfo & getPointerInfo() const
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
This class is used to represent an MLOAD node.
FMA - Perform a * b + c with no intermediate rounding step.
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MGATHER node.
SDValue getValueType(EVT)
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
bool isUndef() const
Return true if the type of the node type undefined.
ISD::LoadExtType getExtensionType() const
SetCC operator - This evaluates to a true value iff the condition is true.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
static bool isLogicalMaskOp(unsigned Opcode)
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
BooleanContent
Enum that describes how the target represents true/false values.
const SDValue & getOperand(unsigned i) const
TRUNCATE - Completely drop the high bits.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Op, int64_t Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object...
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
Perform various unary floating-point operations inspired by libm.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
LLVMContext * getContext() const
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
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...
const SDValue & getMask() const
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
This class is used to represent ISD::LOAD nodes.