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);
69 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
81 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
83 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
89 R = ScalarizeVecRes_VecInregOp(
N);
140 R = ScalarizeVecRes_UnaryOp(
N);
143 R = ScalarizeVecRes_ADDRSPACECAST(
N);
149 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
206 R = ScalarizeVecRes_BinOp(
N);
211 R = ScalarizeVecRes_CMP(
N);
217 R = ScalarizeVecRes_TernaryOp(
N);
220#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
221 case ISD::STRICT_##DAGN:
222#include "llvm/IR/ConstrainedOps.def"
223 R = ScalarizeVecRes_StrictFPOp(
N);
228 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
237 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
247 R = ScalarizeVecRes_FIX(
N);
253 SetScalarizedVector(
SDValue(
N, ResNo), R);
257 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
258 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
259 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
268 if (getTypeAction(
LHS.getValueType()) ==
270 LHS = GetScalarizedVector(
LHS);
271 RHS = GetScalarizedVector(
RHS);
273 EVT VT =
LHS.getValueType().getVectorElementType();
274 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
275 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
278 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
279 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
283 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
284 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
285 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
286 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
291 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
292 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
299DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
301 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
302 "Unexpected vector type!");
303 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
305 EVT VT0 =
N->getValueType(0);
306 EVT VT1 =
N->getValueType(1);
310 DAG.getNode(
N->getOpcode(), dl,
311 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
315 unsigned OtherNo = 1 - ResNo;
316 EVT OtherVT =
N->getValueType(OtherNo);
318 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
322 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
325 return SDValue(ScalarNode, ResNo);
330 unsigned NumOpers =
N->getNumOperands();
332 EVT ValueVTs[] = {VT, MVT::Other};
341 for (
unsigned i = 1; i < NumOpers; ++i) {
347 Oper = GetScalarizedVector(Oper);
356 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
357 Opers,
N->getFlags());
368 EVT ResVT =
N->getValueType(0);
369 EVT OvVT =
N->getValueType(1);
373 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
374 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
377 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
378 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
379 ScalarLHS = ElemsLHS[0];
380 ScalarRHS = ElemsRHS[0];
383 SDVTList ScalarVTs = DAG.getVTList(
385 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
386 {ScalarLHS, ScalarRHS},
N->getFlags())
390 unsigned OtherNo = 1 - ResNo;
391 EVT OtherVT =
N->getValueType(OtherNo);
393 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
397 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
400 return SDValue(ScalarNode, ResNo);
405 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
406 return GetScalarizedVector(
Op);
409SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
411 SDValue SourceValue =
N->getOperand(0);
412 SDValue SinkValue =
N->getOperand(1);
413 SDValue EltSizeInBytes =
N->getOperand(2);
414 SDValue LaneOffset =
N->getOperand(3);
422 if (IsReadAfterWrite)
430 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
435 return DAG.getNode(
ISD::OR,
DL, CmpVT, Cmp,
442 Op = GetScalarizedVector(
Op);
443 EVT NewVT =
N->getValueType(0).getVectorElementType();
448SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
458SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
460 N->getValueType(0).getVectorElementType(),
461 N->getOperand(0),
N->getOperand(1));
467 EVT OpVT =
Op.getValueType();
471 Op = GetScalarizedVector(
Op);
474 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
477 N->getValueType(0).getVectorElementType(),
Op,
481SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
482 SDValue Op = GetScalarizedVector(
N->getOperand(0));
483 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
487SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
492 if (
Op.getValueType() != EltVT)
500 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
501 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
511 assert(
N->isUnindexed() &&
"Indexed vector load?");
515 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
516 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
517 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
518 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
530 EVT OpVT =
Op.getValueType();
540 Op = GetScalarizedVector(
Op);
543 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
545 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
551 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
552 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
553 LHS, DAG.getValueType(ExtVT));
560 EVT OpVT =
Op.getValueType();
565 Op = GetScalarizedVector(
Op);
567 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
570 switch (
N->getOpcode()) {
582SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
585 EVT OpVT =
Op.getValueType();
595 Op = GetScalarizedVector(
Op);
598 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
601 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
602 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
603 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
606SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
618 EVT OpVT =
Cond.getValueType();
627 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
630 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
632 TLI.getBooleanContents(
false,
false);
639 if (TLI.getBooleanContents(
false,
false) !=
640 TLI.getBooleanContents(
false,
true)) {
644 EVT OpVT =
Cond->getOperand(0).getValueType();
646 VecBool = TLI.getBooleanContents(OpVT);
651 EVT CondVT =
Cond.getValueType();
652 if (ScalarBool != VecBool) {
653 switch (ScalarBool) {
661 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
668 Cond, DAG.getValueType(MVT::i1));
674 auto BoolVT = getSetCCResultType(CondVT);
675 if (BoolVT.bitsLT(CondVT))
678 return DAG.getSelect(SDLoc(
N),
680 GetScalarizedVector(
N->getOperand(2)));
684 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
685 return DAG.getSelect(SDLoc(
N),
686 LHS.getValueType(),
N->getOperand(0),
LHS,
687 GetScalarizedVector(
N->getOperand(2)));
691 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
693 N->getOperand(0),
N->getOperand(1),
694 LHS, GetScalarizedVector(
N->getOperand(3)),
699 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
702SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
706 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
708 return GetScalarizedVector(
N->getOperand(
Op));
711SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
713 EVT SrcVT = Src.getValueType();
718 Src = GetScalarizedVector(Src);
722 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
724 EVT DstVT =
N->getValueType(0).getVectorElementType();
725 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
729 assert(
N->getValueType(0).isVector() &&
730 N->getOperand(0).getValueType().isVector() &&
731 "Operand types must be vectors");
734 EVT OpVT =
LHS.getValueType();
735 EVT NVT =
N->getValueType(0).getVectorElementType();
740 LHS = GetScalarizedVector(
LHS);
741 RHS = GetScalarizedVector(
RHS);
744 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
745 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
755 return DAG.getNode(ExtendCode,
DL, NVT, Res);
766 Arg = GetScalarizedVector(Arg);
769 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
778 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
785bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
790 switch (
N->getOpcode()) {
793 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
800 Res = ScalarizeVecOp_BITCAST(
N);
803 Res = ScalarizeVecOp_FAKE_USE(
N);
817 Res = ScalarizeVecOp_UnaryOp(
N);
821 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
827 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
830 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
833 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
836 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
839 Res = ScalarizeVecOp_VSELECT(
N);
842 Res = ScalarizeVecOp_VSETCC(
N);
846 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
852 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
855 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
858 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
861 Res = ScalarizeVecOp_FP_EXTEND(
N);
878 Res = ScalarizeVecOp_VECREDUCE(
N);
882 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
886 Res = ScalarizeVecOp_CMP(
N);
889 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
894 if (!Res.
getNode())
return false;
902 "Invalid operand expansion");
904 ReplaceValueWith(
SDValue(
N, 0), Res);
911 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
913 N->getValueType(0), Elt);
918 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
919 "Fake Use: Unexpected vector type!");
920 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
921 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
927 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
928 "Unexpected vector type!");
929 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
931 N->getValueType(0).getScalarType(), Elt);
939SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
940 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
941 "Unexpected vector type!");
942 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
944 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
945 Elt,
N->getOperand(1));
953SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
954 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
955 "Unexpected vector type!");
956 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
958 {
N->getValueType(0).getScalarType(), MVT::Other },
959 {
N->getOperand(0), Elt });
969 ReplaceValueWith(
SDValue(
N, 0), Res);
974SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
976 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
977 Ops[i] = GetScalarizedVector(
N->getOperand(i));
978 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
983SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
987 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
988 SDValue ContainingVec =
N->getOperand(0);
996SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
997 EVT VT =
N->getValueType(0);
998 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1010 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1011 EVT VT =
N->getValueType(0);
1013 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1021 assert(
N->getValueType(0).isVector() &&
1022 N->getOperand(0).getValueType().isVector() &&
1023 "Operand types must be vectors");
1024 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1026 EVT VT =
N->getValueType(0);
1027 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1028 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1030 EVT OpVT =
N->getOperand(0).getValueType();
1042 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1048SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1050 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1051 assert(
N->getValueType(0).isVector() &&
1052 N->getOperand(1).getValueType().isVector() &&
1053 "Operand types must be vectors");
1054 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1056 EVT VT =
N->getValueType(0);
1058 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1059 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1062 EVT OpVT =
N->getOperand(1).getValueType();
1066 {Ch, LHS, RHS, CC});
1075 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1080 ReplaceValueWith(
SDValue(
N, 0), Res);
1087 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1088 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1091 if (
N->isTruncatingStore())
1092 return DAG.getTruncStore(
1093 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1094 N->getBasePtr(),
N->getPointerInfo(),
1095 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1096 N->getMemOperand()->getFlags(),
N->getAAInfo());
1098 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1099 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1100 N->getMemOperand()->getFlags(),
N->getAAInfo());
1105SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1106 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1107 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1109 N->getValueType(0).getVectorElementType(), Elt,
1114SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1116 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1117 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1120 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1130 ReplaceValueWith(
SDValue(
N, 0), Res);
1137 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1139 N->getValueType(0).getVectorElementType(), Elt);
1145SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1146 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1149 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1150 {
N->getOperand(0), Elt});
1159 ReplaceValueWith(
SDValue(
N, 0), Res);
1164 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1171SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1177 SDValue Op = GetScalarizedVector(VecOp);
1178 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1179 AccOp,
Op,
N->getFlags());
1183 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1184 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1191SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1199 EVT VT =
N->getValueType(0);
1200 return DAG.getConstant(0, SDLoc(
N), VT);
1211void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1216 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1219 switch (
N->getOpcode()) {
1222 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1231 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1239 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1255 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1258 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1267 case ISD::VP_LOAD_FF:
1270 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1277 case ISD::VP_GATHER:
1281 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1285 SplitVecRes_SETCC(
N,
Lo,
Hi);
1288 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1295 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1298 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1301 SplitVecRes_VECTOR_INTERLEAVE(
N);
1304 SplitVecRes_VAARG(
N,
Lo,
Hi);
1310 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1316 case ISD::VP_BITREVERSE:
1324 case ISD::VP_CTLZ_ZERO_UNDEF:
1326 case ISD::VP_CTTZ_ZERO_UNDEF:
1341 case ISD::VP_FFLOOR:
1346 case ISD::VP_FNEARBYINT:
1351 case ISD::VP_FP_EXTEND:
1353 case ISD::VP_FP_ROUND:
1355 case ISD::VP_FP_TO_SINT:
1357 case ISD::VP_FP_TO_UINT:
1363 case ISD::VP_LLRINT:
1365 case ISD::VP_FROUND:
1367 case ISD::VP_FROUNDEVEN:
1376 case ISD::VP_FROUNDTOZERO:
1378 case ISD::VP_SINT_TO_FP:
1380 case ISD::VP_TRUNCATE:
1382 case ISD::VP_UINT_TO_FP:
1385 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1388 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1394 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1400 case ISD::VP_SIGN_EXTEND:
1401 case ISD::VP_ZERO_EXTEND:
1402 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1424 case ISD::VP_FMINNUM:
1427 case ISD::VP_FMAXNUM:
1429 case ISD::VP_FMINIMUM:
1431 case ISD::VP_FMAXIMUM:
1440 case ISD::OR:
case ISD::VP_OR:
1460 case ISD::VP_FCOPYSIGN:
1461 SplitVecRes_BinOp(
N,
Lo,
Hi);
1468 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1472 SplitVecRes_CMP(
N,
Lo,
Hi);
1475#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1476 case ISD::STRICT_##DAGN:
1477#include "llvm/IR/ConstrainedOps.def"
1478 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1483 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1492 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1502 SplitVecRes_FIX(
N,
Lo,
Hi);
1504 case ISD::EXPERIMENTAL_VP_SPLICE:
1505 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1507 case ISD::EXPERIMENTAL_VP_REVERSE:
1508 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1514 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1517 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1526void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1528 uint64_t *ScaledOffset) {
1533 SDValue BytesIncrement = DAG.getVScale(
1536 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1538 *ScaledOffset += IncrementSize;
1548std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1549 return SplitMask(Mask, SDLoc(Mask));
1552std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1555 EVT MaskVT =
Mask.getValueType();
1557 GetSplitVector(Mask, MaskLo, MaskHi);
1559 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1560 return std::make_pair(MaskLo, MaskHi);
1565 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1567 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1570 const SDNodeFlags
Flags =
N->getFlags();
1571 unsigned Opcode =
N->getOpcode();
1572 if (
N->getNumOperands() == 2) {
1573 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1574 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1578 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1579 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1582 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1585 std::tie(EVLLo, EVLHi) =
1586 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1589 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1591 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1597 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1599 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1601 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1604 const SDNodeFlags
Flags =
N->getFlags();
1605 unsigned Opcode =
N->getOpcode();
1606 if (
N->getNumOperands() == 3) {
1607 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1608 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1612 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1613 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1616 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1619 std::tie(EVLLo, EVLHi) =
1620 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1623 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1625 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1629 LLVMContext &Ctxt = *DAG.getContext();
1635 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1637 GetSplitVector(
LHS, LHSLo, LHSHi);
1638 GetSplitVector(
RHS, RHSLo, RHSHi);
1640 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1641 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1645 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1646 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1651 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1653 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1657 unsigned Opcode =
N->getOpcode();
1658 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1660 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1669 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1676 switch (getTypeAction(InVT)) {
1690 GetExpandedOp(InOp,
Lo,
Hi);
1691 if (DAG.getDataLayout().isBigEndian())
1701 GetSplitVector(InOp,
Lo,
Hi);
1710 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1719 if (DAG.getDataLayout().isBigEndian())
1722 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1724 if (DAG.getDataLayout().isBigEndian())
1730void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1736 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1739 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1744 unsigned LaneOffset =
1747 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1749 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1756 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1759 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1762 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1767 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1769 unsigned NumSubvectors =
N->getNumOperands() / 2;
1770 if (NumSubvectors == 1) {
1771 Lo =
N->getOperand(0);
1772 Hi =
N->getOperand(1);
1777 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1786void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1793 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1808 GetSplitVector(Vec,
Lo,
Hi);
1811 EVT LoVT =
Lo.getValueType();
1821 if (IdxVal + SubElems <= LoElems) {
1829 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1831 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1837 SDValue WideSubVec = GetWidenedVector(SubVec);
1839 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1847 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1849 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1850 auto &MF = DAG.getMachineFunction();
1854 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1859 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1860 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1864 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1869 MachinePointerInfo MPI =
Load->getPointerInfo();
1870 IncrementPointer(Load, LoVT, MPI, StackPtr);
1873 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1882 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1887 EVT RHSVT =
RHS.getValueType();
1890 GetSplitVector(
RHS, RHSLo, RHSHi);
1892 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1907 SDValue FpValue =
N->getOperand(0);
1909 GetSplitVector(FpValue, ArgLo, ArgHi);
1911 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1913 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1922 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1926 std::tie(LoVT, HiVT) =
1930 DAG.getValueType(LoVT));
1932 DAG.getValueType(HiVT));
1937 unsigned Opcode =
N->getOpcode();
1944 GetSplitVector(N0, InLo, InHi);
1946 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1951 EVT OutLoVT, OutHiVT;
1952 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1954 assert((2 * OutNumElements) <= InNumElements &&
1955 "Illegal extend vector in reg split");
1964 SmallVector<int, 8> SplitHi(InNumElements, -1);
1965 for (
unsigned i = 0; i != OutNumElements; ++i)
1966 SplitHi[i] = i + OutNumElements;
1967 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
1969 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1970 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1975 unsigned NumOps =
N->getNumOperands();
1979 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1989 for (
unsigned i = 1; i <
NumOps; ++i) {
1994 EVT InVT =
Op.getValueType();
1999 GetSplitVector(
Op, OpLo, OpHi);
2001 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2008 EVT LoValueVTs[] = {LoVT, MVT::Other};
2009 EVT HiValueVTs[] = {HiVT, MVT::Other};
2010 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2012 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2018 Lo.getValue(1),
Hi.getValue(1));
2022 ReplaceValueWith(
SDValue(
N, 1), Chain);
2025SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2027 EVT VT =
N->getValueType(0);
2038 else if (NE > ResNE)
2042 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2046 for (i = 0; i !=
NE; ++i) {
2047 Operands[0] = Chain;
2048 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2049 SDValue Operand =
N->getOperand(j);
2053 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2055 Operands[
j] = Operand;
2059 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2067 for (; i < ResNE; ++i)
2068 Scalars.
push_back(DAG.getPOISON(EltVT));
2072 ReplaceValueWith(
SDValue(
N, 1), Chain);
2076 return DAG.getBuildVector(VecVT, dl, Scalars);
2079void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2082 EVT ResVT =
N->getValueType(0);
2083 EVT OvVT =
N->getValueType(1);
2084 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2085 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2086 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2088 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2090 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2091 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2093 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2094 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2097 unsigned Opcode =
N->getOpcode();
2098 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2099 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2101 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2103 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2109 unsigned OtherNo = 1 - ResNo;
2110 EVT OtherVT =
N->getValueType(OtherNo);
2112 SetSplitVector(
SDValue(
N, OtherNo),
2118 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2122void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2128 GetSplitVector(Vec,
Lo,
Hi);
2131 unsigned IdxVal = CIdx->getZExtValue();
2132 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2133 if (IdxVal < LoNumElts) {
2135 Lo.getValueType(),
Lo, Elt, Idx);
2138 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2158 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2160 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2161 auto &MF = DAG.getMachineFunction();
2165 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2170 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2171 Store = DAG.getTruncStore(
2177 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2180 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2184 MachinePointerInfo MPI =
Load->getPointerInfo();
2185 IncrementPointer(Load, LoVT, MPI, StackPtr);
2187 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2190 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2191 if (LoVT !=
Lo.getValueType())
2193 if (HiVT !=
Hi.getValueType())
2201 assert(
N->getValueType(0).isScalableVector() &&
2202 "Only scalable vectors are supported for STEP_VECTOR");
2203 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2224 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2225 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2227 Hi = DAG.getPOISON(HiVT);
2239 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2245 EVT MemoryVT =
LD->getMemoryVT();
2247 AAMDNodes AAInfo =
LD->getAAInfo();
2249 EVT LoMemVT, HiMemVT;
2250 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2254 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2255 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2256 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2261 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2264 MachinePointerInfo MPI;
2265 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2268 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2277 ReplaceValueWith(
SDValue(LD, 1), Ch);
2282 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2285 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2291 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2292 Align Alignment =
LD->getBaseAlign();
2295 EVT MemoryVT =
LD->getMemoryVT();
2297 EVT LoMemVT, HiMemVT;
2298 bool HiIsEmpty =
false;
2299 std::tie(LoMemVT, HiMemVT) =
2300 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2305 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2308 GetSplitVector(Mask, MaskLo, MaskHi);
2310 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2315 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2317 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2323 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2324 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2332 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2333 LD->isExpandingLoad());
2335 MachinePointerInfo MPI;
2337 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2339 MPI =
LD->getPointerInfo().getWithOffset(
2342 MMO = DAG.getMachineFunction().getMachineMemOperand(
2344 Alignment,
LD->getAAInfo(),
LD->getRanges());
2346 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2347 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2348 LD->isExpandingLoad());
2358 ReplaceValueWith(
SDValue(LD, 1), Ch);
2364 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2368 Align Alignment =
LD->getBaseAlign();
2375 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2378 GetSplitVector(Mask, MaskLo, MaskHi);
2380 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2384 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2386 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2391 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2394 Hi = DAG.getPOISON(HiVT);
2396 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2397 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2403 "Indexed VP strided load during type legalization!");
2405 "Unexpected indexed variable-length load offset");
2410 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2412 EVT LoMemVT, HiMemVT;
2413 bool HiIsEmpty =
false;
2414 std::tie(LoMemVT, HiMemVT) =
2415 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2420 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2423 GetSplitVector(Mask, LoMask, HiMask);
2425 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2429 std::tie(LoEVL, HiEVL) =
2433 Lo = DAG.getStridedLoadVP(
2460 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2467 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2478 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2486 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2491 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2501 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2504 GetSplitVector(Mask, MaskLo, MaskHi);
2506 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2510 EVT LoMemVT, HiMemVT;
2511 bool HiIsEmpty =
false;
2512 std::tie(LoMemVT, HiMemVT) =
2513 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2515 SDValue PassThruLo, PassThruHi;
2517 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2519 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2521 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2525 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2535 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2538 MachinePointerInfo MPI;
2545 MMO = DAG.getMachineFunction().getMachineMemOperand(
2549 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2561 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2569 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2577 }
Ops = [&]() -> Operands {
2579 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2582 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2585 EVT MemoryVT =
N->getMemoryVT();
2586 Align Alignment =
N->getBaseAlign();
2591 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2593 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2596 EVT LoMemVT, HiMemVT;
2598 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2601 if (getTypeAction(
Ops.Index.getValueType()) ==
2603 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2605 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2608 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2610 Alignment,
N->getAAInfo(),
N->getRanges());
2613 SDValue PassThru = MGT->getPassThru();
2614 SDValue PassThruLo, PassThruHi;
2617 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2619 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2624 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2625 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2626 OpsLo, MMO, IndexTy, ExtType);
2628 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2629 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2630 OpsHi, MMO, IndexTy, ExtType);
2634 std::tie(EVLLo, EVLHi) =
2635 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2637 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2638 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2639 MMO, VPGT->getIndexType());
2641 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2642 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2643 MMO, VPGT->getIndexType());
2653 ReplaceValueWith(
SDValue(
N, 1), Ch);
2667 EVT VecVT =
N->getValueType(0);
2669 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2670 bool HasCustomLowering =
false;
2677 HasCustomLowering =
true;
2683 SDValue Passthru =
N->getOperand(2);
2684 if (!HasCustomLowering) {
2685 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2686 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2693 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2694 std::tie(LoMask, HiMask) = SplitMask(Mask);
2696 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2701 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2702 MachineFunction &MF = DAG.getMachineFunction();
2714 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2716 SDValue Chain = DAG.getEntryNode();
2717 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2721 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2726 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2730 assert(
N->getValueType(0).isVector() &&
2731 N->getOperand(0).getValueType().isVector() &&
2732 "Operand types must be vectors");
2736 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2740 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2742 GetSplitVector(
N->getOperand(0), LL, LH);
2744 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2746 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2748 GetSplitVector(
N->getOperand(1), RL, RH);
2750 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2753 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2754 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2756 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2757 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2758 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2759 std::tie(EVLLo, EVLHi) =
2760 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2761 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2763 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2773 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2777 EVT InVT =
N->getOperand(0).getValueType();
2779 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2781 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2783 const SDNodeFlags
Flags =
N->getFlags();
2784 unsigned Opcode =
N->getOpcode();
2785 if (
N->getNumOperands() <= 2) {
2787 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2788 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2790 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2791 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2796 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2797 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2800 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2803 std::tie(EVLLo, EVLHi) =
2804 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2807 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2813 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2817 EVT InVT =
N->getOperand(0).getValueType();
2819 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2821 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2824 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2825 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2826 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2827 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2830void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2835 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2836 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2840 EVT InVT =
N->getOperand(0).getValueType();
2842 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2844 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2846 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2847 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2849 SDNode *HiNode =
Hi.getNode();
2850 SDNode *LoNode =
Lo.getNode();
2853 unsigned OtherNo = 1 - ResNo;
2854 EVT OtherVT =
N->getValueType(OtherNo);
2862 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2869 EVT SrcVT =
N->getOperand(0).getValueType();
2870 EVT DestVT =
N->getValueType(0);
2872 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2889 LLVMContext &Ctx = *DAG.getContext();
2893 EVT SplitLoVT, SplitHiVT;
2894 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2895 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2896 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2897 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2898 N->dump(&DAG);
dbgs() <<
"\n");
2899 if (!
N->isVPOpcode()) {
2902 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2904 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2906 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2907 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2913 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2914 N->getOperand(1),
N->getOperand(2));
2916 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2919 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2922 std::tie(EVLLo, EVLHi) =
2923 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2925 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2926 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2931 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2939 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2940 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2946 return N.getResNo() == 0 &&
2950 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2952 ArrayRef<int>
Mask) {
2955 "Expected build vector node.");
2958 for (
unsigned I = 0;
I < NewElts; ++
I) {
2961 unsigned Idx =
Mask[
I];
2963 Ops[
I] = Input2.getOperand(Idx - NewElts);
2965 Ops[
I] = Input1.getOperand(Idx);
2970 return DAG.getBuildVector(NewVT,
DL,
Ops);
2976 SmallVector<int> OrigMask(
N->getMask());
2978 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2979 &
DL](SmallVectorImpl<int> &
Mask) {
2981 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2982 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2993 for (
auto &
P : ShufflesIdxs) {
2994 if (
P.second.size() < 2)
2998 for (
int &Idx : Mask) {
3001 unsigned SrcRegIdx = Idx / NewElts;
3002 if (Inputs[SrcRegIdx].
isUndef()) {
3010 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3015 Idx = MaskElt % NewElts +
3016 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3022 Inputs[
P.second[0]] =
P.first.first;
3023 Inputs[
P.second[1]] =
P.first.second;
3026 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3029 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3030 for (
int &Idx : Mask) {
3033 unsigned SrcRegIdx = Idx / NewElts;
3034 if (Inputs[SrcRegIdx].
isUndef()) {
3041 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3042 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3045 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3047 if (UsedSubVector.count() > 1) {
3049 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3050 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3052 if (Pairs.
empty() || Pairs.
back().size() == 2)
3054 if (UsedSubVector.test(2 *
I)) {
3055 Pairs.
back().emplace_back(
I, 0);
3057 assert(UsedSubVector.test(2 *
I + 1) &&
3058 "Expected to be used one of the subvectors.");
3059 Pairs.
back().emplace_back(
I, 1);
3062 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3064 for (
int &Idx : Mask) {
3067 unsigned SrcRegIdx = Idx / NewElts;
3069 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3070 return Idxs.front().first == SrcRegIdx ||
3071 Idxs.back().first == SrcRegIdx;
3073 if (It == Pairs.
end())
3075 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3076 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3079 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3080 Inputs[Idxs.front().first] = DAG.
getNode(
3082 Inputs[Idxs.front().first].getValueType(),
3083 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3084 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3093 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3097 if (Shuffle->getOperand(0).getValueType() != NewVT)
3100 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3101 !Shuffle->isSplat()) {
3103 }
else if (!Inputs[
I].hasOneUse() &&
3104 !Shuffle->getOperand(1).isUndef()) {
3106 for (
int &Idx : Mask) {
3109 unsigned SrcRegIdx = Idx / NewElts;
3112 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3117 int OpIdx = MaskElt / NewElts;
3131 if (Shuffle->getOperand(
OpIdx).isUndef())
3133 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3134 if (It == std::end(Inputs))
3136 int FoundOp = std::distance(std::begin(Inputs), It);
3139 for (
int &Idx : Mask) {
3142 unsigned SrcRegIdx = Idx / NewElts;
3145 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3150 int MaskIdx = MaskElt / NewElts;
3151 if (
OpIdx == MaskIdx)
3152 Idx = MaskElt % NewElts + FoundOp * NewElts;
3163 for (
int &Idx : Mask) {
3166 unsigned SrcRegIdx = Idx / NewElts;
3169 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3170 int OpIdx = MaskElt / NewElts;
3173 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3179 TryPeekThroughShufflesInputs(OrigMask);
3181 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3182 NewElts](SmallVectorImpl<int> &
Mask) {
3183 SetVector<SDValue> UniqueInputs;
3184 SetVector<SDValue> UniqueConstantInputs;
3185 for (
const auto &
I : Inputs) {
3187 UniqueConstantInputs.
insert(
I);
3188 else if (!
I.isUndef())
3193 if (UniqueInputs.
size() != std::size(Inputs)) {
3194 auto &&UniqueVec = UniqueInputs.
takeVector();
3195 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3196 unsigned ConstNum = UniqueConstantVec.size();
3197 for (
int &Idx : Mask) {
3200 unsigned SrcRegIdx = Idx / NewElts;
3201 if (Inputs[SrcRegIdx].
isUndef()) {
3205 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3206 if (It != UniqueConstantVec.end()) {
3207 Idx = (Idx % NewElts) +
3208 NewElts * std::distance(UniqueConstantVec.begin(), It);
3209 assert(Idx >= 0 &&
"Expected defined mask idx.");
3212 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3213 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3214 Idx = (Idx % NewElts) +
3215 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3216 assert(Idx >= 0 &&
"Expected defined mask idx.");
3218 copy(UniqueConstantVec, std::begin(Inputs));
3219 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3222 MakeUniqueInputs(OrigMask);
3224 copy(Inputs, std::begin(OrigInputs));
3230 unsigned FirstMaskIdx =
High * NewElts;
3233 assert(!Output &&
"Expected default initialized initial value.");
3234 TryPeekThroughShufflesInputs(Mask);
3235 MakeUniqueInputs(Mask);
3237 copy(Inputs, std::begin(TmpInputs));
3240 bool SecondIteration =
false;
3241 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3246 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3247 SecondIteration =
true;
3248 return SecondIteration;
3251 Mask, std::size(Inputs), std::size(Inputs),
3253 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3254 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3255 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3257 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3259 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3260 DAG.getPOISON(NewVT), Mask);
3261 Inputs[Idx] = Output;
3263 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3264 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3265 unsigned Idx2,
bool ) {
3266 if (AccumulateResults(Idx1)) {
3269 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3271 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3272 Inputs[Idx2], Mask);
3276 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3278 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3279 TmpInputs[Idx2], Mask);
3281 Inputs[Idx1] = Output;
3283 copy(OrigInputs, std::begin(Inputs));
3288 EVT OVT =
N->getValueType(0);
3295 const Align Alignment =
3296 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3298 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3299 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3304 ReplaceValueWith(
SDValue(
N, 1), Chain);
3309 EVT DstVTLo, DstVTHi;
3310 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3314 EVT SrcVT =
N->getOperand(0).getValueType();
3316 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3318 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3320 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3321 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3327 GetSplitVector(
N->getOperand(0), InLo, InHi);
3338 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3339 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3344 EVT VT =
N->getValueType(0);
3351 Align Alignment = DAG.getReducedAlign(VT,
false);
3356 EVT PtrVT =
StackPtr.getValueType();
3357 auto &MF = DAG.getMachineFunction();
3361 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3364 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3370 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3371 DAG.getConstant(1,
DL, PtrVT));
3373 DAG.getConstant(EltWidth,
DL, PtrVT));
3375 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3377 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3378 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3379 DAG.getPOISON(PtrVT), Stride, TrueMask,
3382 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3384 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3389 EVT VT =
N->getValueType(0);
3401 EVL1 = ZExtPromotedInteger(EVL1);
3403 Align Alignment = DAG.getReducedAlign(VT,
false);
3408 EVT PtrVT =
StackPtr.getValueType();
3409 auto &MF = DAG.getMachineFunction();
3413 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3416 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3420 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3421 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3423 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3425 DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr, PoisonPtr, TrueMask,
3429 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3434 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3435 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3437 uint64_t TrailingElts = -
Imm;
3439 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3448 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3452 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3454 DAG.getVectorIdxConstant(0,
DL));
3460void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3468 GetSplitVector(Acc, AccLo, AccHi);
3469 unsigned Opcode =
N->getOpcode();
3481 GetSplitVector(Input1, Input1Lo, Input1Hi);
3482 GetSplitVector(Input2, Input2Lo, Input2Hi);
3485 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3486 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3489void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3497 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3505void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3506 unsigned Factor =
N->getNumOperands();
3509 for (
unsigned i = 0; i != Factor; ++i) {
3511 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3513 Ops[i * 2 + 1] = OpHi;
3524 for (
unsigned i = 0; i != Factor; ++i)
3528void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
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 + Factor] = OpHi;
3547 for (
unsigned i = 0; i != Factor; ++i) {
3548 unsigned IdxLo = 2 * i;
3549 unsigned IdxHi = 2 * i + 1;
3550 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3551 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3563bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3568 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3571 switch (
N->getOpcode()) {
3574 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3584 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3591 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3593 case ISD::VP_TRUNCATE:
3595 Res = SplitVecOp_TruncateHelper(
N);
3598 case ISD::VP_FP_ROUND:
3607 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3614 case ISD::VP_SCATTER:
3618 case ISD::VP_GATHER:
3622 Res = SplitVecOp_VSELECT(
N, OpNo);
3625 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3631 case ISD::VP_SINT_TO_FP:
3632 case ISD::VP_UINT_TO_FP:
3633 if (
N->getValueType(0).bitsLT(
3634 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3635 Res = SplitVecOp_TruncateHelper(
N);
3637 Res = SplitVecOp_UnaryOp(
N);
3641 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3645 case ISD::VP_FP_TO_SINT:
3646 case ISD::VP_FP_TO_UINT:
3659 Res = SplitVecOp_UnaryOp(
N);
3662 Res = SplitVecOp_FPOpDifferentTypes(
N);
3667 Res = SplitVecOp_CMP(
N);
3671 Res = SplitVecOp_FAKE_USE(
N);
3676 Res = SplitVecOp_ExtVecInRegOp(
N);
3694 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3698 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3700 case ISD::VP_REDUCE_FADD:
3701 case ISD::VP_REDUCE_SEQ_FADD:
3702 case ISD::VP_REDUCE_FMUL:
3703 case ISD::VP_REDUCE_SEQ_FMUL:
3704 case ISD::VP_REDUCE_ADD:
3705 case ISD::VP_REDUCE_MUL:
3706 case ISD::VP_REDUCE_AND:
3707 case ISD::VP_REDUCE_OR:
3708 case ISD::VP_REDUCE_XOR:
3709 case ISD::VP_REDUCE_SMAX:
3710 case ISD::VP_REDUCE_SMIN:
3711 case ISD::VP_REDUCE_UMAX:
3712 case ISD::VP_REDUCE_UMIN:
3713 case ISD::VP_REDUCE_FMAX:
3714 case ISD::VP_REDUCE_FMIN:
3715 case ISD::VP_REDUCE_FMAXIMUM:
3716 case ISD::VP_REDUCE_FMINIMUM:
3717 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3719 case ISD::VP_CTTZ_ELTS:
3720 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3721 Res = SplitVecOp_VP_CttzElements(
N);
3724 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3730 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3735 if (!Res.
getNode())
return false;
3742 if (
N->isStrictFPOpcode())
3744 "Invalid operand expansion");
3747 "Invalid operand expansion");
3749 ReplaceValueWith(
SDValue(
N, 0), Res);
3753SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3757 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3759 EVT VT =
N->getValueType(0);
3772 getSetCCResultType(MVT::i1), MVT::i1);
3777 DAG.getElementCount(
DL, VT, SplitEC)),
3781SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3784 assert(OpNo == 0 &&
"Illegal operand must be mask");
3791 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3794 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3795 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3796 "Lo and Hi have differing types");
3799 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3800 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3802 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3803 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3804 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3805 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3815SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3818 assert(OpNo == 1 &&
"Illegal operand must be mask");
3823 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3825 EVT VecVT =
N->getValueType(0);
3829SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3830 EVT ResVT =
N->getValueType(0);
3836 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3837 GetSplitVector(VecOp,
Lo,
Hi);
3839 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3844 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3845 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3849 EVT ResVT =
N->getValueType(0);
3855 SDNodeFlags
Flags =
N->getFlags();
3858 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3859 GetSplitVector(VecOp,
Lo,
Hi);
3861 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3867 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3870SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3871 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3872 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3874 unsigned Opc =
N->getOpcode();
3875 EVT ResVT =
N->getValueType(0);
3881 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3882 GetSplitVector(VecOp,
Lo,
Hi);
3885 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3888 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3890 const SDNodeFlags
Flags =
N->getFlags();
3894 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3899 EVT ResVT =
N->getValueType(0);
3902 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3903 EVT InVT =
Lo.getValueType();
3908 if (
N->isStrictFPOpcode()) {
3909 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3910 {N->getOperand(0), Lo});
3911 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3912 {N->getOperand(0), Hi});
3921 ReplaceValueWith(
SDValue(
N, 1), Ch);
3922 }
else if (
N->getNumOperands() == 3) {
3923 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3924 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3925 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3926 std::tie(EVLLo, EVLHi) =
3927 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3928 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3929 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3931 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3932 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3941 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3951 EVT ResVT =
N->getValueType(0);
3953 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3957 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3963 Lo = BitConvertToInteger(
Lo);
3964 Hi = BitConvertToInteger(
Hi);
3966 if (DAG.getDataLayout().isBigEndian())
3974 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3976 EVT ResVT =
N->getValueType(0);
3984 GetSplitVector(SubVec,
Lo,
Hi);
3993 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3995 return SecondInsertion;
3998SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4005 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4007 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4009 ElementCount IdxVal =
4013 EVT SrcVT =
N->getOperand(0).getValueType();
4032 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4033 LoEltsMin - IdxValMin);
4034 DAG.ExtractVectorElements(
Hi, Elts, 0,
4037 return DAG.getBuildVector(SubVT, dl, Elts);
4041 ElementCount ExtractIdx = IdxVal - LoElts;
4043 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4046 EVT HiVT =
Hi.getValueType();
4048 "Only fixed-vector extracts are supported in this case");
4058 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4059 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4065 "Extracting scalable subvector from fixed-width unsupported");
4073 "subvector from a scalable predicate vector");
4079 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4081 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4082 auto &MF = DAG.getMachineFunction();
4086 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4090 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4093 SubVT, dl, Store, StackPtr,
4097SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4103 uint64_t IdxVal =
Index->getZExtValue();
4106 GetSplitVector(Vec,
Lo,
Hi);
4108 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4110 if (IdxVal < LoElts)
4111 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4114 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4119 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4131 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4137 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4139 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4140 auto &MF = DAG.getMachineFunction();
4143 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4147 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4151 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4153 return DAG.getExtLoad(
4164 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4172 SplitVecRes_Gather(
N,
Lo,
Hi);
4175 ReplaceValueWith(
SDValue(
N, 0), Res);
4180 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4184 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4186 SDValue EVL =
N->getVectorLength();
4188 Align Alignment =
N->getBaseAlign();
4194 GetSplitVector(
Data, DataLo, DataHi);
4196 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4201 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4204 GetSplitVector(Mask, MaskLo, MaskHi);
4206 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4209 EVT MemoryVT =
N->getMemoryVT();
4210 EVT LoMemVT, HiMemVT;
4211 bool HiIsEmpty =
false;
4212 std::tie(LoMemVT, HiMemVT) =
4213 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4217 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4220 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4225 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4226 N->getAddressingMode(),
N->isTruncatingStore(),
4227 N->isCompressingStore());
4233 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4234 N->isCompressingStore());
4236 MachinePointerInfo MPI;
4240 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4245 MMO = DAG.getMachineFunction().getMachineMemOperand(
4247 Alignment,
N->getAAInfo(),
N->getRanges());
4249 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4250 N->getAddressingMode(),
N->isTruncatingStore(),
4251 N->isCompressingStore());
4260 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4261 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4268 GetSplitVector(
Data, LoData, HiData);
4270 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4272 EVT LoMemVT, HiMemVT;
4273 bool HiIsEmpty =
false;
4274 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4280 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4281 else if (getTypeAction(
Mask.getValueType()) ==
4283 GetSplitVector(Mask, LoMask, HiMask);
4285 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4288 std::tie(LoEVL, HiEVL) =
4289 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4293 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4294 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4295 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4306 EVT PtrVT =
N->getBasePtr().getValueType();
4309 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4312 Align Alignment =
N->getBaseAlign();
4317 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4318 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4320 Alignment,
N->getAAInfo(),
N->getRanges());
4323 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4324 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4325 N->isCompressingStore());
4334 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4338 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4341 Align Alignment =
N->getBaseAlign();
4347 GetSplitVector(
Data, DataLo, DataHi);
4349 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4354 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4357 GetSplitVector(Mask, MaskLo, MaskHi);
4359 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4362 EVT MemoryVT =
N->getMemoryVT();
4363 EVT LoMemVT, HiMemVT;
4364 bool HiIsEmpty =
false;
4365 std::tie(LoMemVT, HiMemVT) =
4366 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4369 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4374 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4375 N->getAddressingMode(),
N->isTruncatingStore(),
4376 N->isCompressingStore());
4384 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4385 N->isCompressingStore());
4387 MachinePointerInfo MPI;
4391 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4396 MMO = DAG.getMachineFunction().getMachineMemOperand(
4398 Alignment,
N->getAAInfo(),
N->getRanges());
4400 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4401 N->getAddressingMode(),
N->isTruncatingStore(),
4402 N->isCompressingStore());
4415 EVT MemoryVT =
N->getMemoryVT();
4416 Align Alignment =
N->getBaseAlign();
4423 }
Ops = [&]() -> Operands {
4425 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4429 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4434 EVT LoMemVT, HiMemVT;
4435 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4440 GetSplitVector(
Ops.Data, DataLo, DataHi);
4442 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4447 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4449 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4453 if (getTypeAction(
Ops.Index.getValueType()) ==
4455 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4457 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4461 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4463 Alignment,
N->getAAInfo(),
N->getRanges());
4466 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4468 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4469 MSC->getIndexType(), MSC->isTruncatingStore());
4474 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4475 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4476 MMO, MSC->getIndexType(),
4477 MSC->isTruncatingStore());
4481 std::tie(EVLLo, EVLHi) =
4482 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4484 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4485 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4486 VPSC->getIndexType());
4491 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4492 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4493 VPSC->getIndexType());
4497 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4498 assert(OpNo == 1 &&
"Can only split the stored value");
4501 bool isTruncating =
N->isTruncatingStore();
4504 EVT MemoryVT =
N->getMemoryVT();
4505 Align Alignment =
N->getBaseAlign();
4507 AAMDNodes AAInfo =
N->getAAInfo();
4509 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4511 EVT LoMemVT, HiMemVT;
4512 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4516 return TLI.scalarizeVectorStore(
N, DAG);
4519 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4520 Alignment, MMOFlags, AAInfo);
4522 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4525 MachinePointerInfo MPI;
4526 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4529 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4530 HiMemVT, Alignment, MMOFlags, AAInfo);
4532 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4548 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4554 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4575 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4576 SDValue InVec =
N->getOperand(OpNo);
4578 EVT OutVT =
N->getValueType(0);
4586 EVT LoOutVT, HiOutVT;
4587 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4588 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4593 if (isTypeLegal(LoOutVT) ||
4594 InElementSize <= OutElementSize * 2)
4595 return SplitVecOp_UnaryOp(
N);
4604 return SplitVecOp_UnaryOp(
N);
4608 GetSplitVector(InVec, InLoVec, InHiVec);
4614 EVT HalfElementVT = IsFloat ?
4616 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4623 if (
N->isStrictFPOpcode()) {
4624 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4625 {N->getOperand(0), InLoVec});
4626 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4627 {N->getOperand(0), InHiVec});
4633 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4634 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4638 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4646 if (
N->isStrictFPOpcode()) {
4650 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4658 DAG.getTargetConstant(
4659 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4666 assert(
N->getValueType(0).isVector() &&
4667 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4668 "Operand types must be vectors");
4670 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4672 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4673 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4675 EVT VT =
N->getValueType(0);
4682 }
else if (isStrict) {
4683 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4684 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4685 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4686 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4689 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4691 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4692 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4693 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4694 std::tie(EVLLo, EVLHi) =
4695 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4696 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4697 N->getOperand(2), MaskLo, EVLLo);
4698 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4699 N->getOperand(2), MaskHi, EVLHi);
4708 EVT ResVT =
N->getValueType(0);
4711 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4712 EVT InVT =
Lo.getValueType();
4717 if (
N->isStrictFPOpcode()) {
4718 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4719 {N->getOperand(0), Lo, N->getOperand(2)});
4720 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4721 {N->getOperand(0), Hi, N->getOperand(2)});
4725 Lo.getValue(1),
Hi.getValue(1));
4726 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4727 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4728 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4729 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4730 std::tie(EVLLo, EVLHi) =
4731 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4732 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4733 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4747SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4750 EVT LHSLoVT, LHSHiVT;
4751 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4753 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4754 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4757 std::tie(LHSLo, LHSHi) =
4758 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4761 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4764 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4770 LLVMContext &Ctxt = *DAG.getContext();
4773 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4774 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4775 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4777 EVT ResVT =
N->getValueType(0);
4782 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4783 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4789 EVT ResVT =
N->getValueType(0);
4792 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4793 EVT InVT =
Lo.getValueType();
4799 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4800 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4807 EVT ResVT =
N->getValueType(0);
4811 GetSplitVector(VecOp,
Lo,
Hi);
4813 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4814 auto [EVLLo, EVLHi] =
4816 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4822 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4824 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4825 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4828SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4839 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4840 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4841 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4842 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4843 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4844 OpsLo, MMO, IndexType);
4845 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4846 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4850SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4853 "Accumulator should already be a legal type, and shouldn't need "
4854 "further splitting");
4857 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4858 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4859 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4860 unsigned Opcode =
N->getOpcode();
4863 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4864 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4871void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4872 unsigned WidenResNo) {
4873 unsigned NumResults =
N->getNumValues();
4874 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4875 if (ResNo == WidenResNo)
4877 EVT ResVT =
N->getValueType(ResNo);
4883 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4884 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4889void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4890 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4893 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4898 auto unrollExpandedOp = [&]() {
4903 EVT VT =
N->getValueType(0);
4904 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4905 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4906 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
4908 if (
N->getNumValues() > 1)
4909 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4915 switch (
N->getOpcode()) {
4918 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4926 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4930 Res = WidenVecRes_ADDRSPACECAST(
N);
4937 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4944 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4948 Res = WidenVecRes_ScalarOp(
N);
4953 case ISD::VP_SELECT:
4955 Res = WidenVecRes_Select(
N);
4959 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4961 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4968 case ISD::VP_LOAD_FF:
4971 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4975 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4983 case ISD::VP_GATHER:
4987 Res = WidenVecRes_VECTOR_REVERSE(
N);
4990 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5000 case ISD::OR:
case ISD::VP_OR:
5011 case ISD::VP_FMINNUM:
5014 case ISD::VP_FMAXNUM:
5016 case ISD::VP_FMINIMUM:
5018 case ISD::VP_FMAXIMUM:
5051 case ISD::VP_FCOPYSIGN:
5052 Res = WidenVecRes_Binary(
N);
5057 Res = WidenVecRes_CMP(
N);
5063 if (unrollExpandedOp())
5078 Res = WidenVecRes_BinaryCanTrap(
N);
5087 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5090#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5091 case ISD::STRICT_##DAGN:
5092#include "llvm/IR/ConstrainedOps.def"
5093 Res = WidenVecRes_StrictFP(
N);
5102 Res = WidenVecRes_OverflowOp(
N, ResNo);
5106 Res = WidenVecRes_FCOPYSIGN(
N);
5111 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5116 if (!unrollExpandedOp())
5117 Res = WidenVecRes_ExpOp(
N);
5123 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5128 case ISD::VP_FP_EXTEND:
5130 case ISD::VP_FP_ROUND:
5132 case ISD::VP_FP_TO_SINT:
5134 case ISD::VP_FP_TO_UINT:
5136 case ISD::VP_SIGN_EXTEND:
5138 case ISD::VP_SINT_TO_FP:
5139 case ISD::VP_TRUNCATE:
5142 case ISD::VP_UINT_TO_FP:
5144 case ISD::VP_ZERO_EXTEND:
5145 Res = WidenVecRes_Convert(
N);
5150 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5156 case ISD::VP_LLRINT:
5159 Res = WidenVecRes_XROUND(
N);
5185 if (unrollExpandedOp())
5195 case ISD::VP_BITREVERSE:
5201 case ISD::VP_CTLZ_ZERO_UNDEF:
5207 case ISD::VP_CTTZ_ZERO_UNDEF:
5212 case ISD::VP_FFLOOR:
5214 case ISD::VP_FNEARBYINT:
5215 case ISD::VP_FROUND:
5216 case ISD::VP_FROUNDEVEN:
5217 case ISD::VP_FROUNDTOZERO:
5222 Res = WidenVecRes_Unary(
N);
5229 Res = WidenVecRes_Ternary(
N);
5235 if (!unrollExpandedOp())
5236 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5243 SetWidenedVector(
SDValue(
N, ResNo), Res);
5249 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5250 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5251 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5252 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5253 if (
N->getNumOperands() == 3)
5254 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5256 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5257 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5261 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5262 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5268 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5269 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5270 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5271 if (
N->getNumOperands() == 2)
5272 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5275 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5276 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5280 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5281 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5285 LLVMContext &Ctxt = *DAG.getContext();
5290 EVT OpVT =
LHS.getValueType();
5292 LHS = GetWidenedVector(
LHS);
5293 RHS = GetWidenedVector(
RHS);
5294 OpVT =
LHS.getValueType();
5297 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5300 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5306SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5309 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5310 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5311 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5313 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5322 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5325 if (ConcatEnd == 1) {
5326 VT = ConcatOps[0].getValueType();
5328 return ConcatOps[0];
5331 SDLoc dl(ConcatOps[0]);
5338 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5339 int Idx = ConcatEnd - 1;
5340 VT = ConcatOps[Idx--].getValueType();
5341 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5354 unsigned NumToInsert = ConcatEnd - Idx - 1;
5355 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5357 ConcatOps[Idx+1] = VecOp;
5358 ConcatEnd = Idx + 2;
5364 unsigned RealVals = ConcatEnd - Idx - 1;
5365 unsigned SubConcatEnd = 0;
5366 unsigned SubConcatIdx = Idx + 1;
5367 while (SubConcatEnd < RealVals)
5368 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5369 while (SubConcatEnd < OpsToConcat)
5370 SubConcatOps[SubConcatEnd++] = undefVec;
5372 NextVT, SubConcatOps);
5373 ConcatEnd = SubConcatIdx + 1;
5378 if (ConcatEnd == 1) {
5379 VT = ConcatOps[0].getValueType();
5381 return ConcatOps[0];
5386 if (
NumOps != ConcatEnd ) {
5388 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5389 ConcatOps[j] = UndefVal;
5397 unsigned Opcode =
N->getOpcode();
5399 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5403 const SDNodeFlags
Flags =
N->getFlags();
5404 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5405 NumElts = NumElts / 2;
5409 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5411 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5412 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5413 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5421 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5424 TLI.isTypeLegal(WideMaskVT)) {
5425 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5426 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5427 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5429 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5430 N->getValueType(0).getVectorElementCount());
5431 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5445 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5446 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5447 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5450 unsigned ConcatEnd = 0;
5458 while (CurNumElts != 0) {
5459 while (CurNumElts >= NumElts) {
5460 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5461 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5462 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5464 CurNumElts -= NumElts;
5467 NumElts = NumElts / 2;
5469 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5472 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5473 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5474 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5475 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5486 switch (
N->getOpcode()) {
5489 return WidenVecRes_STRICT_FSETCC(
N);
5496 return WidenVecRes_Convert_StrictFP(
N);
5503 unsigned Opcode =
N->getOpcode();
5505 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5509 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5510 NumElts = NumElts / 2;
5521 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5525 unsigned ConcatEnd = 0;
5532 for (
unsigned i = 1; i < NumOpers; ++i) {
5538 Oper = GetWidenedVector(Oper);
5544 DAG.getPOISON(WideOpVT), Oper,
5545 DAG.getVectorIdxConstant(0, dl));
5557 while (CurNumElts != 0) {
5558 while (CurNumElts >= NumElts) {
5561 for (
unsigned i = 0; i < NumOpers; ++i) {
5564 EVT OpVT =
Op.getValueType();
5569 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5575 EVT OperVT[] = {VT, MVT::Other};
5577 ConcatOps[ConcatEnd++] = Oper;
5580 CurNumElts -= NumElts;
5583 NumElts = NumElts / 2;
5585 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5588 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5591 for (
unsigned i = 0; i < NumOpers; ++i) {
5594 EVT OpVT =
Op.getValueType();
5602 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5604 ConcatOps[ConcatEnd++] = Oper;
5613 if (Chains.
size() == 1)
5614 NewChain = Chains[0];
5617 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5622SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5624 EVT ResVT =
N->getValueType(0);
5625 EVT OvVT =
N->getValueType(1);
5626 EVT WideResVT, WideOvVT;
5631 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5636 WideLHS = GetWidenedVector(
N->getOperand(0));
5637 WideRHS = GetWidenedVector(
N->getOperand(1));
5639 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5648 N->getOperand(0), Zero);
5650 N->getOperand(1), Zero);
5653 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5654 SDNode *WideNode = DAG.getNode(
5655 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5658 unsigned OtherNo = 1 - ResNo;
5659 EVT OtherVT =
N->getValueType(OtherNo);
5666 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5669 return SDValue(WideNode, ResNo);
5673 LLVMContext &Ctx = *DAG.getContext();
5677 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5682 unsigned Opcode =
N->getOpcode();
5683 const SDNodeFlags
Flags =
N->getFlags();
5689 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5691 InOp = ZExtPromotedInteger(InOp);
5702 InOp = GetWidenedVector(
N->getOperand(0));
5705 if (InVTEC == WidenEC) {
5706 if (
N->getNumOperands() == 1)
5707 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5708 if (
N->getNumOperands() == 3) {
5709 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5712 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5714 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5740 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5744 if (TLI.isTypeLegal(InWidenVT)) {
5752 unsigned NumConcat =
5757 if (
N->getNumOperands() == 1)
5758 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5759 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5763 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5765 if (
N->getNumOperands() == 1)
5766 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5767 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5776 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5777 for (
unsigned i=0; i < MinElts; ++i) {
5778 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5779 if (
N->getNumOperands() == 1)
5782 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5785 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5790 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5794 EVT SrcVT = Src.getValueType();
5798 Src = GetWidenedVector(Src);
5799 SrcVT = Src.getValueType();
5806 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5811 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5815 EVT SrcVT = Src.getValueType();
5819 Src = GetWidenedVector(Src);
5820 SrcVT = Src.getValueType();
5827 if (
N->getNumOperands() == 1)
5828 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5830 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5831 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5835 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5838SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5843 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5849 unsigned Opcode =
N->getOpcode();
5855 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5860 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5861 for (
unsigned i=0; i < MinElts; ++i) {
5862 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5863 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5867 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5869 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5872SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5873 unsigned Opcode =
N->getOpcode();
5877 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5886 InOp = GetWidenedVector(InOp);
5893 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5900 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5901 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5918 while (
Ops.size() != WidenNumElts)
5919 Ops.push_back(DAG.getPOISON(WidenSVT));
5921 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5927 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5928 return WidenVecRes_BinaryCanTrap(
N);
5931 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5938SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5940 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5943 SDValue Arg = GetWidenedVector(FpValue);
5944 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5949 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5950 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5952 EVT ExpVT =
RHS.getValueType();
5957 ExpOp = ModifyToType(
RHS, WideExpVT);
5960 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5965 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5966 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5967 if (
N->getNumOperands() == 1)
5968 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5970 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5971 N->getOperand(1),
N->getFlags());
5973 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5974 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5978 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5979 {InOp,
Mask,
N->getOperand(2)});
5983 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5986 .getVectorElementType(),
5988 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5989 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5990 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5993SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5995 EVT VT0 =
N->getValueType(0);
5996 EVT VT1 =
N->getValueType(1);
6000 "expected both results to be vectors of matching element count");
6002 LLVMContext &Ctx = *DAG.getContext();
6003 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6005 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6012 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6015 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6016 return SDValue(WidenNode, ResNo);
6019SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6020 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6021 return GetWidenedVector(WidenVec);
6025 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6026 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6029 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6030 AddrSpaceCastN->getSrcAddressSpace(),
6031 AddrSpaceCastN->getDestAddressSpace());
6037 EVT VT =
N->getValueType(0);
6038 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6041 switch (getTypeAction(InVT)) {
6055 SDValue NInOp = GetPromotedInteger(InOp);
6057 if (WidenVT.
bitsEq(NInVT)) {
6060 if (DAG.getDataLayout().isBigEndian()) {
6063 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6081 InOp = GetWidenedVector(InOp);
6083 if (WidenVT.
bitsEq(InVT))
6093 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6098 unsigned NewNumParts = WidenSize / InSize;
6111 EVT OrigInVT =
N->getOperand(0).getValueType();
6116 if (TLI.isTypeLegal(NewInVT)) {
6124 if (WidenSize % InSize == 0) {
6131 DAG.ExtractVectorElements(InOp,
Ops);
6132 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6144 return CreateStackStoreLoad(InOp, WidenVT);
6147SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6149 N->getOpcode(), SDLoc(
N),
6150 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6151 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6157 EVT VT =
N->getValueType(0);
6161 EVT EltVT =
N->getOperand(0).getValueType();
6164 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6168 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6169 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6171 return DAG.getBuildVector(WidenVT, dl, NewOps);
6175 EVT InVT =
N->getOperand(0).getValueType();
6176 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6178 unsigned NumOperands =
N->getNumOperands();
6180 bool InputWidened =
false;
6184 if (WidenNumElts % NumInElts == 0) {
6186 unsigned NumConcat = WidenNumElts / NumInElts;
6187 SDValue UndefVal = DAG.getPOISON(InVT);
6189 for (
unsigned i=0; i < NumOperands; ++i)
6190 Ops[i] =
N->getOperand(i);
6191 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6196 InputWidened =
true;
6197 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6200 for (i=1; i < NumOperands; ++i)
6201 if (!
N->getOperand(i).isUndef())
6204 if (i == NumOperands)
6207 return GetWidenedVector(
N->getOperand(0));
6209 if (NumOperands == 2) {
6211 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6216 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6217 for (
unsigned i = 0; i < NumInElts; ++i) {
6219 MaskOps[i + NumInElts] = i + WidenNumElts;
6221 return DAG.getVectorShuffle(WidenVT, dl,
6222 GetWidenedVector(
N->getOperand(0)),
6223 GetWidenedVector(
N->getOperand(1)),
6230 "Cannot use build vectors to widen CONCAT_VECTOR result");
6238 for (
unsigned i=0; i < NumOperands; ++i) {
6241 InOp = GetWidenedVector(InOp);
6242 for (
unsigned j = 0;
j < NumInElts; ++
j)
6243 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6245 SDValue UndefVal = DAG.getPOISON(EltVT);
6246 for (; Idx < WidenNumElts; ++Idx)
6247 Ops[Idx] = UndefVal;
6248 return DAG.getBuildVector(WidenVT, dl,
Ops);
6251SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6252 EVT VT =
N->getValueType(0);
6253 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6254 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6261SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6262 EVT VT =
N->getValueType(0);
6264 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6269 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6271 InOp = GetWidenedVector(InOp);
6277 if (IdxVal == 0 && InVT == WidenVT)
6284 assert(IdxVal % VTNumElts == 0 &&
6285 "Expected Idx to be a multiple of subvector minimum vector length");
6286 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6299 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6300 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6301 "down type's element count");
6308 for (;
I < VTNumElts / GCD; ++
I)
6310 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6311 for (;
I < WidenNumElts / GCD; ++
I)
6319 Align Alignment = DAG.getReducedAlign(InVT,
false);
6321 MachineFunction &MF = DAG.getMachineFunction();
6333 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6340 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6341 return DAG.getMaskedLoad(
6342 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6350 for (i = 0; i < VTNumElts; ++i)
6351 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6353 SDValue UndefVal = DAG.getPOISON(EltVT);
6354 for (; i < WidenNumElts; ++i)
6356 return DAG.getBuildVector(WidenVT, dl,
Ops);
6362 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6367SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6368 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6371 N->getOperand(1),
N->getOperand(2));
6380 "Load width must be less than or equal to first value type width");
6389 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6400 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6401 EVT LdVT =
LD->getMemoryVT();
6405 "Must be scalable");
6407 "Expected equivalent element types");
6415 TypeSize WidthDiff = WidenWidth - LdWidth;
6418 std::optional<EVT> FirstVT =
6419 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6426 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6429 Chain, BasePtr,
LD->getMemOperand());
6433 FirstVTWidth, dl, DAG);
6451 if (!
LD->getMemoryVT().isByteSized()) {
6453 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6455 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6464 EVT VT =
LD->getValueType(0);
6465 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6466 EVT WideMaskVT = getSetCCResultType(WideVT);
6469 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6470 TLI.isTypeLegal(WideMaskVT)) {
6473 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6477 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6478 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6490 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6492 Result = GenWidenVectorLoads(LdChain, LD);
6499 if (LdChain.
size() == 1)
6500 NewChain = LdChain[0];
6506 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6517 SDValue NewLoad = DAG.getMaskedLoad(
6518 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6519 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6520 LD->getAddressingMode(),
LD->getExtensionType());
6530 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6532 SDValue EVL =
N->getVectorLength();
6539 "Unable to widen binary VP op");
6540 Mask = GetWidenedVector(Mask);
6541 assert(
Mask.getValueType().getVectorElementCount() ==
6542 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6543 .getVectorElementCount() &&
6544 "Unable to widen vector load");
6547 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6548 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6549 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6557 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6559 SDValue EVL =
N->getVectorLength();
6565 "Unable to widen binary VP op");
6566 Mask = GetWidenedVector(Mask);
6567 assert(
Mask.getValueType().getVectorElementCount() ==
6568 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6569 .getVectorElementCount() &&
6570 "Unable to widen vector load");
6572 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6573 Mask, EVL,
N->getMemOperand());
6586 "Unable to widen VP strided load");
6587 Mask = GetWidenedVector(Mask);
6589 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6590 assert(
Mask.getValueType().getVectorElementCount() ==
6592 "Data and mask vectors should have the same number of elements");
6594 SDValue Res = DAG.getStridedLoadVP(
6595 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6596 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6597 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6598 N->isExpandingLoad());
6606SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6611 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6613 Mask.getValueType().getVectorElementType(),
6616 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6617 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6618 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6620 WideMask, WidePassthru);
6624 EVT VT =
N->getValueType(0);
6625 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6627 EVT MaskVT =
Mask.getValueType();
6628 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6637 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6638 TLI.isTypeLegal(WideMaskVT) &&
6644 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6645 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6649 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6650 N->getMemoryVT(),
N->getMemOperand());
6654 if (!
N->getPassThru()->isUndef()) {
6658 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6659 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6660 DAG.getPOISON(WidenVT), EVL);
6671 Mask = ModifyToType(Mask, WideMaskVT,
true);
6673 SDValue Res = DAG.getMaskedLoad(
6674 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6675 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6676 ExtType,
N->isExpandingLoad());
6685 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6687 EVT MaskVT =
Mask.getValueType();
6688 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6697 Mask = ModifyToType(Mask, WideMaskVT,
true);
6702 Index.getValueType().getScalarType(),
6704 Index = ModifyToType(Index, WideIndexVT);
6710 N->getMemoryVT().getScalarType(), NumElts);
6711 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6712 WideMemVT, dl,
Ops,
N->getMemOperand(),
6713 N->getIndexType(),
N->getExtensionType());
6722 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6730 N->getMemoryVT().getScalarType(), WideEC);
6731 Mask = GetWidenedMask(Mask, WideEC);
6734 Mask,
N->getVectorLength()};
6735 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6736 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6745 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6746 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6774 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6775 return N->getOperand(OpNo).getValueType();
6783 N =
N.getOperand(0);
6785 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6786 if (!
N->getOperand(i)->isUndef())
6788 N =
N.getOperand(0);
6792 N =
N.getOperand(0);
6794 N =
N.getOperand(0);
6821 { MaskVT, MVT::Other },
Ops);
6822 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6830 LLVMContext &Ctx = *DAG.getContext();
6833 if (MaskScalarBits < ToMaskScalBits) {
6837 }
else if (MaskScalarBits > ToMaskScalBits) {
6843 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6845 "Mask should have the right element size by now.");
6848 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6850 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6853 EVT SubVT =
Mask->getValueType(0);
6859 assert((
Mask->getValueType(0) == ToMaskVT) &&
6860 "A mask of ToMaskVT should have been produced by now.");
6870 LLVMContext &Ctx = *DAG.getContext();
6881 EVT CondVT =
Cond->getValueType(0);
6885 EVT VSelVT =
N->getValueType(0);
6897 EVT FinalVT = VSelVT;
6908 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6909 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6916 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6924 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6927 EVT ToMaskVT = VSelVT;
6934 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6950 if (ScalarBits0 != ScalarBits1) {
6951 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6952 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6964 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6965 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6966 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6969 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6977 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6982 unsigned Opcode =
N->getOpcode();
6984 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6985 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6986 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6988 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6994 Cond1 = GetWidenedVector(Cond1);
7002 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7003 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7008 Cond1 = ModifyToType(Cond1, CondWidenVT);
7011 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7012 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7014 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7015 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7017 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7021 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7022 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7025 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7029 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7030 return DAG.getUNDEF(WidenVT);
7034 EVT VT =
N->getValueType(0);
7037 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7041 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7042 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7045 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7046 for (
unsigned i = 0; i != NumElts; ++i) {
7047 int Idx =
N->getMaskElt(i);
7048 if (Idx < (
int)NumElts)
7051 NewMask[i] = Idx - NumElts + WidenNumElts;
7053 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7057 EVT VT =
N->getValueType(0);
7061 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7062 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7068 unsigned IdxVal = WidenNumElts - VTNumElts;
7081 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7084 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7085 "down type's element count");
7088 for (; i < VTNumElts / GCD; ++i)
7090 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7091 for (; i < WidenNumElts / GCD; ++i)
7099 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7100 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7102 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7106SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7107 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7112 assert(
N->getValueType(0).isVector() &&
7113 N->getOperand(0).getValueType().isVector() &&
7114 "Operands must be vectors");
7115 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7128 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7129 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7136 InOp1 = GetWidenedVector(InOp1);
7137 InOp2 = GetWidenedVector(InOp2);
7140 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7151 "Input not widened to expected type!");
7153 if (
N->getOpcode() == ISD::VP_SETCC) {
7156 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7157 N->getOperand(2), Mask,
N->getOperand(4));
7159 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7164 assert(
N->getValueType(0).isVector() &&
7165 N->getOperand(1).getValueType().isVector() &&
7166 "Operands must be vectors");
7167 EVT VT =
N->getValueType(0);
7168 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7178 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7183 for (
unsigned i = 0; i != NumElts; ++i) {
7184 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7185 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7187 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7188 {Chain, LHSElem, RHSElem, CC});
7189 Chains[i] = Scalars[i].getValue(1);
7190 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7191 DAG.getBoolConstant(
true, dl, EltVT, VT),
7192 DAG.getBoolConstant(
false, dl, EltVT, VT));
7196 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7198 return DAG.getBuildVector(WidenVT, dl, Scalars);
7204bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7205 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7209 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7212 switch (
N->getOpcode()) {
7215 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7223 Res = WidenVecOp_FAKE_USE(
N);
7229 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7230 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7231 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7232 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7237 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7239 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7240 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7242 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7243 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7253 Res = WidenVecOp_UnrollVectorOp(
N);
7260 Res = WidenVecOp_EXTEND(
N);
7265 Res = WidenVecOp_CMP(
N);
7281 Res = WidenVecOp_Convert(
N);
7286 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7304 Res = WidenVecOp_VECREDUCE(
N);
7308 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7310 case ISD::VP_REDUCE_FADD:
7311 case ISD::VP_REDUCE_SEQ_FADD:
7312 case ISD::VP_REDUCE_FMUL:
7313 case ISD::VP_REDUCE_SEQ_FMUL:
7314 case ISD::VP_REDUCE_ADD:
7315 case ISD::VP_REDUCE_MUL:
7316 case ISD::VP_REDUCE_AND:
7317 case ISD::VP_REDUCE_OR:
7318 case ISD::VP_REDUCE_XOR:
7319 case ISD::VP_REDUCE_SMAX:
7320 case ISD::VP_REDUCE_SMIN:
7321 case ISD::VP_REDUCE_UMAX:
7322 case ISD::VP_REDUCE_UMIN:
7323 case ISD::VP_REDUCE_FMAX:
7324 case ISD::VP_REDUCE_FMIN:
7325 case ISD::VP_REDUCE_FMAXIMUM:
7326 case ISD::VP_REDUCE_FMINIMUM:
7327 Res = WidenVecOp_VP_REDUCE(
N);
7329 case ISD::VP_CTTZ_ELTS:
7330 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7331 Res = WidenVecOp_VP_CttzElements(
N);
7334 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7339 if (!Res.
getNode())
return false;
7347 if (
N->isStrictFPOpcode())
7349 "Invalid operand expansion");
7352 "Invalid operand expansion");
7354 ReplaceValueWith(
SDValue(
N, 0), Res);
7360 EVT VT =
N->getValueType(0);
7365 "Unexpected type action");
7366 InOp = GetWidenedVector(InOp);
7369 "Input wasn't widened!");
7377 EVT FixedEltVT = FixedVT.getVectorElementType();
7378 if (TLI.isTypeLegal(FixedVT) &&
7380 FixedEltVT == InEltVT) {
7382 "Not enough elements in the fixed type for the operand!");
7384 "We can't have the same type as we started with!");
7386 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7388 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7397 return WidenVecOp_Convert(
N);
7402 switch (
N->getOpcode()) {
7417 EVT OpVT =
N->getOperand(0).getValueType();
7418 EVT ResVT =
N->getValueType(0);
7425 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7426 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7432 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7433 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7435 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7442 return DAG.UnrollVectorOp(
N);
7447 EVT ResultVT =
N->getValueType(0);
7449 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7452 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7458 {WideArg,
Test},
N->getFlags());
7464 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7466 EVT OpVT =
N->getOperand(0).getValueType();
7469 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7474 EVT VT =
N->getValueType(0);
7480 "Unexpected type action");
7481 InOp = GetWidenedVector(InOp);
7483 unsigned Opcode =
N->getOpcode();
7489 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7491 if (
N->isStrictFPOpcode()) {
7493 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7496 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7497 {
N->getOperand(0), InOp });
7503 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7505 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7507 return DAG.getExtractSubvector(dl, VT, Res, 0);
7515 if (
N->isStrictFPOpcode()) {
7518 for (
unsigned i=0; i < NumElts; ++i) {
7519 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7520 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7524 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7526 for (
unsigned i = 0; i < NumElts; ++i)
7527 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7528 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7531 return DAG.getBuildVector(VT, dl,
Ops);
7535 EVT DstVT =
N->getValueType(0);
7536 SDValue Src = GetWidenedVector(
N->getOperand(0));
7537 EVT SrcVT = Src.getValueType();
7544 if (TLI.isTypeLegal(WideDstVT)) {
7546 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7549 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7553 return DAG.UnrollVectorOp(
N);
7557 EVT VT =
N->getValueType(0);
7558 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7566 if (!VT.
isVector() && VT != MVT::x86mmx &&
7570 if (TLI.isTypeLegal(NewVT)) {
7572 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7584 ElementCount NewNumElts =
7586 .divideCoefficientBy(EltSize);
7588 if (TLI.isTypeLegal(NewVT)) {
7590 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7595 return CreateStackStoreLoad(InOp, VT);
7603 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7604 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7609 EVT VT =
N->getValueType(0);
7611 EVT InVT =
N->getOperand(0).getValueType();
7616 unsigned NumOperands =
N->getNumOperands();
7617 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7619 for (i = 1; i < NumOperands; ++i)
7620 if (!
N->getOperand(i).isUndef())
7623 if (i == NumOperands)
7624 return GetWidenedVector(
N->getOperand(0));
7634 for (
unsigned i=0; i < NumOperands; ++i) {
7638 "Unexpected type action");
7639 InOp = GetWidenedVector(InOp);
7640 for (
unsigned j = 0;
j < NumInElts; ++
j)
7641 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7643 return DAG.getBuildVector(VT, dl,
Ops);
7646SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7647 EVT VT =
N->getValueType(0);
7652 SubVec = GetWidenedVector(SubVec);
7657 bool IndicesValid =
false;
7660 IndicesValid =
true;
7664 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7665 Attribute::VScaleRange);
7670 IndicesValid =
true;
7676 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7682 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7689 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7696 Align Alignment = DAG.getReducedAlign(VT,
false);
7698 MachineFunction &MF = DAG.getMachineFunction();
7711 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7719 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7720 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7725 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7730 unsigned Idx =
N->getConstantOperandVal(2);
7736 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7742SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7743 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7745 N->getValueType(0), InOp,
N->getOperand(1));
7748SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7749 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7751 N->getValueType(0), InOp,
N->getOperand(1));
7754SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7756 EVT ResVT =
N->getValueType(0);
7759 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
7765 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
7773 "Widened input size must be a multiple of result element size");
7776 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
7778 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
7779 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
7787 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7788 return TLI.scalarizeVectorStore(ST, DAG);
7790 if (
ST->isTruncatingStore())
7791 return TLI.scalarizeVectorStore(ST, DAG);
7801 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7802 EVT WideMaskVT = getSetCCResultType(WideVT);
7804 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7805 TLI.isTypeLegal(WideMaskVT)) {
7808 StVal = GetWidenedVector(StVal);
7810 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7812 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7813 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7814 ST->getAddressingMode());
7818 if (GenWidenVectorStores(StChain, ST)) {
7819 if (StChain.
size() == 1)
7828 SDValue WideStVal = GetWidenedVector(StVal);
7832 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7833 ST->getOffset(), Mask,
ST->getMemoryVT(),
7834 ST->getMemOperand(),
ST->getAddressingMode(),
7835 ST->isTruncatingStore());
7841SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7842 assert((OpNo == 1 || OpNo == 3) &&
7843 "Can widen only data or mask operand of vp_store");
7851 StVal = GetWidenedVector(StVal);
7857 "Unable to widen VP store");
7858 Mask = GetWidenedVector(Mask);
7860 Mask = GetWidenedVector(Mask);
7866 "Unable to widen VP store");
7867 StVal = GetWidenedVector(StVal);
7870 assert(
Mask.getValueType().getVectorElementCount() ==
7872 "Mask and data vectors should have the same number of elements");
7873 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7874 ST->getOffset(), Mask,
ST->getVectorLength(),
7875 ST->getMemoryVT(),
ST->getMemOperand(),
7876 ST->getAddressingMode(),
ST->isTruncatingStore(),
7877 ST->isCompressingStore());
7882 assert((OpNo == 1 || OpNo == 4) &&
7883 "Can widen only data or mask operand of vp_strided_store");
7892 "Unable to widen VP strided store");
7896 "Unable to widen VP strided store");
7898 StVal = GetWidenedVector(StVal);
7899 Mask = GetWidenedVector(Mask);
7902 Mask.getValueType().getVectorElementCount() &&
7903 "Data and mask vectors should have the same number of elements");
7905 return DAG.getStridedStoreVP(
7912SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7913 assert((OpNo == 1 || OpNo == 4) &&
7914 "Can widen only data or mask operand of mstore");
7917 EVT MaskVT =
Mask.getValueType();
7922 EVT WideVT, WideMaskVT;
7925 StVal = GetWidenedVector(StVal);
7932 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7939 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7940 TLI.isTypeLegal(WideMaskVT)) {
7941 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7942 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7951 Mask = ModifyToType(Mask, WideMaskVT,
true);
7954 Mask = ModifyToType(Mask, WideMaskVT,
true);
7956 StVal = ModifyToType(StVal, WideVT);
7959 assert(
Mask.getValueType().getVectorElementCount() ==
7961 "Mask and data vectors should have the same number of elements");
7968SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7969 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7971 SDValue DataOp = MG->getPassThru();
7973 SDValue Scale = MG->getScale();
7981 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7982 MG->getMemOperand(), MG->getIndexType(),
7983 MG->getExtensionType());
7989SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7998 DataOp = GetWidenedVector(DataOp);
8002 EVT IndexVT =
Index.getValueType();
8005 Index = ModifyToType(Index, WideIndexVT);
8008 EVT MaskVT =
Mask.getValueType();
8011 Mask = ModifyToType(Mask, WideMaskVT,
true);
8016 }
else if (OpNo == 4) {
8018 Index = GetWidenedVector(Index);
8024 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8029SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8038 DataOp = GetWidenedVector(DataOp);
8039 Index = GetWidenedVector(Index);
8041 Mask = GetWidenedMask(Mask, WideEC);
8044 }
else if (OpNo == 3) {
8046 Index = GetWidenedVector(Index);
8053 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8058 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8059 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8061 EVT VT =
N->getValueType(0);
8076 SVT, InOp0, InOp1,
N->getOperand(2));
8082 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8084 EVT OpVT =
N->getOperand(0).getValueType();
8087 return DAG.getNode(ExtendCode, dl, VT, CC);
8097 EVT VT =
N->getValueType(0);
8099 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8106 for (
unsigned i = 0; i != NumElts; ++i) {
8107 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8108 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8110 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8111 {Chain, LHSElem, RHSElem, CC});
8112 Chains[i] = Scalars[i].getValue(1);
8113 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8114 DAG.getBoolConstant(
true, dl, EltVT, VT),
8115 DAG.getBoolConstant(
false, dl, EltVT, VT));
8119 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8121 return DAG.getBuildVector(VT, dl, Scalars);
8145 SDValue Op = GetWidenedVector(
N->getOperand(0));
8146 EVT VT =
N->getValueType(0);
8147 EVT OrigVT =
N->getOperand(0).getValueType();
8148 EVT WideVT =
Op.getValueType();
8150 SDNodeFlags
Flags =
N->getFlags();
8152 unsigned Opc =
N->getOpcode();
8154 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8155 assert(NeutralElem &&
"Neutral element must exist");
8165 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8172 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8173 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8179 unsigned GCD = std::gcd(OrigElts, WideElts);
8182 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8183 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8184 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8185 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8188 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8189 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8191 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8200 EVT VT =
N->getValueType(0);
8202 EVT WideVT =
Op.getValueType();
8204 SDNodeFlags
Flags =
N->getFlags();
8206 unsigned Opc =
N->getOpcode();
8208 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8218 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8221 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8222 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8228 unsigned GCD = std::gcd(OrigElts, WideElts);
8231 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8232 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8233 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8234 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8237 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8238 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8240 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8244 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8247 SDValue Op = GetWidenedVector(
N->getOperand(1));
8249 Op.getValueType().getVectorElementCount());
8251 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8252 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8260 EVT VT =
N->getValueType(0);
8264 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8265 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8270 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8276 EVT SrcVT =
Source.getValueType();
8280 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8281 {Source, Mask, N->getOperand(2)},
N->getFlags());
8284SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8287 EVT OrigMaskVT =
Mask.getValueType();
8288 SDValue WideMask = GetWidenedVector(Mask);
8294 if (OrigElts != WideElts) {
8295 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8297 Mask, DAG.getVectorIdxConstant(0,
DL));
8318 unsigned WidenEx = 0) {
8323 unsigned AlignInBits =
Align*8;
8325 EVT RetVT = WidenEltVT;
8330 if (Width == WidenEltWidth)
8341 (WidenWidth % MemVTWidth) == 0 &&
8343 (MemVTWidth <= Width ||
8344 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8345 if (MemVTWidth == WidenWidth)
8364 (WidenWidth % MemVTWidth) == 0 &&
8366 (MemVTWidth <= Width ||
8367 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8376 return std::nullopt;
8387 unsigned Start,
unsigned End) {
8388 SDLoc dl(LdOps[Start]);
8389 EVT LdTy = LdOps[Start].getValueType();
8397 for (
unsigned i = Start + 1; i != End; ++i) {
8398 EVT NewLdTy = LdOps[i].getValueType();
8399 if (NewLdTy != LdTy) {
8418 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8419 EVT LdVT =
LD->getMemoryVT();
8429 AAMDNodes AAInfo =
LD->getAAInfo();
8433 TypeSize WidthDiff = WidenWidth - LdWidth;
8440 std::optional<EVT> FirstVT =
8441 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8448 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8453 std::optional<EVT> NewVT = FirstVT;
8454 TypeSize RemainingWidth = LdWidth;
8455 TypeSize NewVTWidth = FirstVTWidth;
8457 RemainingWidth -= NewVTWidth;
8464 NewVTWidth = NewVT->getSizeInBits();
8470 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8471 LD->getBaseAlign(), MMOFlags, AAInfo);
8483 uint64_t ScaledOffset = 0;
8484 MachinePointerInfo MPI =
LD->getPointerInfo();
8490 for (EVT MemVT : MemVTs) {
8491 Align NewAlign = ScaledOffset == 0
8492 ?
LD->getBaseAlign()
8495 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8503 unsigned End = LdOps.
size();
8514 EVT LdTy = LdOps[i].getValueType();
8517 for (--i; i >= 0; --i) {
8518 LdTy = LdOps[i].getValueType();
8525 ConcatOps[--Idx] = LdOps[i];
8526 for (--i; i >= 0; --i) {
8527 EVT NewLdTy = LdOps[i].getValueType();
8528 if (NewLdTy != LdTy) {
8538 for (;
j != End-Idx; ++
j)
8539 WidenOps[j] = ConcatOps[Idx+j];
8541 WidenOps[j] = DAG.getPOISON(LdTy);
8548 ConcatOps[--Idx] = LdOps[i];
8553 ArrayRef(&ConcatOps[Idx], End - Idx));
8559 SDValue UndefVal = DAG.getPOISON(LdTy);
8562 for (; i != End-Idx; ++i)
8563 WidenOps[i] = ConcatOps[Idx+i];
8565 WidenOps[i] = UndefVal;
8576 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8577 EVT LdVT =
LD->getMemoryVT();
8586 AAMDNodes AAInfo =
LD->getAAInfo();
8600 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8601 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8607 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8608 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8609 LD->getBaseAlign(), MMOFlags, AAInfo);
8614 SDValue UndefVal = DAG.getPOISON(EltVT);
8615 for (; i != WidenNumElts; ++i)
8618 return DAG.getBuildVector(WidenVT, dl,
Ops);
8629 AAMDNodes AAInfo =
ST->getAAInfo();
8630 SDValue ValOp = GetWidenedVector(
ST->getValue());
8633 EVT StVT =
ST->getMemoryVT();
8641 "Mismatch between store and value types");
8645 MachinePointerInfo MPI =
ST->getPointerInfo();
8646 uint64_t ScaledOffset = 0;
8655 std::optional<EVT> NewVT =
8660 TypeSize NewVTWidth = NewVT->getSizeInBits();
8663 StWidth -= NewVTWidth;
8664 MemVTs.
back().second++;
8668 for (
const auto &Pair : MemVTs) {
8669 EVT NewVT = Pair.first;
8670 unsigned Count = Pair.second;
8676 Align NewAlign = ScaledOffset == 0
8677 ?
ST->getBaseAlign()
8679 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8680 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8696 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8697 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8698 ST->getBaseAlign(), MMOFlags, AAInfo);
8715 bool FillWithZeroes) {
8720 "input and widen element type must match");
8722 "cannot modify scalable vectors in this way");
8735 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
8737 for (
unsigned i = 1; i != NumConcat; ++i)
8744 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8747 "Scalable vectors should have been handled already.");
8755 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8757 for (Idx = 0; Idx < MinNumElts; ++Idx)
8758 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8760 SDValue UndefVal = DAG.getPOISON(EltVT);
8761 for (; Idx < WidenNumElts; ++Idx)
8762 Ops[Idx] = UndefVal;
8764 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8765 if (!FillWithZeroes)
8769 "We expect to never want to FillWithZeroes for non-integral types.");
8772 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8773 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8775 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8776 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...
@ 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.