34#define DEBUG_TYPE "legalize-types"
40void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
45 switch (
N->getOpcode()) {
48 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
60 case ISD::FPOWI: R = ScalarizeVecRes_ExpOp(
N);
break;
62 case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(
N));
break;
68 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
69 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
75 R = ScalarizeVecRes_VecInregOp(
N);
117 R = ScalarizeVecRes_UnaryOp(
N);
120 R = ScalarizeVecRes_FFREXP(
N, ResNo);
165 R = ScalarizeVecRes_BinOp(
N);
170 R = ScalarizeVecRes_TernaryOp(
N);
173#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
174 case ISD::STRICT_##DAGN:
175#include "llvm/IR/ConstrainedOps.def"
176 R = ScalarizeVecRes_StrictFPOp(
N);
181 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
190 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
200 R = ScalarizeVecRes_FIX(
N);
206 SetScalarizedVector(
SDValue(
N, ResNo), R);
210 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
211 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
213 LHS.getValueType(), LHS, RHS,
N->getFlags());
217 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
218 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
219 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
225 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
226 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
232SDValue DAGTypeLegalizer::ScalarizeVecRes_FFREXP(
SDNode *
N,
unsigned ResNo) {
233 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
234 "Unexpected vector type!");
235 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
237 EVT VT0 =
N->getValueType(0);
238 EVT VT1 =
N->getValueType(1);
243 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
247 unsigned OtherNo = 1 - ResNo;
248 EVT OtherVT =
N->getValueType(OtherNo);
250 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
254 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
257 return SDValue(ScalarNode, ResNo);
261 EVT VT =
N->getValueType(0).getVectorElementType();
262 unsigned NumOpers =
N->getNumOperands();
264 EVT ValueVTs[] = {VT, MVT::Other};
273 for (
unsigned i = 1; i < NumOpers; ++i) {
279 Oper = GetScalarizedVector(Oper);
290 Opers,
N->getFlags());
301 EVT ResVT =
N->getValueType(0);
302 EVT OvVT =
N->getValueType(1);
306 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
307 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
312 ScalarLHS = ElemsLHS[0];
313 ScalarRHS = ElemsRHS[0];
319 N->getOpcode(),
DL, ScalarVTs, ScalarLHS, ScalarRHS).
getNode();
323 unsigned OtherNo = 1 - ResNo;
324 EVT OtherVT =
N->getValueType(OtherNo);
326 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
330 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
333 return SDValue(ScalarNode, ResNo);
338 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
339 return GetScalarizedVector(
Op);
344 if (
Op.getValueType().isVector()
345 &&
Op.getValueType().getVectorNumElements() == 1
346 && !isSimpleLegalType(
Op.getValueType()))
347 Op = GetScalarizedVector(
Op);
348 EVT NewVT =
N->getValueType(0).getVectorElementType();
353SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
354 EVT EltVT =
N->getValueType(0).getVectorElementType();
363SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
365 N->getValueType(0).getVectorElementType(),
366 N->getOperand(0),
N->getOperand(1));
372 EVT OpVT =
Op.getValueType();
376 Op = GetScalarizedVector(
Op);
383 N->getValueType(0).getVectorElementType(),
Op,
388 SDValue Op = GetScalarizedVector(
N->getOperand(0));
393SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
397 EVT EltVT =
N->getValueType(0).getVectorElementType();
398 if (
Op.getValueType() != EltVT)
405 assert(
N->isUnindexed() &&
"Indexed vector load?");
409 N->getValueType(0).getVectorElementType(),
SDLoc(
N),
N->getChain(),
410 N->getBasePtr(), DAG.
getUNDEF(
N->getBasePtr().getValueType()),
411 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
412 N->getOriginalAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
422 EVT DestVT =
N->getValueType(0).getVectorElementType();
424 EVT OpVT =
Op.getValueType();
434 Op = GetScalarizedVector(
Op);
444 EVT EltVT =
N->getValueType(0).getVectorElementType();
446 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
455 EVT OpVT =
Op.getValueType();
457 EVT EltVT =
N->getValueType(0).getVectorElementType();
460 Op = GetScalarizedVector(
Op);
466 switch (
N->getOpcode()) {
478SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
481 EVT EltVT =
N->getValueType(0).getVectorElementType();
490 EVT OpVT =
Cond.getValueType();
503 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
517 EVT OpVT =
Cond->getOperand(0).getValueType();
524 EVT CondVT =
Cond.getValueType();
525 if (ScalarBool != VecBool) {
526 switch (ScalarBool) {
547 auto BoolVT = getSetCCResultType(CondVT);
548 if (BoolVT.bitsLT(CondVT))
553 GetScalarizedVector(
N->getOperand(2)));
557 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
559 LHS.getValueType(),
N->getOperand(0), LHS,
560 GetScalarizedVector(
N->getOperand(2)));
564 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
566 N->getOperand(0),
N->getOperand(1),
567 LHS, GetScalarizedVector(
N->getOperand(3)),
572 return DAG.
getUNDEF(
N->getValueType(0).getVectorElementType());
575SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
577 SDValue Arg =
N->getOperand(2).getOperand(0);
579 return DAG.
getUNDEF(
N->getValueType(0).getVectorElementType());
580 unsigned Op = !cast<ConstantSDNode>(Arg)->isZero();
581 return GetScalarizedVector(
N->getOperand(
Op));
584SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
586 EVT SrcVT = Src.getValueType();
591 Src = GetScalarizedVector(Src);
597 EVT DstVT =
N->getValueType(0).getVectorElementType();
598 return DAG.
getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
602 assert(
N->getValueType(0).isVector() &&
603 N->getOperand(0).getValueType().isVector() &&
604 "Operand types must be vectors");
607 EVT OpVT =
LHS.getValueType();
608 EVT NVT =
N->getValueType(0).getVectorElementType();
613 LHS = GetScalarizedVector(LHS);
614 RHS = GetScalarizedVector(RHS);
630 return DAG.
getNode(ExtendCode,
DL, NVT, Res);
638 EVT ResultVT =
N->getValueType(0).getVectorElementType();
641 Arg = GetScalarizedVector(Arg);
654 return DAG.
getNode(ExtendCode,
DL, ResultVT, Res);
661bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
666 switch (
N->getOpcode()) {
669 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
676 Res = ScalarizeVecOp_BITCAST(
N);
688 Res = ScalarizeVecOp_UnaryOp(
N);
694 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
697 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
700 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
703 Res = ScalarizeVecOp_VSELECT(
N);
706 Res = ScalarizeVecOp_VSETCC(
N);
709 Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(
N), OpNo);
712 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
715 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
718 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
721 Res = ScalarizeVecOp_FP_EXTEND(
N);
738 Res = ScalarizeVecOp_VECREDUCE(
N);
742 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
747 if (!Res.
getNode())
return false;
755 "Invalid operand expansion");
757 ReplaceValueWith(
SDValue(
N, 0), Res);
764 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
766 N->getValueType(0), Elt);
772 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
773 "Unexpected vector type!");
774 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
776 N->getValueType(0).getScalarType(), Elt);
784SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
785 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
786 "Unexpected vector type!");
787 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
789 {
N->getValueType(0).getScalarType(), MVT::Other },
790 {
N->getOperand(0), Elt });
800 ReplaceValueWith(
SDValue(
N, 0), Res);
805SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
807 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
808 Ops[i] = GetScalarizedVector(
N->getOperand(i));
814SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
815 EVT VT =
N->getValueType(0);
816 SDValue Res = GetScalarizedVector(
N->getOperand(0));
828 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
829 EVT VT =
N->getValueType(0);
839 assert(
N->getValueType(0).isVector() &&
840 N->getOperand(0).getValueType().isVector() &&
841 "Operand types must be vectors");
842 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
844 EVT VT =
N->getValueType(0);
845 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
846 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
848 EVT OpVT =
N->getOperand(0).getValueType();
860 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
868 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
869 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
872 if (
N->isTruncatingStore())
874 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
875 N->getBasePtr(),
N->getPointerInfo(),
876 N->getMemoryVT().getVectorElementType(),
N->getOriginalAlign(),
877 N->getMemOperand()->getFlags(),
N->getAAInfo());
879 return DAG.
getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
880 N->getBasePtr(),
N->getPointerInfo(),
881 N->getOriginalAlign(),
N->getMemOperand()->getFlags(),
887SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
888 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
889 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
891 N->getValueType(0).getVectorElementType(), Elt,
896SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
898 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
899 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
903 {
N->getOperand(0), Elt,
N->getOperand(2) });
912 ReplaceValueWith(
SDValue(
N, 0), Res);
919 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
921 N->getValueType(0).getVectorElementType(), Elt);
927SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
928 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
932 {
N->getOperand(0), Elt});
941 ReplaceValueWith(
SDValue(
N, 0), Res);
946 SDValue Res = GetScalarizedVector(
N->getOperand(0));
953SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
961 AccOp,
Op,
N->getFlags());
972void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
977 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
980 switch (
N->getOpcode()) {
983 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
995 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1010 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1013 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1017 SplitVecRes_LOAD(cast<LoadSDNode>(
N),
Lo,
Hi);
1020 SplitVecRes_VP_LOAD(cast<VPLoadSDNode>(
N),
Lo,
Hi);
1022 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1023 SplitVecRes_VP_STRIDED_LOAD(cast<VPStridedLoadSDNode>(
N),
Lo,
Hi);
1026 SplitVecRes_MLOAD(cast<MaskedLoadSDNode>(
N),
Lo,
Hi);
1029 case ISD::VP_GATHER:
1030 SplitVecRes_Gather(cast<MemSDNode>(
N),
Lo,
Hi,
true);
1034 SplitVecRes_SETCC(
N,
Lo,
Hi);
1037 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1040 SplitVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(
N),
Lo,
Hi);
1043 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1046 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1049 SplitVecRes_VECTOR_INTERLEAVE(
N);
1052 SplitVecRes_VAARG(
N,
Lo,
Hi);
1058 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1064 case ISD::VP_BITREVERSE:
1072 case ISD::VP_CTLZ_ZERO_UNDEF:
1074 case ISD::VP_CTTZ_ZERO_UNDEF:
1085 case ISD::VP_FFLOOR:
1090 case ISD::VP_FNEARBYINT:
1095 case ISD::VP_FP_EXTEND:
1097 case ISD::VP_FP_ROUND:
1099 case ISD::VP_FP_TO_SINT:
1101 case ISD::VP_FP_TO_UINT:
1107 case ISD::VP_FROUND:
1109 case ISD::VP_FROUNDEVEN:
1113 case ISD::VP_FROUNDTOZERO:
1115 case ISD::VP_SINT_TO_FP:
1117 case ISD::VP_TRUNCATE:
1119 case ISD::VP_UINT_TO_FP:
1121 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1124 SplitVecRes_FFREXP(
N, ResNo,
Lo,
Hi);
1130 case ISD::VP_SIGN_EXTEND:
1131 case ISD::VP_ZERO_EXTEND:
1132 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1152 case ISD::OR:
case ISD::VP_OR:
1172 case ISD::VP_FCOPYSIGN:
1173 SplitVecRes_BinOp(
N,
Lo,
Hi);
1180 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1183#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1184 case ISD::STRICT_##DAGN:
1185#include "llvm/IR/ConstrainedOps.def"
1186 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1191 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1200 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1210 SplitVecRes_FIX(
N,
Lo,
Hi);
1212 case ISD::EXPERIMENTAL_VP_REVERSE:
1213 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1222void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1231 DL,
Ptr.getValueType(),
1232 APInt(
Ptr.getValueSizeInBits().getFixedValue(), IncrementSize));
1234 Flags.setNoUnsignedWrap(
true);
1236 *ScaledOffset += IncrementSize;
1240 MPI =
N->getPointerInfo().getWithOffset(IncrementSize);
1246std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1247 return SplitMask(Mask,
SDLoc(Mask));
1250std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1253 EVT MaskVT =
Mask.getValueType();
1255 GetSplitVector(Mask, MaskLo, MaskHi);
1258 return std::make_pair(MaskLo, MaskHi);
1263 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1265 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1269 unsigned Opcode =
N->getOpcode();
1270 if (
N->getNumOperands() == 2) {
1276 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1277 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1280 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1283 std::tie(EVLLo, EVLHi) =
1284 DAG.
SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1287 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1289 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1295 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1297 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1299 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1303 unsigned Opcode =
N->getOpcode();
1304 if (
N->getNumOperands() == 3) {
1310 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1311 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1314 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1317 std::tie(EVLLo, EVLHi) =
1318 DAG.
SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1321 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1323 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1328 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1330 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1334 unsigned Opcode =
N->getOpcode();
1353 switch (getTypeAction(InVT)) {
1368 GetExpandedOp(InOp,
Lo,
Hi);
1379 GetSplitVector(InOp,
Lo,
Hi);
1393 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1416 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1418 unsigned NumSubvectors =
N->getNumOperands() / 2;
1419 if (NumSubvectors == 1) {
1420 Lo =
N->getOperand(0);
1421 Hi =
N->getOperand(1);
1435void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1445 uint64_t IdxVal = cast<ConstantSDNode>(
Idx)->getZExtValue();
1457 GetSplitVector(Vec,
Lo,
Hi);
1460 EVT LoVT =
Lo.getValueType();
1469 unsigned IdxVal = cast<ConstantSDNode>(
Idx)->getZExtValue();
1470 if (IdxVal + SubElems <= LoElems) {
1478 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1504 Lo = DAG.
getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1508 auto *
Load = cast<LoadSDNode>(
Lo);
1510 IncrementPointer(Load, LoVT, MPI, StackPtr);
1513 Hi = DAG.
getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1522 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1527 EVT RHSVT =
RHS.getValueType();
1530 GetSplitVector(RHS, RHSLo, RHSHi);
1547 SDValue FpValue =
N->getOperand(0);
1549 GetSplitVector(FpValue, ArgLo, ArgHi);
1562 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1566 std::tie(LoVT, HiVT) =
1577 unsigned Opcode =
N->getOpcode();
1584 GetSplitVector(N0, InLo, InHi);
1591 EVT OutLoVT, OutHiVT;
1594 assert((2 * OutNumElements) <= InNumElements &&
1595 "Illegal extend vector in reg split");
1605 for (
unsigned i = 0; i != OutNumElements; ++i)
1606 SplitHi[i] = i + OutNumElements;
1615 unsigned NumOps =
N->getNumOperands();
1629 for (
unsigned i = 1; i < NumOps; ++i) {
1634 EVT InVT =
Op.getValueType();
1639 GetSplitVector(
Op, OpLo, OpHi);
1648 EVT LoValueVTs[] = {LoVT, MVT::Other};
1649 EVT HiValueVTs[] = {HiVT, MVT::Other};
1658 Lo.getValue(1),
Hi.getValue(1));
1662 ReplaceValueWith(
SDValue(
N, 1), Chain);
1665SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
1667 EVT VT =
N->getValueType(0);
1678 else if (NE > ResNE)
1682 EVT ChainVTs[] = {EltVT, MVT::Other};
1686 for (i = 0; i !=
NE; ++i) {
1688 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
1689 SDValue Operand =
N->getOperand(j);
1700 Scalar.getNode()->setFlags(
N->getFlags());
1708 for (; i < ResNE; ++i)
1713 ReplaceValueWith(
SDValue(
N, 1), Chain);
1720void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
1723 EVT ResVT =
N->getValueType(0);
1724 EVT OvVT =
N->getValueType(1);
1725 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
1729 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
1731 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
1732 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
1738 unsigned Opcode =
N->getOpcode();
1750 unsigned OtherNo = 1 - ResNo;
1751 EVT OtherVT =
N->getValueType(OtherNo);
1753 SetSplitVector(
SDValue(
N, OtherNo),
1759 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
1763void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
1769 GetSplitVector(Vec,
Lo,
Hi);
1772 unsigned IdxVal = CIdx->getZExtValue();
1773 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
1774 if (IdxVal < LoNumElts) {
1776 Lo.getValueType(),
Lo, Elt,
Idx);
1786 if (CustomLowerNode(
N,
N->getValueType(0),
true))
1827 Lo = DAG.
getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
1830 auto Load = cast<LoadSDNode>(
Lo);
1832 IncrementPointer(Load, LoVT, MPI, StackPtr);
1834 Hi = DAG.
getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
1838 if (LoVT !=
Lo.getValueType())
1840 if (HiVT !=
Hi.getValueType())
1848 assert(
N->getValueType(0).isScalableVector() &&
1849 "Only scalable vectors are supported for STEP_VECTOR");
1857 APInt StepVal = cast<ConstantSDNode>(Step)->getAPIntValue();
1872 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
1892 EVT MemoryVT =
LD->getMemoryVT();
1896 EVT LoMemVT, HiMemVT;
1903 ReplaceValueWith(
SDValue(LD, 1), NewChain);
1908 LD->getPointerInfo(), LoMemVT,
LD->getOriginalAlign(),
1912 IncrementPointer(LD, LoMemVT, MPI,
Ptr);
1915 HiMemVT,
LD->getOriginalAlign(), MMOFlags, AAInfo);
1924 ReplaceValueWith(
SDValue(LD, 1), Ch);
1929 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
1938 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
1939 Align Alignment =
LD->getOriginalAlign();
1942 EVT MemoryVT =
LD->getMemoryVT();
1944 EVT LoMemVT, HiMemVT;
1945 bool HiIsEmpty =
false;
1946 std::tie(LoMemVT, HiMemVT) =
1952 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1955 GetSplitVector(Mask, MaskLo, MaskHi);
1957 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, dl);
1962 std::tie(EVLLo, EVLHi) = DAG.
SplitEVL(EVL,
LD->getValueType(0), dl);
1970 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
1979 LD->isExpandingLoad());
1985 MPI =
LD->getPointerInfo().getWithOffset(
1990 LD->getAAInfo(),
LD->getRanges());
1993 Offset, MaskHi, EVLHi, HiMemVT, MMO,
1994 LD->isExpandingLoad());
2004 ReplaceValueWith(
SDValue(LD, 1), Ch);
2010 "Indexed VP strided load during type legalization!");
2012 "Unexpected indexed variable-length load offset");
2019 EVT LoMemVT, HiMemVT;
2020 bool HiIsEmpty =
false;
2021 std::tie(LoMemVT, HiMemVT) =
2027 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2030 GetSplitVector(Mask, LoMask, HiMask);
2036 std::tie(LoEVL, HiEVL) =
2074 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2085 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2098 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2107 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2110 GetSplitVector(Mask, MaskLo, MaskHi);
2112 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, dl);
2116 EVT LoMemVT, HiMemVT;
2117 bool HiIsEmpty =
false;
2118 std::tie(LoMemVT, HiMemVT) =
2121 SDValue PassThruLo, PassThruHi;
2123 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2125 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, dl);
2168 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2185 if (
auto *MSC = dyn_cast<MaskedGatherSDNode>(
N)) {
2186 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2188 auto *VPSC = cast<VPGatherSDNode>(
N);
2189 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2192 EVT MemoryVT =
N->getMemoryVT();
2193 Align Alignment =
N->getOriginalAlign();
2197 if (SplitSETCC && Ops.Mask.getOpcode() ==
ISD::SETCC) {
2198 SplitVecRes_SETCC(Ops.Mask.getNode(), MaskLo, MaskHi);
2200 std::tie(MaskLo, MaskHi) = SplitMask(Ops.Mask, dl);
2203 EVT LoMemVT, HiMemVT;
2208 if (getTypeAction(Ops.Index.getValueType()) ==
2210 GetSplitVector(Ops.Index, IndexLo, IndexHi);
2212 std::tie(IndexLo, IndexHi) = DAG.
SplitVector(Ops.Index, dl);
2218 if (
auto *MGT = dyn_cast<MaskedGatherSDNode>(
N)) {
2219 SDValue PassThru = MGT->getPassThru();
2220 SDValue PassThruLo, PassThruHi;
2223 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2225 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, dl);
2230 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo,
Ptr, IndexLo, Ops.Scale};
2232 OpsLo, MMO, IndexTy, ExtType);
2234 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi,
Ptr, IndexHi, Ops.Scale};
2236 OpsHi, MMO, IndexTy, ExtType);
2238 auto *VPGT = cast<VPGatherSDNode>(
N);
2240 std::tie(EVLLo, EVLHi) =
2241 DAG.
SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2243 SDValue OpsLo[] = {Ch,
Ptr, IndexLo, Ops.Scale, MaskLo, EVLLo};
2245 MMO, VPGT->getIndexType());
2247 SDValue OpsHi[] = {Ch,
Ptr, IndexHi, Ops.Scale, MaskHi, EVLHi};
2249 MMO, VPGT->getIndexType());
2259 ReplaceValueWith(
SDValue(
N, 1), Ch);
2263 assert(
N->getValueType(0).isVector() &&
2264 N->getOperand(0).getValueType().isVector() &&
2265 "Operand types must be vectors");
2273 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2275 GetSplitVector(
N->getOperand(0), LL, LH);
2279 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2281 GetSplitVector(
N->getOperand(1), RL, RH);
2286 Lo = DAG.
getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2287 Hi = DAG.
getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2289 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2290 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2291 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2292 std::tie(EVLLo, EVLHi) =
2293 DAG.
SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2294 Lo = DAG.
getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2296 Hi = DAG.
getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2310 EVT InVT =
N->getOperand(0).getValueType();
2312 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2317 unsigned Opcode =
N->getOpcode();
2318 if (
N->getNumOperands() <= 2) {
2329 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2330 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2333 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2336 std::tie(EVLLo, EVLHi) =
2337 DAG.
SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2343void DAGTypeLegalizer::SplitVecRes_FFREXP(
SDNode *
N,
unsigned ResNo,
2351 EVT InVT =
N->getOperand(0).getValueType();
2353 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2357 Lo = DAG.
getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo);
2358 Hi = DAG.
getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi);
2359 Lo->setFlags(
N->getFlags());
2360 Hi->setFlags(
N->getFlags());
2366 unsigned OtherNo = 1 - ResNo;
2367 EVT OtherVT =
N->getValueType(OtherNo);
2375 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2382 EVT SrcVT =
N->getOperand(0).getValueType();
2383 EVT DestVT =
N->getValueType(0);
2406 EVT SplitLoVT, SplitHiVT;
2410 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2411 N->dump(&DAG);
dbgs() <<
"\n");
2412 if (!
N->isVPOpcode()) {
2415 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2426 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2427 N->getOperand(1),
N->getOperand(2));
2432 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2435 std::tie(EVLLo, EVLHi) =
2436 DAG.
SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2438 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2439 Hi = DAG.
getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2444 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2452 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2453 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2459 return N.getResNo() == 0 &&
2463 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2468 "Expected build vector node.");
2471 for (
unsigned I = 0;
I < NewElts; ++
I) {
2476 Ops[
I] = Input2.getOperand(
Idx - NewElts);
2478 Ops[
I] = Input1.getOperand(
Idx);
2480 if (Ops[
I].getValueType().bitsGT(EltVT))
2483 return DAG.getBuildVector(NewVT,
DL, Ops);
2491 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2495 for (
unsigned Idx = 0;
Idx < std::size(Inputs); ++
Idx) {
2497 auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Input.
getNode());
2506 for (
auto &
P : ShufflesIdxs) {
2507 if (
P.second.size() < 2)
2511 for (
int &
Idx : Mask) {
2514 unsigned SrcRegIdx =
Idx / NewElts;
2515 if (Inputs[SrcRegIdx].
isUndef()) {
2520 dyn_cast<ShuffleVectorSDNode>(Inputs[SrcRegIdx].getNode());
2523 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2528 Idx = MaskElt % NewElts +
2529 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
2535 Inputs[
P.second[0]] =
P.first.first;
2536 Inputs[
P.second[1]] =
P.first.second;
2539 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
2543 for (
int &
Idx : Mask) {
2546 unsigned SrcRegIdx =
Idx / NewElts;
2547 if (Inputs[SrcRegIdx].
isUndef()) {
2552 getTypeAction(Inputs[SrcRegIdx].getValueType());
2554 Inputs[SrcRegIdx].getNumOperands() == 2 &&
2555 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
2558 UsedSubVector.set(2 * SrcRegIdx + (
Idx % NewElts) / (NewElts / 2));
2560 if (UsedSubVector.count() > 1) {
2562 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
2563 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
2565 if (Pairs.
empty() || Pairs.
back().size() == 2)
2567 if (UsedSubVector.test(2 *
I)) {
2568 Pairs.
back().emplace_back(
I, 0);
2570 assert(UsedSubVector.test(2 *
I + 1) &&
2571 "Expected to be used one of the subvectors.");
2572 Pairs.
back().emplace_back(
I, 1);
2575 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
2577 for (
int &
Idx : Mask) {
2580 unsigned SrcRegIdx =
Idx / NewElts;
2582 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
2583 return Idxs.front().first == SrcRegIdx ||
2584 Idxs.back().first == SrcRegIdx;
2586 if (It == Pairs.
end())
2588 Idx = It->front().first * NewElts + (
Idx % NewElts) % (NewElts / 2) +
2589 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
2592 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
2593 Inputs[Idxs.front().first] = DAG.
getNode(
2595 Inputs[Idxs.front().first].getValueType(),
2596 Inputs[Idxs.front().first].
getOperand(Idxs.front().second),
2597 Inputs[Idxs.back().first].
getOperand(Idxs.back().second));
2606 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
2607 auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Inputs[
I].getNode());
2610 if (Shuffle->getOperand(0).getValueType() != NewVT)
2613 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
2614 !Shuffle->isSplat()) {
2616 }
else if (!Inputs[
I].hasOneUse() &&
2617 !Shuffle->getOperand(1).isUndef()) {
2619 for (
int &
Idx : Mask) {
2622 unsigned SrcRegIdx =
Idx / NewElts;
2625 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2630 int OpIdx = MaskElt / NewElts;
2643 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
2644 if (Shuffle->getOperand(OpIdx).isUndef())
2646 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
2647 if (It == std::end(Inputs))
2649 int FoundOp = std::distance(std::begin(Inputs), It);
2652 for (
int &
Idx : Mask) {
2655 unsigned SrcRegIdx =
Idx / NewElts;
2658 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2663 int MaskIdx = MaskElt / NewElts;
2664 if (OpIdx == MaskIdx)
2665 Idx = MaskElt % NewElts + FoundOp * NewElts;
2668 Op = (OpIdx + 1) % 2;
2676 for (
int &
Idx : Mask) {
2679 unsigned SrcRegIdx =
Idx / NewElts;
2682 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2683 int OpIdx = MaskElt / NewElts;
2686 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
2692 TryPeekThroughShufflesInputs(OrigMask);
2694 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
2698 for (
const auto &
I : Inputs) {
2700 UniqueConstantInputs.
insert(
I);
2701 else if (!
I.isUndef())
2706 if (UniqueInputs.
size() != std::size(Inputs)) {
2707 auto &&UniqueVec = UniqueInputs.
takeVector();
2708 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
2709 unsigned ConstNum = UniqueConstantVec.size();
2710 for (
int &
Idx : Mask) {
2713 unsigned SrcRegIdx =
Idx / NewElts;
2714 if (Inputs[SrcRegIdx].
isUndef()) {
2718 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
2719 if (It != UniqueConstantVec.end()) {
2721 NewElts * std::distance(UniqueConstantVec.begin(), It);
2722 assert(
Idx >= 0 &&
"Expected defined mask idx.");
2725 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
2726 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
2728 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
2729 assert(
Idx >= 0 &&
"Expected defined mask idx.");
2731 copy(UniqueConstantVec, std::begin(Inputs));
2732 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
2735 MakeUniqueInputs(OrigMask);
2737 copy(Inputs, std::begin(OrigInputs));
2743 unsigned FirstMaskIdx =
High * NewElts;
2746 assert(!Output &&
"Expected default initialized initial value.");
2747 TryPeekThroughShufflesInputs(Mask);
2748 MakeUniqueInputs(Mask);
2750 copy(Inputs, std::begin(TmpInputs));
2753 bool SecondIteration =
false;
2754 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
2759 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) ==
Idx)
2760 SecondIteration =
true;
2761 return SecondIteration;
2764 Mask, std::size(Inputs), std::size(Inputs),
2766 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
2767 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
2770 Output = BuildVector(Inputs[
Idx], Inputs[
Idx], Mask);
2772 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[
Idx],
2773 DAG.getUNDEF(NewVT), Mask);
2774 Inputs[
Idx] = Output;
2776 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
2779 if (AccumulateResults(Idx1)) {
2782 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
2784 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
2785 Inputs[Idx2], Mask);
2789 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
2791 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
2792 TmpInputs[Idx2], Mask);
2794 Inputs[Idx1] = Output;
2796 copy(OrigInputs, std::begin(Inputs));
2801 EVT OVT =
N->getValueType(0);
2808 const Align Alignment =
2809 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
2811 Lo = DAG.getVAArg(NVT, dl, Chain,
Ptr, SV, Alignment.
value());
2812 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1),
Ptr, SV, Alignment.
value());
2813 Chain =
Hi.getValue(1);
2817 ReplaceValueWith(
SDValue(
N, 1), Chain);
2822 EVT DstVTLo, DstVTHi;
2823 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
2827 EVT SrcVT =
N->getOperand(0).getValueType();
2829 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
2831 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
2833 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
2834 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
2840 GetSplitVector(
N->getOperand(0), InLo, InHi);
2849 EVT VT =
N->getValueType(0);
2853 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2857 DAG.getVectorIdxConstant(0,
DL));
2865 EVT VT =
N->getValueType(0);
2872 Align Alignment = DAG.getReducedAlign(VT,
false);
2878 auto &MF = DAG.getMachineFunction();
2892 DAG.getConstant(1,
DL, PtrVT));
2894 DAG.getConstant(EltWidth,
DL, PtrVT));
2896 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
2898 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
2899 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
2900 DAG.getUNDEF(PtrVT), Stride, TrueMask,
2903 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
2905 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VT);
2907 DAG.getVectorIdxConstant(0,
DL));
2913void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
2915 SDValue Op0Lo, Op0Hi, Op1Lo, Op1Hi;
2916 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
2917 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
2921 DAG.getVTList(VT, VT), Op0Lo, Op0Hi);
2923 DAG.getVTList(VT, VT), Op1Lo, Op1Hi);
2929void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
2930 SDValue Op0Lo, Op0Hi, Op1Lo, Op1Hi;
2931 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
2932 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
2936 DAG.getVTList(VT, VT), Op0Lo, Op1Lo),
2938 DAG.getVTList(VT, VT), Op0Hi, Op1Hi)};
2940 SetSplitVector(
SDValue(
N, 0), Res[0].getValue(0), Res[0].getValue(1));
2941 SetSplitVector(
SDValue(
N, 1), Res[1].getValue(0), Res[1].getValue(1));
2952bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
2957 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2960 switch (
N->getOpcode()) {
2963 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
2971 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
2977 case ISD::VP_TRUNCATE:
2979 Res = SplitVecOp_TruncateHelper(
N);
2982 case ISD::VP_FP_ROUND:
2986 Res = SplitVecOp_STORE(cast<StoreSDNode>(
N), OpNo);
2989 Res = SplitVecOp_VP_STORE(cast<VPStoreSDNode>(
N), OpNo);
2991 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2992 Res = SplitVecOp_VP_STRIDED_STORE(cast<VPStridedStoreSDNode>(
N), OpNo);
2995 Res = SplitVecOp_MSTORE(cast<MaskedStoreSDNode>(
N), OpNo);
2998 case ISD::VP_SCATTER:
2999 Res = SplitVecOp_Scatter(cast<MemSDNode>(
N), OpNo);
3002 case ISD::VP_GATHER:
3003 Res = SplitVecOp_Gather(cast<MemSDNode>(
N), OpNo);
3006 Res = SplitVecOp_VSELECT(
N, OpNo);
3012 case ISD::VP_SINT_TO_FP:
3013 case ISD::VP_UINT_TO_FP:
3014 if (
N->getValueType(0).bitsLT(
3015 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3016 Res = SplitVecOp_TruncateHelper(
N);
3018 Res = SplitVecOp_UnaryOp(
N);
3022 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3026 case ISD::VP_FP_TO_SINT:
3027 case ISD::VP_FP_TO_UINT:
3038 Res = SplitVecOp_UnaryOp(
N);
3041 Res = SplitVecOp_FPOpDifferentTypes(
N);
3047 Res = SplitVecOp_ExtVecInRegOp(
N);
3065 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3069 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3071 case ISD::VP_REDUCE_FADD:
3072 case ISD::VP_REDUCE_SEQ_FADD:
3073 case ISD::VP_REDUCE_FMUL:
3074 case ISD::VP_REDUCE_SEQ_FMUL:
3075 case ISD::VP_REDUCE_ADD:
3076 case ISD::VP_REDUCE_MUL:
3077 case ISD::VP_REDUCE_AND:
3078 case ISD::VP_REDUCE_OR:
3079 case ISD::VP_REDUCE_XOR:
3080 case ISD::VP_REDUCE_SMAX:
3081 case ISD::VP_REDUCE_SMIN:
3082 case ISD::VP_REDUCE_UMAX:
3083 case ISD::VP_REDUCE_UMIN:
3084 case ISD::VP_REDUCE_FMAX:
3085 case ISD::VP_REDUCE_FMIN:
3086 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3091 if (!Res.
getNode())
return false;
3098 if (
N->isStrictFPOpcode())
3100 "Invalid operand expansion");
3103 "Invalid operand expansion");
3105 ReplaceValueWith(
SDValue(
N, 0), Res);
3109SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3112 assert(OpNo == 0 &&
"Illegal operand must be mask");
3119 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3122 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3123 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3124 "Lo and Hi have differing types");
3127 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3128 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3130 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3131 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3132 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3133 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3143SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3144 EVT ResVT =
N->getValueType(0);
3148 SDValue VecOp =
N->getOperand(OpNo);
3150 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3151 GetSplitVector(VecOp,
Lo,
Hi);
3153 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3159 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3163 EVT ResVT =
N->getValueType(0);
3172 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3173 GetSplitVector(VecOp,
Lo,
Hi);
3175 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3181 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3184SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3185 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3186 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3188 unsigned Opc =
N->getOpcode();
3189 EVT ResVT =
N->getValueType(0);
3193 SDValue VecOp =
N->getOperand(OpNo);
3195 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3196 GetSplitVector(VecOp,
Lo,
Hi);
3199 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3202 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3207 DAG.
getNode(Opc, dl, ResVT, {
N->getOperand(0),
Lo, MaskLo, EVLLo},
Flags);
3208 return DAG.getNode(Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3213 EVT ResVT =
N->getValueType(0);
3216 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3217 EVT InVT =
Lo.getValueType();
3222 if (
N->isStrictFPOpcode()) {
3223 Lo = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3224 { N->getOperand(0), Lo });
3225 Hi = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3226 { N->getOperand(0), Hi });
3235 ReplaceValueWith(
SDValue(
N, 1), Ch);
3236 }
else if (
N->getNumOperands() == 3) {
3237 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3238 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3239 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3240 std::tie(EVLLo, EVLHi) =
3241 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3242 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3243 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3245 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3246 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3257 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3258 Lo = BitConvertToInteger(
Lo);
3259 Hi = BitConvertToInteger(
Hi);
3261 if (DAG.getDataLayout().isBigEndian())
3265 JoinIntegers(
Lo,
Hi));
3270 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3272 EVT ResVT =
N->getValueType(0);
3280 GetSplitVector(SubVec,
Lo,
Hi);
3282 uint64_t IdxVal = cast<ConstantSDNode>(
Idx)->getZExtValue();
3283 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
3289 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3291 return SecondInsertion;
3294SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3296 EVT SubVT =
N->getValueType(0);
3301 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3303 uint64_t LoEltsMin =
Lo.getValueType().getVectorMinNumElements();
3304 uint64_t IdxVal = cast<ConstantSDNode>(
Idx)->getZExtValue();
3306 if (IdxVal < LoEltsMin) {
3308 "Extracted subvector crosses vector split!");
3311 N->getOperand(0).getValueType().isScalableVector())
3313 DAG.getVectorIdxConstant(IdxVal - LoEltsMin, dl));
3318 "Extracting scalable subvector from fixed-width unsupported");
3326 "subvector from a scalable predicate vector");
3332 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
3334 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
3335 auto &MF = DAG.getMachineFunction();
3339 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
3346 SubVT, dl, Store, StackPtr,
3350SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
3359 GetSplitVector(Vec,
Lo,
Hi);
3361 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
3363 if (IdxVal < LoElts)
3367 DAG.getConstant(IdxVal - LoElts,
SDLoc(
N),
3368 Idx.getValueType())), 0);
3372 if (CustomLowerNode(
N,
N->getValueType(0),
true))
3388 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
3390 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
3391 auto &MF = DAG.getMachineFunction();
3394 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
3402 if (
N->getValueType(0).bitsLT(EltVT)) {
3403 SDValue Load = DAG.getLoad(EltVT, dl, Store, StackPtr,
3405 return DAG.getZExtOrTrunc(Load, dl,
N->getValueType(0));
3408 return DAG.getExtLoad(
3419 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
3427 SplitVecRes_Gather(
N,
Lo,
Hi);
3430 ReplaceValueWith(
SDValue(
N, 0), Res);
3435 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
3439 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
3441 SDValue EVL =
N->getVectorLength();
3443 Align Alignment =
N->getOriginalAlign();
3449 GetSplitVector(
Data, DataLo, DataHi);
3451 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
3456 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
3459 GetSplitVector(Mask, MaskLo, MaskHi);
3461 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
3464 EVT MemoryVT =
N->getMemoryVT();
3465 EVT LoMemVT, HiMemVT;
3466 bool HiIsEmpty =
false;
3467 std::tie(LoMemVT, HiMemVT) =
3468 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
3472 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
3479 Lo = DAG.getStoreVP(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
3480 N->getAddressingMode(),
N->isTruncatingStore(),
3481 N->isCompressingStore());
3488 N->isCompressingStore());
3496 MPI =
N->getPointerInfo().getWithOffset(
3499 MMO = DAG.getMachineFunction().getMachineMemOperand(
3501 N->getAAInfo(),
N->getRanges());
3503 Hi = DAG.getStoreVP(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
3504 N->getAddressingMode(),
N->isTruncatingStore(),
3505 N->isCompressingStore());
3514 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
3515 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
3522 GetSplitVector(
Data, LoData, HiData);
3524 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
3526 EVT LoMemVT, HiMemVT;
3527 bool HiIsEmpty =
false;
3528 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
3534 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
3535 else if (getTypeAction(
Mask.getValueType()) ==
3537 GetSplitVector(Mask, LoMask, HiMask);
3539 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3542 std::tie(LoEVL, HiEVL) =
3543 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
3547 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
3548 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
3549 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
3560 EVT PtrVT =
N->getBasePtr().getValueType();
3563 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
3566 Align Alignment =
N->getOriginalAlign();
3574 N->getAAInfo(),
N->getRanges());
3577 N->getChain(),
DL, HiData,
Ptr,
N->getOffset(),
N->getStride(), HiMask,
3578 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
3579 N->isCompressingStore());
3588 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
3592 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
3595 Align Alignment =
N->getOriginalAlign();
3601 GetSplitVector(
Data, DataLo, DataHi);
3603 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
3608 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
3611 GetSplitVector(Mask, MaskLo, MaskHi);
3613 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
3616 EVT MemoryVT =
N->getMemoryVT();
3617 EVT LoMemVT, HiMemVT;
3618 bool HiIsEmpty =
false;
3619 std::tie(LoMemVT, HiMemVT) =
3620 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
3627 Lo = DAG.getMaskedStore(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, LoMemVT, MMO,
3628 N->getAddressingMode(),
N->isTruncatingStore(),
3629 N->isCompressingStore());
3638 N->isCompressingStore());
3646 MPI =
N->getPointerInfo().getWithOffset(
3649 MMO = DAG.getMachineFunction().getMachineMemOperand(
3651 N->getAAInfo(),
N->getRanges());
3653 Hi = DAG.getMaskedStore(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, HiMemVT, MMO,
3654 N->getAddressingMode(),
N->isTruncatingStore(),
3655 N->isCompressingStore());
3668 EVT MemoryVT =
N->getMemoryVT();
3669 Align Alignment =
N->getOriginalAlign();
3677 if (
auto *MSC = dyn_cast<MaskedScatterSDNode>(
N)) {
3678 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
3681 auto *VPSC = cast<VPScatterSDNode>(
N);
3682 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
3687 EVT LoMemVT, HiMemVT;
3688 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
3693 GetSplitVector(Ops.Data, DataLo, DataHi);
3695 std::tie(DataLo, DataHi) = DAG.SplitVector(Ops.Data,
DL);
3699 if (OpNo == 1 && Ops.Mask.getOpcode() ==
ISD::SETCC) {
3700 SplitVecRes_SETCC(Ops.Mask.getNode(), MaskLo, MaskHi);
3702 std::tie(MaskLo, MaskHi) = SplitMask(Ops.Mask,
DL);
3706 if (getTypeAction(Ops.Index.getValueType()) ==
3708 GetSplitVector(Ops.Index, IndexLo, IndexHi);
3710 std::tie(IndexLo, IndexHi) = DAG.SplitVector(Ops.Index,
DL);
3717 if (
auto *MSC = dyn_cast<MaskedScatterSDNode>(
N)) {
3718 SDValue OpsLo[] = {Ch, DataLo, MaskLo,
Ptr, IndexLo, Ops.Scale};
3720 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
3721 MSC->getIndexType(), MSC->isTruncatingStore());
3726 SDValue OpsHi[] = {
Lo, DataHi, MaskHi,
Ptr, IndexHi, Ops.Scale};
3727 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
3728 MMO, MSC->getIndexType(),
3729 MSC->isTruncatingStore());
3731 auto *VPSC = cast<VPScatterSDNode>(
N);
3733 std::tie(EVLLo, EVLHi) =
3734 DAG.SplitEVL(VPSC->getVectorLength(), Ops.Data.getValueType(),
DL);
3736 SDValue OpsLo[] = {Ch, DataLo,
Ptr, IndexLo, Ops.Scale, MaskLo, EVLLo};
3737 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
3738 VPSC->getIndexType());
3743 SDValue OpsHi[] = {
Lo, DataHi,
Ptr, IndexHi, Ops.Scale, MaskHi, EVLHi};
3744 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
3745 VPSC->getIndexType());
3749 assert(
N->isUnindexed() &&
"Indexed store of vector?");
3750 assert(OpNo == 1 &&
"Can only split the stored value");
3753 bool isTruncating =
N->isTruncatingStore();
3756 EVT MemoryVT =
N->getMemoryVT();
3757 Align Alignment =
N->getOriginalAlign();
3761 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3763 EVT LoMemVT, HiMemVT;
3764 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
3771 Lo = DAG.getTruncStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), LoMemVT,
3772 Alignment, MMOFlags, AAInfo);
3774 Lo = DAG.getStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
3778 IncrementPointer(
N, LoMemVT, MPI,
Ptr);
3781 Hi = DAG.getTruncStore(Ch,
DL,
Hi,
Ptr, MPI,
3782 HiMemVT, Alignment, MMOFlags, AAInfo);
3784 Hi = DAG.getStore(Ch,
DL,
Hi,
Ptr, MPI, Alignment, MMOFlags, AAInfo);
3798 EVT EltVT =
N->getValueType(0).getVectorElementType();
3800 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
3803 DAG.getVectorIdxConstant(i,
DL)));
3807 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
3828 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
3829 SDValue InVec =
N->getOperand(OpNo);
3831 EVT OutVT =
N->getValueType(0);
3839 EVT LoOutVT, HiOutVT;
3840 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
3841 assert(LoOutVT == HiOutVT &&
"Unequal split?");
3846 if (isTypeLegal(LoOutVT) ||
3847 InElementSize <= OutElementSize * 2)
3848 return SplitVecOp_UnaryOp(
N);
3857 return SplitVecOp_UnaryOp(
N);
3861 GetSplitVector(InVec, InLoVec, InHiVec);
3867 EVT HalfElementVT = IsFloat ?
3869 EVT::getIntegerVT(*DAG.getContext(), InElementSize/2);
3876 if (
N->isStrictFPOpcode()) {
3877 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
3878 {N->getOperand(0), InLoVec});
3879 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
3880 {N->getOperand(0), InHiVec});
3886 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
3887 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
3899 if (
N->isStrictFPOpcode()) {
3903 DAG.getTargetConstant(0,
DL, TLI.
getPointerTy(DAG.getDataLayout()))});
3911 DAG.getTargetConstant(
3917 assert(
N->getValueType(0).isVector() &&
3918 N->getOperand(0).getValueType().isVector() &&
3919 "Operand types must be vectors");
3921 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
3923 GetSplitVector(
N->getOperand(0), Lo0, Hi0);
3924 GetSplitVector(
N->getOperand(1), Lo1, Hi1);
3935 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
3936 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3937 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
3938 std::tie(EVLLo, EVLHi) =
3939 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
3940 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
3941 N->getOperand(2), MaskLo, EVLLo);
3942 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
3943 N->getOperand(2), MaskHi, EVLHi);
3947 EVT OpVT =
N->getOperand(0).getValueType();
3950 return DAG.getNode(ExtendCode,
DL,
N->getValueType(0), Con);
3956 EVT ResVT =
N->getValueType(0);
3959 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3960 EVT InVT =
Lo.getValueType();
3965 if (
N->isStrictFPOpcode()) {
3966 Lo = DAG.getNode(
N->getOpcode(),
DL, { OutVT, MVT::Other },
3967 { N->getOperand(0), Lo, N->getOperand(2) });
3968 Hi = DAG.getNode(
N->getOpcode(),
DL, { OutVT, MVT::Other },
3969 { N->getOperand(0), Hi, N->getOperand(2) });
3973 Lo.getValue(1),
Hi.getValue(1));
3974 ReplaceValueWith(
SDValue(
N, 1), NewChain);
3975 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
3976 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3977 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3978 std::tie(EVLLo, EVLHi) =
3979 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
3980 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
3981 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
3995SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
3998 EVT LHSLoVT, LHSHiVT;
3999 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4001 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4002 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4005 std::tie(LHSLo, LHSHi) =
4006 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4009 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4011 SDValue Lo = DAG.getNode(
N->getOpcode(),
DL, LHSLoVT, LHSLo, RHSLo);
4012 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4018 EVT ResVT =
N->getValueType(0);
4021 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4022 EVT InVT =
Lo.getValueType();
4028 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4029 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4038void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4039 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4042 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4047 auto unrollExpandedOp = [&]() {
4052 EVT VT =
N->getValueType(0);
4062 switch (
N->getOpcode()) {
4065 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4077 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4081 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4085 Res = WidenVecRes_ScalarOp(
N);
4090 case ISD::VP_SELECT:
4092 Res = WidenVecRes_Select(
N);
4096 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4097 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4099 Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(
N));
4102 Res = WidenVecRes_VP_LOAD(cast<VPLoadSDNode>(
N));
4104 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4105 Res = WidenVecRes_VP_STRIDED_LOAD(cast<VPStridedLoadSDNode>(
N));
4108 Res = WidenVecRes_MLOAD(cast<MaskedLoadSDNode>(
N));
4111 Res = WidenVecRes_MGATHER(cast<MaskedGatherSDNode>(