35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
46 switch (
N->getOpcode()) {
49 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
58 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
66 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
72 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
84 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
86 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
92 R = ScalarizeVecRes_VecInregOp(
N);
143 R = ScalarizeVecRes_UnaryOp(
N);
146 R = ScalarizeVecRes_ADDRSPACECAST(
N);
152 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
209 R = ScalarizeVecRes_BinOp(
N);
214 R = ScalarizeVecRes_CMP(
N);
220 R = ScalarizeVecRes_TernaryOp(
N);
223#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
224 case ISD::STRICT_##DAGN:
225#include "llvm/IR/ConstrainedOps.def"
226 R = ScalarizeVecRes_StrictFPOp(
N);
231 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
240 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
250 R = ScalarizeVecRes_FIX(
N);
256 SetScalarizedVector(
SDValue(
N, ResNo), R);
260 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
261 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
262 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
271 if (getTypeAction(
LHS.getValueType()) ==
273 LHS = GetScalarizedVector(
LHS);
274 RHS = GetScalarizedVector(
RHS);
276 EVT VT =
LHS.getValueType().getVectorElementType();
277 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
278 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
281 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
282 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
286 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
287 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
288 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
289 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
294 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
295 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
302DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
304 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
305 "Unexpected vector type!");
306 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
308 EVT VT0 =
N->getValueType(0);
309 EVT VT1 =
N->getValueType(1);
313 DAG.getNode(
N->getOpcode(), dl,
314 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
318 unsigned OtherNo = 1 - ResNo;
319 EVT OtherVT =
N->getValueType(OtherNo);
321 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
325 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
328 return SDValue(ScalarNode, ResNo);
333 unsigned NumOpers =
N->getNumOperands();
335 EVT ValueVTs[] = {VT, MVT::Other};
344 for (
unsigned i = 1; i < NumOpers; ++i) {
350 Oper = GetScalarizedVector(Oper);
359 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
360 Opers,
N->getFlags());
371 EVT ResVT =
N->getValueType(0);
372 EVT OvVT =
N->getValueType(1);
376 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
377 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
380 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
381 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
382 ScalarLHS = ElemsLHS[0];
383 ScalarRHS = ElemsRHS[0];
386 SDVTList ScalarVTs = DAG.getVTList(
388 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
389 {ScalarLHS, ScalarRHS},
N->getFlags())
393 unsigned OtherNo = 1 - ResNo;
394 EVT OtherVT =
N->getValueType(OtherNo);
396 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
400 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
403 return SDValue(ScalarNode, ResNo);
408 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
409 return GetScalarizedVector(
Op);
412SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
414 SDValue SourceValue =
N->getOperand(0);
415 SDValue SinkValue =
N->getOperand(1);
416 SDValue EltSizeInBytes =
N->getOperand(2);
417 SDValue LaneOffset =
N->getOperand(3);
425 if (IsReadAfterWrite)
433 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
438 return DAG.getNode(
ISD::OR,
DL, CmpVT, Cmp,
445 Op = GetScalarizedVector(
Op);
446 EVT NewVT =
N->getValueType(0).getVectorElementType();
451SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
461SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
463 N->getValueType(0).getVectorElementType(),
464 N->getOperand(0),
N->getOperand(1));
470 EVT OpVT =
Op.getValueType();
474 Op = GetScalarizedVector(
Op);
477 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
480 N->getValueType(0).getVectorElementType(),
Op,
484SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
487 EVT OpVT =
Op.getValueType();
491 Op = GetScalarizedVector(
Op);
494 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
497 N->getValueType(0).getVectorElementType(),
Op,
501SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
502 SDValue Op = GetScalarizedVector(
N->getOperand(0));
503 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
507SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
512 if (
Op.getValueType() != EltVT)
520 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
521 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
531 assert(
N->isUnindexed() &&
"Indexed vector load?");
535 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
536 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
537 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
538 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
550 EVT OpVT =
Op.getValueType();
560 Op = GetScalarizedVector(
Op);
563 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
565 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
571 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
572 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
573 LHS, DAG.getValueType(ExtVT));
580 EVT OpVT =
Op.getValueType();
585 Op = GetScalarizedVector(
Op);
587 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
590 switch (
N->getOpcode()) {
602SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
605 EVT OpVT =
Op.getValueType();
615 Op = GetScalarizedVector(
Op);
618 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
621 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
622 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
623 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
626SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
638 EVT OpVT =
Cond.getValueType();
647 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
650 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
652 TLI.getBooleanContents(
false,
false);
659 if (TLI.getBooleanContents(
false,
false) !=
660 TLI.getBooleanContents(
false,
true)) {
664 EVT OpVT =
Cond->getOperand(0).getValueType();
666 VecBool = TLI.getBooleanContents(OpVT);
671 EVT CondVT =
Cond.getValueType();
672 if (ScalarBool != VecBool) {
673 switch (ScalarBool) {
681 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
688 Cond, DAG.getValueType(MVT::i1));
694 auto BoolVT = getSetCCResultType(CondVT);
695 if (BoolVT.bitsLT(CondVT))
698 return DAG.getSelect(SDLoc(
N),
700 GetScalarizedVector(
N->getOperand(2)));
704 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
705 return DAG.getSelect(SDLoc(
N),
706 LHS.getValueType(),
N->getOperand(0),
LHS,
707 GetScalarizedVector(
N->getOperand(2)));
711 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
713 N->getOperand(0),
N->getOperand(1),
714 LHS, GetScalarizedVector(
N->getOperand(3)),
719 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
722SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
726 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
728 return GetScalarizedVector(
N->getOperand(
Op));
731SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
733 EVT SrcVT = Src.getValueType();
738 Src = GetScalarizedVector(Src);
742 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
744 EVT DstVT =
N->getValueType(0).getVectorElementType();
745 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
749 assert(
N->getValueType(0).isVector() &&
750 N->getOperand(0).getValueType().isVector() &&
751 "Operand types must be vectors");
754 EVT OpVT =
LHS.getValueType();
755 EVT NVT =
N->getValueType(0).getVectorElementType();
760 LHS = GetScalarizedVector(
LHS);
761 RHS = GetScalarizedVector(
RHS);
764 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
765 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
775 return DAG.getNode(ExtendCode,
DL, NVT, Res);
786 Arg = GetScalarizedVector(Arg);
789 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
798 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
805bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
810 switch (
N->getOpcode()) {
813 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
820 Res = ScalarizeVecOp_BITCAST(
N);
823 Res = ScalarizeVecOp_FAKE_USE(
N);
837 Res = ScalarizeVecOp_UnaryOp(
N);
842 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
848 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
851 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
854 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
857 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
860 Res = ScalarizeVecOp_VSELECT(
N);
863 Res = ScalarizeVecOp_VSETCC(
N);
867 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
873 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
876 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
879 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
882 Res = ScalarizeVecOp_FP_EXTEND(
N);
899 Res = ScalarizeVecOp_VECREDUCE(
N);
903 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
907 Res = ScalarizeVecOp_CMP(
N);
910 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
914 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
919 if (!Res.
getNode())
return false;
927 "Invalid operand expansion");
929 ReplaceValueWith(
SDValue(
N, 0), Res);
936 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
938 N->getValueType(0), Elt);
943 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
944 "Fake Use: Unexpected vector type!");
945 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
946 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
952 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
953 "Unexpected vector type!");
954 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
956 N->getValueType(0).getScalarType(), Elt);
964SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
965 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
966 "Unexpected vector type!");
967 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
969 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
970 Elt,
N->getOperand(1));
978SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
979 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
980 "Unexpected vector type!");
981 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
983 {
N->getValueType(0).getScalarType(), MVT::Other },
984 {
N->getOperand(0), Elt });
994 ReplaceValueWith(
SDValue(
N, 0), Res);
999SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1001 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1002 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1003 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1008SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1012 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1013 SDValue ContainingVec =
N->getOperand(0);
1021SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1022 EVT VT =
N->getValueType(0);
1023 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1035 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1036 EVT VT =
N->getValueType(0);
1038 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1046 assert(
N->getValueType(0).isVector() &&
1047 N->getOperand(0).getValueType().isVector() &&
1048 "Operand types must be vectors");
1049 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1051 EVT VT =
N->getValueType(0);
1052 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1053 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1055 EVT OpVT =
N->getOperand(0).getValueType();
1067 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1073SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1075 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1076 assert(
N->getValueType(0).isVector() &&
1077 N->getOperand(1).getValueType().isVector() &&
1078 "Operand types must be vectors");
1079 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1081 EVT VT =
N->getValueType(0);
1083 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1084 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1087 EVT OpVT =
N->getOperand(1).getValueType();
1091 {Ch, LHS, RHS, CC});
1100 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1105 ReplaceValueWith(
SDValue(
N, 0), Res);
1112 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1113 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1116 if (
N->isTruncatingStore())
1117 return DAG.getTruncStore(
1118 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1119 N->getBasePtr(),
N->getPointerInfo(),
1120 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1121 N->getMemOperand()->getFlags(),
N->getAAInfo());
1123 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1124 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1125 N->getMemOperand()->getFlags(),
N->getAAInfo());
1130SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1131 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1132 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1134 N->getValueType(0).getVectorElementType(), Elt,
1139SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1141 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1142 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1145 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1155 ReplaceValueWith(
SDValue(
N, 0), Res);
1162 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1164 N->getValueType(0).getVectorElementType(), Elt);
1170SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1171 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1174 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1175 {
N->getOperand(0), Elt});
1184 ReplaceValueWith(
SDValue(
N, 0), Res);
1189 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1196SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1202 SDValue Op = GetScalarizedVector(VecOp);
1203 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1204 AccOp,
Op,
N->getFlags());
1208 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1209 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1216SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1224 EVT VT =
N->getValueType(0);
1225 return DAG.getConstant(0, SDLoc(
N), VT);
1232 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1233 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1235 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1236 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1237 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1248void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1253 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1256 switch (
N->getOpcode()) {
1259 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1268 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1276 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1292 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1295 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1304 case ISD::VP_LOAD_FF:
1307 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1314 case ISD::VP_GATHER:
1318 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1322 SplitVecRes_SETCC(
N,
Lo,
Hi);
1325 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1332 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1335 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1338 SplitVecRes_VECTOR_INTERLEAVE(
N);
1341 SplitVecRes_VAARG(
N,
Lo,
Hi);
1347 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1353 case ISD::VP_BITREVERSE:
1361 case ISD::VP_CTLZ_ZERO_UNDEF:
1363 case ISD::VP_CTTZ_ZERO_UNDEF:
1378 case ISD::VP_FFLOOR:
1383 case ISD::VP_FNEARBYINT:
1388 case ISD::VP_FP_EXTEND:
1390 case ISD::VP_FP_ROUND:
1392 case ISD::VP_FP_TO_SINT:
1394 case ISD::VP_FP_TO_UINT:
1400 case ISD::VP_LLRINT:
1402 case ISD::VP_FROUND:
1404 case ISD::VP_FROUNDEVEN:
1413 case ISD::VP_FROUNDTOZERO:
1415 case ISD::VP_SINT_TO_FP:
1417 case ISD::VP_TRUNCATE:
1419 case ISD::VP_UINT_TO_FP:
1423 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1426 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1432 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1438 case ISD::VP_SIGN_EXTEND:
1439 case ISD::VP_ZERO_EXTEND:
1440 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1462 case ISD::VP_FMINNUM:
1465 case ISD::VP_FMAXNUM:
1467 case ISD::VP_FMINIMUM:
1469 case ISD::VP_FMAXIMUM:
1478 case ISD::OR:
case ISD::VP_OR:
1498 case ISD::VP_FCOPYSIGN:
1499 SplitVecRes_BinOp(
N,
Lo,
Hi);
1506 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1510 SplitVecRes_CMP(
N,
Lo,
Hi);
1513#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1514 case ISD::STRICT_##DAGN:
1515#include "llvm/IR/ConstrainedOps.def"
1516 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1521 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1530 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1540 SplitVecRes_FIX(
N,
Lo,
Hi);
1542 case ISD::EXPERIMENTAL_VP_SPLICE:
1543 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1545 case ISD::EXPERIMENTAL_VP_REVERSE:
1546 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1552 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1555 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1564void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1566 uint64_t *ScaledOffset) {
1571 SDValue BytesIncrement = DAG.getVScale(
1574 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1576 *ScaledOffset += IncrementSize;
1586std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1587 return SplitMask(Mask, SDLoc(Mask));
1590std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1593 EVT MaskVT =
Mask.getValueType();
1595 GetSplitVector(Mask, MaskLo, MaskHi);
1597 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1598 return std::make_pair(MaskLo, MaskHi);
1603 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1605 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1608 const SDNodeFlags
Flags =
N->getFlags();
1609 unsigned Opcode =
N->getOpcode();
1610 if (
N->getNumOperands() == 2) {
1611 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1612 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1616 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1617 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1620 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1623 std::tie(EVLLo, EVLHi) =
1624 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1627 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1629 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1635 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1637 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1639 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1642 const SDNodeFlags
Flags =
N->getFlags();
1643 unsigned Opcode =
N->getOpcode();
1644 if (
N->getNumOperands() == 3) {
1645 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1646 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1650 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1651 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1654 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1657 std::tie(EVLLo, EVLHi) =
1658 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1661 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1663 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1667 LLVMContext &Ctxt = *DAG.getContext();
1673 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1675 GetSplitVector(
LHS, LHSLo, LHSHi);
1676 GetSplitVector(
RHS, RHSLo, RHSHi);
1678 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1679 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1683 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1684 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1689 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1691 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1695 unsigned Opcode =
N->getOpcode();
1696 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1698 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1707 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1714 switch (getTypeAction(InVT)) {
1728 GetExpandedOp(InOp,
Lo,
Hi);
1729 if (DAG.getDataLayout().isBigEndian())
1739 GetSplitVector(InOp,
Lo,
Hi);
1748 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1757 if (DAG.getDataLayout().isBigEndian())
1760 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1762 if (DAG.getDataLayout().isBigEndian())
1768void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1774 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1777 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1782 unsigned LaneOffset =
1785 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1787 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1794 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1797 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1800 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1805 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1807 unsigned NumSubvectors =
N->getNumOperands() / 2;
1808 if (NumSubvectors == 1) {
1809 Lo =
N->getOperand(0);
1810 Hi =
N->getOperand(1);
1815 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1824void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1831 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1846 GetSplitVector(Vec,
Lo,
Hi);
1849 EVT LoVT =
Lo.getValueType();
1859 if (IdxVal + SubElems <= LoElems) {
1867 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1869 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1875 SDValue WideSubVec = GetWidenedVector(SubVec);
1877 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1885 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1887 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1888 auto &MF = DAG.getMachineFunction();
1892 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1897 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1898 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1902 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1907 MachinePointerInfo MPI =
Load->getPointerInfo();
1908 IncrementPointer(Load, LoVT, MPI, StackPtr);
1911 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1920 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1925 EVT RHSVT =
RHS.getValueType();
1928 GetSplitVector(
RHS, RHSLo, RHSHi);
1930 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1945 SDValue FpValue =
N->getOperand(0);
1947 GetSplitVector(FpValue, ArgLo, ArgHi);
1949 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1951 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1960 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1964 std::tie(LoVT, HiVT) =
1968 DAG.getValueType(LoVT));
1970 DAG.getValueType(HiVT));
1975 unsigned Opcode =
N->getOpcode();
1982 GetSplitVector(N0, InLo, InHi);
1984 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1989 EVT OutLoVT, OutHiVT;
1990 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1992 assert((2 * OutNumElements) <= InNumElements &&
1993 "Illegal extend vector in reg split");
2002 SmallVector<int, 8> SplitHi(InNumElements, -1);
2003 for (
unsigned i = 0; i != OutNumElements; ++i)
2004 SplitHi[i] = i + OutNumElements;
2005 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2007 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2008 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2013 unsigned NumOps =
N->getNumOperands();
2017 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2027 for (
unsigned i = 1; i <
NumOps; ++i) {
2032 EVT InVT =
Op.getValueType();
2037 GetSplitVector(
Op, OpLo, OpHi);
2039 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2046 EVT LoValueVTs[] = {LoVT, MVT::Other};
2047 EVT HiValueVTs[] = {HiVT, MVT::Other};
2048 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2050 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2056 Lo.getValue(1),
Hi.getValue(1));
2060 ReplaceValueWith(
SDValue(
N, 1), Chain);
2063SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2065 EVT VT =
N->getValueType(0);
2076 else if (NE > ResNE)
2080 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2084 for (i = 0; i !=
NE; ++i) {
2085 Operands[0] = Chain;
2086 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2087 SDValue Operand =
N->getOperand(j);
2091 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2093 Operands[
j] = Operand;
2097 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2105 for (; i < ResNE; ++i)
2106 Scalars.
push_back(DAG.getPOISON(EltVT));
2110 ReplaceValueWith(
SDValue(
N, 1), Chain);
2114 return DAG.getBuildVector(VecVT, dl, Scalars);
2117void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2120 EVT ResVT =
N->getValueType(0);
2121 EVT OvVT =
N->getValueType(1);
2122 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2123 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2124 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2126 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2128 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2129 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2131 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2132 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2135 unsigned Opcode =
N->getOpcode();
2136 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2137 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2139 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2141 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2147 unsigned OtherNo = 1 - ResNo;
2148 EVT OtherVT =
N->getValueType(OtherNo);
2150 SetSplitVector(
SDValue(
N, OtherNo),
2156 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2160void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2166 GetSplitVector(Vec,
Lo,
Hi);
2169 unsigned IdxVal = CIdx->getZExtValue();
2170 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2171 if (IdxVal < LoNumElts) {
2173 Lo.getValueType(),
Lo, Elt, Idx);
2176 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2196 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2198 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2199 auto &MF = DAG.getMachineFunction();
2203 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2208 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2209 Store = DAG.getTruncStore(
2215 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2218 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2222 MachinePointerInfo MPI =
Load->getPointerInfo();
2223 IncrementPointer(Load, LoVT, MPI, StackPtr);
2225 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2228 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2229 if (LoVT !=
Lo.getValueType())
2231 if (HiVT !=
Hi.getValueType())
2239 assert(
N->getValueType(0).isScalableVector() &&
2240 "Only scalable vectors are supported for STEP_VECTOR");
2241 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2262 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2263 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2265 Hi = DAG.getPOISON(HiVT);
2277 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2283 EVT MemoryVT =
LD->getMemoryVT();
2285 AAMDNodes AAInfo =
LD->getAAInfo();
2287 EVT LoMemVT, HiMemVT;
2288 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2292 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2293 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2294 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2299 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2302 MachinePointerInfo MPI;
2303 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2306 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2315 ReplaceValueWith(
SDValue(LD, 1), Ch);
2320 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2323 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2329 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2330 Align Alignment =
LD->getBaseAlign();
2333 EVT MemoryVT =
LD->getMemoryVT();
2335 EVT LoMemVT, HiMemVT;
2336 bool HiIsEmpty =
false;
2337 std::tie(LoMemVT, HiMemVT) =
2338 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2343 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2346 GetSplitVector(Mask, MaskLo, MaskHi);
2348 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2353 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2355 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2361 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2362 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2370 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2371 LD->isExpandingLoad());
2373 MachinePointerInfo MPI;
2375 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2377 MPI =
LD->getPointerInfo().getWithOffset(
2380 MMO = DAG.getMachineFunction().getMachineMemOperand(
2382 Alignment,
LD->getAAInfo(),
LD->getRanges());
2384 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2385 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2386 LD->isExpandingLoad());
2396 ReplaceValueWith(
SDValue(LD, 1), Ch);
2402 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2406 Align Alignment =
LD->getBaseAlign();
2413 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2416 GetSplitVector(Mask, MaskLo, MaskHi);
2418 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2422 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2424 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2429 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2432 Hi = DAG.getPOISON(HiVT);
2434 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2435 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2441 "Indexed VP strided load during type legalization!");
2443 "Unexpected indexed variable-length load offset");
2448 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2450 EVT LoMemVT, HiMemVT;
2451 bool HiIsEmpty =
false;
2452 std::tie(LoMemVT, HiMemVT) =
2453 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2458 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2461 GetSplitVector(Mask, LoMask, HiMask);
2463 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2467 std::tie(LoEVL, HiEVL) =
2471 Lo = DAG.getStridedLoadVP(
2498 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2505 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2516 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2524 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2529 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2539 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2542 GetSplitVector(Mask, MaskLo, MaskHi);
2544 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2548 EVT LoMemVT, HiMemVT;
2549 bool HiIsEmpty =
false;
2550 std::tie(LoMemVT, HiMemVT) =
2551 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2553 SDValue PassThruLo, PassThruHi;
2555 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2557 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2559 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2563 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2573 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2576 MachinePointerInfo MPI;
2583 MMO = DAG.getMachineFunction().getMachineMemOperand(
2587 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2599 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2607 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2615 }
Ops = [&]() -> Operands {
2617 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2620 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2623 EVT MemoryVT =
N->getMemoryVT();
2624 Align Alignment =
N->getBaseAlign();
2629 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2631 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2634 EVT LoMemVT, HiMemVT;
2636 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2639 if (getTypeAction(
Ops.Index.getValueType()) ==
2641 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2643 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2646 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2648 Alignment,
N->getAAInfo(),
N->getRanges());
2651 SDValue PassThru = MGT->getPassThru();
2652 SDValue PassThruLo, PassThruHi;
2655 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2657 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2662 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2663 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2664 OpsLo, MMO, IndexTy, ExtType);
2666 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2667 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2668 OpsHi, MMO, IndexTy, ExtType);
2672 std::tie(EVLLo, EVLHi) =
2673 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2675 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2676 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2677 MMO, VPGT->getIndexType());
2679 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2680 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2681 MMO, VPGT->getIndexType());
2691 ReplaceValueWith(
SDValue(
N, 1), Ch);
2705 EVT VecVT =
N->getValueType(0);
2707 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2708 bool HasCustomLowering =
false;
2715 HasCustomLowering =
true;
2721 SDValue Passthru =
N->getOperand(2);
2722 if (!HasCustomLowering) {
2723 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2724 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2731 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2732 std::tie(LoMask, HiMask) = SplitMask(Mask);
2734 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2739 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2740 MachineFunction &MF = DAG.getMachineFunction();
2752 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2754 SDValue Chain = DAG.getEntryNode();
2755 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2759 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2764 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2768 assert(
N->getValueType(0).isVector() &&
2769 N->getOperand(0).getValueType().isVector() &&
2770 "Operand types must be vectors");
2774 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2778 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2780 GetSplitVector(
N->getOperand(0), LL, LH);
2782 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2784 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2786 GetSplitVector(
N->getOperand(1), RL, RH);
2788 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2791 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2792 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2794 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2795 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2796 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2797 std::tie(EVLLo, EVLHi) =
2798 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2799 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2801 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2811 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2815 EVT InVT =
N->getOperand(0).getValueType();
2817 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2819 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2821 const SDNodeFlags
Flags =
N->getFlags();
2822 unsigned Opcode =
N->getOpcode();
2823 if (
N->getNumOperands() <= 2) {
2826 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2827 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2829 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2830 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2835 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2836 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2839 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2842 std::tie(EVLLo, EVLHi) =
2843 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2846 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2852 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2856 EVT InVT =
N->getOperand(0).getValueType();
2858 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2860 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2863 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2864 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2865 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2866 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2869void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2874 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2875 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2879 EVT InVT =
N->getOperand(0).getValueType();
2881 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2883 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2885 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2886 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2888 SDNode *HiNode =
Hi.getNode();
2889 SDNode *LoNode =
Lo.getNode();
2892 unsigned OtherNo = 1 - ResNo;
2893 EVT OtherVT =
N->getValueType(OtherNo);
2901 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2908 EVT SrcVT =
N->getOperand(0).getValueType();
2909 EVT DestVT =
N->getValueType(0);
2911 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2928 LLVMContext &Ctx = *DAG.getContext();
2932 EVT SplitLoVT, SplitHiVT;
2933 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2934 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2935 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2936 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2937 N->dump(&DAG);
dbgs() <<
"\n");
2938 if (!
N->isVPOpcode()) {
2941 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2943 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2945 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2946 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2952 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2953 N->getOperand(1),
N->getOperand(2));
2955 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2958 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2961 std::tie(EVLLo, EVLHi) =
2962 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2964 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2965 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2970 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2978 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2979 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2985 return N.getResNo() == 0 &&
2989 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2991 ArrayRef<int>
Mask) {
2994 "Expected build vector node.");
2997 for (
unsigned I = 0;
I < NewElts; ++
I) {
3000 unsigned Idx =
Mask[
I];
3002 Ops[
I] = Input2.getOperand(Idx - NewElts);
3004 Ops[
I] = Input1.getOperand(Idx);
3009 return DAG.getBuildVector(NewVT,
DL,
Ops);
3015 SmallVector<int> OrigMask(
N->getMask());
3017 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3018 &
DL](SmallVectorImpl<int> &
Mask) {
3020 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3021 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3032 for (
auto &
P : ShufflesIdxs) {
3033 if (
P.second.size() < 2)
3037 for (
int &Idx : Mask) {
3040 unsigned SrcRegIdx = Idx / NewElts;
3041 if (Inputs[SrcRegIdx].
isUndef()) {
3049 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3054 Idx = MaskElt % NewElts +
3055 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3061 Inputs[
P.second[0]] =
P.first.first;
3062 Inputs[
P.second[1]] =
P.first.second;
3065 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3068 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3069 for (
int &Idx : Mask) {
3072 unsigned SrcRegIdx = Idx / NewElts;
3073 if (Inputs[SrcRegIdx].
isUndef()) {
3080 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3081 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3084 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3086 if (UsedSubVector.count() > 1) {
3088 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3089 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3091 if (Pairs.
empty() || Pairs.
back().size() == 2)
3093 if (UsedSubVector.test(2 *
I)) {
3094 Pairs.
back().emplace_back(
I, 0);
3096 assert(UsedSubVector.test(2 *
I + 1) &&
3097 "Expected to be used one of the subvectors.");
3098 Pairs.
back().emplace_back(
I, 1);
3101 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3103 for (
int &Idx : Mask) {
3106 unsigned SrcRegIdx = Idx / NewElts;
3108 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3109 return Idxs.front().first == SrcRegIdx ||
3110 Idxs.back().first == SrcRegIdx;
3112 if (It == Pairs.
end())
3114 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3115 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3118 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3119 Inputs[Idxs.front().first] = DAG.
getNode(
3121 Inputs[Idxs.front().first].getValueType(),
3122 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3123 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3132 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3136 if (Shuffle->getOperand(0).getValueType() != NewVT)
3139 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3140 !Shuffle->isSplat()) {
3142 }
else if (!Inputs[
I].hasOneUse() &&
3143 !Shuffle->getOperand(1).isUndef()) {
3145 for (
int &Idx : Mask) {
3148 unsigned SrcRegIdx = Idx / NewElts;
3151 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3156 int OpIdx = MaskElt / NewElts;
3170 if (Shuffle->getOperand(
OpIdx).isUndef())
3172 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3173 if (It == std::end(Inputs))
3175 int FoundOp = std::distance(std::begin(Inputs), It);
3178 for (
int &Idx : Mask) {
3181 unsigned SrcRegIdx = Idx / NewElts;
3184 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3189 int MaskIdx = MaskElt / NewElts;
3190 if (
OpIdx == MaskIdx)
3191 Idx = MaskElt % NewElts + FoundOp * NewElts;
3202 for (
int &Idx : Mask) {
3205 unsigned SrcRegIdx = Idx / NewElts;
3208 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3209 int OpIdx = MaskElt / NewElts;
3212 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3218 TryPeekThroughShufflesInputs(OrigMask);
3220 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3221 NewElts](SmallVectorImpl<int> &
Mask) {
3222 SetVector<SDValue> UniqueInputs;
3223 SetVector<SDValue> UniqueConstantInputs;
3224 for (
const auto &
I : Inputs) {
3226 UniqueConstantInputs.
insert(
I);
3227 else if (!
I.isUndef())
3232 if (UniqueInputs.
size() != std::size(Inputs)) {
3233 auto &&UniqueVec = UniqueInputs.
takeVector();
3234 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3235 unsigned ConstNum = UniqueConstantVec.size();
3236 for (
int &Idx : Mask) {
3239 unsigned SrcRegIdx = Idx / NewElts;
3240 if (Inputs[SrcRegIdx].
isUndef()) {
3244 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3245 if (It != UniqueConstantVec.end()) {
3246 Idx = (Idx % NewElts) +
3247 NewElts * std::distance(UniqueConstantVec.begin(), It);
3248 assert(Idx >= 0 &&
"Expected defined mask idx.");
3251 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3252 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3253 Idx = (Idx % NewElts) +
3254 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3255 assert(Idx >= 0 &&
"Expected defined mask idx.");
3257 copy(UniqueConstantVec, std::begin(Inputs));
3258 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3261 MakeUniqueInputs(OrigMask);
3263 copy(Inputs, std::begin(OrigInputs));
3269 unsigned FirstMaskIdx =
High * NewElts;
3272 assert(!Output &&
"Expected default initialized initial value.");
3273 TryPeekThroughShufflesInputs(Mask);
3274 MakeUniqueInputs(Mask);
3276 copy(Inputs, std::begin(TmpInputs));
3279 bool SecondIteration =
false;
3280 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3285 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3286 SecondIteration =
true;
3287 return SecondIteration;
3290 Mask, std::size(Inputs), std::size(Inputs),
3292 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3293 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3294 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3296 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3298 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3299 DAG.getPOISON(NewVT), Mask);
3300 Inputs[Idx] = Output;
3302 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3303 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3304 unsigned Idx2,
bool ) {
3305 if (AccumulateResults(Idx1)) {
3308 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3310 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3311 Inputs[Idx2], Mask);
3315 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3317 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3318 TmpInputs[Idx2], Mask);
3320 Inputs[Idx1] = Output;
3322 copy(OrigInputs, std::begin(Inputs));
3327 EVT OVT =
N->getValueType(0);
3334 const Align Alignment =
3335 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3337 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3338 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3343 ReplaceValueWith(
SDValue(
N, 1), Chain);
3348 EVT DstVTLo, DstVTHi;
3349 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3353 EVT SrcVT =
N->getOperand(0).getValueType();
3355 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3357 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3359 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3360 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3366 GetSplitVector(
N->getOperand(0), InLo, InHi);
3377 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3378 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3383 EVT VT =
N->getValueType(0);
3390 Align Alignment = DAG.getReducedAlign(VT,
false);
3395 EVT PtrVT =
StackPtr.getValueType();
3396 auto &MF = DAG.getMachineFunction();
3400 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3403 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3409 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3410 DAG.getConstant(1,
DL, PtrVT));
3412 DAG.getConstant(EltWidth,
DL, PtrVT));
3414 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3416 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3417 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3418 DAG.getPOISON(PtrVT), Stride, TrueMask,
3421 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3423 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3428 EVT VT =
N->getValueType(0);
3440 EVL1 = ZExtPromotedInteger(EVL1);
3442 Align Alignment = DAG.getReducedAlign(VT,
false);
3447 EVT PtrVT =
StackPtr.getValueType();
3448 auto &MF = DAG.getMachineFunction();
3452 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3455 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3459 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3460 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3462 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3464 DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr, PoisonPtr, TrueMask,
3468 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3473 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3474 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3476 uint64_t TrailingElts = -
Imm;
3478 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3487 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3491 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3493 DAG.getVectorIdxConstant(0,
DL));
3499void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3507 GetSplitVector(Acc, AccLo, AccHi);
3508 unsigned Opcode =
N->getOpcode();
3520 GetSplitVector(Input1, Input1Lo, Input1Hi);
3521 GetSplitVector(Input2, Input2Lo, Input2Hi);
3524 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3525 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3528void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3536 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3544void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3545 unsigned Factor =
N->getNumOperands();
3548 for (
unsigned i = 0; i != Factor; ++i) {
3550 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3552 Ops[i * 2 + 1] = OpHi;
3563 for (
unsigned i = 0; i != Factor; ++i)
3567void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3568 unsigned Factor =
N->getNumOperands();
3571 for (
unsigned i = 0; i != Factor; ++i) {
3573 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3575 Ops[i + Factor] = OpHi;
3586 for (
unsigned i = 0; i != Factor; ++i) {
3587 unsigned IdxLo = 2 * i;
3588 unsigned IdxHi = 2 * i + 1;
3589 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3590 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3602bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3607 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3610 switch (
N->getOpcode()) {
3613 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3623 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3630 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3632 case ISD::VP_TRUNCATE:
3634 Res = SplitVecOp_TruncateHelper(
N);
3637 case ISD::VP_FP_ROUND:
3640 Res = SplitVecOp_FP_ROUND(
N);
3649 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3656 case ISD::VP_SCATTER:
3660 case ISD::VP_GATHER:
3664 Res = SplitVecOp_VSELECT(
N, OpNo);
3667 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3673 case ISD::VP_SINT_TO_FP:
3674 case ISD::VP_UINT_TO_FP:
3675 if (
N->getValueType(0).bitsLT(
3676 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3677 Res = SplitVecOp_TruncateHelper(
N);
3679 Res = SplitVecOp_UnaryOp(
N);
3683 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3687 case ISD::VP_FP_TO_SINT:
3688 case ISD::VP_FP_TO_UINT:
3701 Res = SplitVecOp_UnaryOp(
N);
3704 Res = SplitVecOp_FPOpDifferentTypes(
N);
3709 Res = SplitVecOp_CMP(
N);
3713 Res = SplitVecOp_FAKE_USE(
N);
3718 Res = SplitVecOp_ExtVecInRegOp(
N);
3736 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3740 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3742 case ISD::VP_REDUCE_FADD:
3743 case ISD::VP_REDUCE_SEQ_FADD:
3744 case ISD::VP_REDUCE_FMUL:
3745 case ISD::VP_REDUCE_SEQ_FMUL:
3746 case ISD::VP_REDUCE_ADD:
3747 case ISD::VP_REDUCE_MUL:
3748 case ISD::VP_REDUCE_AND:
3749 case ISD::VP_REDUCE_OR:
3750 case ISD::VP_REDUCE_XOR:
3751 case ISD::VP_REDUCE_SMAX:
3752 case ISD::VP_REDUCE_SMIN:
3753 case ISD::VP_REDUCE_UMAX:
3754 case ISD::VP_REDUCE_UMIN:
3755 case ISD::VP_REDUCE_FMAX:
3756 case ISD::VP_REDUCE_FMIN:
3757 case ISD::VP_REDUCE_FMAXIMUM:
3758 case ISD::VP_REDUCE_FMINIMUM:
3759 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3763 Res = SplitVecOp_CttzElts(
N);
3765 case ISD::VP_CTTZ_ELTS:
3766 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3767 Res = SplitVecOp_VP_CttzElements(
N);
3770 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3776 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3781 if (!Res.
getNode())
return false;
3788 if (
N->isStrictFPOpcode())
3790 "Invalid operand expansion");
3793 "Invalid operand expansion");
3795 ReplaceValueWith(
SDValue(
N, 0), Res);
3799SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3803 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3805 EVT VT =
N->getValueType(0);
3818 getSetCCResultType(MVT::i1), MVT::i1);
3823 DAG.getElementCount(
DL, VT, SplitEC)),
3827SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3830 assert(OpNo == 0 &&
"Illegal operand must be mask");
3837 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3840 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3841 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3842 "Lo and Hi have differing types");
3845 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3846 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3848 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3849 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3850 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3851 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3861SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3864 assert(OpNo == 1 &&
"Illegal operand must be mask");
3869 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3871 EVT VecVT =
N->getValueType(0);
3875SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3876 EVT ResVT =
N->getValueType(0);
3882 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3883 GetSplitVector(VecOp,
Lo,
Hi);
3885 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3890 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3891 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3895 EVT ResVT =
N->getValueType(0);
3901 SDNodeFlags
Flags =
N->getFlags();
3904 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3905 GetSplitVector(VecOp,
Lo,
Hi);
3907 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3913 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3916SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3917 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3918 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3920 unsigned Opc =
N->getOpcode();
3921 EVT ResVT =
N->getValueType(0);
3927 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3928 GetSplitVector(VecOp,
Lo,
Hi);
3931 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3934 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3936 const SDNodeFlags
Flags =
N->getFlags();
3940 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3945 EVT ResVT =
N->getValueType(0);
3948 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3949 EVT InVT =
Lo.getValueType();
3954 if (
N->isStrictFPOpcode()) {
3955 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3956 {N->getOperand(0), Lo});
3957 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3958 {N->getOperand(0), Hi});
3967 ReplaceValueWith(
SDValue(
N, 1), Ch);
3968 }
else if (
N->getNumOperands() == 3) {
3969 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3970 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3971 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3972 std::tie(EVLLo, EVLHi) =
3973 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3974 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3975 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3977 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3978 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3987 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3997 EVT ResVT =
N->getValueType(0);
3999 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4003 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4009 Lo = BitConvertToInteger(
Lo);
4010 Hi = BitConvertToInteger(
Hi);
4012 if (DAG.getDataLayout().isBigEndian())
4020 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4022 EVT ResVT =
N->getValueType(0);
4030 GetSplitVector(SubVec,
Lo,
Hi);
4039 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4041 return SecondInsertion;
4044SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4051 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4053 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4055 ElementCount IdxVal =
4059 EVT SrcVT =
N->getOperand(0).getValueType();
4078 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4079 LoEltsMin - IdxValMin);
4080 DAG.ExtractVectorElements(
Hi, Elts, 0,
4083 return DAG.getBuildVector(SubVT, dl, Elts);
4087 ElementCount ExtractIdx = IdxVal - LoElts;
4089 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4092 EVT HiVT =
Hi.getValueType();
4094 "Only fixed-vector extracts are supported in this case");
4104 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4105 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4111 "Extracting scalable subvector from fixed-width unsupported");
4119 "subvector from a scalable predicate vector");
4125 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4127 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4128 auto &MF = DAG.getMachineFunction();
4132 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4136 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4139 SubVT, dl, Store, StackPtr,
4143SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4149 uint64_t IdxVal =
Index->getZExtValue();
4152 GetSplitVector(Vec,
Lo,
Hi);
4154 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4156 if (IdxVal < LoElts)
4157 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4160 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4165 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4177 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4183 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4185 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4186 auto &MF = DAG.getMachineFunction();
4189 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4193 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4197 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4199 return DAG.getExtLoad(
4210 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4218 SplitVecRes_Gather(
N,
Lo,
Hi);
4221 ReplaceValueWith(
SDValue(
N, 0), Res);
4226 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4230 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4232 SDValue EVL =
N->getVectorLength();
4234 Align Alignment =
N->getBaseAlign();
4240 GetSplitVector(
Data, DataLo, DataHi);
4242 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4247 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4250 GetSplitVector(Mask, MaskLo, MaskHi);
4252 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4255 EVT MemoryVT =
N->getMemoryVT();
4256 EVT LoMemVT, HiMemVT;
4257 bool HiIsEmpty =
false;
4258 std::tie(LoMemVT, HiMemVT) =
4259 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4263 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4266 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4271 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4272 N->getAddressingMode(),
N->isTruncatingStore(),
4273 N->isCompressingStore());
4279 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4280 N->isCompressingStore());
4282 MachinePointerInfo MPI;
4286 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4291 MMO = DAG.getMachineFunction().getMachineMemOperand(
4293 Alignment,
N->getAAInfo(),
N->getRanges());
4295 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4296 N->getAddressingMode(),
N->isTruncatingStore(),
4297 N->isCompressingStore());
4306 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4307 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4314 GetSplitVector(
Data, LoData, HiData);
4316 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4318 EVT LoMemVT, HiMemVT;
4319 bool HiIsEmpty =
false;
4320 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4326 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4327 else if (getTypeAction(
Mask.getValueType()) ==
4329 GetSplitVector(Mask, LoMask, HiMask);
4331 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4334 std::tie(LoEVL, HiEVL) =
4335 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4339 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4340 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4341 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4352 EVT PtrVT =
N->getBasePtr().getValueType();
4355 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4358 Align Alignment =
N->getBaseAlign();
4363 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4364 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4366 Alignment,
N->getAAInfo(),
N->getRanges());
4369 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4370 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4371 N->isCompressingStore());
4380 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4384 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4387 Align Alignment =
N->getBaseAlign();
4393 GetSplitVector(
Data, DataLo, DataHi);
4395 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4400 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4403 GetSplitVector(Mask, MaskLo, MaskHi);
4405 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4408 EVT MemoryVT =
N->getMemoryVT();
4409 EVT LoMemVT, HiMemVT;
4410 bool HiIsEmpty =
false;
4411 std::tie(LoMemVT, HiMemVT) =
4412 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4415 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4420 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4421 N->getAddressingMode(),
N->isTruncatingStore(),
4422 N->isCompressingStore());
4430 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4431 N->isCompressingStore());
4433 MachinePointerInfo MPI;
4437 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4442 MMO = DAG.getMachineFunction().getMachineMemOperand(
4444 Alignment,
N->getAAInfo(),
N->getRanges());
4446 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4447 N->getAddressingMode(),
N->isTruncatingStore(),
4448 N->isCompressingStore());
4461 EVT MemoryVT =
N->getMemoryVT();
4462 Align Alignment =
N->getBaseAlign();
4469 }
Ops = [&]() -> Operands {
4471 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4475 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4480 EVT LoMemVT, HiMemVT;
4481 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4486 GetSplitVector(
Ops.Data, DataLo, DataHi);
4488 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4493 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4495 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4499 if (getTypeAction(
Ops.Index.getValueType()) ==
4501 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4503 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4507 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4509 Alignment,
N->getAAInfo(),
N->getRanges());
4512 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4514 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4515 MSC->getIndexType(), MSC->isTruncatingStore());
4520 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4521 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4522 MMO, MSC->getIndexType(),
4523 MSC->isTruncatingStore());
4527 std::tie(EVLLo, EVLHi) =
4528 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4530 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4531 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4532 VPSC->getIndexType());
4537 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4538 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4539 VPSC->getIndexType());
4543 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4544 assert(OpNo == 1 &&
"Can only split the stored value");
4547 bool isTruncating =
N->isTruncatingStore();
4550 EVT MemoryVT =
N->getMemoryVT();
4551 Align Alignment =
N->getBaseAlign();
4553 AAMDNodes AAInfo =
N->getAAInfo();
4555 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4557 EVT LoMemVT, HiMemVT;
4558 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4562 return TLI.scalarizeVectorStore(
N, DAG);
4565 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4566 Alignment, MMOFlags, AAInfo);
4568 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4571 MachinePointerInfo MPI;
4572 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4575 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4576 HiMemVT, Alignment, MMOFlags, AAInfo);
4578 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4594 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4600 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4621 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4622 SDValue InVec =
N->getOperand(OpNo);
4624 EVT OutVT =
N->getValueType(0);
4632 EVT LoOutVT, HiOutVT;
4633 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4634 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4639 if (isTypeLegal(LoOutVT) ||
4640 InElementSize <= OutElementSize * 2)
4641 return SplitVecOp_UnaryOp(
N);
4650 return SplitVecOp_UnaryOp(
N);
4654 GetSplitVector(InVec, InLoVec, InHiVec);
4660 EVT HalfElementVT = IsFloat ?
4662 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4669 if (
N->isStrictFPOpcode()) {
4670 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4671 {N->getOperand(0), InLoVec});
4672 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4673 {N->getOperand(0), InHiVec});
4679 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4680 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4684 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4692 if (
N->isStrictFPOpcode()) {
4696 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4704 DAG.getTargetConstant(
4705 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4712 assert(
N->getValueType(0).isVector() &&
4713 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4714 "Operand types must be vectors");
4716 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4718 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4719 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4721 EVT VT =
N->getValueType(0);
4728 }
else if (isStrict) {
4729 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4730 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4731 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4732 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4735 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4737 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4738 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4739 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4740 std::tie(EVLLo, EVLHi) =
4741 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4742 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4743 N->getOperand(2), MaskLo, EVLLo);
4744 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4745 N->getOperand(2), MaskHi, EVLHi);
4754 EVT ResVT =
N->getValueType(0);
4757 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4758 EVT InVT =
Lo.getValueType();
4763 if (
N->isStrictFPOpcode()) {
4764 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4765 {N->getOperand(0), Lo, N->getOperand(2)});
4766 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4767 {N->getOperand(0), Hi, N->getOperand(2)});
4771 Lo.getValue(1),
Hi.getValue(1));
4772 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4773 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4774 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4775 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4776 std::tie(EVLLo, EVLHi) =
4777 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4778 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4779 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4781 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4782 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
4793SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4796 EVT LHSLoVT, LHSHiVT;
4797 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4799 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4800 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4803 std::tie(LHSLo, LHSHi) =
4804 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4807 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4810 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4816 LLVMContext &Ctxt = *DAG.getContext();
4819 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4820 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4821 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4823 EVT ResVT =
N->getValueType(0);
4828 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4829 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4835 EVT ResVT =
N->getValueType(0);
4838 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4839 EVT InVT =
Lo.getValueType();
4845 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4846 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4853 EVT ResVT =
N->getValueType(0);
4857 GetSplitVector(VecOp,
Lo,
Hi);
4863 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
4865 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
4867 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
4868 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
4873 EVT ResVT =
N->getValueType(0);
4877 GetSplitVector(VecOp,
Lo,
Hi);
4879 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4880 auto [EVLLo, EVLHi] =
4882 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4888 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4890 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4891 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4894SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4905 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4906 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4907 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4908 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4909 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4910 OpsLo, MMO, IndexType);
4911 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4912 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4916SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4919 "Accumulator should already be a legal type, and shouldn't need "
4920 "further splitting");
4923 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4924 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4925 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4926 unsigned Opcode =
N->getOpcode();
4929 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4930 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4937void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4938 unsigned WidenResNo) {
4939 unsigned NumResults =
N->getNumValues();
4940 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4941 if (ResNo == WidenResNo)
4943 EVT ResVT =
N->getValueType(ResNo);
4949 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4950 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4955void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4956 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4959 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4964 auto unrollExpandedOp = [&]() {
4969 EVT VT =
N->getValueType(0);
4970 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4971 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4972 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
4974 if (
N->getNumValues() > 1)
4975 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4981 switch (
N->getOpcode()) {
4984 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4992 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4996 Res = WidenVecRes_ADDRSPACECAST(
N);
5003 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5010 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5014 Res = WidenVecRes_ScalarOp(
N);
5019 case ISD::VP_SELECT:
5021 Res = WidenVecRes_Select(
N);
5025 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5027 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5034 case ISD::VP_LOAD_FF:
5037 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5041 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5049 case ISD::VP_GATHER:
5053 Res = WidenVecRes_VECTOR_REVERSE(
N);
5056 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5066 case ISD::OR:
case ISD::VP_OR:
5077 case ISD::VP_FMINNUM:
5080 case ISD::VP_FMAXNUM:
5082 case ISD::VP_FMINIMUM:
5084 case ISD::VP_FMAXIMUM:
5117 case ISD::VP_FCOPYSIGN:
5118 Res = WidenVecRes_Binary(
N);
5123 Res = WidenVecRes_CMP(
N);
5129 if (unrollExpandedOp())
5144 Res = WidenVecRes_BinaryCanTrap(
N);
5153 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5156#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5157 case ISD::STRICT_##DAGN:
5158#include "llvm/IR/ConstrainedOps.def"
5159 Res = WidenVecRes_StrictFP(
N);
5168 Res = WidenVecRes_OverflowOp(
N, ResNo);
5172 Res = WidenVecRes_FCOPYSIGN(
N);
5177 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5182 if (!unrollExpandedOp())
5183 Res = WidenVecRes_ExpOp(
N);
5189 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5194 case ISD::VP_FP_EXTEND:
5196 case ISD::VP_FP_ROUND:
5198 case ISD::VP_FP_TO_SINT:
5200 case ISD::VP_FP_TO_UINT:
5202 case ISD::VP_SIGN_EXTEND:
5204 case ISD::VP_SINT_TO_FP:
5205 case ISD::VP_TRUNCATE:
5208 case ISD::VP_UINT_TO_FP:
5210 case ISD::VP_ZERO_EXTEND:
5212 Res = WidenVecRes_Convert(
N);
5217 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5223 case ISD::VP_LLRINT:
5226 Res = WidenVecRes_XROUND(
N);
5252 if (unrollExpandedOp())
5262 case ISD::VP_BITREVERSE:
5268 case ISD::VP_CTLZ_ZERO_UNDEF:
5274 case ISD::VP_CTTZ_ZERO_UNDEF:
5279 case ISD::VP_FFLOOR:
5281 case ISD::VP_FNEARBYINT:
5282 case ISD::VP_FROUND:
5283 case ISD::VP_FROUNDEVEN:
5284 case ISD::VP_FROUNDTOZERO:
5289 Res = WidenVecRes_Unary(
N);
5296 Res = WidenVecRes_Ternary(
N);
5302 if (!unrollExpandedOp())
5303 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5310 SetWidenedVector(
SDValue(
N, ResNo), Res);
5316 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5317 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5318 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5319 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5320 if (
N->getNumOperands() == 3)
5321 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5323 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5324 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5328 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5329 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5335 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5336 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5337 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5338 if (
N->getNumOperands() == 2)
5339 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5342 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5343 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5347 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5348 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5352 LLVMContext &Ctxt = *DAG.getContext();
5357 EVT OpVT =
LHS.getValueType();
5359 LHS = GetWidenedVector(
LHS);
5360 RHS = GetWidenedVector(
RHS);
5361 OpVT =
LHS.getValueType();
5364 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5367 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5373SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5376 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5377 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5378 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5380 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5389 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5392 if (ConcatEnd == 1) {
5393 VT = ConcatOps[0].getValueType();
5395 return ConcatOps[0];
5398 SDLoc dl(ConcatOps[0]);
5405 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5406 int Idx = ConcatEnd - 1;
5407 VT = ConcatOps[Idx--].getValueType();
5408 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5421 unsigned NumToInsert = ConcatEnd - Idx - 1;
5422 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5424 ConcatOps[Idx+1] = VecOp;
5425 ConcatEnd = Idx + 2;
5431 unsigned RealVals = ConcatEnd - Idx - 1;
5432 unsigned SubConcatEnd = 0;
5433 unsigned SubConcatIdx = Idx + 1;
5434 while (SubConcatEnd < RealVals)
5435 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5436 while (SubConcatEnd < OpsToConcat)
5437 SubConcatOps[SubConcatEnd++] = undefVec;
5439 NextVT, SubConcatOps);
5440 ConcatEnd = SubConcatIdx + 1;
5445 if (ConcatEnd == 1) {
5446 VT = ConcatOps[0].getValueType();
5448 return ConcatOps[0];
5453 if (
NumOps != ConcatEnd ) {
5455 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5456 ConcatOps[j] = UndefVal;
5464 unsigned Opcode =
N->getOpcode();
5466 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5470 const SDNodeFlags
Flags =
N->getFlags();
5471 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5472 NumElts = NumElts / 2;
5476 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5478 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5479 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5480 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5488 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5491 TLI.isTypeLegal(WideMaskVT)) {
5492 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5493 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5494 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5496 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5497 N->getValueType(0).getVectorElementCount());
5498 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5512 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5513 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5514 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5517 unsigned ConcatEnd = 0;
5525 while (CurNumElts != 0) {
5526 while (CurNumElts >= NumElts) {
5527 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5528 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5529 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5531 CurNumElts -= NumElts;
5534 NumElts = NumElts / 2;
5536 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5539 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5540 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5541 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5542 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5553 switch (
N->getOpcode()) {
5556 return WidenVecRes_STRICT_FSETCC(
N);
5563 return WidenVecRes_Convert_StrictFP(
N);
5570 unsigned Opcode =
N->getOpcode();
5572 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5576 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5577 NumElts = NumElts / 2;
5588 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5592 unsigned ConcatEnd = 0;
5599 for (
unsigned i = 1; i < NumOpers; ++i) {
5605 Oper = GetWidenedVector(Oper);
5611 DAG.getPOISON(WideOpVT), Oper,
5612 DAG.getVectorIdxConstant(0, dl));
5624 while (CurNumElts != 0) {
5625 while (CurNumElts >= NumElts) {
5628 for (
unsigned i = 0; i < NumOpers; ++i) {
5631 EVT OpVT =
Op.getValueType();
5636 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5642 EVT OperVT[] = {VT, MVT::Other};
5644 ConcatOps[ConcatEnd++] = Oper;
5647 CurNumElts -= NumElts;
5650 NumElts = NumElts / 2;
5652 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5655 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5658 for (
unsigned i = 0; i < NumOpers; ++i) {
5661 EVT OpVT =
Op.getValueType();
5669 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5671 ConcatOps[ConcatEnd++] = Oper;
5680 if (Chains.
size() == 1)
5681 NewChain = Chains[0];
5684 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5689SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5691 EVT ResVT =
N->getValueType(0);
5692 EVT OvVT =
N->getValueType(1);
5693 EVT WideResVT, WideOvVT;
5698 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5703 WideLHS = GetWidenedVector(
N->getOperand(0));
5704 WideRHS = GetWidenedVector(
N->getOperand(1));
5706 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5715 N->getOperand(0), Zero);
5717 N->getOperand(1), Zero);
5720 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5721 SDNode *WideNode = DAG.getNode(
5722 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5725 unsigned OtherNo = 1 - ResNo;
5726 EVT OtherVT =
N->getValueType(OtherNo);
5733 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5736 return SDValue(WideNode, ResNo);
5740 LLVMContext &Ctx = *DAG.getContext();
5744 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5749 unsigned Opcode =
N->getOpcode();
5750 const SDNodeFlags
Flags =
N->getFlags();
5756 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5758 InOp = ZExtPromotedInteger(InOp);
5769 InOp = GetWidenedVector(
N->getOperand(0));
5772 if (InVTEC == WidenEC) {
5773 if (
N->getNumOperands() == 1)
5774 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5775 if (
N->getNumOperands() == 3) {
5776 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5779 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5781 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5807 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5811 if (TLI.isTypeLegal(InWidenVT)) {
5819 unsigned NumConcat =
5824 if (
N->getNumOperands() == 1)
5825 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5826 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5830 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5832 if (
N->getNumOperands() == 1)
5833 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5834 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5843 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5844 for (
unsigned i=0; i < MinElts; ++i) {
5845 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5846 if (
N->getNumOperands() == 1)
5849 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5852 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5857 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5861 EVT SrcVT = Src.getValueType();
5865 Src = GetWidenedVector(Src);
5866 SrcVT = Src.getValueType();
5873 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5878 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5882 EVT SrcVT = Src.getValueType();
5886 Src = GetWidenedVector(Src);
5887 SrcVT = Src.getValueType();
5894 if (
N->getNumOperands() == 1)
5895 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5897 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5898 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5902 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5905SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5910 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5916 unsigned Opcode =
N->getOpcode();
5922 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5927 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5928 for (
unsigned i=0; i < MinElts; ++i) {
5929 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5930 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5934 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5936 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5939SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5940 unsigned Opcode =
N->getOpcode();
5944 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5953 InOp = GetWidenedVector(InOp);
5960 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5967 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5968 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5985 while (
Ops.size() != WidenNumElts)
5986 Ops.push_back(DAG.getPOISON(WidenSVT));
5988 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5994 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5995 return WidenVecRes_BinaryCanTrap(
N);
5998 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6005SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6007 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6010 SDValue Arg = GetWidenedVector(FpValue);
6011 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6016 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6017 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6019 EVT ExpVT =
RHS.getValueType();
6024 ExpOp = ModifyToType(
RHS, WideExpVT);
6027 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6032 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6033 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6034 if (
N->getNumOperands() == 1)
6035 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6037 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6038 N->getOperand(1),
N->getFlags());
6040 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6041 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6045 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6046 {InOp,
Mask,
N->getOperand(2)});
6050 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6053 .getVectorElementType(),
6055 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6056 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6057 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6060SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6062 EVT VT0 =
N->getValueType(0);
6063 EVT VT1 =
N->getValueType(1);
6067 "expected both results to be vectors of matching element count");
6069 LLVMContext &Ctx = *DAG.getContext();
6070 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6072 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6079 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6082 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6083 return SDValue(WidenNode, ResNo);
6086SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6087 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6088 return GetWidenedVector(WidenVec);
6092 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6093 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6096 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6097 AddrSpaceCastN->getSrcAddressSpace(),
6098 AddrSpaceCastN->getDestAddressSpace());
6104 EVT VT =
N->getValueType(0);
6105 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6108 switch (getTypeAction(InVT)) {
6122 SDValue NInOp = GetPromotedInteger(InOp);
6124 if (WidenVT.
bitsEq(NInVT)) {
6127 if (DAG.getDataLayout().isBigEndian()) {
6130 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6148 InOp = GetWidenedVector(InOp);
6150 if (WidenVT.
bitsEq(InVT))
6160 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6165 unsigned NewNumParts = WidenSize / InSize;
6178 EVT OrigInVT =
N->getOperand(0).getValueType();
6183 if (TLI.isTypeLegal(NewInVT)) {
6191 if (WidenSize % InSize == 0) {
6198 DAG.ExtractVectorElements(InOp,
Ops);
6199 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6211 return CreateStackStoreLoad(InOp, WidenVT);
6214SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6216 N->getOpcode(), SDLoc(
N),
6217 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6218 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6224 EVT VT =
N->getValueType(0);
6228 EVT EltVT =
N->getOperand(0).getValueType();
6231 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6235 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6236 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6238 return DAG.getBuildVector(WidenVT, dl, NewOps);
6242 EVT InVT =
N->getOperand(0).getValueType();
6243 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6245 unsigned NumOperands =
N->getNumOperands();
6247 bool InputWidened =
false;
6251 if (WidenNumElts % NumInElts == 0) {
6253 unsigned NumConcat = WidenNumElts / NumInElts;
6254 SDValue UndefVal = DAG.getPOISON(InVT);
6256 for (
unsigned i=0; i < NumOperands; ++i)
6257 Ops[i] =
N->getOperand(i);
6258 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6263 InputWidened =
true;
6264 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6267 for (i=1; i < NumOperands; ++i)
6268 if (!
N->getOperand(i).isUndef())
6271 if (i == NumOperands)
6274 return GetWidenedVector(
N->getOperand(0));
6276 if (NumOperands == 2) {
6278 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6283 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6284 for (
unsigned i = 0; i < NumInElts; ++i) {
6286 MaskOps[i + NumInElts] = i + WidenNumElts;
6288 return DAG.getVectorShuffle(WidenVT, dl,
6289 GetWidenedVector(
N->getOperand(0)),
6290 GetWidenedVector(
N->getOperand(1)),
6297 "Cannot use build vectors to widen CONCAT_VECTOR result");
6305 for (
unsigned i=0; i < NumOperands; ++i) {
6308 InOp = GetWidenedVector(InOp);
6309 for (
unsigned j = 0;
j < NumInElts; ++
j)
6310 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6312 SDValue UndefVal = DAG.getPOISON(EltVT);
6313 for (; Idx < WidenNumElts; ++Idx)
6314 Ops[Idx] = UndefVal;
6315 return DAG.getBuildVector(WidenVT, dl,
Ops);
6318SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6319 EVT VT =
N->getValueType(0);
6320 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6321 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6328SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6329 EVT VT =
N->getValueType(0);
6331 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6336 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6338 InOp = GetWidenedVector(InOp);
6344 if (IdxVal == 0 && InVT == WidenVT)
6351 assert(IdxVal % VTNumElts == 0 &&
6352 "Expected Idx to be a multiple of subvector minimum vector length");
6353 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6366 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6367 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6368 "down type's element count");
6375 for (;
I < VTNumElts / GCD; ++
I)
6377 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6378 for (;
I < WidenNumElts / GCD; ++
I)
6386 Align Alignment = DAG.getReducedAlign(InVT,
false);
6388 MachineFunction &MF = DAG.getMachineFunction();
6400 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6407 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6408 return DAG.getMaskedLoad(
6409 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6417 for (i = 0; i < VTNumElts; ++i)
6418 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6420 SDValue UndefVal = DAG.getPOISON(EltVT);
6421 for (; i < WidenNumElts; ++i)
6423 return DAG.getBuildVector(WidenVT, dl,
Ops);
6429 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6434SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6435 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6438 N->getOperand(1),
N->getOperand(2));
6447 "Load width must be less than or equal to first value type width");
6456 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6467 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6468 EVT LdVT =
LD->getMemoryVT();
6472 "Must be scalable");
6474 "Expected equivalent element types");
6482 TypeSize WidthDiff = WidenWidth - LdWidth;
6485 std::optional<EVT> FirstVT =
6486 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6493 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6496 Chain, BasePtr,
LD->getMemOperand());
6500 FirstVTWidth, dl, DAG);
6518 if (!
LD->getMemoryVT().isByteSized()) {
6520 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6522 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6531 EVT VT =
LD->getValueType(0);
6532 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6533 EVT WideMaskVT = getSetCCResultType(WideVT);
6536 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6537 TLI.isTypeLegal(WideMaskVT)) {
6540 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6544 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6545 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6557 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6559 Result = GenWidenVectorLoads(LdChain, LD);
6566 if (LdChain.
size() == 1)
6567 NewChain = LdChain[0];
6573 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6584 SDValue NewLoad = DAG.getMaskedLoad(
6585 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6586 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6587 LD->getAddressingMode(),
LD->getExtensionType());
6597 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6599 SDValue EVL =
N->getVectorLength();
6606 "Unable to widen binary VP op");
6607 Mask = GetWidenedVector(Mask);
6608 assert(
Mask.getValueType().getVectorElementCount() ==
6609 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6610 .getVectorElementCount() &&
6611 "Unable to widen vector load");
6614 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6615 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6616 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6624 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6626 SDValue EVL =
N->getVectorLength();
6632 "Unable to widen binary VP op");
6633 Mask = GetWidenedVector(Mask);
6634 assert(
Mask.getValueType().getVectorElementCount() ==
6635 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6636 .getVectorElementCount() &&
6637 "Unable to widen vector load");
6639 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6640 Mask, EVL,
N->getMemOperand());
6653 "Unable to widen VP strided load");
6654 Mask = GetWidenedVector(Mask);
6656 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6657 assert(
Mask.getValueType().getVectorElementCount() ==
6659 "Data and mask vectors should have the same number of elements");
6661 SDValue Res = DAG.getStridedLoadVP(
6662 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6663 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6664 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6665 N->isExpandingLoad());
6673SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6678 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6680 Mask.getValueType().getVectorElementType(),
6683 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6684 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6685 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6687 WideMask, WidePassthru);
6691 EVT VT =
N->getValueType(0);
6692 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6694 EVT MaskVT =
Mask.getValueType();
6695 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6704 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6705 TLI.isTypeLegal(WideMaskVT) &&
6711 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6712 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6716 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6717 N->getMemoryVT(),
N->getMemOperand());
6721 if (!
N->getPassThru()->isUndef()) {
6725 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6726 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6727 DAG.getPOISON(WidenVT), EVL);
6738 Mask = ModifyToType(Mask, WideMaskVT,
true);
6740 SDValue Res = DAG.getMaskedLoad(
6741 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6742 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6743 ExtType,
N->isExpandingLoad());
6752 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6754 EVT MaskVT =
Mask.getValueType();
6755 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6764 Mask = ModifyToType(Mask, WideMaskVT,
true);
6769 Index.getValueType().getScalarType(),
6771 Index = ModifyToType(Index, WideIndexVT);
6777 N->getMemoryVT().getScalarType(), NumElts);
6778 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6779 WideMemVT, dl,
Ops,
N->getMemOperand(),
6780 N->getIndexType(),
N->getExtensionType());
6789 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6797 N->getMemoryVT().getScalarType(), WideEC);
6798 Mask = GetWidenedMask(Mask, WideEC);
6801 Mask,
N->getVectorLength()};
6802 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6803 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6812 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6813 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6841 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6842 return N->getOperand(OpNo).getValueType();
6850 N =
N.getOperand(0);
6852 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6853 if (!
N->getOperand(i)->isUndef())
6855 N =
N.getOperand(0);
6859 N =
N.getOperand(0);
6861 N =
N.getOperand(0);
6888 { MaskVT, MVT::Other },
Ops);
6889 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6897 LLVMContext &Ctx = *DAG.getContext();
6900 if (MaskScalarBits < ToMaskScalBits) {
6904 }
else if (MaskScalarBits > ToMaskScalBits) {
6910 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6912 "Mask should have the right element size by now.");
6915 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6917 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6920 EVT SubVT =
Mask->getValueType(0);
6926 assert((
Mask->getValueType(0) == ToMaskVT) &&
6927 "A mask of ToMaskVT should have been produced by now.");
6937 LLVMContext &Ctx = *DAG.getContext();
6948 EVT CondVT =
Cond->getValueType(0);
6952 EVT VSelVT =
N->getValueType(0);
6964 EVT FinalVT = VSelVT;
6975 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6976 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6983 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6991 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6994 EVT ToMaskVT = VSelVT;
7001 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7017 if (ScalarBits0 != ScalarBits1) {
7018 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7019 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7031 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7032 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7033 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7036 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7044 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7049 unsigned Opcode =
N->getOpcode();
7051 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7052 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7053 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7055 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7061 Cond1 = GetWidenedVector(Cond1);
7069 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7070 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7075 Cond1 = ModifyToType(Cond1, CondWidenVT);
7078 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7079 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7081 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7082 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7084 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7088 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7089 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7092 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7096 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7097 return DAG.getUNDEF(WidenVT);
7101 EVT VT =
N->getValueType(0);
7104 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7108 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7109 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7112 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7113 for (
unsigned i = 0; i != NumElts; ++i) {
7114 int Idx =
N->getMaskElt(i);
7115 if (Idx < (
int)NumElts)
7118 NewMask[i] = Idx - NumElts + WidenNumElts;
7120 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7124 EVT VT =
N->getValueType(0);
7128 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7129 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7135 unsigned IdxVal = WidenNumElts - VTNumElts;
7148 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7151 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7152 "down type's element count");
7155 for (; i < VTNumElts / GCD; ++i)
7157 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7158 for (; i < WidenNumElts / GCD; ++i)
7166 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7167 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7169 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7173SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7174 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7179 assert(
N->getValueType(0).isVector() &&
7180 N->getOperand(0).getValueType().isVector() &&
7181 "Operands must be vectors");
7182 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7195 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7196 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7203 InOp1 = GetWidenedVector(InOp1);
7204 InOp2 = GetWidenedVector(InOp2);
7207 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7218 "Input not widened to expected type!");
7220 if (
N->getOpcode() == ISD::VP_SETCC) {
7223 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7224 N->getOperand(2), Mask,
N->getOperand(4));
7226 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7231 assert(
N->getValueType(0).isVector() &&
7232 N->getOperand(1).getValueType().isVector() &&
7233 "Operands must be vectors");
7234 EVT VT =
N->getValueType(0);
7235 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7245 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7250 for (
unsigned i = 0; i != NumElts; ++i) {
7251 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7252 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7254 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7255 {Chain, LHSElem, RHSElem, CC});
7256 Chains[i] = Scalars[i].getValue(1);
7257 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7258 DAG.getBoolConstant(
true, dl, EltVT, VT),
7259 DAG.getBoolConstant(
false, dl, EltVT, VT));
7263 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7265 return DAG.getBuildVector(WidenVT, dl, Scalars);
7271bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7272 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7276 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7279 switch (
N->getOpcode()) {
7282 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7290 Res = WidenVecOp_FAKE_USE(
N);
7296 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7297 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7298 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7299 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7304 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7306 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7307 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7309 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7310 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7320 Res = WidenVecOp_UnrollVectorOp(
N);
7327 Res = WidenVecOp_EXTEND(
N);
7332 Res = WidenVecOp_CMP(
N);
7349 Res = WidenVecOp_Convert(
N);
7354 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7372 Res = WidenVecOp_VECREDUCE(
N);
7376 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7378 case ISD::VP_REDUCE_FADD:
7379 case ISD::VP_REDUCE_SEQ_FADD:
7380 case ISD::VP_REDUCE_FMUL:
7381 case ISD::VP_REDUCE_SEQ_FMUL:
7382 case ISD::VP_REDUCE_ADD:
7383 case ISD::VP_REDUCE_MUL:
7384 case ISD::VP_REDUCE_AND:
7385 case ISD::VP_REDUCE_OR:
7386 case ISD::VP_REDUCE_XOR:
7387 case ISD::VP_REDUCE_SMAX:
7388 case ISD::VP_REDUCE_SMIN:
7389 case ISD::VP_REDUCE_UMAX:
7390 case ISD::VP_REDUCE_UMIN:
7391 case ISD::VP_REDUCE_FMAX:
7392 case ISD::VP_REDUCE_FMIN:
7393 case ISD::VP_REDUCE_FMAXIMUM:
7394 case ISD::VP_REDUCE_FMINIMUM:
7395 Res = WidenVecOp_VP_REDUCE(
N);
7397 case ISD::VP_CTTZ_ELTS:
7398 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7399 Res = WidenVecOp_VP_CttzElements(
N);
7402 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7407 if (!Res.
getNode())
return false;
7415 if (
N->isStrictFPOpcode())
7417 "Invalid operand expansion");
7420 "Invalid operand expansion");
7422 ReplaceValueWith(
SDValue(
N, 0), Res);
7428 EVT VT =
N->getValueType(0);
7433 "Unexpected type action");
7434 InOp = GetWidenedVector(InOp);
7437 "Input wasn't widened!");
7445 EVT FixedEltVT = FixedVT.getVectorElementType();
7446 if (TLI.isTypeLegal(FixedVT) &&
7448 FixedEltVT == InEltVT) {
7450 "Not enough elements in the fixed type for the operand!");
7452 "We can't have the same type as we started with!");
7454 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7456 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7465 return WidenVecOp_Convert(
N);
7470 switch (
N->getOpcode()) {
7485 EVT OpVT =
N->getOperand(0).getValueType();
7486 EVT ResVT =
N->getValueType(0);
7493 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7494 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7500 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7501 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7503 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7510 return DAG.UnrollVectorOp(
N);
7515 EVT ResultVT =
N->getValueType(0);
7517 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7520 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7526 {WideArg,
Test},
N->getFlags());
7532 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7534 EVT OpVT =
N->getOperand(0).getValueType();
7537 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7542 EVT VT =
N->getValueType(0);
7548 "Unexpected type action");
7549 InOp = GetWidenedVector(InOp);
7551 unsigned Opcode =
N->getOpcode();
7557 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7559 if (
N->isStrictFPOpcode()) {
7561 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7564 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7565 {
N->getOperand(0), InOp });
7571 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7573 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7575 return DAG.getExtractSubvector(dl, VT, Res, 0);
7583 if (
N->isStrictFPOpcode()) {
7586 for (
unsigned i=0; i < NumElts; ++i) {
7587 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7588 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7592 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7594 for (
unsigned i = 0; i < NumElts; ++i) {
7595 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7597 Ops[i] = DAG.
getNode(Opcode, dl, EltVT, Elt,
N->getOperand(1));
7599 Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
7603 return DAG.getBuildVector(VT, dl,
Ops);
7607 EVT DstVT =
N->getValueType(0);
7608 SDValue Src = GetWidenedVector(
N->getOperand(0));
7609 EVT SrcVT = Src.getValueType();
7616 if (TLI.isTypeLegal(WideDstVT)) {
7618 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7621 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7625 return DAG.UnrollVectorOp(
N);
7629 EVT VT =
N->getValueType(0);
7630 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7638 if (!VT.
isVector() && VT != MVT::x86mmx &&
7642 if (TLI.isTypeLegal(NewVT)) {
7644 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7656 ElementCount NewNumElts =
7658 .divideCoefficientBy(EltSize);
7660 if (TLI.isTypeLegal(NewVT)) {
7662 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7667 return CreateStackStoreLoad(InOp, VT);
7675 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7676 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7681 EVT VT =
N->getValueType(0);
7683 EVT InVT =
N->getOperand(0).getValueType();
7688 unsigned NumOperands =
N->getNumOperands();
7689 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7691 for (i = 1; i < NumOperands; ++i)
7692 if (!
N->getOperand(i).isUndef())
7695 if (i == NumOperands)
7696 return GetWidenedVector(
N->getOperand(0));
7706 for (
unsigned i=0; i < NumOperands; ++i) {
7710 "Unexpected type action");
7711 InOp = GetWidenedVector(InOp);
7712 for (
unsigned j = 0;
j < NumInElts; ++
j)
7713 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7715 return DAG.getBuildVector(VT, dl,
Ops);
7718SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7719 EVT VT =
N->getValueType(0);
7724 SubVec = GetWidenedVector(SubVec);
7729 bool IndicesValid =
false;
7732 IndicesValid =
true;
7736 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7737 Attribute::VScaleRange);
7742 IndicesValid =
true;
7748 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7754 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7761 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7768 Align Alignment = DAG.getReducedAlign(VT,
false);
7770 MachineFunction &MF = DAG.getMachineFunction();
7783 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7791 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7792 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7797 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7802 unsigned Idx =
N->getConstantOperandVal(2);
7808 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7814SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7815 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7817 N->getValueType(0), InOp,
N->getOperand(1));
7820SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7821 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7823 N->getValueType(0), InOp,
N->getOperand(1));
7826SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7828 EVT ResVT =
N->getValueType(0);
7831 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
7837 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
7845 "Widened input size must be a multiple of result element size");
7848 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
7850 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
7851 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
7859 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7860 return TLI.scalarizeVectorStore(ST, DAG);
7862 if (
ST->isTruncatingStore())
7863 return TLI.scalarizeVectorStore(ST, DAG);
7873 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7874 EVT WideMaskVT = getSetCCResultType(WideVT);
7876 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7877 TLI.isTypeLegal(WideMaskVT)) {
7880 StVal = GetWidenedVector(StVal);
7882 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7884 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7885 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7886 ST->getAddressingMode());
7890 if (GenWidenVectorStores(StChain, ST)) {
7891 if (StChain.
size() == 1)
7900 SDValue WideStVal = GetWidenedVector(StVal);
7904 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7905 ST->getOffset(), Mask,
ST->getMemoryVT(),
7906 ST->getMemOperand(),
ST->getAddressingMode(),
7907 ST->isTruncatingStore());
7913SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7914 assert((OpNo == 1 || OpNo == 3) &&
7915 "Can widen only data or mask operand of vp_store");
7923 StVal = GetWidenedVector(StVal);
7929 "Unable to widen VP store");
7930 Mask = GetWidenedVector(Mask);
7932 Mask = GetWidenedVector(Mask);
7938 "Unable to widen VP store");
7939 StVal = GetWidenedVector(StVal);
7942 assert(
Mask.getValueType().getVectorElementCount() ==
7944 "Mask and data vectors should have the same number of elements");
7945 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7946 ST->getOffset(), Mask,
ST->getVectorLength(),
7947 ST->getMemoryVT(),
ST->getMemOperand(),
7948 ST->getAddressingMode(),
ST->isTruncatingStore(),
7949 ST->isCompressingStore());
7954 assert((OpNo == 1 || OpNo == 4) &&
7955 "Can widen only data or mask operand of vp_strided_store");
7964 "Unable to widen VP strided store");
7968 "Unable to widen VP strided store");
7970 StVal = GetWidenedVector(StVal);
7971 Mask = GetWidenedVector(Mask);
7974 Mask.getValueType().getVectorElementCount() &&
7975 "Data and mask vectors should have the same number of elements");
7977 return DAG.getStridedStoreVP(
7984SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7985 assert((OpNo == 1 || OpNo == 4) &&
7986 "Can widen only data or mask operand of mstore");
7989 EVT MaskVT =
Mask.getValueType();
7994 EVT WideVT, WideMaskVT;
7997 StVal = GetWidenedVector(StVal);
8004 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8011 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8012 TLI.isTypeLegal(WideMaskVT)) {
8013 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8014 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8023 Mask = ModifyToType(Mask, WideMaskVT,
true);
8026 Mask = ModifyToType(Mask, WideMaskVT,
true);
8028 StVal = ModifyToType(StVal, WideVT);
8031 assert(
Mask.getValueType().getVectorElementCount() ==
8033 "Mask and data vectors should have the same number of elements");
8040SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8041 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8043 SDValue DataOp = MG->getPassThru();
8045 SDValue Scale = MG->getScale();
8053 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8054 MG->getMemOperand(), MG->getIndexType(),
8055 MG->getExtensionType());
8061SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8070 DataOp = GetWidenedVector(DataOp);
8074 EVT IndexVT =
Index.getValueType();
8077 Index = ModifyToType(Index, WideIndexVT);
8080 EVT MaskVT =
Mask.getValueType();
8083 Mask = ModifyToType(Mask, WideMaskVT,
true);
8088 }
else if (OpNo == 4) {
8090 Index = GetWidenedVector(Index);
8096 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8101SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8110 DataOp = GetWidenedVector(DataOp);
8111 Index = GetWidenedVector(Index);
8113 Mask = GetWidenedMask(Mask, WideEC);
8116 }
else if (OpNo == 3) {
8118 Index = GetWidenedVector(Index);
8125 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8130 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8131 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8133 EVT VT =
N->getValueType(0);
8148 SVT, InOp0, InOp1,
N->getOperand(2));
8154 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8156 EVT OpVT =
N->getOperand(0).getValueType();
8159 return DAG.getNode(ExtendCode, dl, VT, CC);
8169 EVT VT =
N->getValueType(0);
8171 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8178 for (
unsigned i = 0; i != NumElts; ++i) {
8179 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8180 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8182 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8183 {Chain, LHSElem, RHSElem, CC});
8184 Chains[i] = Scalars[i].getValue(1);
8185 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8186 DAG.getBoolConstant(
true, dl, EltVT, VT),
8187 DAG.getBoolConstant(
false, dl, EltVT, VT));
8191 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8193 return DAG.getBuildVector(VT, dl, Scalars);
8217 SDValue Op = GetWidenedVector(
N->getOperand(0));
8218 EVT VT =
N->getValueType(0);
8219 EVT OrigVT =
N->getOperand(0).getValueType();
8220 EVT WideVT =
Op.getValueType();
8222 SDNodeFlags
Flags =
N->getFlags();
8224 unsigned Opc =
N->getOpcode();
8226 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8227 assert(NeutralElem &&
"Neutral element must exist");
8237 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8244 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8245 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8251 unsigned GCD = std::gcd(OrigElts, WideElts);
8254 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8255 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8256 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8257 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8260 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8261 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8263 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8272 EVT VT =
N->getValueType(0);
8274 EVT WideVT =
Op.getValueType();
8276 SDNodeFlags
Flags =
N->getFlags();
8278 unsigned Opc =
N->getOpcode();
8280 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8290 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8293 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8294 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8300 unsigned GCD = std::gcd(OrigElts, WideElts);
8303 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8304 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8305 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8306 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8309 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8310 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8312 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8316 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8319 SDValue Op = GetWidenedVector(
N->getOperand(1));
8321 Op.getValueType().getVectorElementCount());
8323 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8324 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8332 EVT VT =
N->getValueType(0);
8336 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8337 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8342 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8348 EVT SrcVT =
Source.getValueType();
8352 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8353 {Source, Mask, N->getOperand(2)},
N->getFlags());
8356SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8359 EVT OrigMaskVT =
Mask.getValueType();
8360 SDValue WideMask = GetWidenedVector(Mask);
8366 if (OrigElts != WideElts) {
8367 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8369 Mask, DAG.getVectorIdxConstant(0,
DL));
8390 unsigned WidenEx = 0) {
8395 unsigned AlignInBits =
Align*8;
8397 EVT RetVT = WidenEltVT;
8402 if (Width == WidenEltWidth)
8413 (WidenWidth % MemVTWidth) == 0 &&
8415 (MemVTWidth <= Width ||
8416 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8417 if (MemVTWidth == WidenWidth)
8436 (WidenWidth % MemVTWidth) == 0 &&
8438 (MemVTWidth <= Width ||
8439 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8448 return std::nullopt;
8459 unsigned Start,
unsigned End) {
8460 SDLoc dl(LdOps[Start]);
8461 EVT LdTy = LdOps[Start].getValueType();
8469 for (
unsigned i = Start + 1; i != End; ++i) {
8470 EVT NewLdTy = LdOps[i].getValueType();
8471 if (NewLdTy != LdTy) {
8490 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8491 EVT LdVT =
LD->getMemoryVT();
8501 AAMDNodes AAInfo =
LD->getAAInfo();
8505 TypeSize WidthDiff = WidenWidth - LdWidth;
8512 std::optional<EVT> FirstVT =
8513 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8520 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8525 std::optional<EVT> NewVT = FirstVT;
8526 TypeSize RemainingWidth = LdWidth;
8527 TypeSize NewVTWidth = FirstVTWidth;
8529 RemainingWidth -= NewVTWidth;
8536 NewVTWidth = NewVT->getSizeInBits();
8542 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8543 LD->getBaseAlign(), MMOFlags, AAInfo);
8555 uint64_t ScaledOffset = 0;
8556 MachinePointerInfo MPI =
LD->getPointerInfo();
8562 for (EVT MemVT : MemVTs) {
8563 Align NewAlign = ScaledOffset == 0
8564 ?
LD->getBaseAlign()
8567 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8575 unsigned End = LdOps.
size();
8586 EVT LdTy = LdOps[i].getValueType();
8589 for (--i; i >= 0; --i) {
8590 LdTy = LdOps[i].getValueType();
8597 ConcatOps[--Idx] = LdOps[i];
8598 for (--i; i >= 0; --i) {
8599 EVT NewLdTy = LdOps[i].getValueType();
8600 if (NewLdTy != LdTy) {
8610 for (;
j != End-Idx; ++
j)
8611 WidenOps[j] = ConcatOps[Idx+j];
8613 WidenOps[j] = DAG.getPOISON(LdTy);
8620 ConcatOps[--Idx] = LdOps[i];
8625 ArrayRef(&ConcatOps[Idx], End - Idx));
8631 SDValue UndefVal = DAG.getPOISON(LdTy);
8634 for (; i != End-Idx; ++i)
8635 WidenOps[i] = ConcatOps[Idx+i];
8637 WidenOps[i] = UndefVal;
8648 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8649 EVT LdVT =
LD->getMemoryVT();
8658 AAMDNodes AAInfo =
LD->getAAInfo();
8672 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8673 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8679 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8680 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8681 LD->getBaseAlign(), MMOFlags, AAInfo);
8686 SDValue UndefVal = DAG.getPOISON(EltVT);
8687 for (; i != WidenNumElts; ++i)
8690 return DAG.getBuildVector(WidenVT, dl,
Ops);
8701 AAMDNodes AAInfo =
ST->getAAInfo();
8702 SDValue ValOp = GetWidenedVector(
ST->getValue());
8705 EVT StVT =
ST->getMemoryVT();
8713 "Mismatch between store and value types");
8717 MachinePointerInfo MPI =
ST->getPointerInfo();
8718 uint64_t ScaledOffset = 0;
8727 std::optional<EVT> NewVT =
8732 TypeSize NewVTWidth = NewVT->getSizeInBits();
8735 StWidth -= NewVTWidth;
8736 MemVTs.
back().second++;
8740 for (
const auto &Pair : MemVTs) {
8741 EVT NewVT = Pair.first;
8742 unsigned Count = Pair.second;
8748 Align NewAlign = ScaledOffset == 0
8749 ?
ST->getBaseAlign()
8751 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8752 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8768 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8769 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8770 ST->getBaseAlign(), MMOFlags, AAInfo);
8787 bool FillWithZeroes) {
8792 "input and widen element type must match");
8794 "cannot modify scalable vectors in this way");
8807 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
8809 for (
unsigned i = 1; i != NumConcat; ++i)
8816 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8819 "Scalable vectors should have been handled already.");
8827 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8829 for (Idx = 0; Idx < MinNumElts; ++Idx)
8830 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8832 SDValue UndefVal = DAG.getPOISON(EltVT);
8833 for (; Idx < WidenNumElts; ++Idx)
8834 Ops[Idx] = UndefVal;
8836 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8837 if (!FillWithZeroes)
8841 "We expect to never want to FillWithZeroes for non-integral types.");
8844 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8845 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8847 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8848 DAG.getBuildVector(NVT, dl, MaskOps));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
This file implements the SmallBitVector class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by OFFSET elements an...
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.