35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
46 switch (
N->getOpcode()) {
49 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
61 case ISD::FPOWI: R = ScalarizeVecRes_ExpOp(
N);
break;
63 case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(
N));
break;
69 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
70 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
76 R = ScalarizeVecRes_VecInregOp(
N);
127 R = ScalarizeVecRes_UnaryOp(
N);
130 R = ScalarizeVecRes_ADDRSPACECAST(
N);
133 R = ScalarizeVecRes_FFREXP(
N, ResNo);
184 R = ScalarizeVecRes_BinOp(
N);
189 R = ScalarizeVecRes_CMP(
N);
195 R = ScalarizeVecRes_TernaryOp(
N);
198#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
199 case ISD::STRICT_##DAGN:
200#include "llvm/IR/ConstrainedOps.def"
201 R = ScalarizeVecRes_StrictFPOp(
N);
206 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
215 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
225 R = ScalarizeVecRes_FIX(
N);
231 SetScalarizedVector(
SDValue(
N, ResNo), R);
235 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
236 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
238 LHS.getValueType(), LHS, RHS,
N->getFlags());
246 if (getTypeAction(
LHS.getValueType()) ==
248 LHS = GetScalarizedVector(LHS);
249 RHS = GetScalarizedVector(RHS);
251 EVT VT =
LHS.getValueType().getVectorElementType();
259 N->getValueType(0).getVectorElementType(), LHS, RHS);
263 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
264 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
265 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
271 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
272 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
278SDValue DAGTypeLegalizer::ScalarizeVecRes_FFREXP(
SDNode *
N,
unsigned ResNo) {
279 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
280 "Unexpected vector type!");
281 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
283 EVT VT0 =
N->getValueType(0);
284 EVT VT1 =
N->getValueType(1);
289 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
293 unsigned OtherNo = 1 - ResNo;
294 EVT OtherVT =
N->getValueType(OtherNo);
296 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
300 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
303 return SDValue(ScalarNode, ResNo);
307 EVT VT =
N->getValueType(0).getVectorElementType();
308 unsigned NumOpers =
N->getNumOperands();
310 EVT ValueVTs[] = {VT, MVT::Other};
319 for (
unsigned i = 1; i < NumOpers; ++i) {
325 Oper = GetScalarizedVector(Oper);
336 Opers,
N->getFlags());
347 EVT ResVT =
N->getValueType(0);
348 EVT OvVT =
N->getValueType(1);
352 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
353 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
358 ScalarLHS = ElemsLHS[0];
359 ScalarRHS = ElemsRHS[0];
365 N->getOpcode(),
DL, ScalarVTs, ScalarLHS, ScalarRHS).
getNode();
369 unsigned OtherNo = 1 - ResNo;
370 EVT OtherVT =
N->getValueType(OtherNo);
372 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
376 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
379 return SDValue(ScalarNode, ResNo);
384 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
385 return GetScalarizedVector(
Op);
390 if (
Op.getValueType().isVector()
391 &&
Op.getValueType().getVectorNumElements() == 1
392 && !isSimpleLegalType(
Op.getValueType()))
393 Op = GetScalarizedVector(
Op);
394 EVT NewVT =
N->getValueType(0).getVectorElementType();
399SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
400 EVT EltVT =
N->getValueType(0).getVectorElementType();
409SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
411 N->getValueType(0).getVectorElementType(),
412 N->getOperand(0),
N->getOperand(1));
418 EVT OpVT =
Op.getValueType();
422 Op = GetScalarizedVector(
Op);
429 N->getValueType(0).getVectorElementType(),
Op,
434 SDValue Op = GetScalarizedVector(
N->getOperand(0));
439SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
443 EVT EltVT =
N->getValueType(0).getVectorElementType();
444 if (
Op.getValueType() != EltVT)
451 assert(
N->isUnindexed() &&
"Indexed vector load?");
455 N->getValueType(0).getVectorElementType(),
SDLoc(
N),
N->getChain(),
456 N->getBasePtr(), DAG.
getUNDEF(
N->getBasePtr().getValueType()),
457 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
458 N->getOriginalAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
468 EVT DestVT =
N->getValueType(0).getVectorElementType();
470 EVT OpVT =
Op.getValueType();
480 Op = GetScalarizedVector(
Op);
490 EVT EltVT =
N->getValueType(0).getVectorElementType();
492 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
501 EVT OpVT =
Op.getValueType();
503 EVT EltVT =
N->getValueType(0).getVectorElementType();
506 Op = GetScalarizedVector(
Op);
512 switch (
N->getOpcode()) {
524SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
525 EVT DestVT =
N->getValueType(0).getVectorElementType();
527 EVT OpVT =
Op.getValueType();
537 Op = GetScalarizedVector(
Op);
543 auto *AddrSpaceCastN = cast<AddrSpaceCastSDNode>(
N);
544 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
545 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
549SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
552 EVT EltVT =
N->getValueType(0).getVectorElementType();
561 EVT OpVT =
Cond.getValueType();
574 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
588 EVT OpVT =
Cond->getOperand(0).getValueType();
595 EVT CondVT =
Cond.getValueType();
596 if (ScalarBool != VecBool) {
597 switch (ScalarBool) {
618 auto BoolVT = getSetCCResultType(CondVT);
619 if (BoolVT.bitsLT(CondVT))
624 GetScalarizedVector(
N->getOperand(2)));
628 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
630 LHS.getValueType(),
N->getOperand(0), LHS,
631 GetScalarizedVector(
N->getOperand(2)));
635 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
637 N->getOperand(0),
N->getOperand(1),
638 LHS, GetScalarizedVector(
N->getOperand(3)),
643 return DAG.
getUNDEF(
N->getValueType(0).getVectorElementType());
646SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
648 SDValue Arg =
N->getOperand(2).getOperand(0);
650 return DAG.
getUNDEF(
N->getValueType(0).getVectorElementType());
651 unsigned Op = !cast<ConstantSDNode>(Arg)->isZero();
652 return GetScalarizedVector(
N->getOperand(
Op));
655SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
657 EVT SrcVT = Src.getValueType();
662 Src = GetScalarizedVector(Src);
668 EVT DstVT =
N->getValueType(0).getVectorElementType();
669 return DAG.
getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
673 assert(
N->getValueType(0).isVector() &&
674 N->getOperand(0).getValueType().isVector() &&
675 "Operand types must be vectors");
678 EVT OpVT =
LHS.getValueType();
679 EVT NVT =
N->getValueType(0).getVectorElementType();
684 LHS = GetScalarizedVector(LHS);
685 RHS = GetScalarizedVector(RHS);
701 return DAG.
getNode(ExtendCode,
DL, NVT, Res);
709 EVT ResultVT =
N->getValueType(0).getVectorElementType();
712 Arg = GetScalarizedVector(Arg);
725 return DAG.
getNode(ExtendCode,
DL, ResultVT, Res);
732bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
737 switch (
N->getOpcode()) {
740 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
747 Res = ScalarizeVecOp_BITCAST(
N);
761 Res = ScalarizeVecOp_UnaryOp(
N);
767 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
770 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
773 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
776 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
779 Res = ScalarizeVecOp_VSELECT(
N);
782 Res = ScalarizeVecOp_VSETCC(
N);
785 Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(
N), OpNo);
788 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
791 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
794 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
797 Res = ScalarizeVecOp_FP_EXTEND(
N);
814 Res = ScalarizeVecOp_VECREDUCE(
N);
818 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
822 Res = ScalarizeVecOp_CMP(
N);
827 if (!Res.
getNode())
return false;
835 "Invalid operand expansion");
837 ReplaceValueWith(
SDValue(
N, 0), Res);
844 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
846 N->getValueType(0), Elt);
852 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
853 "Unexpected vector type!");
854 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
856 N->getValueType(0).getScalarType(), Elt);
864SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
865 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
866 "Unexpected vector type!");
867 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
869 {
N->getValueType(0).getScalarType(), MVT::Other },
870 {
N->getOperand(0), Elt });
880 ReplaceValueWith(
SDValue(
N, 0), Res);
885SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
887 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
888 Ops[i] = GetScalarizedVector(
N->getOperand(i));
894SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
898 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
899 SDValue ContainingVec =
N->getOperand(0);
907SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
908 EVT VT =
N->getValueType(0);
909 SDValue Res = GetScalarizedVector(
N->getOperand(0));
921 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
922 EVT VT =
N->getValueType(0);
932 assert(
N->getValueType(0).isVector() &&
933 N->getOperand(0).getValueType().isVector() &&
934 "Operand types must be vectors");
935 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
937 EVT VT =
N->getValueType(0);
938 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
939 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
941 EVT OpVT =
N->getOperand(0).getValueType();
953 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
961 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
962 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
965 if (
N->isTruncatingStore())
967 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
968 N->getBasePtr(),
N->getPointerInfo(),
969 N->getMemoryVT().getVectorElementType(),
N->getOriginalAlign(),
970 N->getMemOperand()->getFlags(),
N->getAAInfo());
972 return DAG.
getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
973 N->getBasePtr(),
N->getPointerInfo(),
974 N->getOriginalAlign(),
N->getMemOperand()->getFlags(),
980SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
981 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
982 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
984 N->getValueType(0).getVectorElementType(), Elt,
989SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
991 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
992 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
996 {
N->getOperand(0), Elt,
N->getOperand(2) });
1005 ReplaceValueWith(
SDValue(
N, 0), Res);
1012 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1014 N->getValueType(0).getVectorElementType(), Elt);
1020SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1021 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1025 {
N->getOperand(0), Elt});
1034 ReplaceValueWith(
SDValue(
N, 0), Res);
1039 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1046SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1052 SDValue Op = GetScalarizedVector(VecOp);
1054 AccOp,
Op,
N->getFlags());
1058 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1059 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1061 EVT ResVT =
N->getValueType(0).getVectorElementType();
1074void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1079 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1082 switch (
N->getOpcode()) {
1085 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1097 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1110 case ISD::EXPERIMENTAL_VP_SPLAT: SplitVecRes_VP_SPLAT(
N,
Lo,
Hi);
break;
1113 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1116 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1120 SplitVecRes_LOAD(cast<LoadSDNode>(
N),
Lo,
Hi);
1123 SplitVecRes_VP_LOAD(cast<VPLoadSDNode>(
N),
Lo,
Hi);
1125 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1126 SplitVecRes_VP_STRIDED_LOAD(cast<VPStridedLoadSDNode>(
N),
Lo,
Hi);
1129 SplitVecRes_MLOAD(cast<MaskedLoadSDNode>(
N),
Lo,
Hi);
1132 case ISD::VP_GATHER:
1133 SplitVecRes_Gather(cast<MemSDNode>(
N),
Lo,
Hi,
true);
1136 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1140 SplitVecRes_SETCC(
N,
Lo,
Hi);
1143 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1146 SplitVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(
N),
Lo,
Hi);
1149 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1152 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1155 SplitVecRes_VECTOR_INTERLEAVE(
N);
1158 SplitVecRes_VAARG(
N,
Lo,
Hi);
1164 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1170 case ISD::VP_BITREVERSE:
1178 case ISD::VP_CTLZ_ZERO_UNDEF:
1180 case ISD::VP_CTTZ_ZERO_UNDEF:
1195 case ISD::VP_FFLOOR:
1200 case ISD::VP_FNEARBYINT:
1205 case ISD::VP_FP_EXTEND:
1207 case ISD::VP_FP_ROUND:
1209 case ISD::VP_FP_TO_SINT:
1211 case ISD::VP_FP_TO_UINT:
1217 case ISD::VP_LLRINT:
1219 case ISD::VP_FROUND:
1221 case ISD::VP_FROUNDEVEN:
1230 case ISD::VP_FROUNDTOZERO:
1232 case ISD::VP_SINT_TO_FP:
1234 case ISD::VP_TRUNCATE:
1236 case ISD::VP_UINT_TO_FP:
1238 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1241 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1244 SplitVecRes_FFREXP(
N, ResNo,
Lo,
Hi);
1250 case ISD::VP_SIGN_EXTEND:
1251 case ISD::VP_ZERO_EXTEND:
1252 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1271 case ISD::VP_FMINNUM:
1274 case ISD::VP_FMAXNUM:
1276 case ISD::VP_FMINIMUM:
1278 case ISD::VP_FMAXIMUM:
1284 case ISD::OR:
case ISD::VP_OR:
1304 case ISD::VP_FCOPYSIGN:
1305 SplitVecRes_BinOp(
N,
Lo,
Hi);
1312 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1316 SplitVecRes_CMP(
N,
Lo,
Hi);
1319#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1320 case ISD::STRICT_##DAGN:
1321#include "llvm/IR/ConstrainedOps.def"
1322 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1327 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1336 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1346 SplitVecRes_FIX(
N,
Lo,
Hi);
1348 case ISD::EXPERIMENTAL_VP_REVERSE:
1349 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1358void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1367 DL,
Ptr.getValueType(),
1368 APInt(
Ptr.getValueSizeInBits().getFixedValue(), IncrementSize));
1370 Flags.setNoUnsignedWrap(
true);
1372 *ScaledOffset += IncrementSize;
1376 MPI =
N->getPointerInfo().getWithOffset(IncrementSize);
1382std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1383 return SplitMask(Mask,
SDLoc(Mask));
1386std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1389 EVT MaskVT =
Mask.getValueType();
1391 GetSplitVector(Mask, MaskLo, MaskHi);
1394 return std::make_pair(MaskLo, MaskHi);
1399 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1401 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1405 unsigned Opcode =
N->getOpcode();
1406 if (
N->getNumOperands() == 2) {
1412 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1413 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1416 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1419 std::tie(EVLLo, EVLHi) =
1420 DAG.
SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1423 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1425 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1431 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1433 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1435 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1439 unsigned Opcode =
N->getOpcode();
1440 if (
N->getNumOperands() == 3) {
1446 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1447 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1450 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1453 std::tie(EVLLo, EVLHi) =
1454 DAG.
SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1457 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1459 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1469 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1471 GetSplitVector(LHS, LHSLo, LHSHi);
1472 GetSplitVector(RHS, RHSLo, RHSHi);
1474 std::tie(LHSLo, LHSHi) = DAG.
SplitVector(LHS, dl);
1475 std::tie(RHSLo, RHSHi) = DAG.
SplitVector(RHS, dl);
1478 EVT SplitResVT =
N->getValueType(0).getHalfNumVectorElementsVT(Ctxt);
1479 Lo = DAG.
getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1480 Hi = DAG.
getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1485 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1487 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1491 unsigned Opcode =
N->getOpcode();
1510 switch (getTypeAction(InVT)) {
1525 GetExpandedOp(InOp,
Lo,
Hi);
1536 GetSplitVector(InOp,
Lo,
Hi);
1557 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1580 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1582 unsigned NumSubvectors =
N->getNumOperands() / 2;
1583 if (NumSubvectors == 1) {
1584 Lo =
N->getOperand(0);
1585 Hi =
N->getOperand(1);
1599void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1621 GetSplitVector(Vec,
Lo,
Hi);
1624 EVT LoVT =
Lo.getValueType();
1633 unsigned IdxVal =
Idx->getAsZExtVal();
1634 if (IdxVal + SubElems <= LoElems) {
1642 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1668 Lo = DAG.
getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1672 auto *
Load = cast<LoadSDNode>(
Lo);
1674 IncrementPointer(Load, LoVT, MPI, StackPtr);
1677 Hi = DAG.
getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1686 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1691 EVT RHSVT =
RHS.getValueType();
1694 GetSplitVector(RHS, RHSLo, RHSHi);
1711 SDValue FpValue =
N->getOperand(0);
1713 GetSplitVector(FpValue, ArgLo, ArgHi);
1726 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1730 std::tie(LoVT, HiVT) =
1741 unsigned Opcode =
N->getOpcode();
1748 GetSplitVector(N0, InLo, InHi);
1755 EVT OutLoVT, OutHiVT;
1758 assert((2 * OutNumElements) <= InNumElements &&
1759 "Illegal extend vector in reg split");
1769 for (
unsigned i = 0; i != OutNumElements; ++i)
1770 SplitHi[i] = i + OutNumElements;
1773 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1774 Hi = DAG.
getNode(Opcode, dl, OutHiVT, InHi);
1779 unsigned NumOps =
N->getNumOperands();
1793 for (
unsigned i = 1; i < NumOps; ++i) {
1798 EVT InVT =
Op.getValueType();
1803 GetSplitVector(
Op, OpLo, OpHi);
1812 EVT LoValueVTs[] = {LoVT, MVT::Other};
1813 EVT HiValueVTs[] = {HiVT, MVT::Other};
1822 Lo.getValue(1),
Hi.getValue(1));
1826 ReplaceValueWith(
SDValue(
N, 1), Chain);
1829SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
1831 EVT VT =
N->getValueType(0);
1842 else if (NE > ResNE)
1846 EVT ChainVTs[] = {EltVT, MVT::Other};
1850 for (i = 0; i !=
NE; ++i) {
1852 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
1853 SDValue Operand =
N->getOperand(j);
1864 Scalar.getNode()->setFlags(
N->getFlags());
1872 for (; i < ResNE; ++i)
1877 ReplaceValueWith(
SDValue(
N, 1), Chain);
1884void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
1887 EVT ResVT =
N->getValueType(0);
1888 EVT OvVT =
N->getValueType(1);
1889 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
1893 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
1895 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
1896 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
1902 unsigned Opcode =
N->getOpcode();
1914 unsigned OtherNo = 1 - ResNo;
1915 EVT OtherVT =
N->getValueType(OtherNo);
1917 SetSplitVector(
SDValue(
N, OtherNo),
1923 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
1927void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
1933 GetSplitVector(Vec,
Lo,
Hi);
1936 unsigned IdxVal = CIdx->getZExtValue();
1937 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
1938 if (IdxVal < LoNumElts) {
1940 Lo.getValueType(),
Lo, Elt,
Idx);
1986 Lo = DAG.
getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
1989 auto Load = cast<LoadSDNode>(
Lo);
1991 IncrementPointer(Load, LoVT, MPI, StackPtr);
1993 Hi = DAG.
getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
1997 if (LoVT !=
Lo.getValueType())
1999 if (HiVT !=
Hi.getValueType())
2007 assert(
N->getValueType(0).isScalableVector() &&
2008 "Only scalable vectors are supported for STEP_VECTOR");
2031 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2044 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
2045 auto [EVLLo, EVLHi] = DAG.
SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2046 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0), MaskLo, EVLLo);
2047 Hi = DAG.
getNode(
N->getOpcode(), dl, HiVT,
N->getOperand(0), MaskHi, EVLHi);
2061 EVT MemoryVT =
LD->getMemoryVT();
2065 EVT LoMemVT, HiMemVT;
2072 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2077 LD->getPointerInfo(), LoMemVT,
LD->getOriginalAlign(),
2081 IncrementPointer(LD, LoMemVT, MPI,
Ptr);
2084 HiMemVT,
LD->getOriginalAlign(), MMOFlags, AAInfo);
2093 ReplaceValueWith(
SDValue(LD, 1), Ch);
2098 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2107 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2108 Align Alignment =
LD->getOriginalAlign();
2111 EVT MemoryVT =
LD->getMemoryVT();
2113 EVT LoMemVT, HiMemVT;
2114 bool HiIsEmpty =
false;
2115 std::tie(LoMemVT, HiMemVT) =
2121 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2124 GetSplitVector(Mask, MaskLo, MaskHi);
2126 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, dl);
2131 std::tie(EVLLo, EVLHi) = DAG.
SplitEVL(EVL,
LD->getValueType(0), dl);
2140 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2149 LD->isExpandingLoad());
2155 MPI =
LD->getPointerInfo().getWithOffset(
2160 Alignment,
LD->getAAInfo(),
LD->getRanges());
2163 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2164 LD->isExpandingLoad());
2174 ReplaceValueWith(
SDValue(LD, 1), Ch);
2180 "Indexed VP strided load during type legalization!");
2182 "Unexpected indexed variable-length load offset");
2189 EVT LoMemVT, HiMemVT;
2190 bool HiIsEmpty =
false;
2191 std::tie(LoMemVT, HiMemVT) =
2197 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2200 GetSplitVector(Mask, LoMask, HiMask);
2206 std::tie(LoEVL, HiEVL) =
2244 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2255 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2268 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2277 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2280 GetSplitVector(Mask, MaskLo, MaskHi);
2282 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, dl);
2286 EVT LoMemVT, HiMemVT;
2287 bool HiIsEmpty =
false;
2288 std::tie(LoMemVT, HiMemVT) =
2291 SDValue PassThruLo, PassThruHi;
2293 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2295 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, dl);
2338 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2355 if (
auto *MSC = dyn_cast<MaskedGatherSDNode>(
N)) {
2356 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2358 auto *VPSC = cast<VPGatherSDNode>(
N);
2359 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2362 EVT MemoryVT =
N->getMemoryVT();
2363 Align Alignment =
N->getOriginalAlign();
2367 if (SplitSETCC && Ops.Mask.getOpcode() ==
ISD::SETCC) {
2368 SplitVecRes_SETCC(Ops.Mask.getNode(), MaskLo, MaskHi);
2370 std::tie(MaskLo, MaskHi) = SplitMask(Ops.Mask, dl);
2373 EVT LoMemVT, HiMemVT;
2378 if (getTypeAction(Ops.Index.getValueType()) ==
2380 GetSplitVector(Ops.Index, IndexLo, IndexHi);
2382 std::tie(IndexLo, IndexHi) = DAG.
SplitVector(Ops.Index, dl);
2389 if (
auto *MGT = dyn_cast<MaskedGatherSDNode>(
N)) {
2390 SDValue PassThru = MGT->getPassThru();
2391 SDValue PassThruLo, PassThruHi;
2394 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2396 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, dl);
2401 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo,
Ptr, IndexLo, Ops.Scale};
2403 OpsLo, MMO, IndexTy, ExtType);
2405 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi,
Ptr, IndexHi, Ops.Scale};
2407 OpsHi, MMO, IndexTy, ExtType);
2409 auto *VPGT = cast<VPGatherSDNode>(
N);
2411 std::tie(EVLLo, EVLHi) =
2412 DAG.
SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2414 SDValue OpsLo[] = {Ch,
Ptr, IndexLo, Ops.Scale, MaskLo, EVLLo};
2416 MMO, VPGT->getIndexType());
2418 SDValue OpsHi[] = {Ch,
Ptr, IndexHi, Ops.Scale, MaskHi, EVLHi};
2420 MMO, VPGT->getIndexType());
2430 ReplaceValueWith(
SDValue(
N, 1), Ch);
2444 EVT VecVT =
N->getValueType(0);
2447 bool HasCustomLowering =
false;
2454 HasCustomLowering =
true;
2460 SDValue Passthru =
N->getOperand(2);
2461 if (!HasCustomLowering || !Passthru.
isUndef()) {
2470 std::tie(LoMask, HiMask) = SplitMask(
N->getOperand(1));
2480 MF, cast<FrameIndexSDNode>(
StackPtr.getNode())->getIndex());
2489 Chain = DAG.
getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2498 assert(
N->getValueType(0).isVector() &&
2499 N->getOperand(0).getValueType().isVector() &&
2500 "Operand types must be vectors");
2508 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2510 GetSplitVector(
N->getOperand(0), LL, LH);
2514 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2516 GetSplitVector(
N->getOperand(1), RL, RH);
2521 Lo = DAG.
getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2522 Hi = DAG.
getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2524 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2525 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2526 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2527 std::tie(EVLLo, EVLHi) =
2528 DAG.
SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2529 Lo = DAG.
getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2531 Hi = DAG.
getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2545 EVT InVT =
N->getOperand(0).getValueType();
2547 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2552 unsigned Opcode =
N->getOpcode();
2553 if (
N->getNumOperands() <= 2) {
2555 Lo = DAG.
getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2556 Hi = DAG.
getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2564 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2565 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2568 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2571 std::tie(EVLLo, EVLHi) =
2572 DAG.
SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2585 EVT InVT =
N->getOperand(0).getValueType();
2587 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2591 auto *AddrSpaceCastN = cast<AddrSpaceCastSDNode>(
N);
2592 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2593 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2598void DAGTypeLegalizer::SplitVecRes_FFREXP(
SDNode *
N,
unsigned ResNo,
2606 EVT InVT =
N->getOperand(0).getValueType();
2608 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2612 Lo = DAG.
getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo);
2613 Hi = DAG.
getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi);
2614 Lo->setFlags(
N->getFlags());
2615 Hi->setFlags(
N->getFlags());
2621 unsigned OtherNo = 1 - ResNo;
2622 EVT OtherVT =
N->getValueType(OtherNo);
2630 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2637 EVT SrcVT =
N->getOperand(0).getValueType();
2638 EVT DestVT =
N->getValueType(0);
2661 EVT SplitLoVT, SplitHiVT;
2665 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2666 N->dump(&DAG);
dbgs() <<
"\n");
2667 if (!
N->isVPOpcode()) {
2670 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2681 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2682 N->getOperand(1),
N->getOperand(2));
2687 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2690 std::tie(EVLLo, EVLHi) =
2691 DAG.
SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2693 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2694 Hi = DAG.
getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2699 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2707 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2708 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2714 return N.getResNo() == 0 &&
2718 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2723 "Expected build vector node.");
2726 for (
unsigned I = 0;
I < NewElts; ++
I) {
2731 Ops[
I] = Input2.getOperand(
Idx - NewElts);
2733 Ops[
I] = Input1.getOperand(
Idx);
2735 if (Ops[
I].getValueType().bitsGT(EltVT))
2738 return DAG.getBuildVector(NewVT,
DL, Ops);
2746 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2750 for (
unsigned Idx = 0;
Idx < std::size(Inputs); ++
Idx) {
2752 auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Input.
getNode());
2761 for (
auto &
P : ShufflesIdxs) {
2762 if (
P.second.size() < 2)
2766 for (
int &
Idx : Mask) {
2769 unsigned SrcRegIdx =
Idx / NewElts;
2770 if (Inputs[SrcRegIdx].
isUndef()) {
2775 dyn_cast<ShuffleVectorSDNode>(Inputs[SrcRegIdx].
getNode());
2778 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2783 Idx = MaskElt % NewElts +
2784 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
2790 Inputs[
P.second[0]] =
P.first.first;
2791 Inputs[
P.second[1]] =
P.first.second;
2794 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
2798 for (
int &
Idx : Mask) {
2801 unsigned SrcRegIdx =
Idx / NewElts;
2802 if (Inputs[SrcRegIdx].
isUndef()) {
2807 getTypeAction(Inputs[SrcRegIdx].getValueType());
2809 Inputs[SrcRegIdx].getNumOperands() == 2 &&
2810 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
2813 UsedSubVector.set(2 * SrcRegIdx + (
Idx % NewElts) / (NewElts / 2));
2815 if (UsedSubVector.count() > 1) {
2817 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
2818 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
2820 if (Pairs.
empty() || Pairs.
back().size() == 2)
2822 if (UsedSubVector.test(2 *
I)) {
2823 Pairs.
back().emplace_back(
I, 0);
2825 assert(UsedSubVector.test(2 *
I + 1) &&
2826 "Expected to be used one of the subvectors.");
2827 Pairs.
back().emplace_back(
I, 1);
2830 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
2832 for (
int &
Idx : Mask) {
2835 unsigned SrcRegIdx =
Idx / NewElts;
2837 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
2838 return Idxs.front().first == SrcRegIdx ||
2839 Idxs.back().first == SrcRegIdx;
2841 if (It == Pairs.
end())
2843 Idx = It->front().first * NewElts + (
Idx % NewElts) % (NewElts / 2) +
2844 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
2847 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
2848 Inputs[Idxs.front().first] = DAG.
getNode(
2850 Inputs[Idxs.front().first].getValueType(),
2851 Inputs[Idxs.front().first].
getOperand(Idxs.front().second),
2852 Inputs[Idxs.back().first].
getOperand(Idxs.back().second));
2861 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
2862 auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Inputs[
I].
getNode());
2865 if (Shuffle->getOperand(0).getValueType() != NewVT)
2868 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
2869 !Shuffle->isSplat()) {
2871 }
else if (!Inputs[
I].hasOneUse() &&
2872 !Shuffle->getOperand(1).isUndef()) {
2874 for (
int &
Idx : Mask) {
2877 unsigned SrcRegIdx =
Idx / NewElts;
2880 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2885 int OpIdx = MaskElt / NewElts;
2898 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
2899 if (Shuffle->getOperand(OpIdx).isUndef())
2901 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
2902 if (It == std::end(Inputs))
2904 int FoundOp = std::distance(std::begin(Inputs), It);
2907 for (
int &
Idx : Mask) {
2910 unsigned SrcRegIdx =
Idx / NewElts;
2913 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2918 int MaskIdx = MaskElt / NewElts;
2919 if (OpIdx == MaskIdx)
2920 Idx = MaskElt % NewElts + FoundOp * NewElts;
2923 Op = (OpIdx + 1) % 2;
2931 for (
int &
Idx : Mask) {
2934 unsigned SrcRegIdx =
Idx / NewElts;
2937 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2938 int OpIdx = MaskElt / NewElts;
2941 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
2947 TryPeekThroughShufflesInputs(OrigMask);
2949 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
2953 for (
const auto &
I : Inputs) {
2955 UniqueConstantInputs.
insert(
I);
2956 else if (!
I.isUndef())
2961 if (UniqueInputs.
size() != std::size(Inputs)) {
2962 auto &&UniqueVec = UniqueInputs.
takeVector();
2963 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
2964 unsigned ConstNum = UniqueConstantVec.size();
2965 for (
int &
Idx : Mask) {
2968 unsigned SrcRegIdx =
Idx / NewElts;
2969 if (Inputs[SrcRegIdx].
isUndef()) {
2973 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
2974 if (It != UniqueConstantVec.end()) {
2976 NewElts * std::distance(UniqueConstantVec.begin(), It);
2977 assert(
Idx >= 0 &&
"Expected defined mask idx.");
2980 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
2981 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
2983 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
2984 assert(
Idx >= 0 &&
"Expected defined mask idx.");
2986 copy(UniqueConstantVec, std::begin(Inputs));
2987 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
2990 MakeUniqueInputs(OrigMask);
2992 copy(Inputs, std::begin(OrigInputs));
2998 unsigned FirstMaskIdx =
High * NewElts;
3001 assert(!Output &&
"Expected default initialized initial value.");
3002 TryPeekThroughShufflesInputs(Mask);
3003 MakeUniqueInputs(Mask);
3005 copy(Inputs, std::begin(TmpInputs));
3008 bool SecondIteration =
false;
3009 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3014 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) ==
Idx)
3015 SecondIteration =
true;
3016 return SecondIteration;
3019 Mask, std::size(Inputs), std::size(Inputs),
3021 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3022 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3025 Output = BuildVector(Inputs[
Idx], Inputs[
Idx], Mask);
3027 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[
Idx],
3028 DAG.getUNDEF(NewVT), Mask);
3029 Inputs[
Idx] = Output;
3031 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3034 if (AccumulateResults(Idx1)) {
3037 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3039 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3040 Inputs[Idx2], Mask);
3044 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3046 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3047 TmpInputs[Idx2], Mask);
3049 Inputs[Idx1] = Output;
3051 copy(OrigInputs, std::begin(Inputs));
3056 EVT OVT =
N->getValueType(0);
3063 const Align Alignment =
3064 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3066 Lo = DAG.getVAArg(NVT, dl, Chain,
Ptr, SV, Alignment.
value());
3067 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1),
Ptr, SV, Alignment.
value());
3068 Chain =
Hi.getValue(1);
3072 ReplaceValueWith(
SDValue(
N, 1), Chain);
3077 EVT DstVTLo, DstVTHi;
3078 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3082 EVT SrcVT =
N->getOperand(0).getValueType();
3084 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3086 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3088 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3089 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3095 GetSplitVector(
N->getOperand(0), InLo, InHi);
3107 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3112 EVT VT =
N->getValueType(0);
3119 Align Alignment = DAG.getReducedAlign(VT,
false);
3125 auto &MF = DAG.getMachineFunction();
3139 DAG.getConstant(1,
DL, PtrVT));
3141 DAG.getConstant(EltWidth,
DL, PtrVT));
3143 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3145 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3146 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3147 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3150 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3152 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3155void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3157 SDValue Op0Lo, Op0Hi, Op1Lo, Op1Hi;
3158 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
3159 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
3163 DAG.getVTList(VT, VT), Op0Lo, Op0Hi);
3165 DAG.getVTList(VT, VT), Op1Lo, Op1Hi);
3171void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3172 SDValue Op0Lo, Op0Hi, Op1Lo, Op1Hi;
3173 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
3174 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
3178 DAG.getVTList(VT, VT), Op0Lo, Op1Lo),
3180 DAG.getVTList(VT, VT), Op0Hi, Op1Hi)};
3182 SetSplitVector(
SDValue(
N, 0), Res[0].getValue(0), Res[0].getValue(1));
3183 SetSplitVector(
SDValue(
N, 1), Res[1].getValue(0), Res[1].getValue(1));
3194bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3199 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3202 switch (
N->getOpcode()) {
3205 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3214 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3220 case ISD::VP_TRUNCATE:
3222 Res = SplitVecOp_TruncateHelper(
N);
3225 case ISD::VP_FP_ROUND:
3229 Res = SplitVecOp_STORE(cast<StoreSDNode>(
N), OpNo);
3232 Res = SplitVecOp_VP_STORE(cast<VPStoreSDNode>(
N), OpNo);
3234 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3235 Res = SplitVecOp_VP_STRIDED_STORE(cast<VPStridedStoreSDNode>(
N), OpNo);
3238 Res = SplitVecOp_MSTORE(cast<MaskedStoreSDNode>(
N), OpNo);
3241 case ISD::VP_SCATTER:
3242 Res = SplitVecOp_Scatter(cast<MemSDNode>(
N), OpNo);
3245 case ISD::VP_GATHER:
3246 Res = SplitVecOp_Gather(cast<MemSDNode>(
N), OpNo);
3249 Res = SplitVecOp_VSELECT(
N, OpNo);
3255 case ISD::VP_SINT_TO_FP:
3256 case ISD::VP_UINT_TO_FP:
3257 if (
N->getValueType(0).bitsLT(
3258 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3259 Res = SplitVecOp_TruncateHelper(
N);
3261 Res = SplitVecOp_UnaryOp(
N);
3265 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3269 case ISD::VP_FP_TO_SINT:
3270 case ISD::VP_FP_TO_UINT:
3283 Res = SplitVecOp_UnaryOp(
N);
3286 Res = SplitVecOp_FPOpDifferentTypes(
N);
3291 Res = SplitVecOp_CMP(
N);
3297 Res = SplitVecOp_ExtVecInRegOp(
N);
3315 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3319 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3321 case ISD::VP_REDUCE_FADD:
3322 case ISD::VP_REDUCE_SEQ_FADD:
3323 case ISD::VP_REDUCE_FMUL:
3324 case ISD::VP_REDUCE_SEQ_FMUL:
3325 case ISD::VP_REDUCE_ADD:
3326 case ISD::VP_REDUCE_MUL:
3327 case ISD::VP_REDUCE_AND:
3328 case ISD::VP_REDUCE_OR:
3329 case ISD::VP_REDUCE_XOR:
3330 case ISD::VP_REDUCE_SMAX:
3331 case ISD::VP_REDUCE_SMIN:
3332 case ISD::VP_REDUCE_UMAX:
3333 case ISD::VP_REDUCE_UMIN:
3334 case ISD::VP_REDUCE_FMAX:
3335 case ISD::VP_REDUCE_FMIN:
3336 case ISD::VP_REDUCE_FMAXIMUM:
3337 case ISD::VP_REDUCE_FMINIMUM:
3338 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3340 case ISD::VP_CTTZ_ELTS:
3341 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3342 Res = SplitVecOp_VP_CttzElements(
N);
3347 if (!Res.
getNode())
return false;
3354 if (
N->isStrictFPOpcode())
3356 "Invalid operand expansion");
3359 "Invalid operand expansion");
3361 ReplaceValueWith(
SDValue(
N, 0), Res);
3365SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3368 assert(OpNo == 0 &&
"Illegal operand must be mask");
3375 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3378 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3379 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3380 "Lo and Hi have differing types");
3383 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3384 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3386 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3387 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3388 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3389 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3399SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3400 EVT ResVT =
N->getValueType(0);
3404 SDValue VecOp =
N->getOperand(OpNo);
3406 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3407 GetSplitVector(VecOp,
Lo,
Hi);
3409 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3415 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3419 EVT ResVT =
N->getValueType(0);
3428 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3429 GetSplitVector(VecOp,
Lo,
Hi);
3431 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3437 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3440SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3441 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3442 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3444 unsigned Opc =
N->getOpcode();
3445 EVT ResVT =
N->getValueType(0);
3449 SDValue VecOp =
N->getOperand(OpNo);
3451 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3452 GetSplitVector(VecOp,
Lo,
Hi);
3455 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3458 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3463 DAG.
getNode(Opc, dl, ResVT, {
N->getOperand(0),
Lo, MaskLo, EVLLo},
Flags);
3464 return DAG.getNode(Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3469 EVT ResVT =
N->getValueType(0);
3472 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3473 EVT InVT =
Lo.getValueType();
3478 if (
N->isStrictFPOpcode()) {
3479 Lo = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3480 { N->getOperand(0), Lo });
3481 Hi = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3482 { N->getOperand(0), Hi });
3491 ReplaceValueWith(
SDValue(
N, 1), Ch);
3492 }
else if (
N->getNumOperands() == 3) {
3493 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3494 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3495 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3496 std::tie(EVLLo, EVLHi) =
3497 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3498 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3499 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3501 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3502 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3512 EVT ResVT =
N->getValueType(0);
3514 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3518 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3524 Lo = BitConvertToInteger(
Lo);
3525 Hi = BitConvertToInteger(
Hi);
3527 if (DAG.getDataLayout().isBigEndian())
3535 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3537 EVT ResVT =
N->getValueType(0);
3545 GetSplitVector(SubVec,
Lo,
Hi);
3548 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
3554 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3556 return SecondInsertion;
3559SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3561 EVT SubVT =
N->getValueType(0);
3566 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3568 uint64_t LoEltsMin =
Lo.getValueType().getVectorMinNumElements();
3571 if (IdxVal < LoEltsMin) {
3573 "Extracted subvector crosses vector split!");
3576 N->getOperand(0).getValueType().isScalableVector())
3578 DAG.getVectorIdxConstant(IdxVal - LoEltsMin, dl));
3583 "Extracting scalable subvector from fixed-width unsupported");
3591 "subvector from a scalable predicate vector");
3597 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
3599 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
3600 auto &MF = DAG.getMachineFunction();
3604 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
3611 SubVT, dl, Store, StackPtr,
3615SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
3624 GetSplitVector(Vec,
Lo,
Hi);
3626 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
3628 if (IdxVal < LoElts)
3632 DAG.getConstant(IdxVal - LoElts,
SDLoc(
N),
3633 Idx.getValueType())), 0);
3637 if (CustomLowerNode(
N,
N->getValueType(0),
true))
3649 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
3655 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
3657 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
3658 auto &MF = DAG.getMachineFunction();
3661 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
3669 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
3671 return DAG.getExtLoad(
3682 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
3690 SplitVecRes_Gather(
N,
Lo,
Hi);
3693 ReplaceValueWith(
SDValue(
N, 0), Res);
3698 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
3702 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
3704 SDValue EVL =
N->getVectorLength();
3706 Align Alignment =
N->getOriginalAlign();
3712 GetSplitVector(
Data, DataLo, DataHi);
3714 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
3719 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
3722 GetSplitVector(Mask, MaskLo, MaskHi);
3724 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
3727 EVT MemoryVT =
N->getMemoryVT();
3728 EVT LoMemVT, HiMemVT;
3729 bool HiIsEmpty =
false;
3730 std::tie(LoMemVT, HiMemVT) =
3731 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
3735 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
3743 Lo = DAG.getStoreVP(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
3744 N->getAddressingMode(),
N->isTruncatingStore(),
3745 N->isCompressingStore());
3752 N->isCompressingStore());
3760 MPI =
N->getPointerInfo().getWithOffset(
3763 MMO = DAG.getMachineFunction().getMachineMemOperand(
3765 Alignment,
N->getAAInfo(),
N->getRanges());
3767 Hi = DAG.getStoreVP(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
3768 N->getAddressingMode(),
N->isTruncatingStore(),
3769 N->isCompressingStore());
3778 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
3779 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
3786 GetSplitVector(
Data, LoData, HiData);
3788 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
3790 EVT LoMemVT, HiMemVT;
3791 bool HiIsEmpty =
false;
3792 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
3798 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
3799 else if (getTypeAction(
Mask.getValueType()) ==
3801 GetSplitVector(Mask, LoMask, HiMask);
3803 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3806 std::tie(LoEVL, HiEVL) =
3807 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
3811 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
3812 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
3813 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
3824 EVT PtrVT =
N->getBasePtr().getValueType();
3827 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
3830 Align Alignment =
N->getOriginalAlign();
3838 Alignment,
N->getAAInfo(),
N->getRanges());
3841 N->getChain(),
DL, HiData,
Ptr,
N->getOffset(),
N->getStride(), HiMask,
3842 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
3843 N->isCompressingStore());
3852 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
3856 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
3859 Align Alignment =
N->getOriginalAlign();
3865 GetSplitVector(
Data, DataLo, DataHi);
3867 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
3872 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
3875 GetSplitVector(Mask, MaskLo, MaskHi);
3877 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
3880 EVT MemoryVT =
N->getMemoryVT();
3881 EVT LoMemVT, HiMemVT;
3882 bool HiIsEmpty =
false;
3883 std::tie(LoMemVT, HiMemVT) =
3884 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
3892 Lo = DAG.getMaskedStore(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, LoMemVT, MMO,
3893 N->getAddressingMode(),
N->isTruncatingStore(),
3894 N->isCompressingStore());
3903 N->isCompressingStore());
3911 MPI =
N->getPointerInfo().getWithOffset(
3914 MMO = DAG.getMachineFunction().getMachineMemOperand(
3916 Alignment,
N->getAAInfo(),
N->getRanges());
3918 Hi = DAG.getMaskedStore(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, HiMemVT, MMO,
3919 N->getAddressingMode(),
N->isTruncatingStore(),
3920 N->isCompressingStore());
3933 EVT MemoryVT =
N->getMemoryVT();
3934 Align Alignment =
N->getOriginalAlign();
3942 if (
auto *MSC = dyn_cast<MaskedScatterSDNode>(
N)) {
3943 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
3946 auto *VPSC = cast<VPScatterSDNode>(
N);
3947 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
3952 EVT LoMemVT, HiMemVT;
3953 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
3958 GetSplitVector(Ops.Data, DataLo, DataHi);
3960 std::tie(DataLo, DataHi) = DAG.SplitVector(Ops.Data,
DL);
3964 if (OpNo == 1 && Ops.Mask.getOpcode() ==
ISD::SETCC) {
3965 SplitVecRes_SETCC(Ops.Mask.getNode(), MaskLo, MaskHi);
3967 std::tie(MaskLo, MaskHi) = SplitMask(Ops.Mask,
DL);
3971 if (getTypeAction(Ops.Index.getValueType()) ==
3973 GetSplitVector(Ops.Index, IndexLo, IndexHi);
3975 std::tie(IndexLo, IndexHi) = DAG.SplitVector(Ops.Index,
DL);
3983 if (
auto *MSC = dyn_cast<MaskedScatterSDNode>(
N)) {
3984 SDValue OpsLo[] = {Ch, DataLo, MaskLo,
Ptr, IndexLo, Ops.Scale};
3986 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
3987 MSC->getIndexType(), MSC->isTruncatingStore());
3992 SDValue OpsHi[] = {
Lo, DataHi, MaskHi,
Ptr, IndexHi, Ops.Scale};
3993 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
3994 MMO, MSC->getIndexType(),
3995 MSC->isTruncatingStore());
3997 auto *VPSC = cast<VPScatterSDNode>(
N);
3999 std::tie(EVLLo, EVLHi) =
4000 DAG.SplitEVL(VPSC->getVectorLength(), Ops.Data.getValueType(),
DL);
4002 SDValue OpsLo[] = {Ch, DataLo,
Ptr, IndexLo, Ops.Scale, MaskLo, EVLLo};
4003 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4004 VPSC->getIndexType());
4009 SDValue OpsHi[] = {
Lo, DataHi,
Ptr, IndexHi, Ops.Scale, MaskHi, EVLHi};
4010 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4011 VPSC->getIndexType());
4015 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4016 assert(OpNo == 1 &&
"Can only split the stored value");
4019 bool isTruncating =
N->isTruncatingStore();
4022 EVT MemoryVT =
N->getMemoryVT();
4023 Align Alignment =
N->getOriginalAlign();
4027 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4029 EVT LoMemVT, HiMemVT;
4030 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4037 Lo = DAG.getTruncStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), LoMemVT,
4038 Alignment, MMOFlags, AAInfo);
4040 Lo = DAG.getStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4044 IncrementPointer(
N, LoMemVT, MPI,
Ptr);
4047 Hi = DAG.getTruncStore(Ch,
DL,
Hi,
Ptr, MPI,
4048 HiMemVT, Alignment, MMOFlags, AAInfo);
4050 Hi = DAG.getStore(Ch,
DL,
Hi,
Ptr, MPI, Alignment, MMOFlags, AAInfo);
4064 EVT EltVT =
N->getValueType(0).getVectorElementType();
4066 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4069 DAG.getVectorIdxConstant(i,
DL)));
4073 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4094 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4095 SDValue InVec =
N->getOperand(OpNo);
4097 EVT OutVT =
N->getValueType(0);