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);
915 if (!Res.
getNode())
return false;
923 "Invalid operand expansion");
925 ReplaceValueWith(
SDValue(
N, 0), Res);
932 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
934 N->getValueType(0), Elt);
939 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
940 "Fake Use: Unexpected vector type!");
941 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
942 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
948 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
949 "Unexpected vector type!");
950 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
952 N->getValueType(0).getScalarType(), Elt);
960SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
961 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
962 "Unexpected vector type!");
963 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
965 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
966 Elt,
N->getOperand(1));
974SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
975 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
976 "Unexpected vector type!");
977 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
979 {
N->getValueType(0).getScalarType(), MVT::Other },
980 {
N->getOperand(0), Elt });
990 ReplaceValueWith(
SDValue(
N, 0), Res);
995SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
997 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
998 Ops[i] = GetScalarizedVector(
N->getOperand(i));
999 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1004SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1008 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1009 SDValue ContainingVec =
N->getOperand(0);
1017SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1018 EVT VT =
N->getValueType(0);
1019 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1031 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1032 EVT VT =
N->getValueType(0);
1034 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1042 assert(
N->getValueType(0).isVector() &&
1043 N->getOperand(0).getValueType().isVector() &&
1044 "Operand types must be vectors");
1045 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1047 EVT VT =
N->getValueType(0);
1048 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1049 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1051 EVT OpVT =
N->getOperand(0).getValueType();
1063 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1069SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1071 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1072 assert(
N->getValueType(0).isVector() &&
1073 N->getOperand(1).getValueType().isVector() &&
1074 "Operand types must be vectors");
1075 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1077 EVT VT =
N->getValueType(0);
1079 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1080 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1083 EVT OpVT =
N->getOperand(1).getValueType();
1087 {Ch, LHS, RHS, CC});
1096 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1101 ReplaceValueWith(
SDValue(
N, 0), Res);
1108 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1109 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1112 if (
N->isTruncatingStore())
1113 return DAG.getTruncStore(
1114 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1115 N->getBasePtr(),
N->getPointerInfo(),
1116 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1117 N->getMemOperand()->getFlags(),
N->getAAInfo());
1119 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1120 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1121 N->getMemOperand()->getFlags(),
N->getAAInfo());
1126SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1127 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1128 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1130 N->getValueType(0).getVectorElementType(), Elt,
1135SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1137 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1138 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1141 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1151 ReplaceValueWith(
SDValue(
N, 0), Res);
1158 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1160 N->getValueType(0).getVectorElementType(), Elt);
1166SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1167 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1170 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1171 {
N->getOperand(0), Elt});
1180 ReplaceValueWith(
SDValue(
N, 0), Res);
1185 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1192SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1198 SDValue Op = GetScalarizedVector(VecOp);
1199 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1200 AccOp,
Op,
N->getFlags());
1204 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1205 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1212SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1220 EVT VT =
N->getValueType(0);
1221 return DAG.getConstant(0, SDLoc(
N), VT);
1232void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1237 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1240 switch (
N->getOpcode()) {
1243 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1252 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1260 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1276 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1279 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1288 case ISD::VP_LOAD_FF:
1291 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1298 case ISD::VP_GATHER:
1302 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1306 SplitVecRes_SETCC(
N,
Lo,
Hi);
1309 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1316 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1319 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1322 SplitVecRes_VECTOR_INTERLEAVE(
N);
1325 SplitVecRes_VAARG(
N,
Lo,
Hi);
1331 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1337 case ISD::VP_BITREVERSE:
1345 case ISD::VP_CTLZ_ZERO_UNDEF:
1347 case ISD::VP_CTTZ_ZERO_UNDEF:
1362 case ISD::VP_FFLOOR:
1367 case ISD::VP_FNEARBYINT:
1372 case ISD::VP_FP_EXTEND:
1374 case ISD::VP_FP_ROUND:
1376 case ISD::VP_FP_TO_SINT:
1378 case ISD::VP_FP_TO_UINT:
1384 case ISD::VP_LLRINT:
1386 case ISD::VP_FROUND:
1388 case ISD::VP_FROUNDEVEN:
1397 case ISD::VP_FROUNDTOZERO:
1399 case ISD::VP_SINT_TO_FP:
1401 case ISD::VP_TRUNCATE:
1403 case ISD::VP_UINT_TO_FP:
1407 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1410 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1416 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1422 case ISD::VP_SIGN_EXTEND:
1423 case ISD::VP_ZERO_EXTEND:
1424 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1446 case ISD::VP_FMINNUM:
1449 case ISD::VP_FMAXNUM:
1451 case ISD::VP_FMINIMUM:
1453 case ISD::VP_FMAXIMUM:
1462 case ISD::OR:
case ISD::VP_OR:
1482 case ISD::VP_FCOPYSIGN:
1483 SplitVecRes_BinOp(
N,
Lo,
Hi);
1490 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1494 SplitVecRes_CMP(
N,
Lo,
Hi);
1497#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1498 case ISD::STRICT_##DAGN:
1499#include "llvm/IR/ConstrainedOps.def"
1500 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1505 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1514 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1524 SplitVecRes_FIX(
N,
Lo,
Hi);
1526 case ISD::EXPERIMENTAL_VP_SPLICE:
1527 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1529 case ISD::EXPERIMENTAL_VP_REVERSE:
1530 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1536 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1539 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1548void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1550 uint64_t *ScaledOffset) {
1555 SDValue BytesIncrement = DAG.getVScale(
1558 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1560 *ScaledOffset += IncrementSize;
1570std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1571 return SplitMask(Mask, SDLoc(Mask));
1574std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1577 EVT MaskVT =
Mask.getValueType();
1579 GetSplitVector(Mask, MaskLo, MaskHi);
1581 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1582 return std::make_pair(MaskLo, MaskHi);
1587 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1589 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1592 const SDNodeFlags
Flags =
N->getFlags();
1593 unsigned Opcode =
N->getOpcode();
1594 if (
N->getNumOperands() == 2) {
1595 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1596 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1600 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1601 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1604 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1607 std::tie(EVLLo, EVLHi) =
1608 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1611 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1613 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1619 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1621 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1623 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1626 const SDNodeFlags
Flags =
N->getFlags();
1627 unsigned Opcode =
N->getOpcode();
1628 if (
N->getNumOperands() == 3) {
1629 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1630 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1634 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1635 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1638 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1641 std::tie(EVLLo, EVLHi) =
1642 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1645 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1647 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1651 LLVMContext &Ctxt = *DAG.getContext();
1657 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1659 GetSplitVector(
LHS, LHSLo, LHSHi);
1660 GetSplitVector(
RHS, RHSLo, RHSHi);
1662 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1663 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1667 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1668 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1673 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1675 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1679 unsigned Opcode =
N->getOpcode();
1680 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1682 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1691 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1698 switch (getTypeAction(InVT)) {
1712 GetExpandedOp(InOp,
Lo,
Hi);
1713 if (DAG.getDataLayout().isBigEndian())
1723 GetSplitVector(InOp,
Lo,
Hi);
1732 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1741 if (DAG.getDataLayout().isBigEndian())
1744 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1746 if (DAG.getDataLayout().isBigEndian())
1752void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1758 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1761 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1766 unsigned LaneOffset =
1769 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1771 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1778 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1781 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1784 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1789 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1791 unsigned NumSubvectors =
N->getNumOperands() / 2;
1792 if (NumSubvectors == 1) {
1793 Lo =
N->getOperand(0);
1794 Hi =
N->getOperand(1);
1799 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1808void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1815 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1830 GetSplitVector(Vec,
Lo,
Hi);
1833 EVT LoVT =
Lo.getValueType();
1843 if (IdxVal + SubElems <= LoElems) {
1851 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1853 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1859 SDValue WideSubVec = GetWidenedVector(SubVec);
1861 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1869 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1871 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1872 auto &MF = DAG.getMachineFunction();
1876 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1881 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1882 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1886 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1891 MachinePointerInfo MPI =
Load->getPointerInfo();
1892 IncrementPointer(Load, LoVT, MPI, StackPtr);
1895 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1904 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1909 EVT RHSVT =
RHS.getValueType();
1912 GetSplitVector(
RHS, RHSLo, RHSHi);
1914 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1929 SDValue FpValue =
N->getOperand(0);
1931 GetSplitVector(FpValue, ArgLo, ArgHi);
1933 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1935 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1944 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1948 std::tie(LoVT, HiVT) =
1952 DAG.getValueType(LoVT));
1954 DAG.getValueType(HiVT));
1959 unsigned Opcode =
N->getOpcode();
1966 GetSplitVector(N0, InLo, InHi);
1968 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1973 EVT OutLoVT, OutHiVT;
1974 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1976 assert((2 * OutNumElements) <= InNumElements &&
1977 "Illegal extend vector in reg split");
1986 SmallVector<int, 8> SplitHi(InNumElements, -1);
1987 for (
unsigned i = 0; i != OutNumElements; ++i)
1988 SplitHi[i] = i + OutNumElements;
1989 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
1991 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1992 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1997 unsigned NumOps =
N->getNumOperands();
2001 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2011 for (
unsigned i = 1; i <
NumOps; ++i) {
2016 EVT InVT =
Op.getValueType();
2021 GetSplitVector(
Op, OpLo, OpHi);
2023 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2030 EVT LoValueVTs[] = {LoVT, MVT::Other};
2031 EVT HiValueVTs[] = {HiVT, MVT::Other};
2032 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2034 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2040 Lo.getValue(1),
Hi.getValue(1));
2044 ReplaceValueWith(
SDValue(
N, 1), Chain);
2047SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2049 EVT VT =
N->getValueType(0);
2060 else if (NE > ResNE)
2064 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2068 for (i = 0; i !=
NE; ++i) {
2069 Operands[0] = Chain;
2070 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2071 SDValue Operand =
N->getOperand(j);
2075 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2077 Operands[
j] = Operand;
2081 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2089 for (; i < ResNE; ++i)
2090 Scalars.
push_back(DAG.getPOISON(EltVT));
2094 ReplaceValueWith(
SDValue(
N, 1), Chain);
2098 return DAG.getBuildVector(VecVT, dl, Scalars);
2101void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2104 EVT ResVT =
N->getValueType(0);
2105 EVT OvVT =
N->getValueType(1);
2106 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2107 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2108 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2110 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2112 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2113 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2115 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2116 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2119 unsigned Opcode =
N->getOpcode();
2120 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2121 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2123 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2125 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2131 unsigned OtherNo = 1 - ResNo;
2132 EVT OtherVT =
N->getValueType(OtherNo);
2134 SetSplitVector(
SDValue(
N, OtherNo),
2140 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2144void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2150 GetSplitVector(Vec,
Lo,
Hi);
2153 unsigned IdxVal = CIdx->getZExtValue();
2154 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2155 if (IdxVal < LoNumElts) {
2157 Lo.getValueType(),
Lo, Elt, Idx);
2160 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2180 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2182 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2183 auto &MF = DAG.getMachineFunction();
2187 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2192 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2193 Store = DAG.getTruncStore(
2199 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2202 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2206 MachinePointerInfo MPI =
Load->getPointerInfo();
2207 IncrementPointer(Load, LoVT, MPI, StackPtr);
2209 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2212 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2213 if (LoVT !=
Lo.getValueType())
2215 if (HiVT !=
Hi.getValueType())
2223 assert(
N->getValueType(0).isScalableVector() &&
2224 "Only scalable vectors are supported for STEP_VECTOR");
2225 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2246 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2247 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2249 Hi = DAG.getPOISON(HiVT);
2261 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2267 EVT MemoryVT =
LD->getMemoryVT();
2269 AAMDNodes AAInfo =
LD->getAAInfo();
2271 EVT LoMemVT, HiMemVT;
2272 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2276 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2277 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2278 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2283 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2286 MachinePointerInfo MPI;
2287 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2290 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2299 ReplaceValueWith(
SDValue(LD, 1), Ch);
2304 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2307 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2313 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2314 Align Alignment =
LD->getBaseAlign();
2317 EVT MemoryVT =
LD->getMemoryVT();
2319 EVT LoMemVT, HiMemVT;
2320 bool HiIsEmpty =
false;
2321 std::tie(LoMemVT, HiMemVT) =
2322 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2327 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2330 GetSplitVector(Mask, MaskLo, MaskHi);
2332 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2337 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2339 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2345 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2346 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2354 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2355 LD->isExpandingLoad());
2357 MachinePointerInfo MPI;
2359 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2361 MPI =
LD->getPointerInfo().getWithOffset(
2364 MMO = DAG.getMachineFunction().getMachineMemOperand(
2366 Alignment,
LD->getAAInfo(),
LD->getRanges());
2368 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2369 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2370 LD->isExpandingLoad());
2380 ReplaceValueWith(
SDValue(LD, 1), Ch);
2386 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2390 Align Alignment =
LD->getBaseAlign();
2397 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2400 GetSplitVector(Mask, MaskLo, MaskHi);
2402 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2406 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2408 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2413 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2416 Hi = DAG.getPOISON(HiVT);
2418 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2419 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2425 "Indexed VP strided load during type legalization!");
2427 "Unexpected indexed variable-length load offset");
2432 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2434 EVT LoMemVT, HiMemVT;
2435 bool HiIsEmpty =
false;
2436 std::tie(LoMemVT, HiMemVT) =
2437 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2442 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2445 GetSplitVector(Mask, LoMask, HiMask);
2447 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2451 std::tie(LoEVL, HiEVL) =
2455 Lo = DAG.getStridedLoadVP(
2482 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2489 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2500 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2508 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2513 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2523 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2526 GetSplitVector(Mask, MaskLo, MaskHi);
2528 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2532 EVT LoMemVT, HiMemVT;
2533 bool HiIsEmpty =
false;
2534 std::tie(LoMemVT, HiMemVT) =
2535 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2537 SDValue PassThruLo, PassThruHi;
2539 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2541 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2543 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2547 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2557 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2560 MachinePointerInfo MPI;
2567 MMO = DAG.getMachineFunction().getMachineMemOperand(
2571 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2583 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2591 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2599 }
Ops = [&]() -> Operands {
2601 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2604 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2607 EVT MemoryVT =
N->getMemoryVT();
2608 Align Alignment =
N->getBaseAlign();
2613 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2615 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2618 EVT LoMemVT, HiMemVT;
2620 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2623 if (getTypeAction(
Ops.Index.getValueType()) ==
2625 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2627 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2630 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2632 Alignment,
N->getAAInfo(),
N->getRanges());
2635 SDValue PassThru = MGT->getPassThru();
2636 SDValue PassThruLo, PassThruHi;
2639 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2641 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2646 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2647 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2648 OpsLo, MMO, IndexTy, ExtType);
2650 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2651 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2652 OpsHi, MMO, IndexTy, ExtType);
2656 std::tie(EVLLo, EVLHi) =
2657 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2659 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2660 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2661 MMO, VPGT->getIndexType());
2663 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2664 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2665 MMO, VPGT->getIndexType());
2675 ReplaceValueWith(
SDValue(
N, 1), Ch);
2689 EVT VecVT =
N->getValueType(0);
2691 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2692 bool HasCustomLowering =
false;
2699 HasCustomLowering =
true;
2705 SDValue Passthru =
N->getOperand(2);
2706 if (!HasCustomLowering) {
2707 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2708 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2715 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2716 std::tie(LoMask, HiMask) = SplitMask(Mask);
2718 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2723 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2724 MachineFunction &MF = DAG.getMachineFunction();
2736 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2738 SDValue Chain = DAG.getEntryNode();
2739 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2743 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2748 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2752 assert(
N->getValueType(0).isVector() &&
2753 N->getOperand(0).getValueType().isVector() &&
2754 "Operand types must be vectors");
2758 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2762 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2764 GetSplitVector(
N->getOperand(0), LL, LH);
2766 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2768 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2770 GetSplitVector(
N->getOperand(1), RL, RH);
2772 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2775 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2776 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2778 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2779 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2780 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2781 std::tie(EVLLo, EVLHi) =
2782 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2783 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2785 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2795 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2799 EVT InVT =
N->getOperand(0).getValueType();
2801 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2803 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2805 const SDNodeFlags
Flags =
N->getFlags();
2806 unsigned Opcode =
N->getOpcode();
2807 if (
N->getNumOperands() <= 2) {
2810 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2811 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2813 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2814 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2819 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2820 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2823 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2826 std::tie(EVLLo, EVLHi) =
2827 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2830 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2836 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2840 EVT InVT =
N->getOperand(0).getValueType();
2842 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2844 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2847 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2848 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2849 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2850 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2853void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2858 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2859 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2863 EVT InVT =
N->getOperand(0).getValueType();
2865 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2867 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2869 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2870 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2872 SDNode *HiNode =
Hi.getNode();
2873 SDNode *LoNode =
Lo.getNode();
2876 unsigned OtherNo = 1 - ResNo;
2877 EVT OtherVT =
N->getValueType(OtherNo);
2885 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2892 EVT SrcVT =
N->getOperand(0).getValueType();
2893 EVT DestVT =
N->getValueType(0);
2895 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2912 LLVMContext &Ctx = *DAG.getContext();
2916 EVT SplitLoVT, SplitHiVT;
2917 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2918 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2919 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2920 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2921 N->dump(&DAG);
dbgs() <<
"\n");
2922 if (!
N->isVPOpcode()) {
2925 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2927 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2929 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2930 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2936 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2937 N->getOperand(1),
N->getOperand(2));
2939 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2942 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2945 std::tie(EVLLo, EVLHi) =
2946 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2948 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2949 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2954 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2962 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2963 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2969 return N.getResNo() == 0 &&
2973 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2975 ArrayRef<int>
Mask) {
2978 "Expected build vector node.");
2981 for (
unsigned I = 0;
I < NewElts; ++
I) {
2984 unsigned Idx =
Mask[
I];
2986 Ops[
I] = Input2.getOperand(Idx - NewElts);
2988 Ops[
I] = Input1.getOperand(Idx);
2993 return DAG.getBuildVector(NewVT,
DL,
Ops);
2999 SmallVector<int> OrigMask(
N->getMask());
3001 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3002 &
DL](SmallVectorImpl<int> &
Mask) {
3004 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3005 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3016 for (
auto &
P : ShufflesIdxs) {
3017 if (
P.second.size() < 2)
3021 for (
int &Idx : Mask) {
3024 unsigned SrcRegIdx = Idx / NewElts;
3025 if (Inputs[SrcRegIdx].
isUndef()) {
3033 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3038 Idx = MaskElt % NewElts +
3039 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3045 Inputs[
P.second[0]] =
P.first.first;
3046 Inputs[
P.second[1]] =
P.first.second;
3049 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3052 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3053 for (
int &Idx : Mask) {
3056 unsigned SrcRegIdx = Idx / NewElts;
3057 if (Inputs[SrcRegIdx].
isUndef()) {
3064 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3065 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3068 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3070 if (UsedSubVector.count() > 1) {
3072 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3073 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3075 if (Pairs.
empty() || Pairs.
back().size() == 2)
3077 if (UsedSubVector.test(2 *
I)) {
3078 Pairs.
back().emplace_back(
I, 0);
3080 assert(UsedSubVector.test(2 *
I + 1) &&
3081 "Expected to be used one of the subvectors.");
3082 Pairs.
back().emplace_back(
I, 1);
3085 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3087 for (
int &Idx : Mask) {
3090 unsigned SrcRegIdx = Idx / NewElts;
3092 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3093 return Idxs.front().first == SrcRegIdx ||
3094 Idxs.back().first == SrcRegIdx;
3096 if (It == Pairs.
end())
3098 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3099 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3102 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3103 Inputs[Idxs.front().first] = DAG.
getNode(
3105 Inputs[Idxs.front().first].getValueType(),
3106 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3107 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3116 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3120 if (Shuffle->getOperand(0).getValueType() != NewVT)
3123 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3124 !Shuffle->isSplat()) {
3126 }
else if (!Inputs[
I].hasOneUse() &&
3127 !Shuffle->getOperand(1).isUndef()) {
3129 for (
int &Idx : Mask) {
3132 unsigned SrcRegIdx = Idx / NewElts;
3135 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3140 int OpIdx = MaskElt / NewElts;
3154 if (Shuffle->getOperand(
OpIdx).isUndef())
3156 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3157 if (It == std::end(Inputs))
3159 int FoundOp = std::distance(std::begin(Inputs), It);
3162 for (
int &Idx : Mask) {
3165 unsigned SrcRegIdx = Idx / NewElts;
3168 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3173 int MaskIdx = MaskElt / NewElts;
3174 if (
OpIdx == MaskIdx)
3175 Idx = MaskElt % NewElts + FoundOp * NewElts;
3186 for (
int &Idx : Mask) {
3189 unsigned SrcRegIdx = Idx / NewElts;
3192 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3193 int OpIdx = MaskElt / NewElts;
3196 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3202 TryPeekThroughShufflesInputs(OrigMask);
3204 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3205 NewElts](SmallVectorImpl<int> &
Mask) {
3206 SetVector<SDValue> UniqueInputs;
3207 SetVector<SDValue> UniqueConstantInputs;
3208 for (
const auto &
I : Inputs) {
3210 UniqueConstantInputs.
insert(
I);
3211 else if (!
I.isUndef())
3216 if (UniqueInputs.
size() != std::size(Inputs)) {
3217 auto &&UniqueVec = UniqueInputs.
takeVector();
3218 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3219 unsigned ConstNum = UniqueConstantVec.size();
3220 for (
int &Idx : Mask) {
3223 unsigned SrcRegIdx = Idx / NewElts;
3224 if (Inputs[SrcRegIdx].
isUndef()) {
3228 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3229 if (It != UniqueConstantVec.end()) {
3230 Idx = (Idx % NewElts) +
3231 NewElts * std::distance(UniqueConstantVec.begin(), It);
3232 assert(Idx >= 0 &&
"Expected defined mask idx.");
3235 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3236 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3237 Idx = (Idx % NewElts) +
3238 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3239 assert(Idx >= 0 &&
"Expected defined mask idx.");
3241 copy(UniqueConstantVec, std::begin(Inputs));
3242 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3245 MakeUniqueInputs(OrigMask);
3247 copy(Inputs, std::begin(OrigInputs));
3253 unsigned FirstMaskIdx =
High * NewElts;
3256 assert(!Output &&
"Expected default initialized initial value.");
3257 TryPeekThroughShufflesInputs(Mask);
3258 MakeUniqueInputs(Mask);
3260 copy(Inputs, std::begin(TmpInputs));
3263 bool SecondIteration =
false;
3264 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3269 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3270 SecondIteration =
true;
3271 return SecondIteration;
3274 Mask, std::size(Inputs), std::size(Inputs),
3276 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3277 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3278 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3280 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3282 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3283 DAG.getPOISON(NewVT), Mask);
3284 Inputs[Idx] = Output;
3286 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3287 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3288 unsigned Idx2,
bool ) {
3289 if (AccumulateResults(Idx1)) {
3292 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3294 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3295 Inputs[Idx2], Mask);
3299 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3301 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3302 TmpInputs[Idx2], Mask);
3304 Inputs[Idx1] = Output;
3306 copy(OrigInputs, std::begin(Inputs));
3311 EVT OVT =
N->getValueType(0);
3318 const Align Alignment =
3319 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3321 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3322 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3327 ReplaceValueWith(
SDValue(
N, 1), Chain);
3332 EVT DstVTLo, DstVTHi;
3333 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3337 EVT SrcVT =
N->getOperand(0).getValueType();
3339 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3341 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3343 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3344 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3350 GetSplitVector(
N->getOperand(0), InLo, InHi);
3361 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3362 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3367 EVT VT =
N->getValueType(0);
3374 Align Alignment = DAG.getReducedAlign(VT,
false);
3379 EVT PtrVT =
StackPtr.getValueType();
3380 auto &MF = DAG.getMachineFunction();
3384 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3387 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3393 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3394 DAG.getConstant(1,
DL, PtrVT));
3396 DAG.getConstant(EltWidth,
DL, PtrVT));
3398 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3400 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3401 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3402 DAG.getPOISON(PtrVT), Stride, TrueMask,
3405 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3407 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3412 EVT VT =
N->getValueType(0);
3424 EVL1 = ZExtPromotedInteger(EVL1);
3426 Align Alignment = DAG.getReducedAlign(VT,
false);
3431 EVT PtrVT =
StackPtr.getValueType();
3432 auto &MF = DAG.getMachineFunction();
3436 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3439 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3443 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3444 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3446 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3448 DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr, PoisonPtr, TrueMask,
3452 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3457 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3458 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3460 uint64_t TrailingElts = -
Imm;
3462 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3471 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3475 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3477 DAG.getVectorIdxConstant(0,
DL));
3483void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3491 GetSplitVector(Acc, AccLo, AccHi);
3492 unsigned Opcode =
N->getOpcode();
3504 GetSplitVector(Input1, Input1Lo, Input1Hi);
3505 GetSplitVector(Input2, Input2Lo, Input2Hi);
3508 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3509 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3512void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3520 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3528void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3529 unsigned Factor =
N->getNumOperands();
3532 for (
unsigned i = 0; i != Factor; ++i) {
3534 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3536 Ops[i * 2 + 1] = OpHi;
3547 for (
unsigned i = 0; i != Factor; ++i)
3551void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3552 unsigned Factor =
N->getNumOperands();
3555 for (
unsigned i = 0; i != Factor; ++i) {
3557 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3559 Ops[i + Factor] = OpHi;
3570 for (
unsigned i = 0; i != Factor; ++i) {
3571 unsigned IdxLo = 2 * i;
3572 unsigned IdxHi = 2 * i + 1;
3573 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3574 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3586bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3591 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3594 switch (
N->getOpcode()) {
3597 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3607 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3614 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3616 case ISD::VP_TRUNCATE:
3618 Res = SplitVecOp_TruncateHelper(
N);
3621 case ISD::VP_FP_ROUND:
3624 Res = SplitVecOp_FP_ROUND(
N);
3633 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3640 case ISD::VP_SCATTER:
3644 case ISD::VP_GATHER:
3648 Res = SplitVecOp_VSELECT(
N, OpNo);
3651 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3657 case ISD::VP_SINT_TO_FP:
3658 case ISD::VP_UINT_TO_FP:
3659 if (
N->getValueType(0).bitsLT(
3660 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3661 Res = SplitVecOp_TruncateHelper(
N);
3663 Res = SplitVecOp_UnaryOp(
N);
3667 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3671 case ISD::VP_FP_TO_SINT:
3672 case ISD::VP_FP_TO_UINT:
3685 Res = SplitVecOp_UnaryOp(
N);
3688 Res = SplitVecOp_FPOpDifferentTypes(
N);
3693 Res = SplitVecOp_CMP(
N);
3697 Res = SplitVecOp_FAKE_USE(
N);
3702 Res = SplitVecOp_ExtVecInRegOp(
N);
3720 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3724 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3726 case ISD::VP_REDUCE_FADD:
3727 case ISD::VP_REDUCE_SEQ_FADD:
3728 case ISD::VP_REDUCE_FMUL:
3729 case ISD::VP_REDUCE_SEQ_FMUL:
3730 case ISD::VP_REDUCE_ADD:
3731 case ISD::VP_REDUCE_MUL:
3732 case ISD::VP_REDUCE_AND:
3733 case ISD::VP_REDUCE_OR:
3734 case ISD::VP_REDUCE_XOR:
3735 case ISD::VP_REDUCE_SMAX:
3736 case ISD::VP_REDUCE_SMIN:
3737 case ISD::VP_REDUCE_UMAX:
3738 case ISD::VP_REDUCE_UMIN:
3739 case ISD::VP_REDUCE_FMAX:
3740 case ISD::VP_REDUCE_FMIN:
3741 case ISD::VP_REDUCE_FMAXIMUM:
3742 case ISD::VP_REDUCE_FMINIMUM:
3743 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3745 case ISD::VP_CTTZ_ELTS:
3746 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3747 Res = SplitVecOp_VP_CttzElements(
N);
3750 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3756 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3761 if (!Res.
getNode())
return false;
3768 if (
N->isStrictFPOpcode())
3770 "Invalid operand expansion");
3773 "Invalid operand expansion");
3775 ReplaceValueWith(
SDValue(
N, 0), Res);
3779SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3783 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3785 EVT VT =
N->getValueType(0);
3798 getSetCCResultType(MVT::i1), MVT::i1);
3803 DAG.getElementCount(
DL, VT, SplitEC)),
3807SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3810 assert(OpNo == 0 &&
"Illegal operand must be mask");
3817 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3820 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3821 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3822 "Lo and Hi have differing types");
3825 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3826 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3828 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3829 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3830 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3831 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3841SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3844 assert(OpNo == 1 &&
"Illegal operand must be mask");
3849 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3851 EVT VecVT =
N->getValueType(0);
3855SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3856 EVT ResVT =
N->getValueType(0);
3862 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3863 GetSplitVector(VecOp,
Lo,
Hi);
3865 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3870 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3871 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3875 EVT ResVT =
N->getValueType(0);
3881 SDNodeFlags
Flags =
N->getFlags();
3884 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3885 GetSplitVector(VecOp,
Lo,
Hi);
3887 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3893 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3896SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3897 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3898 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3900 unsigned Opc =
N->getOpcode();
3901 EVT ResVT =
N->getValueType(0);
3907 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3908 GetSplitVector(VecOp,
Lo,
Hi);
3911 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3914 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3916 const SDNodeFlags
Flags =
N->getFlags();
3920 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3925 EVT ResVT =
N->getValueType(0);
3928 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3929 EVT InVT =
Lo.getValueType();
3934 if (
N->isStrictFPOpcode()) {
3935 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3936 {N->getOperand(0), Lo});
3937 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3938 {N->getOperand(0), Hi});
3947 ReplaceValueWith(
SDValue(
N, 1), Ch);
3948 }
else if (
N->getNumOperands() == 3) {
3949 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3950 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3951 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3952 std::tie(EVLLo, EVLHi) =
3953 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3954 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3955 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3957 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3958 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3967 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3977 EVT ResVT =
N->getValueType(0);
3979 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3983 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3989 Lo = BitConvertToInteger(
Lo);
3990 Hi = BitConvertToInteger(
Hi);
3992 if (DAG.getDataLayout().isBigEndian())
4000 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4002 EVT ResVT =
N->getValueType(0);
4010 GetSplitVector(SubVec,
Lo,
Hi);
4019 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4021 return SecondInsertion;
4024SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4031 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4033 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4035 ElementCount IdxVal =
4039 EVT SrcVT =
N->getOperand(0).getValueType();
4058 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4059 LoEltsMin - IdxValMin);
4060 DAG.ExtractVectorElements(
Hi, Elts, 0,
4063 return DAG.getBuildVector(SubVT, dl, Elts);
4067 ElementCount ExtractIdx = IdxVal - LoElts;
4069 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4072 EVT HiVT =
Hi.getValueType();
4074 "Only fixed-vector extracts are supported in this case");
4084 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4085 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4091 "Extracting scalable subvector from fixed-width unsupported");
4099 "subvector from a scalable predicate vector");
4105 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4107 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4108 auto &MF = DAG.getMachineFunction();
4112 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4116 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4119 SubVT, dl, Store, StackPtr,
4123SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4129 uint64_t IdxVal =
Index->getZExtValue();
4132 GetSplitVector(Vec,
Lo,
Hi);
4134 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4136 if (IdxVal < LoElts)
4137 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4140 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4145 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4157 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4163 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4165 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4166 auto &MF = DAG.getMachineFunction();
4169 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4173 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4177 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4179 return DAG.getExtLoad(
4190 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4198 SplitVecRes_Gather(
N,
Lo,
Hi);
4201 ReplaceValueWith(
SDValue(
N, 0), Res);
4206 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4210 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4212 SDValue EVL =
N->getVectorLength();
4214 Align Alignment =
N->getBaseAlign();
4220 GetSplitVector(
Data, DataLo, DataHi);
4222 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4227 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4230 GetSplitVector(Mask, MaskLo, MaskHi);
4232 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4235 EVT MemoryVT =
N->getMemoryVT();
4236 EVT LoMemVT, HiMemVT;
4237 bool HiIsEmpty =
false;
4238 std::tie(LoMemVT, HiMemVT) =
4239 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4243 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4246 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4251 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4252 N->getAddressingMode(),
N->isTruncatingStore(),
4253 N->isCompressingStore());
4259 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4260 N->isCompressingStore());
4262 MachinePointerInfo MPI;
4266 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4271 MMO = DAG.getMachineFunction().getMachineMemOperand(
4273 Alignment,
N->getAAInfo(),
N->getRanges());
4275 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4276 N->getAddressingMode(),
N->isTruncatingStore(),
4277 N->isCompressingStore());
4286 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4287 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4294 GetSplitVector(
Data, LoData, HiData);
4296 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4298 EVT LoMemVT, HiMemVT;
4299 bool HiIsEmpty =
false;
4300 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4306 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4307 else if (getTypeAction(
Mask.getValueType()) ==
4309 GetSplitVector(Mask, LoMask, HiMask);
4311 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4314 std::tie(LoEVL, HiEVL) =
4315 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4319 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4320 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4321 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4332 EVT PtrVT =
N->getBasePtr().getValueType();
4335 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4338 Align Alignment =
N->getBaseAlign();
4343 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4344 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4346 Alignment,
N->getAAInfo(),
N->getRanges());
4349 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4350 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4351 N->isCompressingStore());
4360 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4364 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4367 Align Alignment =
N->getBaseAlign();
4373 GetSplitVector(
Data, DataLo, DataHi);
4375 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4380 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4383 GetSplitVector(Mask, MaskLo, MaskHi);
4385 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4388 EVT MemoryVT =
N->getMemoryVT();
4389 EVT LoMemVT, HiMemVT;
4390 bool HiIsEmpty =
false;
4391 std::tie(LoMemVT, HiMemVT) =
4392 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4395 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4400 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4401 N->getAddressingMode(),
N->isTruncatingStore(),
4402 N->isCompressingStore());
4410 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4411 N->isCompressingStore());
4413 MachinePointerInfo MPI;
4417 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4422 MMO = DAG.getMachineFunction().getMachineMemOperand(
4424 Alignment,
N->getAAInfo(),
N->getRanges());
4426 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4427 N->getAddressingMode(),
N->isTruncatingStore(),
4428 N->isCompressingStore());
4441 EVT MemoryVT =
N->getMemoryVT();
4442 Align Alignment =
N->getBaseAlign();
4449 }
Ops = [&]() -> Operands {
4451 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4455 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4460 EVT LoMemVT, HiMemVT;
4461 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4466 GetSplitVector(
Ops.Data, DataLo, DataHi);
4468 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4473 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4475 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4479 if (getTypeAction(
Ops.Index.getValueType()) ==
4481 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4483 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4487 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4489 Alignment,
N->getAAInfo(),
N->getRanges());
4492 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4494 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4495 MSC->getIndexType(), MSC->isTruncatingStore());
4500 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4501 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4502 MMO, MSC->getIndexType(),
4503 MSC->isTruncatingStore());
4507 std::tie(EVLLo, EVLHi) =
4508 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4510 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4511 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4512 VPSC->getIndexType());
4517 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4518 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4519 VPSC->getIndexType());
4523 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4524 assert(OpNo == 1 &&
"Can only split the stored value");
4527 bool isTruncating =
N->isTruncatingStore();
4530 EVT MemoryVT =
N->getMemoryVT();
4531 Align Alignment =
N->getBaseAlign();
4533 AAMDNodes AAInfo =
N->getAAInfo();
4535 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4537 EVT LoMemVT, HiMemVT;
4538 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4542 return TLI.scalarizeVectorStore(
N, DAG);
4545 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4546 Alignment, MMOFlags, AAInfo);
4548 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4551 MachinePointerInfo MPI;
4552 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4555 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4556 HiMemVT, Alignment, MMOFlags, AAInfo);
4558 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4574 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4580 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4601 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4602 SDValue InVec =
N->getOperand(OpNo);
4604 EVT OutVT =
N->getValueType(0);
4612 EVT LoOutVT, HiOutVT;
4613 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4614 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4619 if (isTypeLegal(LoOutVT) ||
4620 InElementSize <= OutElementSize * 2)
4621 return SplitVecOp_UnaryOp(
N);
4630 return SplitVecOp_UnaryOp(
N);
4634 GetSplitVector(InVec, InLoVec, InHiVec);
4640 EVT HalfElementVT = IsFloat ?
4642 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4649 if (
N->isStrictFPOpcode()) {
4650 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4651 {N->getOperand(0), InLoVec});
4652 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4653 {N->getOperand(0), InHiVec});
4659 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4660 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4664 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4672 if (
N->isStrictFPOpcode()) {
4676 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4684 DAG.getTargetConstant(
4685 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4692 assert(
N->getValueType(0).isVector() &&
4693 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4694 "Operand types must be vectors");
4696 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4698 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4699 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4701 EVT VT =
N->getValueType(0);
4708 }
else if (isStrict) {
4709 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4710 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4711 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4712 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4715 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4717 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4718 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4719 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4720 std::tie(EVLLo, EVLHi) =
4721 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4722 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4723 N->getOperand(2), MaskLo, EVLLo);
4724 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4725 N->getOperand(2), MaskHi, EVLHi);
4734 EVT ResVT =
N->getValueType(0);
4737 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4738 EVT InVT =
Lo.getValueType();
4743 if (
N->isStrictFPOpcode()) {
4744 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4745 {N->getOperand(0), Lo, N->getOperand(2)});
4746 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4747 {N->getOperand(0), Hi, N->getOperand(2)});
4751 Lo.getValue(1),
Hi.getValue(1));
4752 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4753 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4754 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4755 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4756 std::tie(EVLLo, EVLHi) =
4757 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4758 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4759 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4761 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4762 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
4773SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4776 EVT LHSLoVT, LHSHiVT;
4777 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4779 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4780 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4783 std::tie(LHSLo, LHSHi) =
4784 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4787 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4790 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4796 LLVMContext &Ctxt = *DAG.getContext();
4799 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4800 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4801 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4803 EVT ResVT =
N->getValueType(0);
4808 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4809 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4815 EVT ResVT =
N->getValueType(0);
4818 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4819 EVT InVT =
Lo.getValueType();
4825 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4826 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4833 EVT ResVT =
N->getValueType(0);
4837 GetSplitVector(VecOp,
Lo,
Hi);
4839 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4840 auto [EVLLo, EVLHi] =
4842 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4848 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4850 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4851 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4854SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4865 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4866 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4867 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4868 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4869 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4870 OpsLo, MMO, IndexType);
4871 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4872 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4876SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4879 "Accumulator should already be a legal type, and shouldn't need "
4880 "further splitting");
4883 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4884 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4885 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4886 unsigned Opcode =
N->getOpcode();
4889 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4890 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4897void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4898 unsigned WidenResNo) {
4899 unsigned NumResults =
N->getNumValues();
4900 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4901 if (ResNo == WidenResNo)
4903 EVT ResVT =
N->getValueType(ResNo);
4909 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4910 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4915void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4916 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4919 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4924 auto unrollExpandedOp = [&]() {
4929 EVT VT =
N->getValueType(0);
4930 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4931 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4932 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
4934 if (
N->getNumValues() > 1)
4935 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4941 switch (
N->getOpcode()) {
4944 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4952 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4956 Res = WidenVecRes_ADDRSPACECAST(
N);
4963 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4970 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4974 Res = WidenVecRes_ScalarOp(
N);
4979 case ISD::VP_SELECT:
4981 Res = WidenVecRes_Select(
N);
4985 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4987 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4994 case ISD::VP_LOAD_FF:
4997 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5001 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5009 case ISD::VP_GATHER:
5013 Res = WidenVecRes_VECTOR_REVERSE(
N);
5016 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5026 case ISD::OR:
case ISD::VP_OR:
5037 case ISD::VP_FMINNUM:
5040 case ISD::VP_FMAXNUM:
5042 case ISD::VP_FMINIMUM:
5044 case ISD::VP_FMAXIMUM:
5077 case ISD::VP_FCOPYSIGN:
5078 Res = WidenVecRes_Binary(
N);
5083 Res = WidenVecRes_CMP(
N);
5089 if (unrollExpandedOp())
5104 Res = WidenVecRes_BinaryCanTrap(
N);
5113 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5116#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5117 case ISD::STRICT_##DAGN:
5118#include "llvm/IR/ConstrainedOps.def"
5119 Res = WidenVecRes_StrictFP(
N);
5128 Res = WidenVecRes_OverflowOp(
N, ResNo);
5132 Res = WidenVecRes_FCOPYSIGN(
N);
5137 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5142 if (!unrollExpandedOp())
5143 Res = WidenVecRes_ExpOp(
N);
5149 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5154 case ISD::VP_FP_EXTEND:
5156 case ISD::VP_FP_ROUND:
5158 case ISD::VP_FP_TO_SINT:
5160 case ISD::VP_FP_TO_UINT:
5162 case ISD::VP_SIGN_EXTEND:
5164 case ISD::VP_SINT_TO_FP:
5165 case ISD::VP_TRUNCATE:
5168 case ISD::VP_UINT_TO_FP:
5170 case ISD::VP_ZERO_EXTEND:
5172 Res = WidenVecRes_Convert(
N);
5177 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5183 case ISD::VP_LLRINT:
5186 Res = WidenVecRes_XROUND(
N);
5212 if (unrollExpandedOp())
5222 case ISD::VP_BITREVERSE:
5228 case ISD::VP_CTLZ_ZERO_UNDEF:
5234 case ISD::VP_CTTZ_ZERO_UNDEF:
5239 case ISD::VP_FFLOOR:
5241 case ISD::VP_FNEARBYINT:
5242 case ISD::VP_FROUND:
5243 case ISD::VP_FROUNDEVEN:
5244 case ISD::VP_FROUNDTOZERO:
5249 Res = WidenVecRes_Unary(
N);
5256 Res = WidenVecRes_Ternary(
N);
5262 if (!unrollExpandedOp())
5263 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5270 SetWidenedVector(
SDValue(
N, ResNo), Res);
5276 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5277 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5278 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5279 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5280 if (
N->getNumOperands() == 3)
5281 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5283 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5284 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5288 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5289 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5295 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5296 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5297 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5298 if (
N->getNumOperands() == 2)
5299 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5302 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5303 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5307 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5308 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5312 LLVMContext &Ctxt = *DAG.getContext();
5317 EVT OpVT =
LHS.getValueType();
5319 LHS = GetWidenedVector(
LHS);
5320 RHS = GetWidenedVector(
RHS);
5321 OpVT =
LHS.getValueType();
5324 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5327 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5333SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5336 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5337 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5338 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5340 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5349 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5352 if (ConcatEnd == 1) {
5353 VT = ConcatOps[0].getValueType();
5355 return ConcatOps[0];
5358 SDLoc dl(ConcatOps[0]);
5365 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5366 int Idx = ConcatEnd - 1;
5367 VT = ConcatOps[Idx--].getValueType();
5368 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5381 unsigned NumToInsert = ConcatEnd - Idx - 1;
5382 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5384 ConcatOps[Idx+1] = VecOp;
5385 ConcatEnd = Idx + 2;
5391 unsigned RealVals = ConcatEnd - Idx - 1;
5392 unsigned SubConcatEnd = 0;
5393 unsigned SubConcatIdx = Idx + 1;
5394 while (SubConcatEnd < RealVals)
5395 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5396 while (SubConcatEnd < OpsToConcat)
5397 SubConcatOps[SubConcatEnd++] = undefVec;
5399 NextVT, SubConcatOps);
5400 ConcatEnd = SubConcatIdx + 1;
5405 if (ConcatEnd == 1) {
5406 VT = ConcatOps[0].getValueType();
5408 return ConcatOps[0];
5413 if (
NumOps != ConcatEnd ) {
5415 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5416 ConcatOps[j] = UndefVal;
5424 unsigned Opcode =
N->getOpcode();
5426 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5430 const SDNodeFlags
Flags =
N->getFlags();
5431 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5432 NumElts = NumElts / 2;
5436 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5438 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5439 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5440 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5448 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5451 TLI.isTypeLegal(WideMaskVT)) {
5452 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5453 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5454 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5456 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5457 N->getValueType(0).getVectorElementCount());
5458 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5472 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5473 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5474 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5477 unsigned ConcatEnd = 0;
5485 while (CurNumElts != 0) {
5486 while (CurNumElts >= NumElts) {
5487 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5488 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5489 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5491 CurNumElts -= NumElts;
5494 NumElts = NumElts / 2;
5496 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5499 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5500 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5501 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5502 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5513 switch (
N->getOpcode()) {
5516 return WidenVecRes_STRICT_FSETCC(
N);
5523 return WidenVecRes_Convert_StrictFP(
N);
5530 unsigned Opcode =
N->getOpcode();
5532 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5536 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5537 NumElts = NumElts / 2;
5548 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5552 unsigned ConcatEnd = 0;
5559 for (
unsigned i = 1; i < NumOpers; ++i) {
5565 Oper = GetWidenedVector(Oper);
5571 DAG.getPOISON(WideOpVT), Oper,
5572 DAG.getVectorIdxConstant(0, dl));
5584 while (CurNumElts != 0) {
5585 while (CurNumElts >= NumElts) {
5588 for (
unsigned i = 0; i < NumOpers; ++i) {
5591 EVT OpVT =
Op.getValueType();
5596 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5602 EVT OperVT[] = {VT, MVT::Other};
5604 ConcatOps[ConcatEnd++] = Oper;
5607 CurNumElts -= NumElts;
5610 NumElts = NumElts / 2;
5612 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5615 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5618 for (
unsigned i = 0; i < NumOpers; ++i) {
5621 EVT OpVT =
Op.getValueType();
5629 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5631 ConcatOps[ConcatEnd++] = Oper;
5640 if (Chains.
size() == 1)
5641 NewChain = Chains[0];
5644 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5649SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5651 EVT ResVT =
N->getValueType(0);
5652 EVT OvVT =
N->getValueType(1);
5653 EVT WideResVT, WideOvVT;
5658 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5663 WideLHS = GetWidenedVector(
N->getOperand(0));
5664 WideRHS = GetWidenedVector(
N->getOperand(1));
5666 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5675 N->getOperand(0), Zero);
5677 N->getOperand(1), Zero);
5680 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5681 SDNode *WideNode = DAG.getNode(
5682 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5685 unsigned OtherNo = 1 - ResNo;
5686 EVT OtherVT =
N->getValueType(OtherNo);
5693 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5696 return SDValue(WideNode, ResNo);
5700 LLVMContext &Ctx = *DAG.getContext();
5704 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5709 unsigned Opcode =
N->getOpcode();
5710 const SDNodeFlags
Flags =
N->getFlags();
5716 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5718 InOp = ZExtPromotedInteger(InOp);
5729 InOp = GetWidenedVector(
N->getOperand(0));
5732 if (InVTEC == WidenEC) {
5733 if (
N->getNumOperands() == 1)
5734 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5735 if (
N->getNumOperands() == 3) {
5736 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5739 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5741 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5767 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5771 if (TLI.isTypeLegal(InWidenVT)) {
5779 unsigned NumConcat =
5784 if (
N->getNumOperands() == 1)
5785 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5786 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5790 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5792 if (
N->getNumOperands() == 1)
5793 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5794 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5803 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5804 for (
unsigned i=0; i < MinElts; ++i) {
5805 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5806 if (
N->getNumOperands() == 1)
5809 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5812 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5817 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5821 EVT SrcVT = Src.getValueType();
5825 Src = GetWidenedVector(Src);
5826 SrcVT = Src.getValueType();
5833 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5838 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5842 EVT SrcVT = Src.getValueType();
5846 Src = GetWidenedVector(Src);
5847 SrcVT = Src.getValueType();
5854 if (
N->getNumOperands() == 1)
5855 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5857 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5858 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5862 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5865SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5870 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5876 unsigned Opcode =
N->getOpcode();
5882 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5887 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5888 for (
unsigned i=0; i < MinElts; ++i) {
5889 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5890 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5894 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5896 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5899SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5900 unsigned Opcode =
N->getOpcode();
5904 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5913 InOp = GetWidenedVector(InOp);
5920 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5927 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5928 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5945 while (
Ops.size() != WidenNumElts)
5946 Ops.push_back(DAG.getPOISON(WidenSVT));
5948 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5954 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5955 return WidenVecRes_BinaryCanTrap(
N);
5958 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5965SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5967 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5970 SDValue Arg = GetWidenedVector(FpValue);
5971 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5976 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5977 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5979 EVT ExpVT =
RHS.getValueType();
5984 ExpOp = ModifyToType(
RHS, WideExpVT);
5987 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5992 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5993 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5994 if (
N->getNumOperands() == 1)
5995 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5997 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5998 N->getOperand(1),
N->getFlags());
6000 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6001 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6005 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6006 {InOp,
Mask,
N->getOperand(2)});
6010 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6013 .getVectorElementType(),
6015 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6016 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6017 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6020SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6022 EVT VT0 =
N->getValueType(0);
6023 EVT VT1 =
N->getValueType(1);
6027 "expected both results to be vectors of matching element count");
6029 LLVMContext &Ctx = *DAG.getContext();
6030 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6032 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6039 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6042 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6043 return SDValue(WidenNode, ResNo);
6046SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6047 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6048 return GetWidenedVector(WidenVec);
6052 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6053 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6056 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6057 AddrSpaceCastN->getSrcAddressSpace(),
6058 AddrSpaceCastN->getDestAddressSpace());
6064 EVT VT =
N->getValueType(0);
6065 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6068 switch (getTypeAction(InVT)) {
6082 SDValue NInOp = GetPromotedInteger(InOp);
6084 if (WidenVT.
bitsEq(NInVT)) {
6087 if (DAG.getDataLayout().isBigEndian()) {
6090 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6108 InOp = GetWidenedVector(InOp);
6110 if (WidenVT.
bitsEq(InVT))
6120 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6125 unsigned NewNumParts = WidenSize / InSize;
6138 EVT OrigInVT =
N->getOperand(0).getValueType();
6143 if (TLI.isTypeLegal(NewInVT)) {
6151 if (WidenSize % InSize == 0) {
6158 DAG.ExtractVectorElements(InOp,
Ops);
6159 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6171 return CreateStackStoreLoad(InOp, WidenVT);
6174SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6176 N->getOpcode(), SDLoc(
N),
6177 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6178 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6184 EVT VT =
N->getValueType(0);
6188 EVT EltVT =
N->getOperand(0).getValueType();
6191 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6195 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6196 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6198 return DAG.getBuildVector(WidenVT, dl, NewOps);
6202 EVT InVT =
N->getOperand(0).getValueType();
6203 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6205 unsigned NumOperands =
N->getNumOperands();
6207 bool InputWidened =
false;
6211 if (WidenNumElts % NumInElts == 0) {
6213 unsigned NumConcat = WidenNumElts / NumInElts;
6214 SDValue UndefVal = DAG.getPOISON(InVT);
6216 for (
unsigned i=0; i < NumOperands; ++i)
6217 Ops[i] =
N->getOperand(i);
6218 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6223 InputWidened =
true;
6224 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6227 for (i=1; i < NumOperands; ++i)
6228 if (!
N->getOperand(i).isUndef())
6231 if (i == NumOperands)
6234 return GetWidenedVector(
N->getOperand(0));
6236 if (NumOperands == 2) {
6238 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6243 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6244 for (
unsigned i = 0; i < NumInElts; ++i) {
6246 MaskOps[i + NumInElts] = i + WidenNumElts;
6248 return DAG.getVectorShuffle(WidenVT, dl,
6249 GetWidenedVector(
N->getOperand(0)),
6250 GetWidenedVector(
N->getOperand(1)),
6257 "Cannot use build vectors to widen CONCAT_VECTOR result");
6265 for (
unsigned i=0; i < NumOperands; ++i) {
6268 InOp = GetWidenedVector(InOp);
6269 for (
unsigned j = 0;
j < NumInElts; ++
j)
6270 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6272 SDValue UndefVal = DAG.getPOISON(EltVT);
6273 for (; Idx < WidenNumElts; ++Idx)
6274 Ops[Idx] = UndefVal;
6275 return DAG.getBuildVector(WidenVT, dl,
Ops);
6278SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6279 EVT VT =
N->getValueType(0);
6280 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6281 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6288SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6289 EVT VT =
N->getValueType(0);
6291 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6296 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6298 InOp = GetWidenedVector(InOp);
6304 if (IdxVal == 0 && InVT == WidenVT)
6311 assert(IdxVal % VTNumElts == 0 &&
6312 "Expected Idx to be a multiple of subvector minimum vector length");
6313 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6326 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6327 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6328 "down type's element count");
6335 for (;
I < VTNumElts / GCD; ++
I)
6337 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6338 for (;
I < WidenNumElts / GCD; ++
I)
6346 Align Alignment = DAG.getReducedAlign(InVT,
false);
6348 MachineFunction &MF = DAG.getMachineFunction();
6360 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6367 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6368 return DAG.getMaskedLoad(
6369 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6377 for (i = 0; i < VTNumElts; ++i)
6378 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6380 SDValue UndefVal = DAG.getPOISON(EltVT);
6381 for (; i < WidenNumElts; ++i)
6383 return DAG.getBuildVector(WidenVT, dl,
Ops);
6389 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6394SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6395 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6398 N->getOperand(1),
N->getOperand(2));
6407 "Load width must be less than or equal to first value type width");
6416 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6427 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6428 EVT LdVT =
LD->getMemoryVT();
6432 "Must be scalable");
6434 "Expected equivalent element types");
6442 TypeSize WidthDiff = WidenWidth - LdWidth;
6445 std::optional<EVT> FirstVT =
6446 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6453 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6456 Chain, BasePtr,
LD->getMemOperand());
6460 FirstVTWidth, dl, DAG);
6478 if (!
LD->getMemoryVT().isByteSized()) {
6480 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6482 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6491 EVT VT =
LD->getValueType(0);
6492 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6493 EVT WideMaskVT = getSetCCResultType(WideVT);
6496 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6497 TLI.isTypeLegal(WideMaskVT)) {
6500 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6504 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6505 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6517 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6519 Result = GenWidenVectorLoads(LdChain, LD);
6526 if (LdChain.
size() == 1)
6527 NewChain = LdChain[0];
6533 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6544 SDValue NewLoad = DAG.getMaskedLoad(
6545 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6546 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6547 LD->getAddressingMode(),
LD->getExtensionType());
6557 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6559 SDValue EVL =
N->getVectorLength();
6566 "Unable to widen binary VP op");
6567 Mask = GetWidenedVector(Mask);
6568 assert(
Mask.getValueType().getVectorElementCount() ==
6569 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6570 .getVectorElementCount() &&
6571 "Unable to widen vector load");
6574 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6575 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6576 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6584 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6586 SDValue EVL =
N->getVectorLength();
6592 "Unable to widen binary VP op");
6593 Mask = GetWidenedVector(Mask);
6594 assert(
Mask.getValueType().getVectorElementCount() ==
6595 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6596 .getVectorElementCount() &&
6597 "Unable to widen vector load");
6599 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6600 Mask, EVL,
N->getMemOperand());
6613 "Unable to widen VP strided load");
6614 Mask = GetWidenedVector(Mask);
6616 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6617 assert(
Mask.getValueType().getVectorElementCount() ==
6619 "Data and mask vectors should have the same number of elements");
6621 SDValue Res = DAG.getStridedLoadVP(
6622 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6623 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6624 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6625 N->isExpandingLoad());
6633SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6638 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6640 Mask.getValueType().getVectorElementType(),
6643 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6644 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6645 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6647 WideMask, WidePassthru);
6651 EVT VT =
N->getValueType(0);
6652 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6654 EVT MaskVT =
Mask.getValueType();
6655 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6664 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6665 TLI.isTypeLegal(WideMaskVT) &&
6671 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6672 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6676 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6677 N->getMemoryVT(),
N->getMemOperand());
6681 if (!
N->getPassThru()->isUndef()) {
6685 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6686 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6687 DAG.getPOISON(WidenVT), EVL);
6698 Mask = ModifyToType(Mask, WideMaskVT,
true);
6700 SDValue Res = DAG.getMaskedLoad(
6701 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6702 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6703 ExtType,
N->isExpandingLoad());
6712 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6714 EVT MaskVT =
Mask.getValueType();
6715 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6724 Mask = ModifyToType(Mask, WideMaskVT,
true);
6729 Index.getValueType().getScalarType(),
6731 Index = ModifyToType(Index, WideIndexVT);
6737 N->getMemoryVT().getScalarType(), NumElts);
6738 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6739 WideMemVT, dl,
Ops,
N->getMemOperand(),
6740 N->getIndexType(),
N->getExtensionType());
6749 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6757 N->getMemoryVT().getScalarType(), WideEC);
6758 Mask = GetWidenedMask(Mask, WideEC);
6761 Mask,
N->getVectorLength()};
6762 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6763 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6772 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6773 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6801 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6802 return N->getOperand(OpNo).getValueType();
6810 N =
N.getOperand(0);
6812 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6813 if (!
N->getOperand(i)->isUndef())
6815 N =
N.getOperand(0);
6819 N =
N.getOperand(0);
6821 N =
N.getOperand(0);
6848 { MaskVT, MVT::Other },
Ops);
6849 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6857 LLVMContext &Ctx = *DAG.getContext();
6860 if (MaskScalarBits < ToMaskScalBits) {
6864 }
else if (MaskScalarBits > ToMaskScalBits) {
6870 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6872 "Mask should have the right element size by now.");
6875 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6877 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6880 EVT SubVT =
Mask->getValueType(0);
6886 assert((
Mask->getValueType(0) == ToMaskVT) &&
6887 "A mask of ToMaskVT should have been produced by now.");
6897 LLVMContext &Ctx = *DAG.getContext();
6908 EVT CondVT =
Cond->getValueType(0);
6912 EVT VSelVT =
N->getValueType(0);
6924 EVT FinalVT = VSelVT;
6935 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6936 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6943 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6951 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6954 EVT ToMaskVT = VSelVT;
6961 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6977 if (ScalarBits0 != ScalarBits1) {
6978 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6979 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6991 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6992 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6993 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6996 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7004 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7009 unsigned Opcode =
N->getOpcode();
7011 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7012 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7013 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7015 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7021 Cond1 = GetWidenedVector(Cond1);
7029 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7030 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7035 Cond1 = ModifyToType(Cond1, CondWidenVT);
7038 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7039 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7041 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7042 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7044 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7048 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7049 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7052 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7056 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7057 return DAG.getUNDEF(WidenVT);
7061 EVT VT =
N->getValueType(0);
7064 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7068 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7069 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7072 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7073 for (
unsigned i = 0; i != NumElts; ++i) {
7074 int Idx =
N->getMaskElt(i);
7075 if (Idx < (
int)NumElts)
7078 NewMask[i] = Idx - NumElts + WidenNumElts;
7080 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7084 EVT VT =
N->getValueType(0);
7088 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7089 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7095 unsigned IdxVal = WidenNumElts - VTNumElts;
7108 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7111 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7112 "down type's element count");
7115 for (; i < VTNumElts / GCD; ++i)
7117 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7118 for (; i < WidenNumElts / GCD; ++i)
7126 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7127 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7129 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7133SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7134 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7139 assert(
N->getValueType(0).isVector() &&
7140 N->getOperand(0).getValueType().isVector() &&
7141 "Operands must be vectors");
7142 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7155 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7156 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7163 InOp1 = GetWidenedVector(InOp1);
7164 InOp2 = GetWidenedVector(InOp2);
7167 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7178 "Input not widened to expected type!");
7180 if (
N->getOpcode() == ISD::VP_SETCC) {
7183 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7184 N->getOperand(2), Mask,
N->getOperand(4));
7186 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7191 assert(
N->getValueType(0).isVector() &&
7192 N->getOperand(1).getValueType().isVector() &&
7193 "Operands must be vectors");
7194 EVT VT =
N->getValueType(0);
7195 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7205 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7210 for (
unsigned i = 0; i != NumElts; ++i) {
7211 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7212 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7214 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7215 {Chain, LHSElem, RHSElem, CC});
7216 Chains[i] = Scalars[i].getValue(1);
7217 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7218 DAG.getBoolConstant(
true, dl, EltVT, VT),
7219 DAG.getBoolConstant(
false, dl, EltVT, VT));
7223 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7225 return DAG.getBuildVector(WidenVT, dl, Scalars);
7231bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7232 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7236 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7239 switch (
N->getOpcode()) {
7242 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7250 Res = WidenVecOp_FAKE_USE(
N);
7256 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7257 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7258 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7259 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7264 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7266 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7267 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7269 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7270 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7280 Res = WidenVecOp_UnrollVectorOp(
N);
7287 Res = WidenVecOp_EXTEND(
N);
7292 Res = WidenVecOp_CMP(
N);
7309 Res = WidenVecOp_Convert(
N);
7314 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7332 Res = WidenVecOp_VECREDUCE(
N);
7336 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7338 case ISD::VP_REDUCE_FADD:
7339 case ISD::VP_REDUCE_SEQ_FADD:
7340 case ISD::VP_REDUCE_FMUL:
7341 case ISD::VP_REDUCE_SEQ_FMUL:
7342 case ISD::VP_REDUCE_ADD:
7343 case ISD::VP_REDUCE_MUL:
7344 case ISD::VP_REDUCE_AND:
7345 case ISD::VP_REDUCE_OR:
7346 case ISD::VP_REDUCE_XOR:
7347 case ISD::VP_REDUCE_SMAX:
7348 case ISD::VP_REDUCE_SMIN:
7349 case ISD::VP_REDUCE_UMAX:
7350 case ISD::VP_REDUCE_UMIN:
7351 case ISD::VP_REDUCE_FMAX:
7352 case ISD::VP_REDUCE_FMIN:
7353 case ISD::VP_REDUCE_FMAXIMUM:
7354 case ISD::VP_REDUCE_FMINIMUM:
7355 Res = WidenVecOp_VP_REDUCE(
N);
7357 case ISD::VP_CTTZ_ELTS:
7358 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7359 Res = WidenVecOp_VP_CttzElements(
N);
7362 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7367 if (!Res.
getNode())
return false;
7375 if (
N->isStrictFPOpcode())
7377 "Invalid operand expansion");
7380 "Invalid operand expansion");
7382 ReplaceValueWith(
SDValue(
N, 0), Res);
7388 EVT VT =
N->getValueType(0);
7393 "Unexpected type action");
7394 InOp = GetWidenedVector(InOp);
7397 "Input wasn't widened!");
7405 EVT FixedEltVT = FixedVT.getVectorElementType();
7406 if (TLI.isTypeLegal(FixedVT) &&
7408 FixedEltVT == InEltVT) {
7410 "Not enough elements in the fixed type for the operand!");
7412 "We can't have the same type as we started with!");
7414 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7416 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7425 return WidenVecOp_Convert(
N);
7430 switch (
N->getOpcode()) {
7445 EVT OpVT =
N->getOperand(0).getValueType();
7446 EVT ResVT =
N->getValueType(0);
7453 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7454 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7460 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7461 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7463 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7470 return DAG.UnrollVectorOp(
N);
7475 EVT ResultVT =
N->getValueType(0);
7477 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7480 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7486 {WideArg,
Test},
N->getFlags());
7492 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7494 EVT OpVT =
N->getOperand(0).getValueType();
7497 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7502 EVT VT =
N->getValueType(0);
7508 "Unexpected type action");
7509 InOp = GetWidenedVector(InOp);
7511 unsigned Opcode =
N->getOpcode();
7517 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7519 if (
N->isStrictFPOpcode()) {
7521 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7524 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7525 {
N->getOperand(0), InOp });
7531 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7533 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7535 return DAG.getExtractSubvector(dl, VT, Res, 0);
7543 if (
N->isStrictFPOpcode()) {
7546 for (
unsigned i=0; i < NumElts; ++i) {
7547 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7548 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7552 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7554 for (
unsigned i = 0; i < NumElts; ++i) {
7555 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7557 Ops[i] = DAG.
getNode(Opcode, dl, EltVT, Elt,
N->getOperand(1));
7559 Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
7563 return DAG.getBuildVector(VT, dl,
Ops);
7567 EVT DstVT =
N->getValueType(0);
7568 SDValue Src = GetWidenedVector(
N->getOperand(0));
7569 EVT SrcVT = Src.getValueType();
7576 if (TLI.isTypeLegal(WideDstVT)) {
7578 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7581 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7585 return DAG.UnrollVectorOp(
N);
7589 EVT VT =
N->getValueType(0);
7590 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7598 if (!VT.
isVector() && VT != MVT::x86mmx &&
7602 if (TLI.isTypeLegal(NewVT)) {
7604 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7616 ElementCount NewNumElts =
7618 .divideCoefficientBy(EltSize);
7620 if (TLI.isTypeLegal(NewVT)) {
7622 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7627 return CreateStackStoreLoad(InOp, VT);
7635 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7636 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7641 EVT VT =
N->getValueType(0);
7643 EVT InVT =
N->getOperand(0).getValueType();
7648 unsigned NumOperands =
N->getNumOperands();
7649 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7651 for (i = 1; i < NumOperands; ++i)
7652 if (!
N->getOperand(i).isUndef())
7655 if (i == NumOperands)
7656 return GetWidenedVector(
N->getOperand(0));
7666 for (
unsigned i=0; i < NumOperands; ++i) {
7670 "Unexpected type action");
7671 InOp = GetWidenedVector(InOp);
7672 for (
unsigned j = 0;
j < NumInElts; ++
j)
7673 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7675 return DAG.getBuildVector(VT, dl,
Ops);
7678SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7679 EVT VT =
N->getValueType(0);
7684 SubVec = GetWidenedVector(SubVec);
7689 bool IndicesValid =
false;
7692 IndicesValid =
true;
7696 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7697 Attribute::VScaleRange);
7702 IndicesValid =
true;
7708 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7714 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7721 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7728 Align Alignment = DAG.getReducedAlign(VT,
false);
7730 MachineFunction &MF = DAG.getMachineFunction();
7743 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7751 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7752 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7757 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7762 unsigned Idx =
N->getConstantOperandVal(2);
7768 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7774SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7775 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7777 N->getValueType(0), InOp,
N->getOperand(1));
7780SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7781 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7783 N->getValueType(0), InOp,
N->getOperand(1));
7786SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7788 EVT ResVT =
N->getValueType(0);
7791 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
7797 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
7805 "Widened input size must be a multiple of result element size");
7808 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
7810 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
7811 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
7819 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7820 return TLI.scalarizeVectorStore(ST, DAG);
7822 if (
ST->isTruncatingStore())
7823 return TLI.scalarizeVectorStore(ST, DAG);
7833 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7834 EVT WideMaskVT = getSetCCResultType(WideVT);
7836 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7837 TLI.isTypeLegal(WideMaskVT)) {
7840 StVal = GetWidenedVector(StVal);
7842 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7844 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7845 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7846 ST->getAddressingMode());
7850 if (GenWidenVectorStores(StChain, ST)) {
7851 if (StChain.
size() == 1)
7860 SDValue WideStVal = GetWidenedVector(StVal);
7864 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7865 ST->getOffset(), Mask,
ST->getMemoryVT(),
7866 ST->getMemOperand(),
ST->getAddressingMode(),
7867 ST->isTruncatingStore());
7873SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7874 assert((OpNo == 1 || OpNo == 3) &&
7875 "Can widen only data or mask operand of vp_store");
7883 StVal = GetWidenedVector(StVal);
7889 "Unable to widen VP store");
7890 Mask = GetWidenedVector(Mask);
7892 Mask = GetWidenedVector(Mask);
7898 "Unable to widen VP store");
7899 StVal = GetWidenedVector(StVal);
7902 assert(
Mask.getValueType().getVectorElementCount() ==
7904 "Mask and data vectors should have the same number of elements");
7905 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7906 ST->getOffset(), Mask,
ST->getVectorLength(),
7907 ST->getMemoryVT(),
ST->getMemOperand(),
7908 ST->getAddressingMode(),
ST->isTruncatingStore(),
7909 ST->isCompressingStore());
7914 assert((OpNo == 1 || OpNo == 4) &&
7915 "Can widen only data or mask operand of vp_strided_store");
7924 "Unable to widen VP strided store");
7928 "Unable to widen VP strided store");
7930 StVal = GetWidenedVector(StVal);
7931 Mask = GetWidenedVector(Mask);
7934 Mask.getValueType().getVectorElementCount() &&
7935 "Data and mask vectors should have the same number of elements");
7937 return DAG.getStridedStoreVP(
7944SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7945 assert((OpNo == 1 || OpNo == 4) &&
7946 "Can widen only data or mask operand of mstore");
7949 EVT MaskVT =
Mask.getValueType();
7954 EVT WideVT, WideMaskVT;
7957 StVal = GetWidenedVector(StVal);
7964 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7971 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7972 TLI.isTypeLegal(WideMaskVT)) {
7973 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7974 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7983 Mask = ModifyToType(Mask, WideMaskVT,
true);
7986 Mask = ModifyToType(Mask, WideMaskVT,
true);
7988 StVal = ModifyToType(StVal, WideVT);
7991 assert(
Mask.getValueType().getVectorElementCount() ==
7993 "Mask and data vectors should have the same number of elements");
8000SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8001 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8003 SDValue DataOp = MG->getPassThru();
8005 SDValue Scale = MG->getScale();
8013 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8014 MG->getMemOperand(), MG->getIndexType(),
8015 MG->getExtensionType());
8021SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8030 DataOp = GetWidenedVector(DataOp);
8034 EVT IndexVT =
Index.getValueType();
8037 Index = ModifyToType(Index, WideIndexVT);
8040 EVT MaskVT =
Mask.getValueType();
8043 Mask = ModifyToType(Mask, WideMaskVT,
true);
8048 }
else if (OpNo == 4) {
8050 Index = GetWidenedVector(Index);
8056 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8061SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8070 DataOp = GetWidenedVector(DataOp);
8071 Index = GetWidenedVector(Index);
8073 Mask = GetWidenedMask(Mask, WideEC);
8076 }
else if (OpNo == 3) {
8078 Index = GetWidenedVector(Index);
8085 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8090 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8091 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8093 EVT VT =
N->getValueType(0);
8108 SVT, InOp0, InOp1,
N->getOperand(2));
8114 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8116 EVT OpVT =
N->getOperand(0).getValueType();
8119 return DAG.getNode(ExtendCode, dl, VT, CC);
8129 EVT VT =
N->getValueType(0);
8131 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8138 for (
unsigned i = 0; i != NumElts; ++i) {
8139 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8140 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8142 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8143 {Chain, LHSElem, RHSElem, CC});
8144 Chains[i] = Scalars[i].getValue(1);
8145 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8146 DAG.getBoolConstant(
true, dl, EltVT, VT),
8147 DAG.getBoolConstant(
false, dl, EltVT, VT));
8151 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8153 return DAG.getBuildVector(VT, dl, Scalars);
8177 SDValue Op = GetWidenedVector(
N->getOperand(0));
8178 EVT VT =
N->getValueType(0);
8179 EVT OrigVT =
N->getOperand(0).getValueType();
8180 EVT WideVT =
Op.getValueType();
8182 SDNodeFlags
Flags =
N->getFlags();
8184 unsigned Opc =
N->getOpcode();
8186 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8187 assert(NeutralElem &&
"Neutral element must exist");
8197 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8204 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8205 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8211 unsigned GCD = std::gcd(OrigElts, WideElts);
8214 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8215 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8216 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8217 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8220 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8221 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8223 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8232 EVT VT =
N->getValueType(0);
8234 EVT WideVT =
Op.getValueType();
8236 SDNodeFlags
Flags =
N->getFlags();
8238 unsigned Opc =
N->getOpcode();
8240 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8250 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8253 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8254 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8260 unsigned GCD = std::gcd(OrigElts, WideElts);
8263 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8264 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8265 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8266 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8269 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8270 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8272 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8276 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8279 SDValue Op = GetWidenedVector(
N->getOperand(1));
8281 Op.getValueType().getVectorElementCount());
8283 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8284 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8292 EVT VT =
N->getValueType(0);
8296 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8297 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8302 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8308 EVT SrcVT =
Source.getValueType();
8312 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8313 {Source, Mask, N->getOperand(2)},
N->getFlags());
8316SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8319 EVT OrigMaskVT =
Mask.getValueType();
8320 SDValue WideMask = GetWidenedVector(Mask);
8326 if (OrigElts != WideElts) {
8327 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8329 Mask, DAG.getVectorIdxConstant(0,
DL));
8350 unsigned WidenEx = 0) {
8355 unsigned AlignInBits =
Align*8;
8357 EVT RetVT = WidenEltVT;
8362 if (Width == WidenEltWidth)
8373 (WidenWidth % MemVTWidth) == 0 &&
8375 (MemVTWidth <= Width ||
8376 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8377 if (MemVTWidth == WidenWidth)
8396 (WidenWidth % MemVTWidth) == 0 &&
8398 (MemVTWidth <= Width ||
8399 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8408 return std::nullopt;
8419 unsigned Start,
unsigned End) {
8420 SDLoc dl(LdOps[Start]);
8421 EVT LdTy = LdOps[Start].getValueType();
8429 for (
unsigned i = Start + 1; i != End; ++i) {
8430 EVT NewLdTy = LdOps[i].getValueType();
8431 if (NewLdTy != LdTy) {
8450 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8451 EVT LdVT =
LD->getMemoryVT();
8461 AAMDNodes AAInfo =
LD->getAAInfo();
8465 TypeSize WidthDiff = WidenWidth - LdWidth;
8472 std::optional<EVT> FirstVT =
8473 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8480 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8485 std::optional<EVT> NewVT = FirstVT;
8486 TypeSize RemainingWidth = LdWidth;
8487 TypeSize NewVTWidth = FirstVTWidth;
8489 RemainingWidth -= NewVTWidth;
8496 NewVTWidth = NewVT->getSizeInBits();
8502 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8503 LD->getBaseAlign(), MMOFlags, AAInfo);
8515 uint64_t ScaledOffset = 0;
8516 MachinePointerInfo MPI =
LD->getPointerInfo();
8522 for (EVT MemVT : MemVTs) {
8523 Align NewAlign = ScaledOffset == 0
8524 ?
LD->getBaseAlign()
8527 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8535 unsigned End = LdOps.
size();
8546 EVT LdTy = LdOps[i].getValueType();
8549 for (--i; i >= 0; --i) {
8550 LdTy = LdOps[i].getValueType();
8557 ConcatOps[--Idx] = LdOps[i];
8558 for (--i; i >= 0; --i) {
8559 EVT NewLdTy = LdOps[i].getValueType();
8560 if (NewLdTy != LdTy) {
8570 for (;
j != End-Idx; ++
j)
8571 WidenOps[j] = ConcatOps[Idx+j];
8573 WidenOps[j] = DAG.getPOISON(LdTy);
8580 ConcatOps[--Idx] = LdOps[i];
8585 ArrayRef(&ConcatOps[Idx], End - Idx));
8591 SDValue UndefVal = DAG.getPOISON(LdTy);
8594 for (; i != End-Idx; ++i)
8595 WidenOps[i] = ConcatOps[Idx+i];
8597 WidenOps[i] = UndefVal;
8608 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8609 EVT LdVT =
LD->getMemoryVT();
8618 AAMDNodes AAInfo =
LD->getAAInfo();
8632 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8633 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8639 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8640 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8641 LD->getBaseAlign(), MMOFlags, AAInfo);
8646 SDValue UndefVal = DAG.getPOISON(EltVT);
8647 for (; i != WidenNumElts; ++i)
8650 return DAG.getBuildVector(WidenVT, dl,
Ops);
8661 AAMDNodes AAInfo =
ST->getAAInfo();
8662 SDValue ValOp = GetWidenedVector(
ST->getValue());
8665 EVT StVT =
ST->getMemoryVT();
8673 "Mismatch between store and value types");
8677 MachinePointerInfo MPI =
ST->getPointerInfo();
8678 uint64_t ScaledOffset = 0;
8687 std::optional<EVT> NewVT =
8692 TypeSize NewVTWidth = NewVT->getSizeInBits();
8695 StWidth -= NewVTWidth;
8696 MemVTs.
back().second++;
8700 for (
const auto &Pair : MemVTs) {
8701 EVT NewVT = Pair.first;
8702 unsigned Count = Pair.second;
8708 Align NewAlign = ScaledOffset == 0
8709 ?
ST->getBaseAlign()
8711 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8712 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8728 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8729 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8730 ST->getBaseAlign(), MMOFlags, AAInfo);
8747 bool FillWithZeroes) {
8752 "input and widen element type must match");
8754 "cannot modify scalable vectors in this way");
8767 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
8769 for (
unsigned i = 1; i != NumConcat; ++i)
8776 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8779 "Scalable vectors should have been handled already.");
8787 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8789 for (Idx = 0; Idx < MinNumElts; ++Idx)
8790 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8792 SDValue UndefVal = DAG.getPOISON(EltVT);
8793 for (; Idx < WidenNumElts; ++Idx)
8794 Ops[Idx] = UndefVal;
8796 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8797 if (!FillWithZeroes)
8801 "We expect to never want to FillWithZeroes for non-integral types.");
8804 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8805 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8807 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8808 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.
@ 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.