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);
125 R = ScalarizeVecRes_UnaryOp(
N);
128 R = ScalarizeVecRes_ADDRSPACECAST(
N);
131 R = ScalarizeVecRes_FFREXP(
N, ResNo);
182 R = ScalarizeVecRes_BinOp(
N);
187 R = ScalarizeVecRes_CMP(
N);
193 R = ScalarizeVecRes_TernaryOp(
N);
196#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
197 case ISD::STRICT_##DAGN:
198#include "llvm/IR/ConstrainedOps.def"
199 R = ScalarizeVecRes_StrictFPOp(
N);
204 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
213 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
223 R = ScalarizeVecRes_FIX(
N);
229 SetScalarizedVector(
SDValue(
N, ResNo), R);
233 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
234 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
236 LHS.getValueType(), LHS, RHS,
N->getFlags());
244 if (getTypeAction(
LHS.getValueType()) ==
246 LHS = GetScalarizedVector(LHS);
247 RHS = GetScalarizedVector(RHS);
249 EVT VT =
LHS.getValueType().getVectorElementType();
257 N->getValueType(0).getVectorElementType(), LHS, RHS);
261 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
262 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
263 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
269 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
270 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
276SDValue DAGTypeLegalizer::ScalarizeVecRes_FFREXP(
SDNode *
N,
unsigned ResNo) {
277 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
278 "Unexpected vector type!");
279 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
281 EVT VT0 =
N->getValueType(0);
282 EVT VT1 =
N->getValueType(1);
287 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
291 unsigned OtherNo = 1 - ResNo;
292 EVT OtherVT =
N->getValueType(OtherNo);
294 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
298 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
301 return SDValue(ScalarNode, ResNo);
305 EVT VT =
N->getValueType(0).getVectorElementType();
306 unsigned NumOpers =
N->getNumOperands();
308 EVT ValueVTs[] = {VT, MVT::Other};
317 for (
unsigned i = 1; i < NumOpers; ++i) {
323 Oper = GetScalarizedVector(Oper);
334 Opers,
N->getFlags());
345 EVT ResVT =
N->getValueType(0);
346 EVT OvVT =
N->getValueType(1);
350 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
351 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
356 ScalarLHS = ElemsLHS[0];
357 ScalarRHS = ElemsRHS[0];
363 N->getOpcode(),
DL, ScalarVTs, ScalarLHS, ScalarRHS).
getNode();
367 unsigned OtherNo = 1 - ResNo;
368 EVT OtherVT =
N->getValueType(OtherNo);
370 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
374 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
377 return SDValue(ScalarNode, ResNo);
382 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
383 return GetScalarizedVector(
Op);
388 if (
Op.getValueType().isVector()
389 &&
Op.getValueType().getVectorNumElements() == 1
390 && !isSimpleLegalType(
Op.getValueType()))
391 Op = GetScalarizedVector(
Op);
392 EVT NewVT =
N->getValueType(0).getVectorElementType();
397SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
398 EVT EltVT =
N->getValueType(0).getVectorElementType();
407SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
409 N->getValueType(0).getVectorElementType(),
410 N->getOperand(0),
N->getOperand(1));
416 EVT OpVT =
Op.getValueType();
420 Op = GetScalarizedVector(
Op);
427 N->getValueType(0).getVectorElementType(),
Op,
432 SDValue Op = GetScalarizedVector(
N->getOperand(0));
437SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
441 EVT EltVT =
N->getValueType(0).getVectorElementType();
442 if (
Op.getValueType() != EltVT)
449 assert(
N->isUnindexed() &&
"Indexed vector load?");
453 N->getValueType(0).getVectorElementType(),
SDLoc(
N),
N->getChain(),
454 N->getBasePtr(), DAG.
getUNDEF(
N->getBasePtr().getValueType()),
455 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
456 N->getOriginalAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
466 EVT DestVT =
N->getValueType(0).getVectorElementType();
468 EVT OpVT =
Op.getValueType();
478 Op = GetScalarizedVector(
Op);
488 EVT EltVT =
N->getValueType(0).getVectorElementType();
490 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
499 EVT OpVT =
Op.getValueType();
501 EVT EltVT =
N->getValueType(0).getVectorElementType();
504 Op = GetScalarizedVector(
Op);
510 switch (
N->getOpcode()) {
522SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
523 EVT DestVT =
N->getValueType(0).getVectorElementType();
525 EVT OpVT =
Op.getValueType();
535 Op = GetScalarizedVector(
Op);
541 auto *AddrSpaceCastN = cast<AddrSpaceCastSDNode>(
N);
542 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
543 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
547SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
550 EVT EltVT =
N->getValueType(0).getVectorElementType();
559 EVT OpVT =
Cond.getValueType();
572 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
586 EVT OpVT =
Cond->getOperand(0).getValueType();
593 EVT CondVT =
Cond.getValueType();
594 if (ScalarBool != VecBool) {
595 switch (ScalarBool) {
616 auto BoolVT = getSetCCResultType(CondVT);
617 if (BoolVT.bitsLT(CondVT))
622 GetScalarizedVector(
N->getOperand(2)));
626 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
628 LHS.getValueType(),
N->getOperand(0), LHS,
629 GetScalarizedVector(
N->getOperand(2)));
633 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
635 N->getOperand(0),
N->getOperand(1),
636 LHS, GetScalarizedVector(
N->getOperand(3)),
641 return DAG.
getUNDEF(
N->getValueType(0).getVectorElementType());
644SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
646 SDValue Arg =
N->getOperand(2).getOperand(0);
648 return DAG.
getUNDEF(
N->getValueType(0).getVectorElementType());
649 unsigned Op = !cast<ConstantSDNode>(Arg)->isZero();
650 return GetScalarizedVector(
N->getOperand(
Op));
653SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
655 EVT SrcVT = Src.getValueType();
660 Src = GetScalarizedVector(Src);
666 EVT DstVT =
N->getValueType(0).getVectorElementType();
667 return DAG.
getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
671 assert(
N->getValueType(0).isVector() &&
672 N->getOperand(0).getValueType().isVector() &&
673 "Operand types must be vectors");
676 EVT OpVT =
LHS.getValueType();
677 EVT NVT =
N->getValueType(0).getVectorElementType();
682 LHS = GetScalarizedVector(LHS);
683 RHS = GetScalarizedVector(RHS);
699 return DAG.
getNode(ExtendCode,
DL, NVT, Res);
707 EVT ResultVT =
N->getValueType(0).getVectorElementType();
710 Arg = GetScalarizedVector(Arg);
723 return DAG.
getNode(ExtendCode,
DL, ResultVT, Res);
730bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
735 switch (
N->getOpcode()) {
738 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
745 Res = ScalarizeVecOp_BITCAST(
N);
757 Res = ScalarizeVecOp_UnaryOp(
N);
763 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
766 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
769 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
772 Res = ScalarizeVecOp_VSELECT(
N);
775 Res = ScalarizeVecOp_VSETCC(
N);
778 Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(
N), OpNo);
781 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
784 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
787 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
790 Res = ScalarizeVecOp_FP_EXTEND(
N);
807 Res = ScalarizeVecOp_VECREDUCE(
N);
811 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
815 Res = ScalarizeVecOp_CMP(
N);
820 if (!Res.
getNode())
return false;
828 "Invalid operand expansion");
830 ReplaceValueWith(
SDValue(
N, 0), Res);
837 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
839 N->getValueType(0), Elt);
845 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
846 "Unexpected vector type!");
847 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
849 N->getValueType(0).getScalarType(), Elt);
857SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
858 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
859 "Unexpected vector type!");
860 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
862 {
N->getValueType(0).getScalarType(), MVT::Other },
863 {
N->getOperand(0), Elt });
873 ReplaceValueWith(
SDValue(
N, 0), Res);
878SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
880 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
881 Ops[i] = GetScalarizedVector(
N->getOperand(i));
887SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
888 EVT VT =
N->getValueType(0);
889 SDValue Res = GetScalarizedVector(
N->getOperand(0));
901 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
902 EVT VT =
N->getValueType(0);
912 assert(
N->getValueType(0).isVector() &&
913 N->getOperand(0).getValueType().isVector() &&
914 "Operand types must be vectors");
915 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
917 EVT VT =
N->getValueType(0);
918 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
919 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
921 EVT OpVT =
N->getOperand(0).getValueType();
933 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
941 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
942 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
945 if (
N->isTruncatingStore())
947 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
948 N->getBasePtr(),
N->getPointerInfo(),
949 N->getMemoryVT().getVectorElementType(),
N->getOriginalAlign(),
950 N->getMemOperand()->getFlags(),
N->getAAInfo());
952 return DAG.
getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
953 N->getBasePtr(),
N->getPointerInfo(),
954 N->getOriginalAlign(),
N->getMemOperand()->getFlags(),
960SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
961 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
962 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
964 N->getValueType(0).getVectorElementType(), Elt,
969SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
971 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
972 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
976 {
N->getOperand(0), Elt,
N->getOperand(2) });
985 ReplaceValueWith(
SDValue(
N, 0), Res);
992 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
994 N->getValueType(0).getVectorElementType(), Elt);
1000SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1001 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1005 {
N->getOperand(0), Elt});
1014 ReplaceValueWith(
SDValue(
N, 0), Res);
1019 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1026SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1032 SDValue Op = GetScalarizedVector(VecOp);
1034 AccOp,
Op,
N->getFlags());
1038 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1039 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1041 EVT ResVT =
N->getValueType(0).getVectorElementType();
1054void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1059 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1062 switch (
N->getOpcode()) {
1065 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1077 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1090 case ISD::EXPERIMENTAL_VP_SPLAT: SplitVecRes_VP_SPLAT(
N,
Lo,
Hi);
break;
1093 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1096 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1100 SplitVecRes_LOAD(cast<LoadSDNode>(
N),
Lo,
Hi);
1103 SplitVecRes_VP_LOAD(cast<VPLoadSDNode>(
N),
Lo,
Hi);
1105 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1106 SplitVecRes_VP_STRIDED_LOAD(cast<VPStridedLoadSDNode>(
N),
Lo,
Hi);
1109 SplitVecRes_MLOAD(cast<MaskedLoadSDNode>(
N),
Lo,
Hi);
1112 case ISD::VP_GATHER:
1113 SplitVecRes_Gather(cast<MemSDNode>(
N),
Lo,
Hi,
true);
1116 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1120 SplitVecRes_SETCC(
N,
Lo,
Hi);
1123 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1126 SplitVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(
N),
Lo,
Hi);
1129 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1132 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1135 SplitVecRes_VECTOR_INTERLEAVE(
N);
1138 SplitVecRes_VAARG(
N,
Lo,
Hi);
1144 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1150 case ISD::VP_BITREVERSE:
1158 case ISD::VP_CTLZ_ZERO_UNDEF:
1160 case ISD::VP_CTTZ_ZERO_UNDEF:
1175 case ISD::VP_FFLOOR:
1180 case ISD::VP_FNEARBYINT:
1185 case ISD::VP_FP_EXTEND:
1187 case ISD::VP_FP_ROUND:
1189 case ISD::VP_FP_TO_SINT:
1191 case ISD::VP_FP_TO_UINT:
1197 case ISD::VP_LLRINT:
1199 case ISD::VP_FROUND:
1201 case ISD::VP_FROUNDEVEN:
1208 case ISD::VP_FROUNDTOZERO:
1210 case ISD::VP_SINT_TO_FP:
1212 case ISD::VP_TRUNCATE:
1214 case ISD::VP_UINT_TO_FP:
1216 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1219 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1222 SplitVecRes_FFREXP(
N, ResNo,
Lo,
Hi);
1228 case ISD::VP_SIGN_EXTEND:
1229 case ISD::VP_ZERO_EXTEND:
1230 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1249 case ISD::VP_FMINNUM:
1252 case ISD::VP_FMAXNUM:
1254 case ISD::VP_FMINIMUM:
1256 case ISD::VP_FMAXIMUM:
1262 case ISD::OR:
case ISD::VP_OR:
1282 case ISD::VP_FCOPYSIGN:
1283 SplitVecRes_BinOp(
N,
Lo,
Hi);
1290 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1294 SplitVecRes_CMP(
N,
Lo,
Hi);
1297#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1298 case ISD::STRICT_##DAGN:
1299#include "llvm/IR/ConstrainedOps.def"
1300 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1305 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1314 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1324 SplitVecRes_FIX(
N,
Lo,
Hi);
1326 case ISD::EXPERIMENTAL_VP_REVERSE:
1327 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1336void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1345 DL,
Ptr.getValueType(),
1346 APInt(
Ptr.getValueSizeInBits().getFixedValue(), IncrementSize));
1348 Flags.setNoUnsignedWrap(
true);
1350 *ScaledOffset += IncrementSize;
1354 MPI =
N->getPointerInfo().getWithOffset(IncrementSize);
1360std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1361 return SplitMask(Mask,
SDLoc(Mask));
1364std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1367 EVT MaskVT =
Mask.getValueType();
1369 GetSplitVector(Mask, MaskLo, MaskHi);
1372 return std::make_pair(MaskLo, MaskHi);
1377 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1379 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1383 unsigned Opcode =
N->getOpcode();
1384 if (
N->getNumOperands() == 2) {
1390 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1391 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1394 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1397 std::tie(EVLLo, EVLHi) =
1398 DAG.
SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1401 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1403 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1409 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1411 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1413 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1417 unsigned Opcode =
N->getOpcode();
1418 if (
N->getNumOperands() == 3) {
1424 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1425 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1428 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1431 std::tie(EVLLo, EVLHi) =
1432 DAG.
SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1435 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1437 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1447 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1449 GetSplitVector(LHS, LHSLo, LHSHi);
1450 GetSplitVector(RHS, RHSLo, RHSHi);
1452 std::tie(LHSLo, LHSHi) = DAG.
SplitVector(LHS, dl);
1453 std::tie(RHSLo, RHSHi) = DAG.
SplitVector(RHS, dl);
1456 EVT SplitResVT =
N->getValueType(0).getHalfNumVectorElementsVT(Ctxt);
1457 Lo = DAG.
getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1458 Hi = DAG.
getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1463 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1465 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1469 unsigned Opcode =
N->getOpcode();
1488 switch (getTypeAction(InVT)) {
1503 GetExpandedOp(InOp,
Lo,
Hi);
1514 GetSplitVector(InOp,
Lo,
Hi);
1535 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1558 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1560 unsigned NumSubvectors =
N->getNumOperands() / 2;
1561 if (NumSubvectors == 1) {
1562 Lo =
N->getOperand(0);
1563 Hi =
N->getOperand(1);
1577void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1599 GetSplitVector(Vec,
Lo,
Hi);
1602 EVT LoVT =
Lo.getValueType();
1611 unsigned IdxVal =
Idx->getAsZExtVal();
1612 if (IdxVal + SubElems <= LoElems) {
1620 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1646 Lo = DAG.
getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1650 auto *
Load = cast<LoadSDNode>(
Lo);
1652 IncrementPointer(Load, LoVT, MPI, StackPtr);
1655 Hi = DAG.
getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1664 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1669 EVT RHSVT =
RHS.getValueType();
1672 GetSplitVector(RHS, RHSLo, RHSHi);
1689 SDValue FpValue =
N->getOperand(0);
1691 GetSplitVector(FpValue, ArgLo, ArgHi);
1704 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1708 std::tie(LoVT, HiVT) =
1719 unsigned Opcode =
N->getOpcode();
1726 GetSplitVector(N0, InLo, InHi);
1733 EVT OutLoVT, OutHiVT;
1736 assert((2 * OutNumElements) <= InNumElements &&
1737 "Illegal extend vector in reg split");
1747 for (
unsigned i = 0; i != OutNumElements; ++i)
1748 SplitHi[i] = i + OutNumElements;
1751 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1752 Hi = DAG.
getNode(Opcode, dl, OutHiVT, InHi);
1757 unsigned NumOps =
N->getNumOperands();
1771 for (
unsigned i = 1; i < NumOps; ++i) {
1776 EVT InVT =
Op.getValueType();
1781 GetSplitVector(
Op, OpLo, OpHi);
1790 EVT LoValueVTs[] = {LoVT, MVT::Other};
1791 EVT HiValueVTs[] = {HiVT, MVT::Other};
1800 Lo.getValue(1),
Hi.getValue(1));
1804 ReplaceValueWith(
SDValue(
N, 1), Chain);
1807SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
1809 EVT VT =
N->getValueType(0);
1820 else if (NE > ResNE)
1824 EVT ChainVTs[] = {EltVT, MVT::Other};
1828 for (i = 0; i !=
NE; ++i) {
1830 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
1831 SDValue Operand =
N->getOperand(j);
1842 Scalar.getNode()->setFlags(
N->getFlags());
1850 for (; i < ResNE; ++i)
1855 ReplaceValueWith(
SDValue(
N, 1), Chain);
1862void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
1865 EVT ResVT =
N->getValueType(0);
1866 EVT OvVT =
N->getValueType(1);
1867 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
1871 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
1873 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
1874 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
1880 unsigned Opcode =
N->getOpcode();
1892 unsigned OtherNo = 1 - ResNo;
1893 EVT OtherVT =
N->getValueType(OtherNo);
1895 SetSplitVector(
SDValue(
N, OtherNo),
1901 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
1905void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
1911 GetSplitVector(Vec,
Lo,
Hi);
1914 unsigned IdxVal = CIdx->getZExtValue();
1915 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
1916 if (IdxVal < LoNumElts) {
1918 Lo.getValueType(),
Lo, Elt,
Idx);
1964 Lo = DAG.
getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
1967 auto Load = cast<LoadSDNode>(
Lo);
1969 IncrementPointer(Load, LoVT, MPI, StackPtr);
1971 Hi = DAG.
getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
1975 if (LoVT !=
Lo.getValueType())
1977 if (HiVT !=
Hi.getValueType())
1985 assert(
N->getValueType(0).isScalableVector() &&
1986 "Only scalable vectors are supported for STEP_VECTOR");
2009 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2022 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
2023 auto [EVLLo, EVLHi] = DAG.
SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2024 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0), MaskLo, EVLLo);
2025 Hi = DAG.
getNode(
N->getOpcode(), dl, HiVT,
N->getOperand(0), MaskHi, EVLHi);
2039 EVT MemoryVT =
LD->getMemoryVT();
2043 EVT LoMemVT, HiMemVT;
2050 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2055 LD->getPointerInfo(), LoMemVT,
LD->getOriginalAlign(),
2059 IncrementPointer(LD, LoMemVT, MPI,
Ptr);
2062 HiMemVT,
LD->getOriginalAlign(), MMOFlags, AAInfo);
2071 ReplaceValueWith(
SDValue(LD, 1), Ch);
2076 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2085 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2086 Align Alignment =
LD->getOriginalAlign();
2089 EVT MemoryVT =
LD->getMemoryVT();
2091 EVT LoMemVT, HiMemVT;
2092 bool HiIsEmpty =
false;
2093 std::tie(LoMemVT, HiMemVT) =
2099 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2102 GetSplitVector(Mask, MaskLo, MaskHi);
2104 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, dl);
2109 std::tie(EVLLo, EVLHi) = DAG.
SplitEVL(EVL,
LD->getValueType(0), dl);
2118 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2127 LD->isExpandingLoad());
2133 MPI =
LD->getPointerInfo().getWithOffset(
2138 Alignment,
LD->getAAInfo(),
LD->getRanges());
2141 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2142 LD->isExpandingLoad());
2152 ReplaceValueWith(
SDValue(LD, 1), Ch);
2158 "Indexed VP strided load during type legalization!");
2160 "Unexpected indexed variable-length load offset");
2167 EVT LoMemVT, HiMemVT;
2168 bool HiIsEmpty =
false;
2169 std::tie(LoMemVT, HiMemVT) =
2175 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2178 GetSplitVector(Mask, LoMask, HiMask);
2184 std::tie(LoEVL, HiEVL) =
2222 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2233 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2246 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2255 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2258 GetSplitVector(Mask, MaskLo, MaskHi);
2260 std::tie(MaskLo, MaskHi) = DAG.
SplitVector(Mask, dl);
2264 EVT LoMemVT, HiMemVT;
2265 bool HiIsEmpty =
false;
2266 std::tie(LoMemVT, HiMemVT) =
2269 SDValue PassThruLo, PassThruHi;
2271 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2273 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, dl);
2316 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2333 if (
auto *MSC = dyn_cast<MaskedGatherSDNode>(
N)) {
2334 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2336 auto *VPSC = cast<VPGatherSDNode>(
N);
2337 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2340 EVT MemoryVT =
N->getMemoryVT();
2341 Align Alignment =
N->getOriginalAlign();
2345 if (SplitSETCC && Ops.Mask.getOpcode() ==
ISD::SETCC) {
2346 SplitVecRes_SETCC(Ops.Mask.getNode(), MaskLo, MaskHi);
2348 std::tie(MaskLo, MaskHi) = SplitMask(Ops.Mask, dl);
2351 EVT LoMemVT, HiMemVT;
2356 if (getTypeAction(Ops.Index.getValueType()) ==
2358 GetSplitVector(Ops.Index, IndexLo, IndexHi);
2360 std::tie(IndexLo, IndexHi) = DAG.
SplitVector(Ops.Index, dl);
2367 if (
auto *MGT = dyn_cast<MaskedGatherSDNode>(
N)) {
2368 SDValue PassThru = MGT->getPassThru();
2369 SDValue PassThruLo, PassThruHi;
2372 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2374 std::tie(PassThruLo, PassThruHi) = DAG.
SplitVector(PassThru, dl);
2379 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo,
Ptr, IndexLo, Ops.Scale};
2381 OpsLo, MMO, IndexTy, ExtType);
2383 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi,
Ptr, IndexHi, Ops.Scale};
2385 OpsHi, MMO, IndexTy, ExtType);
2387 auto *VPGT = cast<VPGatherSDNode>(
N);
2389 std::tie(EVLLo, EVLHi) =
2390 DAG.
SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2392 SDValue OpsLo[] = {Ch,
Ptr, IndexLo, Ops.Scale, MaskLo, EVLLo};
2394 MMO, VPGT->getIndexType());
2396 SDValue OpsHi[] = {Ch,
Ptr, IndexHi, Ops.Scale, MaskHi, EVLHi};
2398 MMO, VPGT->getIndexType());
2408 ReplaceValueWith(
SDValue(
N, 1), Ch);
2423 assert(
N->getValueType(0).isVector() &&
2424 N->getOperand(0).getValueType().isVector() &&
2425 "Operand types must be vectors");
2433 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2435 GetSplitVector(
N->getOperand(0), LL, LH);
2439 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2441 GetSplitVector(
N->getOperand(1), RL, RH);
2446 Lo = DAG.
getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2447 Hi = DAG.
getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2449 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2450 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2451 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2452 std::tie(EVLLo, EVLHi) =
2453 DAG.
SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2454 Lo = DAG.
getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2456 Hi = DAG.
getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2470 EVT InVT =
N->getOperand(0).getValueType();
2472 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2477 unsigned Opcode =
N->getOpcode();
2478 if (
N->getNumOperands() <= 2) {
2480 Lo = DAG.
getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2481 Hi = DAG.
getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2489 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2490 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2493 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2496 std::tie(EVLLo, EVLHi) =
2497 DAG.
SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2510 EVT InVT =
N->getOperand(0).getValueType();
2512 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2516 auto *AddrSpaceCastN = cast<AddrSpaceCastSDNode>(
N);
2517 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2518 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2523void DAGTypeLegalizer::SplitVecRes_FFREXP(
SDNode *
N,
unsigned ResNo,
2531 EVT InVT =
N->getOperand(0).getValueType();
2533 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2537 Lo = DAG.
getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo);
2538 Hi = DAG.
getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi);
2539 Lo->setFlags(
N->getFlags());
2540 Hi->setFlags(
N->getFlags());
2546 unsigned OtherNo = 1 - ResNo;
2547 EVT OtherVT =
N->getValueType(OtherNo);
2555 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2562 EVT SrcVT =
N->getOperand(0).getValueType();
2563 EVT DestVT =
N->getValueType(0);
2586 EVT SplitLoVT, SplitHiVT;
2590 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2591 N->dump(&DAG);
dbgs() <<
"\n");
2592 if (!
N->isVPOpcode()) {
2595 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2606 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2607 N->getOperand(1),
N->getOperand(2));
2612 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2615 std::tie(EVLLo, EVLHi) =
2616 DAG.
SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2618 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2619 Hi = DAG.
getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2624 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2632 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2633 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2639 return N.getResNo() == 0 &&
2643 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2648 "Expected build vector node.");
2651 for (
unsigned I = 0;
I < NewElts; ++
I) {
2656 Ops[
I] = Input2.getOperand(
Idx - NewElts);
2658 Ops[
I] = Input1.getOperand(
Idx);
2660 if (Ops[
I].getValueType().bitsGT(EltVT))
2663 return DAG.getBuildVector(NewVT,
DL, Ops);
2671 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2675 for (
unsigned Idx = 0;
Idx < std::size(Inputs); ++
Idx) {
2677 auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Input.
getNode());
2686 for (
auto &
P : ShufflesIdxs) {
2687 if (
P.second.size() < 2)
2691 for (
int &
Idx : Mask) {
2694 unsigned SrcRegIdx =
Idx / NewElts;
2695 if (Inputs[SrcRegIdx].
isUndef()) {
2700 dyn_cast<ShuffleVectorSDNode>(Inputs[SrcRegIdx].
getNode());
2703 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2708 Idx = MaskElt % NewElts +
2709 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
2715 Inputs[
P.second[0]] =
P.first.first;
2716 Inputs[
P.second[1]] =
P.first.second;
2719 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
2723 for (
int &
Idx : Mask) {
2726 unsigned SrcRegIdx =
Idx / NewElts;
2727 if (Inputs[SrcRegIdx].
isUndef()) {
2732 getTypeAction(Inputs[SrcRegIdx].getValueType());
2734 Inputs[SrcRegIdx].getNumOperands() == 2 &&
2735 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
2738 UsedSubVector.set(2 * SrcRegIdx + (
Idx % NewElts) / (NewElts / 2));
2740 if (UsedSubVector.count() > 1) {
2742 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
2743 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
2745 if (Pairs.
empty() || Pairs.
back().size() == 2)
2747 if (UsedSubVector.test(2 *
I)) {
2748 Pairs.
back().emplace_back(
I, 0);
2750 assert(UsedSubVector.test(2 *
I + 1) &&
2751 "Expected to be used one of the subvectors.");
2752 Pairs.
back().emplace_back(
I, 1);
2755 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
2757 for (
int &
Idx : Mask) {
2760 unsigned SrcRegIdx =
Idx / NewElts;
2762 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
2763 return Idxs.front().first == SrcRegIdx ||
2764 Idxs.back().first == SrcRegIdx;
2766 if (It == Pairs.
end())
2768 Idx = It->front().first * NewElts + (
Idx % NewElts) % (NewElts / 2) +
2769 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
2772 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
2773 Inputs[Idxs.front().first] = DAG.
getNode(
2775 Inputs[Idxs.front().first].getValueType(),
2776 Inputs[Idxs.front().first].
getOperand(Idxs.front().second),
2777 Inputs[Idxs.back().first].
getOperand(Idxs.back().second));
2786 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
2787 auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Inputs[
I].
getNode());
2790 if (Shuffle->getOperand(0).getValueType() != NewVT)
2793 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
2794 !Shuffle->isSplat()) {
2796 }
else if (!Inputs[
I].hasOneUse() &&
2797 !Shuffle->getOperand(1).isUndef()) {
2799 for (
int &
Idx : Mask) {
2802 unsigned SrcRegIdx =
Idx / NewElts;
2805 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2810 int OpIdx = MaskElt / NewElts;
2823 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
2824 if (Shuffle->getOperand(OpIdx).isUndef())
2826 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
2827 if (It == std::end(Inputs))
2829 int FoundOp = std::distance(std::begin(Inputs), It);
2832 for (
int &
Idx : Mask) {
2835 unsigned SrcRegIdx =
Idx / NewElts;
2838 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2843 int MaskIdx = MaskElt / NewElts;
2844 if (OpIdx == MaskIdx)
2845 Idx = MaskElt % NewElts + FoundOp * NewElts;
2848 Op = (OpIdx + 1) % 2;
2856 for (
int &
Idx : Mask) {
2859 unsigned SrcRegIdx =
Idx / NewElts;
2862 int MaskElt = Shuffle->getMaskElt(
Idx % NewElts);
2863 int OpIdx = MaskElt / NewElts;
2866 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
2872 TryPeekThroughShufflesInputs(OrigMask);
2874 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
2878 for (
const auto &
I : Inputs) {
2880 UniqueConstantInputs.
insert(
I);
2881 else if (!
I.isUndef())
2886 if (UniqueInputs.
size() != std::size(Inputs)) {
2887 auto &&UniqueVec = UniqueInputs.
takeVector();
2888 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
2889 unsigned ConstNum = UniqueConstantVec.size();
2890 for (
int &
Idx : Mask) {
2893 unsigned SrcRegIdx =
Idx / NewElts;
2894 if (Inputs[SrcRegIdx].
isUndef()) {
2898 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
2899 if (It != UniqueConstantVec.end()) {
2901 NewElts * std::distance(UniqueConstantVec.begin(), It);
2902 assert(
Idx >= 0 &&
"Expected defined mask idx.");
2905 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
2906 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
2908 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
2909 assert(
Idx >= 0 &&
"Expected defined mask idx.");
2911 copy(UniqueConstantVec, std::begin(Inputs));
2912 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
2915 MakeUniqueInputs(OrigMask);
2917 copy(Inputs, std::begin(OrigInputs));
2923 unsigned FirstMaskIdx =
High * NewElts;
2926 assert(!Output &&
"Expected default initialized initial value.");
2927 TryPeekThroughShufflesInputs(Mask);
2928 MakeUniqueInputs(Mask);
2930 copy(Inputs, std::begin(TmpInputs));
2933 bool SecondIteration =
false;
2934 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
2939 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) ==
Idx)
2940 SecondIteration =
true;
2941 return SecondIteration;
2944 Mask, std::size(Inputs), std::size(Inputs),
2946 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
2947 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
2950 Output = BuildVector(Inputs[
Idx], Inputs[
Idx], Mask);
2952 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[
Idx],
2953 DAG.getUNDEF(NewVT), Mask);
2954 Inputs[
Idx] = Output;
2956 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
2959 if (AccumulateResults(Idx1)) {
2962 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
2964 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
2965 Inputs[Idx2], Mask);
2969 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
2971 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
2972 TmpInputs[Idx2], Mask);
2974 Inputs[Idx1] = Output;
2976 copy(OrigInputs, std::begin(Inputs));
2981 EVT OVT =
N->getValueType(0);
2988 const Align Alignment =
2989 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
2991 Lo = DAG.getVAArg(NVT, dl, Chain,
Ptr, SV, Alignment.
value());
2992 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1),
Ptr, SV, Alignment.
value());
2993 Chain =
Hi.getValue(1);
2997 ReplaceValueWith(
SDValue(
N, 1), Chain);
3002 EVT DstVTLo, DstVTHi;
3003 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3007 EVT SrcVT =
N->getOperand(0).getValueType();
3009 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3011 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3013 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3014 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3020 GetSplitVector(
N->getOperand(0), InLo, InHi);
3032 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3037 EVT VT =
N->getValueType(0);
3044 Align Alignment = DAG.getReducedAlign(VT,
false);
3050 auto &MF = DAG.getMachineFunction();
3064 DAG.getConstant(1,
DL, PtrVT));
3066 DAG.getConstant(EltWidth,
DL, PtrVT));
3068 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3070 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3071 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3072 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3075 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3077 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3080void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3082 SDValue Op0Lo, Op0Hi, Op1Lo, Op1Hi;
3083 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
3084 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
3088 DAG.getVTList(VT, VT), Op0Lo, Op0Hi);
3090 DAG.getVTList(VT, VT), Op1Lo, Op1Hi);
3096void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3097 SDValue Op0Lo, Op0Hi, Op1Lo, Op1Hi;
3098 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
3099 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
3103 DAG.getVTList(VT, VT), Op0Lo, Op1Lo),
3105 DAG.getVTList(VT, VT), Op0Hi, Op1Hi)};
3107 SetSplitVector(
SDValue(
N, 0), Res[0].getValue(0), Res[0].getValue(1));
3108 SetSplitVector(
SDValue(
N, 1), Res[1].getValue(0), Res[1].getValue(1));
3119bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3124 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3127 switch (
N->getOpcode()) {
3130 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3139 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3145 case ISD::VP_TRUNCATE:
3147 Res = SplitVecOp_TruncateHelper(
N);
3150 case ISD::VP_FP_ROUND:
3154 Res = SplitVecOp_STORE(cast<StoreSDNode>(
N), OpNo);
3157 Res = SplitVecOp_VP_STORE(cast<VPStoreSDNode>(
N), OpNo);
3159 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3160 Res = SplitVecOp_VP_STRIDED_STORE(cast<VPStridedStoreSDNode>(
N), OpNo);
3163 Res = SplitVecOp_MSTORE(cast<MaskedStoreSDNode>(
N), OpNo);
3166 case ISD::VP_SCATTER:
3167 Res = SplitVecOp_Scatter(cast<MemSDNode>(
N), OpNo);
3170 case ISD::VP_GATHER:
3171 Res = SplitVecOp_Gather(cast<MemSDNode>(
N), OpNo);
3174 Res = SplitVecOp_VSELECT(
N, OpNo);
3180 case ISD::VP_SINT_TO_FP:
3181 case ISD::VP_UINT_TO_FP:
3182 if (
N->getValueType(0).bitsLT(
3183 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3184 Res = SplitVecOp_TruncateHelper(
N);
3186 Res = SplitVecOp_UnaryOp(
N);
3190 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3194 case ISD::VP_FP_TO_SINT:
3195 case ISD::VP_FP_TO_UINT:
3206 Res = SplitVecOp_UnaryOp(
N);
3209 Res = SplitVecOp_FPOpDifferentTypes(
N);
3214 Res = SplitVecOp_CMP(
N);
3220 Res = SplitVecOp_ExtVecInRegOp(
N);
3238 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3242 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3244 case ISD::VP_REDUCE_FADD:
3245 case ISD::VP_REDUCE_SEQ_FADD:
3246 case ISD::VP_REDUCE_FMUL:
3247 case ISD::VP_REDUCE_SEQ_FMUL:
3248 case ISD::VP_REDUCE_ADD:
3249 case ISD::VP_REDUCE_MUL:
3250 case ISD::VP_REDUCE_AND:
3251 case ISD::VP_REDUCE_OR:
3252 case ISD::VP_REDUCE_XOR:
3253 case ISD::VP_REDUCE_SMAX:
3254 case ISD::VP_REDUCE_SMIN:
3255 case ISD::VP_REDUCE_UMAX:
3256 case ISD::VP_REDUCE_UMIN:
3257 case ISD::VP_REDUCE_FMAX:
3258 case ISD::VP_REDUCE_FMIN:
3259 case ISD::VP_REDUCE_FMAXIMUM:
3260 case ISD::VP_REDUCE_FMINIMUM:
3261 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3263 case ISD::VP_CTTZ_ELTS:
3264 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3265 Res = SplitVecOp_VP_CttzElements(
N);
3270 if (!Res.
getNode())
return false;
3277 if (
N->isStrictFPOpcode())
3279 "Invalid operand expansion");
3282 "Invalid operand expansion");
3284 ReplaceValueWith(
SDValue(
N, 0), Res);
3288SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3291 assert(OpNo == 0 &&
"Illegal operand must be mask");
3298 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3301 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3302 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3303 "Lo and Hi have differing types");
3306 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3307 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3309 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3310 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3311 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3312 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3322SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3323 EVT ResVT =
N->getValueType(0);
3327 SDValue VecOp =
N->getOperand(OpNo);
3329 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3330 GetSplitVector(VecOp,
Lo,
Hi);
3332 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3338 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3342 EVT ResVT =
N->getValueType(0);
3351 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3352 GetSplitVector(VecOp,
Lo,
Hi);
3354 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3360 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3363SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3364 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3365 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3367 unsigned Opc =
N->getOpcode();
3368 EVT ResVT =
N->getValueType(0);
3372 SDValue VecOp =
N->getOperand(OpNo);
3374 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3375 GetSplitVector(VecOp,
Lo,
Hi);
3378 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3381 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3386 DAG.
getNode(Opc, dl, ResVT, {
N->getOperand(0),
Lo, MaskLo, EVLLo},
Flags);
3387 return DAG.getNode(Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3392 EVT ResVT =
N->getValueType(0);
3395 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3396 EVT InVT =
Lo.getValueType();
3401 if (
N->isStrictFPOpcode()) {
3402 Lo = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3403 { N->getOperand(0), Lo });
3404 Hi = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3405 { N->getOperand(0), Hi });
3414 ReplaceValueWith(
SDValue(
N, 1), Ch);
3415 }
else if (
N->getNumOperands() == 3) {
3416 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3417 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3418 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3419 std::tie(EVLLo, EVLHi) =
3420 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3421 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3422 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3424 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3425 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3435 EVT ResVT =
N->getValueType(0);
3437 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3441 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3447 Lo = BitConvertToInteger(
Lo);
3448 Hi = BitConvertToInteger(
Hi);
3450 if (DAG.getDataLayout().isBigEndian())
3458 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3460 EVT ResVT =
N->getValueType(0);
3468 GetSplitVector(SubVec,
Lo,
Hi);
3471 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
3477 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3479 return SecondInsertion;
3482SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3484 EVT SubVT =
N->getValueType(0);
3489 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3491 uint64_t LoEltsMin =
Lo.getValueType().getVectorMinNumElements();
3494 if (IdxVal < LoEltsMin) {
3496 "Extracted subvector crosses vector split!");
3499 N->getOperand(0).getValueType().isScalableVector())
3501 DAG.getVectorIdxConstant(IdxVal - LoEltsMin, dl));
3506 "Extracting scalable subvector from fixed-width unsupported");
3514 "subvector from a scalable predicate vector");
3520 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
3522 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
3523 auto &MF = DAG.getMachineFunction();
3527 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
3534 SubVT, dl, Store, StackPtr,
3538SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
3547 GetSplitVector(Vec,
Lo,
Hi);
3549 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
3551 if (IdxVal < LoElts)
3555 DAG.getConstant(IdxVal - LoElts,
SDLoc(
N),
3556 Idx.getValueType())), 0);
3560 if (CustomLowerNode(
N,
N->getValueType(0),
true))
3572 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
3578 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
3580 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
3581 auto &MF = DAG.getMachineFunction();
3584 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
3592 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
3594 return DAG.getExtLoad(
3605 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
3613 SplitVecRes_Gather(
N,
Lo,
Hi);
3616 ReplaceValueWith(
SDValue(
N, 0), Res);
3621 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
3625 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
3627 SDValue EVL =
N->getVectorLength();
3629 Align Alignment =
N->getOriginalAlign();
3635 GetSplitVector(
Data, DataLo, DataHi);
3637 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
3642 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
3645 GetSplitVector(Mask, MaskLo, MaskHi);
3647 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
3650 EVT MemoryVT =
N->getMemoryVT();
3651 EVT LoMemVT, HiMemVT;
3652 bool HiIsEmpty =
false;
3653 std::tie(LoMemVT, HiMemVT) =
3654 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
3658 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
3666 Lo = DAG.getStoreVP(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
3667 N->getAddressingMode(),
N->isTruncatingStore(),
3668 N->isCompressingStore());
3675 N->isCompressingStore());
3683 MPI =
N->getPointerInfo().getWithOffset(
3686 MMO = DAG.getMachineFunction().getMachineMemOperand(
3688 Alignment,
N->getAAInfo(),
N->getRanges());
3690 Hi = DAG.getStoreVP(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
3691 N->getAddressingMode(),
N->isTruncatingStore(),
3692 N->isCompressingStore());
3701 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
3702 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
3709 GetSplitVector(
Data, LoData, HiData);
3711 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
3713 EVT LoMemVT, HiMemVT;
3714 bool HiIsEmpty =
false;
3715 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
3721 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
3722 else if (getTypeAction(
Mask.getValueType()) ==
3724 GetSplitVector(Mask, LoMask, HiMask);
3726 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3729 std::tie(LoEVL, HiEVL) =
3730 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
3734 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
3735 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
3736 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
3747 EVT PtrVT =
N->getBasePtr().getValueType();
3750 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
3753 Align Alignment =
N->getOriginalAlign();
3761 Alignment,
N->getAAInfo(),
N->getRanges());
3764 N->getChain(),
DL, HiData,
Ptr,
N->getOffset(),
N->getStride(), HiMask,
3765 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
3766 N->isCompressingStore());
3775 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
3779 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
3782 Align Alignment =
N->getOriginalAlign();
3788 GetSplitVector(
Data, DataLo, DataHi);
3790 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
3795 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
3798 GetSplitVector(Mask, MaskLo, MaskHi);
3800 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
3803 EVT MemoryVT =
N->getMemoryVT();
3804 EVT LoMemVT, HiMemVT;
3805 bool HiIsEmpty =
false;
3806 std::tie(LoMemVT, HiMemVT) =
3807 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
3815 Lo = DAG.getMaskedStore(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, LoMemVT, MMO,
3816 N->getAddressingMode(),
N->isTruncatingStore(),
3817 N->isCompressingStore());
3826 N->isCompressingStore());
3834 MPI =
N->getPointerInfo().getWithOffset(
3837 MMO = DAG.getMachineFunction().getMachineMemOperand(
3839 Alignment,
N->getAAInfo(),
N->getRanges());
3841 Hi = DAG.getMaskedStore(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, HiMemVT, MMO,
3842 N->getAddressingMode(),
N->isTruncatingStore(),
3843 N->isCompressingStore());
3856 EVT MemoryVT =
N->getMemoryVT();
3857 Align Alignment =
N->getOriginalAlign();
3865 if (
auto *MSC = dyn_cast<MaskedScatterSDNode>(
N)) {
3866 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
3869 auto *VPSC = cast<VPScatterSDNode>(
N);
3870 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
3875 EVT LoMemVT, HiMemVT;
3876 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
3881 GetSplitVector(Ops.Data, DataLo, DataHi);
3883 std::tie(DataLo, DataHi) = DAG.SplitVector(Ops.Data,
DL);
3887 if (OpNo == 1 && Ops.Mask.getOpcode() ==
ISD::SETCC) {
3888 SplitVecRes_SETCC(Ops.Mask.getNode(), MaskLo, MaskHi);
3890 std::tie(MaskLo, MaskHi) = SplitMask(Ops.Mask,
DL);
3894 if (getTypeAction(Ops.Index.getValueType()) ==
3896 GetSplitVector(Ops.Index, IndexLo, IndexHi);
3898 std::tie(IndexLo, IndexHi) = DAG.SplitVector(Ops.Index,
DL);
3906 if (
auto *MSC = dyn_cast<MaskedScatterSDNode>(
N)) {
3907 SDValue OpsLo[] = {Ch, DataLo, MaskLo,
Ptr, IndexLo, Ops.Scale};
3909 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
3910 MSC->getIndexType(), MSC->isTruncatingStore());
3915 SDValue OpsHi[] = {
Lo, DataHi, MaskHi,
Ptr, IndexHi, Ops.Scale};
3916 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
3917 MMO, MSC->getIndexType(),
3918 MSC->isTruncatingStore());
3920 auto *VPSC = cast<VPScatterSDNode>(
N);
3922 std::tie(EVLLo, EVLHi) =
3923 DAG.SplitEVL(VPSC->getVectorLength(), Ops.Data.getValueType(),
DL);
3925 SDValue OpsLo[] = {Ch, DataLo,
Ptr, IndexLo, Ops.Scale, MaskLo, EVLLo};
3926 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
3927 VPSC->getIndexType());
3932 SDValue OpsHi[] = {
Lo, DataHi,
Ptr, IndexHi, Ops.Scale, MaskHi, EVLHi};
3933 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
3934 VPSC->getIndexType());
3938 assert(
N->isUnindexed() &&
"Indexed store of vector?");
3939 assert(OpNo == 1 &&
"Can only split the stored value");
3942 bool isTruncating =
N->isTruncatingStore();
3945 EVT MemoryVT =
N->getMemoryVT();
3946 Align Alignment =
N->getOriginalAlign();
3950 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3952 EVT LoMemVT, HiMemVT;
3953 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
3960 Lo = DAG.getTruncStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), LoMemVT,
3961 Alignment, MMOFlags, AAInfo);
3963 Lo = DAG.getStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
3967 IncrementPointer(
N, LoMemVT, MPI,
Ptr);
3970 Hi = DAG.getTruncStore(Ch,
DL,
Hi,
Ptr, MPI,
3971 HiMemVT, Alignment, MMOFlags, AAInfo);
3973 Hi = DAG.getStore(Ch,
DL,
Hi,
Ptr, MPI, Alignment, MMOFlags, AAInfo);
3987 EVT EltVT =
N->getValueType(0).getVectorElementType();
3989 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
3992 DAG.getVectorIdxConstant(i,
DL)));
3996 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4017 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4018 SDValue InVec =
N->getOperand(OpNo);
4020 EVT OutVT =
N->getValueType(0);
4028 EVT LoOutVT, HiOutVT;
4029 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4030 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4035 if (isTypeLegal(LoOutVT) ||
4036 InElementSize <= OutElementSize * 2)
4037 return SplitVecOp_UnaryOp(
N);
4046 return SplitVecOp_UnaryOp(
N);
4050 GetSplitVector(InVec, InLoVec, InHiVec);
4056 EVT HalfElementVT = IsFloat ?
4058 EVT::getIntegerVT(*DAG.getContext(), InElementSize/2);
4065 if (
N->isStrictFPOpcode()) {
4066 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4067 {N->getOperand(0), InLoVec});
4068 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4069 {N->getOperand(0), InHiVec});
4075 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4076 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4088 if (
N->isStrictFPOpcode()) {
4092 DAG.getTargetConstant(0,
DL, TLI.
getPointerTy(DAG.getDataLayout()))});
4100 DAG.getTargetConstant(
4107 assert(
N->getValueType(0).isVector() &&
4108 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4109 "Operand types must be vectors");
4111 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4113 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4114 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);