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);
891 if (!Res.
getNode())
return false;
899 "Invalid operand expansion");
901 ReplaceValueWith(
SDValue(
N, 0), Res);
908 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
910 N->getValueType(0), Elt);
915 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
916 "Fake Use: Unexpected vector type!");
917 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
918 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
924 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
925 "Unexpected vector type!");
926 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
928 N->getValueType(0).getScalarType(), Elt);
936SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
937 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
938 "Unexpected vector type!");
939 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
941 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
942 Elt,
N->getOperand(1));
950SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
951 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
952 "Unexpected vector type!");
953 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
955 {
N->getValueType(0).getScalarType(), MVT::Other },
956 {
N->getOperand(0), Elt });
966 ReplaceValueWith(
SDValue(
N, 0), Res);
971SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
973 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
974 Ops[i] = GetScalarizedVector(
N->getOperand(i));
975 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
980SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
984 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
985 SDValue ContainingVec =
N->getOperand(0);
993SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
994 EVT VT =
N->getValueType(0);
995 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1007 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1008 EVT VT =
N->getValueType(0);
1010 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1018 assert(
N->getValueType(0).isVector() &&
1019 N->getOperand(0).getValueType().isVector() &&
1020 "Operand types must be vectors");
1021 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1023 EVT VT =
N->getValueType(0);
1024 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1025 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1027 EVT OpVT =
N->getOperand(0).getValueType();
1039 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1045SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1047 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1048 assert(
N->getValueType(0).isVector() &&
1049 N->getOperand(1).getValueType().isVector() &&
1050 "Operand types must be vectors");
1051 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1053 EVT VT =
N->getValueType(0);
1055 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1056 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1059 EVT OpVT =
N->getOperand(1).getValueType();
1063 {Ch, LHS, RHS, CC});
1072 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1077 ReplaceValueWith(
SDValue(
N, 0), Res);
1084 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1085 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1088 if (
N->isTruncatingStore())
1089 return DAG.getTruncStore(
1090 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1091 N->getBasePtr(),
N->getPointerInfo(),
1092 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1093 N->getMemOperand()->getFlags(),
N->getAAInfo());
1095 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1096 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1097 N->getMemOperand()->getFlags(),
N->getAAInfo());
1102SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1103 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1104 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1106 N->getValueType(0).getVectorElementType(), Elt,
1111SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1113 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1114 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1117 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1127 ReplaceValueWith(
SDValue(
N, 0), Res);
1134 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1136 N->getValueType(0).getVectorElementType(), Elt);
1142SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1143 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1146 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1147 {
N->getOperand(0), Elt});
1156 ReplaceValueWith(
SDValue(
N, 0), Res);
1161 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1168SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1174 SDValue Op = GetScalarizedVector(VecOp);
1175 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1176 AccOp,
Op,
N->getFlags());
1180 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1181 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1196void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1201 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1204 switch (
N->getOpcode()) {
1207 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1216 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1223 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1239 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1242 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1251 case ISD::VP_LOAD_FF:
1254 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1261 case ISD::VP_GATHER:
1265 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1269 SplitVecRes_SETCC(
N,
Lo,
Hi);
1272 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1279 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1282 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1285 SplitVecRes_VECTOR_INTERLEAVE(
N);
1288 SplitVecRes_VAARG(
N,
Lo,
Hi);
1294 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1300 case ISD::VP_BITREVERSE:
1308 case ISD::VP_CTLZ_ZERO_UNDEF:
1310 case ISD::VP_CTTZ_ZERO_UNDEF:
1325 case ISD::VP_FFLOOR:
1330 case ISD::VP_FNEARBYINT:
1335 case ISD::VP_FP_EXTEND:
1337 case ISD::VP_FP_ROUND:
1339 case ISD::VP_FP_TO_SINT:
1341 case ISD::VP_FP_TO_UINT:
1347 case ISD::VP_LLRINT:
1349 case ISD::VP_FROUND:
1351 case ISD::VP_FROUNDEVEN:
1360 case ISD::VP_FROUNDTOZERO:
1362 case ISD::VP_SINT_TO_FP:
1364 case ISD::VP_TRUNCATE:
1366 case ISD::VP_UINT_TO_FP:
1369 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1372 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1378 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1384 case ISD::VP_SIGN_EXTEND:
1385 case ISD::VP_ZERO_EXTEND:
1386 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1408 case ISD::VP_FMINNUM:
1411 case ISD::VP_FMAXNUM:
1413 case ISD::VP_FMINIMUM:
1415 case ISD::VP_FMAXIMUM:
1424 case ISD::OR:
case ISD::VP_OR:
1444 case ISD::VP_FCOPYSIGN:
1445 SplitVecRes_BinOp(
N,
Lo,
Hi);
1452 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1456 SplitVecRes_CMP(
N,
Lo,
Hi);
1459#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1460 case ISD::STRICT_##DAGN:
1461#include "llvm/IR/ConstrainedOps.def"
1462 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1467 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1476 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1486 SplitVecRes_FIX(
N,
Lo,
Hi);
1488 case ISD::EXPERIMENTAL_VP_SPLICE:
1489 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1491 case ISD::EXPERIMENTAL_VP_REVERSE:
1492 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1498 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1501 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1510void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1512 uint64_t *ScaledOffset) {
1517 SDValue BytesIncrement = DAG.getVScale(
1520 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1522 *ScaledOffset += IncrementSize;
1532std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1533 return SplitMask(Mask, SDLoc(Mask));
1536std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1539 EVT MaskVT =
Mask.getValueType();
1541 GetSplitVector(Mask, MaskLo, MaskHi);
1543 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1544 return std::make_pair(MaskLo, MaskHi);
1549 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1551 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1554 const SDNodeFlags
Flags =
N->getFlags();
1555 unsigned Opcode =
N->getOpcode();
1556 if (
N->getNumOperands() == 2) {
1557 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1558 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1562 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1563 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1566 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1569 std::tie(EVLLo, EVLHi) =
1570 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1573 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1575 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1581 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1583 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1585 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1588 const SDNodeFlags
Flags =
N->getFlags();
1589 unsigned Opcode =
N->getOpcode();
1590 if (
N->getNumOperands() == 3) {
1591 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1592 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1596 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1597 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1600 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1603 std::tie(EVLLo, EVLHi) =
1604 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1607 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1609 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1613 LLVMContext &Ctxt = *DAG.getContext();
1619 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1621 GetSplitVector(
LHS, LHSLo, LHSHi);
1622 GetSplitVector(
RHS, RHSLo, RHSHi);
1624 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1625 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1629 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1630 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1635 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1637 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1641 unsigned Opcode =
N->getOpcode();
1642 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1644 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1653 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1660 switch (getTypeAction(InVT)) {
1675 GetExpandedOp(InOp,
Lo,
Hi);
1676 if (DAG.getDataLayout().isBigEndian())
1686 GetSplitVector(InOp,
Lo,
Hi);
1695 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1704 if (DAG.getDataLayout().isBigEndian())
1707 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1709 if (DAG.getDataLayout().isBigEndian())
1715void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1721 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1724 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1729 unsigned LaneOffset =
1732 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1734 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1741 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1744 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1747 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1752 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1754 unsigned NumSubvectors =
N->getNumOperands() / 2;
1755 if (NumSubvectors == 1) {
1756 Lo =
N->getOperand(0);
1757 Hi =
N->getOperand(1);
1762 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1771void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1778 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1793 GetSplitVector(Vec,
Lo,
Hi);
1796 EVT LoVT =
Lo.getValueType();
1806 if (IdxVal + SubElems <= LoElems) {
1814 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1816 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1822 SDValue WideSubVec = GetWidenedVector(SubVec);
1824 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1832 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1834 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1835 auto &MF = DAG.getMachineFunction();
1839 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1844 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1845 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1849 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1854 MachinePointerInfo MPI =
Load->getPointerInfo();
1855 IncrementPointer(Load, LoVT, MPI, StackPtr);
1858 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1867 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1872 EVT RHSVT =
RHS.getValueType();
1875 GetSplitVector(
RHS, RHSLo, RHSHi);
1877 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1892 SDValue FpValue =
N->getOperand(0);
1894 GetSplitVector(FpValue, ArgLo, ArgHi);
1896 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1898 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1907 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1911 std::tie(LoVT, HiVT) =
1915 DAG.getValueType(LoVT));
1917 DAG.getValueType(HiVT));
1922 unsigned Opcode =
N->getOpcode();
1929 GetSplitVector(N0, InLo, InHi);
1931 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1936 EVT OutLoVT, OutHiVT;
1937 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1939 assert((2 * OutNumElements) <= InNumElements &&
1940 "Illegal extend vector in reg split");
1949 SmallVector<int, 8> SplitHi(InNumElements, -1);
1950 for (
unsigned i = 0; i != OutNumElements; ++i)
1951 SplitHi[i] = i + OutNumElements;
1952 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1954 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1955 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1960 unsigned NumOps =
N->getNumOperands();
1964 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1974 for (
unsigned i = 1; i <
NumOps; ++i) {
1979 EVT InVT =
Op.getValueType();
1984 GetSplitVector(
Op, OpLo, OpHi);
1986 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
1993 EVT LoValueVTs[] = {LoVT, MVT::Other};
1994 EVT HiValueVTs[] = {HiVT, MVT::Other};
1995 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1997 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2003 Lo.getValue(1),
Hi.getValue(1));
2007 ReplaceValueWith(
SDValue(
N, 1), Chain);
2010SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2012 EVT VT =
N->getValueType(0);
2023 else if (NE > ResNE)
2027 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2031 for (i = 0; i !=
NE; ++i) {
2032 Operands[0] = Chain;
2033 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2034 SDValue Operand =
N->getOperand(j);
2038 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2040 Operands[
j] = Operand;
2044 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2052 for (; i < ResNE; ++i)
2057 ReplaceValueWith(
SDValue(
N, 1), Chain);
2061 return DAG.getBuildVector(VecVT, dl, Scalars);
2064void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2067 EVT ResVT =
N->getValueType(0);
2068 EVT OvVT =
N->getValueType(1);
2069 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2070 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2071 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2073 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2075 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2076 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2078 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2079 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2082 unsigned Opcode =
N->getOpcode();
2083 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2084 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2086 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2088 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2094 unsigned OtherNo = 1 - ResNo;
2095 EVT OtherVT =
N->getValueType(OtherNo);
2097 SetSplitVector(
SDValue(
N, OtherNo),
2103 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2107void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2113 GetSplitVector(Vec,
Lo,
Hi);
2116 unsigned IdxVal = CIdx->getZExtValue();
2117 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2118 if (IdxVal < LoNumElts) {
2120 Lo.getValueType(),
Lo, Elt, Idx);
2123 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2143 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2145 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2146 auto &MF = DAG.getMachineFunction();
2150 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2155 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2156 Store = DAG.getTruncStore(
2162 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2165 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2169 MachinePointerInfo MPI =
Load->getPointerInfo();
2170 IncrementPointer(Load, LoVT, MPI, StackPtr);
2172 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2175 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2176 if (LoVT !=
Lo.getValueType())
2178 if (HiVT !=
Hi.getValueType())
2186 assert(
N->getValueType(0).isScalableVector() &&
2187 "Only scalable vectors are supported for STEP_VECTOR");
2188 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2209 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2210 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2212 Hi = DAG.getPOISON(HiVT);
2224 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2230 EVT MemoryVT =
LD->getMemoryVT();
2232 AAMDNodes AAInfo =
LD->getAAInfo();
2234 EVT LoMemVT, HiMemVT;
2235 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2239 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2240 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2241 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2246 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2249 MachinePointerInfo MPI;
2250 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2253 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2262 ReplaceValueWith(
SDValue(LD, 1), Ch);
2267 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2270 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2276 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2277 Align Alignment =
LD->getBaseAlign();
2280 EVT MemoryVT =
LD->getMemoryVT();
2282 EVT LoMemVT, HiMemVT;
2283 bool HiIsEmpty =
false;
2284 std::tie(LoMemVT, HiMemVT) =
2285 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2290 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2293 GetSplitVector(Mask, MaskLo, MaskHi);
2295 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2300 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2302 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2308 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2309 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2317 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2318 LD->isExpandingLoad());
2320 MachinePointerInfo MPI;
2322 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2324 MPI =
LD->getPointerInfo().getWithOffset(
2327 MMO = DAG.getMachineFunction().getMachineMemOperand(
2329 Alignment,
LD->getAAInfo(),
LD->getRanges());
2331 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2332 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2333 LD->isExpandingLoad());
2343 ReplaceValueWith(
SDValue(LD, 1), Ch);
2349 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2353 Align Alignment =
LD->getBaseAlign();
2360 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2363 GetSplitVector(Mask, MaskLo, MaskHi);
2365 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2369 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2371 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2376 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2379 Hi = DAG.getPOISON(HiVT);
2381 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2382 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2388 "Indexed VP strided load during type legalization!");
2390 "Unexpected indexed variable-length load offset");
2395 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2397 EVT LoMemVT, HiMemVT;
2398 bool HiIsEmpty =
false;
2399 std::tie(LoMemVT, HiMemVT) =
2400 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2405 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2408 GetSplitVector(Mask, LoMask, HiMask);
2410 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2414 std::tie(LoEVL, HiEVL) =
2418 Lo = DAG.getStridedLoadVP(
2445 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2452 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2463 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2471 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2476 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2486 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2489 GetSplitVector(Mask, MaskLo, MaskHi);
2491 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2495 EVT LoMemVT, HiMemVT;
2496 bool HiIsEmpty =
false;
2497 std::tie(LoMemVT, HiMemVT) =
2498 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2500 SDValue PassThruLo, PassThruHi;
2502 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2504 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2506 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2510 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2520 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2523 MachinePointerInfo MPI;
2530 MMO = DAG.getMachineFunction().getMachineMemOperand(
2534 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2546 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2554 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2562 }
Ops = [&]() -> Operands {
2564 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2567 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2570 EVT MemoryVT =
N->getMemoryVT();
2571 Align Alignment =
N->getBaseAlign();
2576 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2578 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2581 EVT LoMemVT, HiMemVT;
2583 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2586 if (getTypeAction(
Ops.Index.getValueType()) ==
2588 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2590 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2593 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2595 Alignment,
N->getAAInfo(),
N->getRanges());
2598 SDValue PassThru = MGT->getPassThru();
2599 SDValue PassThruLo, PassThruHi;
2602 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2604 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2609 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2610 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2611 OpsLo, MMO, IndexTy, ExtType);
2613 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2614 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2615 OpsHi, MMO, IndexTy, ExtType);
2619 std::tie(EVLLo, EVLHi) =
2620 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2622 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2623 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2624 MMO, VPGT->getIndexType());
2626 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2627 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2628 MMO, VPGT->getIndexType());
2638 ReplaceValueWith(
SDValue(
N, 1), Ch);
2652 EVT VecVT =
N->getValueType(0);
2654 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2655 bool HasCustomLowering =
false;
2662 HasCustomLowering =
true;
2668 SDValue Passthru =
N->getOperand(2);
2669 if (!HasCustomLowering) {
2670 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2671 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2678 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2679 std::tie(LoMask, HiMask) = SplitMask(Mask);
2681 SDValue UndefPassthru = DAG.getUNDEF(LoVT);
2686 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2687 MachineFunction &MF = DAG.getMachineFunction();
2699 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2701 SDValue Chain = DAG.getEntryNode();
2702 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2706 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2711 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2715 assert(
N->getValueType(0).isVector() &&
2716 N->getOperand(0).getValueType().isVector() &&
2717 "Operand types must be vectors");
2721 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2725 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2727 GetSplitVector(
N->getOperand(0), LL, LH);
2729 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2731 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2733 GetSplitVector(
N->getOperand(1), RL, RH);
2735 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2738 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2739 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2741 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2742 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2743 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2744 std::tie(EVLLo, EVLHi) =
2745 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2746 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2748 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2758 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2762 EVT InVT =
N->getOperand(0).getValueType();
2764 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2766 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2768 const SDNodeFlags
Flags =
N->getFlags();
2769 unsigned Opcode =
N->getOpcode();
2770 if (
N->getNumOperands() <= 2) {
2772 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2773 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2775 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2776 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2781 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2782 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2785 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2788 std::tie(EVLLo, EVLHi) =
2789 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2792 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2798 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2802 EVT InVT =
N->getOperand(0).getValueType();
2804 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2806 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2809 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2810 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2811 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2812 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2815void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2820 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2821 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2825 EVT InVT =
N->getOperand(0).getValueType();
2827 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2829 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2831 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2832 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2834 SDNode *HiNode =
Hi.getNode();
2835 SDNode *LoNode =
Lo.getNode();
2838 unsigned OtherNo = 1 - ResNo;
2839 EVT OtherVT =
N->getValueType(OtherNo);
2847 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2854 EVT SrcVT =
N->getOperand(0).getValueType();
2855 EVT DestVT =
N->getValueType(0);
2857 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2874 LLVMContext &Ctx = *DAG.getContext();
2878 EVT SplitLoVT, SplitHiVT;
2879 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2880 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2881 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2882 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2883 N->dump(&DAG);
dbgs() <<
"\n");
2884 if (!
N->isVPOpcode()) {
2887 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2889 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2891 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2892 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2898 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2899 N->getOperand(1),
N->getOperand(2));
2901 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2904 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2907 std::tie(EVLLo, EVLHi) =
2908 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2910 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2911 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2916 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2924 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2925 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2931 return N.getResNo() == 0 &&
2935 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2937 ArrayRef<int>
Mask) {
2940 "Expected build vector node.");
2943 for (
unsigned I = 0;
I < NewElts; ++
I) {
2946 unsigned Idx =
Mask[
I];
2948 Ops[
I] = Input2.getOperand(Idx - NewElts);
2950 Ops[
I] = Input1.getOperand(Idx);
2955 return DAG.getBuildVector(NewVT,
DL,
Ops);
2961 SmallVector<int> OrigMask(
N->getMask());
2963 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2964 &
DL](SmallVectorImpl<int> &
Mask) {
2966 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2967 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2978 for (
auto &
P : ShufflesIdxs) {
2979 if (
P.second.size() < 2)
2983 for (
int &Idx : Mask) {
2986 unsigned SrcRegIdx = Idx / NewElts;
2987 if (Inputs[SrcRegIdx].
isUndef()) {
2995 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3000 Idx = MaskElt % NewElts +
3001 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3007 Inputs[
P.second[0]] =
P.first.first;
3008 Inputs[
P.second[1]] =
P.first.second;
3011 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3014 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3015 for (
int &Idx : Mask) {
3018 unsigned SrcRegIdx = Idx / NewElts;
3019 if (Inputs[SrcRegIdx].
isUndef()) {
3026 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3027 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3030 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3032 if (UsedSubVector.count() > 1) {
3034 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3035 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3037 if (Pairs.
empty() || Pairs.
back().size() == 2)
3039 if (UsedSubVector.test(2 *
I)) {
3040 Pairs.
back().emplace_back(
I, 0);
3042 assert(UsedSubVector.test(2 *
I + 1) &&
3043 "Expected to be used one of the subvectors.");
3044 Pairs.
back().emplace_back(
I, 1);
3047 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3049 for (
int &Idx : Mask) {
3052 unsigned SrcRegIdx = Idx / NewElts;
3054 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3055 return Idxs.front().first == SrcRegIdx ||
3056 Idxs.back().first == SrcRegIdx;
3058 if (It == Pairs.
end())
3060 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3061 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3064 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3065 Inputs[Idxs.front().first] = DAG.
getNode(
3067 Inputs[Idxs.front().first].getValueType(),
3068 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3069 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3078 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3082 if (Shuffle->getOperand(0).getValueType() != NewVT)
3085 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3086 !Shuffle->isSplat()) {
3088 }
else if (!Inputs[
I].hasOneUse() &&
3089 !Shuffle->getOperand(1).isUndef()) {
3091 for (
int &Idx : Mask) {
3094 unsigned SrcRegIdx = Idx / NewElts;
3097 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3102 int OpIdx = MaskElt / NewElts;
3116 if (Shuffle->getOperand(
OpIdx).isUndef())
3118 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3119 if (It == std::end(Inputs))
3121 int FoundOp = std::distance(std::begin(Inputs), It);
3124 for (
int &Idx : Mask) {
3127 unsigned SrcRegIdx = Idx / NewElts;
3130 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3135 int MaskIdx = MaskElt / NewElts;
3136 if (
OpIdx == MaskIdx)
3137 Idx = MaskElt % NewElts + FoundOp * NewElts;
3148 for (
int &Idx : Mask) {
3151 unsigned SrcRegIdx = Idx / NewElts;
3154 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3155 int OpIdx = MaskElt / NewElts;
3158 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3164 TryPeekThroughShufflesInputs(OrigMask);
3166 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3167 NewElts](SmallVectorImpl<int> &
Mask) {
3168 SetVector<SDValue> UniqueInputs;
3169 SetVector<SDValue> UniqueConstantInputs;
3170 for (
const auto &
I : Inputs) {
3172 UniqueConstantInputs.
insert(
I);
3173 else if (!
I.isUndef())
3178 if (UniqueInputs.
size() != std::size(Inputs)) {
3179 auto &&UniqueVec = UniqueInputs.
takeVector();
3180 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3181 unsigned ConstNum = UniqueConstantVec.size();
3182 for (
int &Idx : Mask) {
3185 unsigned SrcRegIdx = Idx / NewElts;
3186 if (Inputs[SrcRegIdx].
isUndef()) {
3190 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3191 if (It != UniqueConstantVec.end()) {
3192 Idx = (Idx % NewElts) +
3193 NewElts * std::distance(UniqueConstantVec.begin(), It);
3194 assert(Idx >= 0 &&
"Expected defined mask idx.");
3197 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3198 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3199 Idx = (Idx % NewElts) +
3200 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3201 assert(Idx >= 0 &&
"Expected defined mask idx.");
3203 copy(UniqueConstantVec, std::begin(Inputs));
3204 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3207 MakeUniqueInputs(OrigMask);
3209 copy(Inputs, std::begin(OrigInputs));
3215 unsigned FirstMaskIdx =
High * NewElts;
3218 assert(!Output &&
"Expected default initialized initial value.");
3219 TryPeekThroughShufflesInputs(Mask);
3220 MakeUniqueInputs(Mask);
3222 copy(Inputs, std::begin(TmpInputs));
3225 bool SecondIteration =
false;
3226 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3231 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3232 SecondIteration =
true;
3233 return SecondIteration;
3236 Mask, std::size(Inputs), std::size(Inputs),
3238 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3239 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3240 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3242 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3244 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3245 DAG.getUNDEF(NewVT), Mask);
3246 Inputs[Idx] = Output;
3248 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3249 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3250 unsigned Idx2,
bool ) {
3251 if (AccumulateResults(Idx1)) {
3254 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3256 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3257 Inputs[Idx2], Mask);
3261 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3263 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3264 TmpInputs[Idx2], Mask);
3266 Inputs[Idx1] = Output;
3268 copy(OrigInputs, std::begin(Inputs));
3273 EVT OVT =
N->getValueType(0);
3280 const Align Alignment =
3281 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3283 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3284 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3289 ReplaceValueWith(
SDValue(
N, 1), Chain);
3294 EVT DstVTLo, DstVTHi;
3295 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3299 EVT SrcVT =
N->getOperand(0).getValueType();
3301 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3303 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3305 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3306 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3312 GetSplitVector(
N->getOperand(0), InLo, InHi);
3323 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3324 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3329 EVT VT =
N->getValueType(0);
3336 Align Alignment = DAG.getReducedAlign(VT,
false);
3341 EVT PtrVT =
StackPtr.getValueType();
3342 auto &MF = DAG.getMachineFunction();
3346 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3349 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3355 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3356 DAG.getConstant(1,
DL, PtrVT));
3358 DAG.getConstant(EltWidth,
DL, PtrVT));
3360 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3362 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3363 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3364 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3367 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3369 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3374 EVT VT =
N->getValueType(0);
3386 EVL1 = ZExtPromotedInteger(EVL1);
3388 Align Alignment = DAG.getReducedAlign(VT,
false);
3393 EVT PtrVT =
StackPtr.getValueType();
3394 auto &MF = DAG.getMachineFunction();
3398 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3401 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3405 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3407 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3408 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3409 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3413 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3418 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3419 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3421 uint64_t TrailingElts = -
Imm;
3423 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3432 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3436 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3438 DAG.getVectorIdxConstant(0,
DL));
3444void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3452 GetSplitVector(Acc, AccLo, AccHi);
3453 unsigned Opcode =
N->getOpcode();
3465 GetSplitVector(Input1, Input1Lo, Input1Hi);
3466 GetSplitVector(Input2, Input2Lo, Input2Hi);
3469 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3470 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3473void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3481 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3489void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3490 unsigned Factor =
N->getNumOperands();
3493 for (
unsigned i = 0; i != Factor; ++i) {
3495 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3497 Ops[i * 2 + 1] = OpHi;
3508 for (
unsigned i = 0; i != Factor; ++i)
3512void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3513 unsigned Factor =
N->getNumOperands();
3516 for (
unsigned i = 0; i != Factor; ++i) {
3518 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3520 Ops[i + Factor] = OpHi;
3531 for (
unsigned i = 0; i != Factor; ++i) {
3532 unsigned IdxLo = 2 * i;
3533 unsigned IdxHi = 2 * i + 1;
3534 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3535 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3547bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3552 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3555 switch (
N->getOpcode()) {
3558 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3568 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3574 case ISD::VP_TRUNCATE:
3576 Res = SplitVecOp_TruncateHelper(
N);
3579 case ISD::VP_FP_ROUND:
3588 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3595 case ISD::VP_SCATTER:
3599 case ISD::VP_GATHER:
3603 Res = SplitVecOp_VSELECT(
N, OpNo);
3606 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3612 case ISD::VP_SINT_TO_FP:
3613 case ISD::VP_UINT_TO_FP:
3614 if (
N->getValueType(0).bitsLT(
3615 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3616 Res = SplitVecOp_TruncateHelper(
N);
3618 Res = SplitVecOp_UnaryOp(
N);
3622 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3626 case ISD::VP_FP_TO_SINT:
3627 case ISD::VP_FP_TO_UINT:
3640 Res = SplitVecOp_UnaryOp(
N);
3643 Res = SplitVecOp_FPOpDifferentTypes(
N);
3648 Res = SplitVecOp_CMP(
N);
3652 Res = SplitVecOp_FAKE_USE(
N);
3657 Res = SplitVecOp_ExtVecInRegOp(
N);
3675 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3679 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3681 case ISD::VP_REDUCE_FADD:
3682 case ISD::VP_REDUCE_SEQ_FADD:
3683 case ISD::VP_REDUCE_FMUL:
3684 case ISD::VP_REDUCE_SEQ_FMUL:
3685 case ISD::VP_REDUCE_ADD:
3686 case ISD::VP_REDUCE_MUL:
3687 case ISD::VP_REDUCE_AND:
3688 case ISD::VP_REDUCE_OR:
3689 case ISD::VP_REDUCE_XOR:
3690 case ISD::VP_REDUCE_SMAX:
3691 case ISD::VP_REDUCE_SMIN:
3692 case ISD::VP_REDUCE_UMAX:
3693 case ISD::VP_REDUCE_UMIN:
3694 case ISD::VP_REDUCE_FMAX:
3695 case ISD::VP_REDUCE_FMIN:
3696 case ISD::VP_REDUCE_FMAXIMUM:
3697 case ISD::VP_REDUCE_FMINIMUM:
3698 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3700 case ISD::VP_CTTZ_ELTS:
3701 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3702 Res = SplitVecOp_VP_CttzElements(
N);
3705 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3711 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3716 if (!Res.
getNode())
return false;
3723 if (
N->isStrictFPOpcode())
3725 "Invalid operand expansion");
3728 "Invalid operand expansion");
3730 ReplaceValueWith(
SDValue(
N, 0), Res);
3734SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3737 assert(OpNo == 0 &&
"Illegal operand must be mask");
3744 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3747 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3748 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3749 "Lo and Hi have differing types");
3752 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3753 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3755 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3756 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3757 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3758 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3768SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3771 assert(OpNo == 1 &&
"Illegal operand must be mask");
3776 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3778 EVT VecVT =
N->getValueType(0);
3782SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3783 EVT ResVT =
N->getValueType(0);
3789 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3790 GetSplitVector(VecOp,
Lo,
Hi);
3792 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3797 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3798 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3802 EVT ResVT =
N->getValueType(0);
3808 SDNodeFlags
Flags =
N->getFlags();
3811 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3812 GetSplitVector(VecOp,
Lo,
Hi);
3814 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3820 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3823SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3824 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3825 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3827 unsigned Opc =
N->getOpcode();
3828 EVT ResVT =
N->getValueType(0);
3834 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3835 GetSplitVector(VecOp,
Lo,
Hi);
3838 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3841 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3843 const SDNodeFlags
Flags =
N->getFlags();
3847 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3852 EVT ResVT =
N->getValueType(0);
3855 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3856 EVT InVT =
Lo.getValueType();
3861 if (
N->isStrictFPOpcode()) {
3862 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3863 {N->getOperand(0), Lo});
3864 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3865 {N->getOperand(0), Hi});
3874 ReplaceValueWith(
SDValue(
N, 1), Ch);
3875 }
else if (
N->getNumOperands() == 3) {
3876 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3877 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3878 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3879 std::tie(EVLLo, EVLHi) =
3880 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3881 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3882 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3884 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3885 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3894 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3904 EVT ResVT =
N->getValueType(0);
3906 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3910 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3916 Lo = BitConvertToInteger(
Lo);
3917 Hi = BitConvertToInteger(
Hi);
3919 if (DAG.getDataLayout().isBigEndian())
3927 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3929 EVT ResVT =
N->getValueType(0);
3937 GetSplitVector(SubVec,
Lo,
Hi);
3946 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3948 return SecondInsertion;
3951SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3958 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3960 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
3962 ElementCount IdxVal =
3966 EVT SrcVT =
N->getOperand(0).getValueType();
3985 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
3986 LoEltsMin - IdxValMin);
3987 DAG.ExtractVectorElements(
Hi, Elts, 0,
3990 return DAG.getBuildVector(SubVT, dl, Elts);
3994 ElementCount ExtractIdx = IdxVal - LoElts;
3996 return DAG.getExtractSubvector(dl, SubVT,
Hi,
3999 EVT HiVT =
Hi.getValueType();
4001 "Only fixed-vector extracts are supported in this case");
4011 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4012 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4018 "Extracting scalable subvector from fixed-width unsupported");
4026 "subvector from a scalable predicate vector");
4032 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4034 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4035 auto &MF = DAG.getMachineFunction();
4039 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4043 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4046 SubVT, dl, Store, StackPtr,
4050SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4056 uint64_t IdxVal =
Index->getZExtValue();
4059 GetSplitVector(Vec,
Lo,
Hi);
4061 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4063 if (IdxVal < LoElts)
4064 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4067 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4072 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4084 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4090 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4092 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4093 auto &MF = DAG.getMachineFunction();
4096 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4100 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4104 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4106 return DAG.getExtLoad(
4117 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4125 SplitVecRes_Gather(
N,
Lo,
Hi);
4128 ReplaceValueWith(
SDValue(
N, 0), Res);
4133 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4137 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4139 SDValue EVL =
N->getVectorLength();
4141 Align Alignment =
N->getBaseAlign();
4147 GetSplitVector(
Data, DataLo, DataHi);
4149 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4154 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4157 GetSplitVector(Mask, MaskLo, MaskHi);
4159 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4162 EVT MemoryVT =
N->getMemoryVT();
4163 EVT LoMemVT, HiMemVT;
4164 bool HiIsEmpty =
false;
4165 std::tie(LoMemVT, HiMemVT) =
4166 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4170 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4173 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4178 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4179 N->getAddressingMode(),
N->isTruncatingStore(),
4180 N->isCompressingStore());
4186 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4187 N->isCompressingStore());
4189 MachinePointerInfo MPI;
4193 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4198 MMO = DAG.getMachineFunction().getMachineMemOperand(
4200 Alignment,
N->getAAInfo(),
N->getRanges());
4202 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4203 N->getAddressingMode(),
N->isTruncatingStore(),
4204 N->isCompressingStore());
4213 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4214 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4221 GetSplitVector(
Data, LoData, HiData);
4223 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4225 EVT LoMemVT, HiMemVT;
4226 bool HiIsEmpty =
false;
4227 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4233 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4234 else if (getTypeAction(
Mask.getValueType()) ==
4236 GetSplitVector(Mask, LoMask, HiMask);
4238 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4241 std::tie(LoEVL, HiEVL) =
4242 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4246 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4247 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4248 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4259 EVT PtrVT =
N->getBasePtr().getValueType();
4262 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4265 Align Alignment =
N->getBaseAlign();
4270 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4271 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4273 Alignment,
N->getAAInfo(),
N->getRanges());
4276 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4277 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4278 N->isCompressingStore());
4287 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4291 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4294 Align Alignment =
N->getBaseAlign();
4300 GetSplitVector(
Data, DataLo, DataHi);
4302 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4307 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4310 GetSplitVector(Mask, MaskLo, MaskHi);
4312 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4315 EVT MemoryVT =
N->getMemoryVT();
4316 EVT LoMemVT, HiMemVT;
4317 bool HiIsEmpty =
false;
4318 std::tie(LoMemVT, HiMemVT) =
4319 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4322 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4327 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4328 N->getAddressingMode(),
N->isTruncatingStore(),
4329 N->isCompressingStore());
4337 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4338 N->isCompressingStore());
4340 MachinePointerInfo MPI;
4344 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4349 MMO = DAG.getMachineFunction().getMachineMemOperand(
4351 Alignment,
N->getAAInfo(),
N->getRanges());
4353 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4354 N->getAddressingMode(),
N->isTruncatingStore(),
4355 N->isCompressingStore());
4368 EVT MemoryVT =
N->getMemoryVT();
4369 Align Alignment =
N->getBaseAlign();
4376 }
Ops = [&]() -> Operands {
4378 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4382 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4387 EVT LoMemVT, HiMemVT;
4388 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4393 GetSplitVector(
Ops.Data, DataLo, DataHi);
4395 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4400 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4402 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4406 if (getTypeAction(
Ops.Index.getValueType()) ==
4408 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4410 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4414 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4416 Alignment,
N->getAAInfo(),
N->getRanges());
4419 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4421 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4422 MSC->getIndexType(), MSC->isTruncatingStore());
4427 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4428 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4429 MMO, MSC->getIndexType(),
4430 MSC->isTruncatingStore());
4434 std::tie(EVLLo, EVLHi) =
4435 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4437 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4438 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4439 VPSC->getIndexType());
4444 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4445 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4446 VPSC->getIndexType());
4450 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4451 assert(OpNo == 1 &&
"Can only split the stored value");
4454 bool isTruncating =
N->isTruncatingStore();
4457 EVT MemoryVT =
N->getMemoryVT();
4458 Align Alignment =
N->getBaseAlign();
4460 AAMDNodes AAInfo =
N->getAAInfo();
4462 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4464 EVT LoMemVT, HiMemVT;
4465 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4469 return TLI.scalarizeVectorStore(
N, DAG);
4472 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4473 Alignment, MMOFlags, AAInfo);
4475 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4478 MachinePointerInfo MPI;
4479 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4482 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4483 HiMemVT, Alignment, MMOFlags, AAInfo);
4485 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4501 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4507 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4528 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4529 SDValue InVec =
N->getOperand(OpNo);
4531 EVT OutVT =
N->getValueType(0);
4539 EVT LoOutVT, HiOutVT;
4540 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4541 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4546 if (isTypeLegal(LoOutVT) ||
4547 InElementSize <= OutElementSize * 2)
4548 return SplitVecOp_UnaryOp(
N);
4557 return SplitVecOp_UnaryOp(
N);
4561 GetSplitVector(InVec, InLoVec, InHiVec);
4567 EVT HalfElementVT = IsFloat ?
4569 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4576 if (
N->isStrictFPOpcode()) {
4577 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4578 {N->getOperand(0), InLoVec});
4579 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4580 {N->getOperand(0), InHiVec});
4586 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4587 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4591 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4599 if (
N->isStrictFPOpcode()) {
4603 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4611 DAG.getTargetConstant(
4612 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4619 assert(
N->getValueType(0).isVector() &&
4620 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4621 "Operand types must be vectors");
4623 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4625 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4626 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4628 EVT VT =
N->getValueType(0);
4635 }
else if (isStrict) {
4636 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4637 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4638 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4639 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4642 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4644 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4645 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4646 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4647 std::tie(EVLLo, EVLHi) =
4648 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4649 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4650 N->getOperand(2), MaskLo, EVLLo);
4651 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4652 N->getOperand(2), MaskHi, EVLHi);
4661 EVT ResVT =
N->getValueType(0);
4664 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4665 EVT InVT =
Lo.getValueType();
4670 if (
N->isStrictFPOpcode()) {
4671 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4672 {N->getOperand(0), Lo, N->getOperand(2)});
4673 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4674 {N->getOperand(0), Hi, N->getOperand(2)});
4678 Lo.getValue(1),
Hi.getValue(1));
4679 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4680 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4681 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4682 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4683 std::tie(EVLLo, EVLHi) =
4684 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4685 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4686 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4700SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4703 EVT LHSLoVT, LHSHiVT;
4704 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4706 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4707 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4710 std::tie(LHSLo, LHSHi) =
4711 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4714 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4717 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4723 LLVMContext &Ctxt = *DAG.getContext();
4726 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4727 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4728 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4730 EVT ResVT =
N->getValueType(0);
4735 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4736 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4742 EVT ResVT =
N->getValueType(0);
4745 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4746 EVT InVT =
Lo.getValueType();
4752 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4753 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4760 EVT ResVT =
N->getValueType(0);
4764 GetSplitVector(VecOp,
Lo,
Hi);
4766 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4767 auto [EVLLo, EVLHi] =
4769 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4775 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4777 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4778 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4781SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4792 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4793 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4794 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4795 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4796 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4797 OpsLo, MMO, IndexType);
4798 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4799 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4803SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4806 "Accumulator should already be a legal type, and shouldn't need "
4807 "further splitting");
4810 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4811 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4812 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4813 unsigned Opcode =
N->getOpcode();
4816 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4817 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4824void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4825 unsigned WidenResNo) {
4826 unsigned NumResults =
N->getNumValues();
4827 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4828 if (ResNo == WidenResNo)
4830 EVT ResVT =
N->getValueType(ResNo);
4836 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4837 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4842void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4843 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4846 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4851 auto unrollExpandedOp = [&]() {
4856 EVT VT =
N->getValueType(0);
4857 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4858 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4859 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
4861 if (
N->getNumValues() > 1)
4862 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4868 switch (
N->getOpcode()) {
4871 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4879 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4883 Res = WidenVecRes_ADDRSPACECAST(
N);
4890 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4897 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4901 Res = WidenVecRes_ScalarOp(
N);
4906 case ISD::VP_SELECT:
4908 Res = WidenVecRes_Select(
N);
4912 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4914 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4921 case ISD::VP_LOAD_FF:
4924 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4928 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4936 case ISD::VP_GATHER:
4940 Res = WidenVecRes_VECTOR_REVERSE(
N);
4943 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4953 case ISD::OR:
case ISD::VP_OR:
4964 case ISD::VP_FMINNUM:
4967 case ISD::VP_FMAXNUM:
4969 case ISD::VP_FMINIMUM:
4971 case ISD::VP_FMAXIMUM:
5004 case ISD::VP_FCOPYSIGN:
5005 Res = WidenVecRes_Binary(
N);
5010 Res = WidenVecRes_CMP(
N);
5016 if (unrollExpandedOp())
5031 Res = WidenVecRes_BinaryCanTrap(
N);
5040 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5043#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5044 case ISD::STRICT_##DAGN:
5045#include "llvm/IR/ConstrainedOps.def"
5046 Res = WidenVecRes_StrictFP(
N);
5055 Res = WidenVecRes_OverflowOp(
N, ResNo);
5059 Res = WidenVecRes_FCOPYSIGN(
N);
5064 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5069 if (!unrollExpandedOp())
5070 Res = WidenVecRes_ExpOp(
N);
5076 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5081 case ISD::VP_FP_EXTEND:
5083 case ISD::VP_FP_ROUND:
5085 case ISD::VP_FP_TO_SINT:
5087 case ISD::VP_FP_TO_UINT:
5089 case ISD::VP_SIGN_EXTEND:
5091 case ISD::VP_SINT_TO_FP:
5092 case ISD::VP_TRUNCATE:
5095 case ISD::VP_UINT_TO_FP:
5097 case ISD::VP_ZERO_EXTEND:
5098 Res = WidenVecRes_Convert(
N);
5103 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5109 case ISD::VP_LLRINT:
5112 Res = WidenVecRes_XROUND(
N);
5138 if (unrollExpandedOp())
5148 case ISD::VP_BITREVERSE:
5154 case ISD::VP_CTLZ_ZERO_UNDEF:
5160 case ISD::VP_CTTZ_ZERO_UNDEF:
5165 case ISD::VP_FFLOOR:
5167 case ISD::VP_FNEARBYINT:
5168 case ISD::VP_FROUND:
5169 case ISD::VP_FROUNDEVEN:
5170 case ISD::VP_FROUNDTOZERO:
5175 Res = WidenVecRes_Unary(
N);
5182 Res = WidenVecRes_Ternary(
N);
5188 if (!unrollExpandedOp())
5189 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5196 SetWidenedVector(
SDValue(
N, ResNo), Res);
5202 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5203 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5204 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5205 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5206 if (
N->getNumOperands() == 3)
5207 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5209 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5210 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5214 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5215 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5221 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5222 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5223 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5224 if (
N->getNumOperands() == 2)
5225 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5228 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5229 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5233 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5234 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5238 LLVMContext &Ctxt = *DAG.getContext();
5243 EVT OpVT =
LHS.getValueType();
5245 LHS = GetWidenedVector(
LHS);
5246 RHS = GetWidenedVector(
RHS);
5247 OpVT =
LHS.getValueType();
5250 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5253 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5259SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5262 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5263 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5264 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5266 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5275 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5278 if (ConcatEnd == 1) {
5279 VT = ConcatOps[0].getValueType();
5281 return ConcatOps[0];
5284 SDLoc dl(ConcatOps[0]);
5291 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5292 int Idx = ConcatEnd - 1;
5293 VT = ConcatOps[Idx--].getValueType();
5294 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5307 unsigned NumToInsert = ConcatEnd - Idx - 1;
5308 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5310 ConcatOps[Idx+1] = VecOp;
5311 ConcatEnd = Idx + 2;
5317 unsigned RealVals = ConcatEnd - Idx - 1;
5318 unsigned SubConcatEnd = 0;
5319 unsigned SubConcatIdx = Idx + 1;
5320 while (SubConcatEnd < RealVals)
5321 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5322 while (SubConcatEnd < OpsToConcat)
5323 SubConcatOps[SubConcatEnd++] = undefVec;
5325 NextVT, SubConcatOps);
5326 ConcatEnd = SubConcatIdx + 1;
5331 if (ConcatEnd == 1) {
5332 VT = ConcatOps[0].getValueType();
5334 return ConcatOps[0];
5339 if (
NumOps != ConcatEnd ) {
5341 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5342 ConcatOps[j] = UndefVal;
5350 unsigned Opcode =
N->getOpcode();
5352 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5356 const SDNodeFlags
Flags =
N->getFlags();
5357 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5358 NumElts = NumElts / 2;
5362 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5364 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5365 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5366 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5374 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5377 TLI.isTypeLegal(WideMaskVT)) {
5378 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5379 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5380 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5382 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5383 N->getValueType(0).getVectorElementCount());
5384 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5398 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5399 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5400 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5403 unsigned ConcatEnd = 0;
5411 while (CurNumElts != 0) {
5412 while (CurNumElts >= NumElts) {
5413 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5414 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5415 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5417 CurNumElts -= NumElts;
5420 NumElts = NumElts / 2;
5422 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5425 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5426 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5427 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5428 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5439 switch (
N->getOpcode()) {
5442 return WidenVecRes_STRICT_FSETCC(
N);
5449 return WidenVecRes_Convert_StrictFP(
N);
5456 unsigned Opcode =
N->getOpcode();
5458 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5462 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5463 NumElts = NumElts / 2;
5474 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5478 unsigned ConcatEnd = 0;
5485 for (
unsigned i = 1; i < NumOpers; ++i) {
5491 Oper = GetWidenedVector(Oper);
5497 DAG.getUNDEF(WideOpVT), Oper,
5498 DAG.getVectorIdxConstant(0, dl));
5510 while (CurNumElts != 0) {
5511 while (CurNumElts >= NumElts) {
5514 for (
unsigned i = 0; i < NumOpers; ++i) {
5517 EVT OpVT =
Op.getValueType();
5522 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5528 EVT OperVT[] = {VT, MVT::Other};
5530 ConcatOps[ConcatEnd++] = Oper;
5533 CurNumElts -= NumElts;
5536 NumElts = NumElts / 2;
5538 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5541 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5544 for (
unsigned i = 0; i < NumOpers; ++i) {
5547 EVT OpVT =
Op.getValueType();
5555 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5557 ConcatOps[ConcatEnd++] = Oper;
5566 if (Chains.
size() == 1)
5567 NewChain = Chains[0];
5570 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5575SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5577 EVT ResVT =
N->getValueType(0);
5578 EVT OvVT =
N->getValueType(1);
5579 EVT WideResVT, WideOvVT;
5584 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5589 WideLHS = GetWidenedVector(
N->getOperand(0));
5590 WideRHS = GetWidenedVector(
N->getOperand(1));
5592 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5600 N->getOperand(0), Zero);
5603 N->getOperand(1), Zero);
5606 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5607 SDNode *WideNode = DAG.getNode(
5608 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5611 unsigned OtherNo = 1 - ResNo;
5612 EVT OtherVT =
N->getValueType(OtherNo);
5619 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5622 return SDValue(WideNode, ResNo);
5626 LLVMContext &Ctx = *DAG.getContext();
5630 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5635 unsigned Opcode =
N->getOpcode();
5636 const SDNodeFlags
Flags =
N->getFlags();
5642 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5644 InOp = ZExtPromotedInteger(InOp);
5655 InOp = GetWidenedVector(
N->getOperand(0));
5658 if (InVTEC == WidenEC) {
5659 if (
N->getNumOperands() == 1)
5660 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5661 if (
N->getNumOperands() == 3) {
5662 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5665 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5667 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5693 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5697 if (TLI.isTypeLegal(InWidenVT)) {
5705 unsigned NumConcat =
5710 if (
N->getNumOperands() == 1)
5711 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5712 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5716 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5718 if (
N->getNumOperands() == 1)
5719 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5720 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5729 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5730 for (
unsigned i=0; i < MinElts; ++i) {
5731 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5732 if (
N->getNumOperands() == 1)
5735 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5738 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5743 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5747 EVT SrcVT = Src.getValueType();
5751 Src = GetWidenedVector(Src);
5752 SrcVT = Src.getValueType();
5759 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5764 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5768 EVT SrcVT = Src.getValueType();
5772 Src = GetWidenedVector(Src);
5773 SrcVT = Src.getValueType();
5780 if (
N->getNumOperands() == 1)
5781 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5783 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5784 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5788 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5791SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5796 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5802 unsigned Opcode =
N->getOpcode();
5808 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5813 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5814 for (
unsigned i=0; i < MinElts; ++i) {
5815 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5816 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5820 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5822 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5825SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5826 unsigned Opcode =
N->getOpcode();
5830 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5839 InOp = GetWidenedVector(InOp);
5846 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5853 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5854 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5871 while (
Ops.size() != WidenNumElts)
5872 Ops.push_back(DAG.getPOISON(WidenSVT));
5874 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5880 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5881 return WidenVecRes_BinaryCanTrap(
N);
5884 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5891SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5893 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5896 SDValue Arg = GetWidenedVector(FpValue);
5897 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5902 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5903 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5905 EVT ExpVT =
RHS.getValueType();
5910 ExpOp = ModifyToType(
RHS, WideExpVT);
5913 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5918 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5919 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5920 if (
N->getNumOperands() == 1)
5921 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5923 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5924 N->getOperand(1),
N->getFlags());
5926 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5927 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5931 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5932 {InOp,
Mask,
N->getOperand(2)});
5936 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5939 .getVectorElementType(),
5941 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5942 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5943 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5946SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5948 EVT VT0 =
N->getValueType(0);
5949 EVT VT1 =
N->getValueType(1);
5953 "expected both results to be vectors of matching element count");
5955 LLVMContext &Ctx = *DAG.getContext();
5956 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5958 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5965 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5968 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5969 return SDValue(WidenNode, ResNo);
5972SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5973 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5974 return GetWidenedVector(WidenVec);
5978 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5979 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5982 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5983 AddrSpaceCastN->getSrcAddressSpace(),
5984 AddrSpaceCastN->getDestAddressSpace());
5990 EVT VT =
N->getValueType(0);
5991 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5994 switch (getTypeAction(InVT)) {
6008 SDValue NInOp = GetPromotedInteger(InOp);
6010 if (WidenVT.
bitsEq(NInVT)) {
6013 if (DAG.getDataLayout().isBigEndian()) {
6016 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6035 InOp = GetWidenedVector(InOp);
6037 if (WidenVT.
bitsEq(InVT))
6047 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6052 unsigned NewNumParts = WidenSize / InSize;
6065 EVT OrigInVT =
N->getOperand(0).getValueType();
6070 if (TLI.isTypeLegal(NewInVT)) {
6078 if (WidenSize % InSize == 0) {
6085 DAG.ExtractVectorElements(InOp,
Ops);
6086 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6098 return CreateStackStoreLoad(InOp, WidenVT);
6101SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6103 N->getOpcode(), SDLoc(
N),
6104 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6105 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6111 EVT VT =
N->getValueType(0);
6115 EVT EltVT =
N->getOperand(0).getValueType();
6118 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6122 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6123 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6125 return DAG.getBuildVector(WidenVT, dl, NewOps);
6129 EVT InVT =
N->getOperand(0).getValueType();
6130 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6132 unsigned NumOperands =
N->getNumOperands();
6134 bool InputWidened =
false;
6138 if (WidenNumElts % NumInElts == 0) {
6140 unsigned NumConcat = WidenNumElts / NumInElts;
6141 SDValue UndefVal = DAG.getPOISON(InVT);
6143 for (
unsigned i=0; i < NumOperands; ++i)
6144 Ops[i] =
N->getOperand(i);
6145 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6150 InputWidened =
true;
6151 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6154 for (i=1; i < NumOperands; ++i)
6155 if (!
N->getOperand(i).isUndef())
6158 if (i == NumOperands)
6161 return GetWidenedVector(
N->getOperand(0));
6163 if (NumOperands == 2) {
6165 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6170 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6171 for (
unsigned i = 0; i < NumInElts; ++i) {
6173 MaskOps[i + NumInElts] = i + WidenNumElts;
6175 return DAG.getVectorShuffle(WidenVT, dl,
6176 GetWidenedVector(
N->getOperand(0)),
6177 GetWidenedVector(
N->getOperand(1)),
6184 "Cannot use build vectors to widen CONCAT_VECTOR result");
6192 for (
unsigned i=0; i < NumOperands; ++i) {
6195 InOp = GetWidenedVector(InOp);
6196 for (
unsigned j = 0;
j < NumInElts; ++
j)
6197 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6199 SDValue UndefVal = DAG.getPOISON(EltVT);
6200 for (; Idx < WidenNumElts; ++Idx)
6201 Ops[Idx] = UndefVal;
6202 return DAG.getBuildVector(WidenVT, dl,
Ops);
6205SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6206 EVT VT =
N->getValueType(0);
6207 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6208 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6215SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6216 EVT VT =
N->getValueType(0);
6218 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6223 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6225 InOp = GetWidenedVector(InOp);
6231 if (IdxVal == 0 && InVT == WidenVT)
6238 assert(IdxVal % VTNumElts == 0 &&
6239 "Expected Idx to be a multiple of subvector minimum vector length");
6240 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6253 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6254 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6255 "down type's element count");
6262 for (;
I < VTNumElts / GCD; ++
I)
6264 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6265 for (;
I < WidenNumElts / GCD; ++
I)
6273 Align Alignment = DAG.getReducedAlign(InVT,
false);
6275 MachineFunction &MF = DAG.getMachineFunction();
6287 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6294 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6295 return DAG.getMaskedLoad(
6296 WidenVT, dl, Ch, StackPtr, DAG.getUNDEF(
StackPtr.getValueType()), Mask,
6304 for (i = 0; i < VTNumElts; ++i)
6305 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6307 SDValue UndefVal = DAG.getPOISON(EltVT);
6308 for (; i < WidenNumElts; ++i)
6310 return DAG.getBuildVector(WidenVT, dl,
Ops);
6316 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6321SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6322 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6325 N->getOperand(1),
N->getOperand(2));
6334 "Load width must be less than or equal to first value type width");
6343 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6354 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6355 EVT LdVT =
LD->getMemoryVT();
6359 "Must be scalable");
6361 "Expected equivalent element types");
6369 TypeSize WidthDiff = WidenWidth - LdWidth;
6372 std::optional<EVT> FirstVT =
6373 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6380 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6383 Chain, BasePtr,
LD->getMemOperand());
6387 FirstVTWidth, dl, DAG);
6405 if (!
LD->getMemoryVT().isByteSized()) {
6407 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6409 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6418 EVT VT =
LD->getValueType(0);
6419 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6420 EVT WideMaskVT = getSetCCResultType(WideVT);
6423 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6424 TLI.isTypeLegal(WideMaskVT)) {
6427 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6431 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6432 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6444 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6446 Result = GenWidenVectorLoads(LdChain, LD);
6453 if (LdChain.
size() == 1)
6454 NewChain = LdChain[0];
6460 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6471 SDValue NewLoad = DAG.getMaskedLoad(
6472 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6473 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6474 LD->getAddressingMode(),
LD->getExtensionType());
6484 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6486 SDValue EVL =
N->getVectorLength();
6493 "Unable to widen binary VP op");
6494 Mask = GetWidenedVector(Mask);
6495 assert(
Mask.getValueType().getVectorElementCount() ==
6496 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6497 .getVectorElementCount() &&
6498 "Unable to widen vector load");
6501 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6502 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6503 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6511 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6513 SDValue EVL =
N->getVectorLength();
6519 "Unable to widen binary VP op");
6520 Mask = GetWidenedVector(Mask);
6521 assert(
Mask.getValueType().getVectorElementCount() ==
6522 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6523 .getVectorElementCount() &&
6524 "Unable to widen vector load");
6526 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6527 Mask, EVL,
N->getMemOperand());
6540 "Unable to widen VP strided load");
6541 Mask = GetWidenedVector(Mask);
6543 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6544 assert(
Mask.getValueType().getVectorElementCount() ==
6546 "Data and mask vectors should have the same number of elements");
6548 SDValue Res = DAG.getStridedLoadVP(
6549 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6550 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6551 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6552 N->isExpandingLoad());
6560SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6565 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6567 Mask.getValueType().getVectorElementType(),
6570 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6571 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6572 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6574 WideMask, WidePassthru);
6578 EVT VT =
N->getValueType(0);
6579 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6581 EVT MaskVT =
Mask.getValueType();
6582 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6591 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6592 TLI.isTypeLegal(WideMaskVT) &&
6598 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6599 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6603 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6604 N->getMemoryVT(),
N->getMemOperand());
6608 if (!
N->getPassThru()->isUndef()) {
6611 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6622 Mask = ModifyToType(Mask, WideMaskVT,
true);
6624 SDValue Res = DAG.getMaskedLoad(
6625 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6626 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6627 ExtType,
N->isExpandingLoad());
6636 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6638 EVT MaskVT =
Mask.getValueType();
6639 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6648 Mask = ModifyToType(Mask, WideMaskVT,
true);
6653 Index.getValueType().getScalarType(),
6655 Index = ModifyToType(Index, WideIndexVT);
6661 N->getMemoryVT().getScalarType(), NumElts);
6662 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6663 WideMemVT, dl,
Ops,
N->getMemOperand(),
6664 N->getIndexType(),
N->getExtensionType());
6673 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6681 N->getMemoryVT().getScalarType(), WideEC);
6682 Mask = GetWidenedMask(Mask, WideEC);
6685 Mask,
N->getVectorLength()};
6686 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6687 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6696 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6697 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6725 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6726 return N->getOperand(OpNo).getValueType();
6734 N =
N.getOperand(0);
6736 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6737 if (!
N->getOperand(i)->isUndef())
6739 N =
N.getOperand(0);
6743 N =
N.getOperand(0);
6745 N =
N.getOperand(0);
6772 { MaskVT, MVT::Other },
Ops);
6773 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6780 LLVMContext &Ctx = *DAG.getContext();
6783 if (MaskScalarBits < ToMaskScalBits) {
6787 }
else if (MaskScalarBits > ToMaskScalBits) {
6793 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6795 "Mask should have the right element size by now.");
6798 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6800 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6803 EVT SubVT =
Mask->getValueType(0);
6809 assert((
Mask->getValueType(0) == ToMaskVT) &&
6810 "A mask of ToMaskVT should have been produced by now.");
6820 LLVMContext &Ctx = *DAG.getContext();
6831 EVT CondVT =
Cond->getValueType(0);
6835 EVT VSelVT =
N->getValueType(0);
6847 EVT FinalVT = VSelVT;
6858 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6859 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6866 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6874 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6877 EVT ToMaskVT = VSelVT;
6884 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6900 if (ScalarBits0 != ScalarBits1) {
6901 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6902 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6914 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6915 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6916 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6919 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6927 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6932 unsigned Opcode =
N->getOpcode();
6934 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6935 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6936 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6938 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6944 Cond1 = GetWidenedVector(Cond1);
6952 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6953 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6958 Cond1 = ModifyToType(Cond1, CondWidenVT);
6961 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6962 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6964 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6965 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6967 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6971 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6972 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6975 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6979 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6980 return DAG.getUNDEF(WidenVT);
6984 EVT VT =
N->getValueType(0);
6987 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6991 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6992 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6995 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6996 for (
unsigned i = 0; i != NumElts; ++i) {
6997 int Idx =
N->getMaskElt(i);
6998 if (Idx < (
int)NumElts)
7001 NewMask[i] = Idx - NumElts + WidenNumElts;
7003 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7007 EVT VT =
N->getValueType(0);
7011 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7012 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7018 unsigned IdxVal = WidenNumElts - VTNumElts;
7031 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7034 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7035 "down type's element count");
7038 for (; i < VTNumElts / GCD; ++i)
7040 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7041 for (; i < WidenNumElts / GCD; ++i)
7049 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7050 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7052 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
7056SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7057 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7062 assert(
N->getValueType(0).isVector() &&
7063 N->getOperand(0).getValueType().isVector() &&
7064 "Operands must be vectors");
7065 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7078 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7079 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7086 InOp1 = GetWidenedVector(InOp1);
7087 InOp2 = GetWidenedVector(InOp2);
7090 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7101 "Input not widened to expected type!");
7103 if (
N->getOpcode() == ISD::VP_SETCC) {
7106 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7107 N->getOperand(2), Mask,
N->getOperand(4));
7109 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7114 assert(
N->getValueType(0).isVector() &&
7115 N->getOperand(1).getValueType().isVector() &&
7116 "Operands must be vectors");
7117 EVT VT =
N->getValueType(0);
7118 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7128 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7133 for (
unsigned i = 0; i != NumElts; ++i) {
7134 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7135 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7137 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7138 {Chain, LHSElem, RHSElem, CC});
7139 Chains[i] = Scalars[i].getValue(1);
7140 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7141 DAG.getBoolConstant(
true, dl, EltVT, VT),
7142 DAG.getBoolConstant(
false, dl, EltVT, VT));
7146 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7148 return DAG.getBuildVector(WidenVT, dl, Scalars);
7154bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7155 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7159 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7162 switch (
N->getOpcode()) {
7165 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7173 Res = WidenVecOp_FAKE_USE(
N);
7179 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7180 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7181 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7182 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7187 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7189 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7190 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7192 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7193 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7203 Res = WidenVecOp_UnrollVectorOp(
N);
7210 Res = WidenVecOp_EXTEND(
N);
7215 Res = WidenVecOp_CMP(
N);
7231 Res = WidenVecOp_Convert(
N);
7236 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7254 Res = WidenVecOp_VECREDUCE(
N);
7258 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7260 case ISD::VP_REDUCE_FADD:
7261 case ISD::VP_REDUCE_SEQ_FADD:
7262 case ISD::VP_REDUCE_FMUL:
7263 case ISD::VP_REDUCE_SEQ_FMUL:
7264 case ISD::VP_REDUCE_ADD:
7265 case ISD::VP_REDUCE_MUL:
7266 case ISD::VP_REDUCE_AND:
7267 case ISD::VP_REDUCE_OR:
7268 case ISD::VP_REDUCE_XOR:
7269 case ISD::VP_REDUCE_SMAX:
7270 case ISD::VP_REDUCE_SMIN:
7271 case ISD::VP_REDUCE_UMAX:
7272 case ISD::VP_REDUCE_UMIN:
7273 case ISD::VP_REDUCE_FMAX:
7274 case ISD::VP_REDUCE_FMIN:
7275 case ISD::VP_REDUCE_FMAXIMUM:
7276 case ISD::VP_REDUCE_FMINIMUM:
7277 Res = WidenVecOp_VP_REDUCE(
N);
7279 case ISD::VP_CTTZ_ELTS:
7280 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7281 Res = WidenVecOp_VP_CttzElements(
N);
7284 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7289 if (!Res.
getNode())
return false;
7297 if (
N->isStrictFPOpcode())
7299 "Invalid operand expansion");
7302 "Invalid operand expansion");
7304 ReplaceValueWith(
SDValue(
N, 0), Res);
7310 EVT VT =
N->getValueType(0);
7315 "Unexpected type action");
7316 InOp = GetWidenedVector(InOp);
7319 "Input wasn't widened!");
7327 EVT FixedEltVT = FixedVT.getVectorElementType();
7328 if (TLI.isTypeLegal(FixedVT) &&
7330 FixedEltVT == InEltVT) {
7332 "Not enough elements in the fixed type for the operand!");
7334 "We can't have the same type as we started with!");
7336 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7338 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7347 return WidenVecOp_Convert(
N);
7352 switch (
N->getOpcode()) {
7367 EVT OpVT =
N->getOperand(0).getValueType();
7368 EVT ResVT =
N->getValueType(0);
7375 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7376 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7382 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7383 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7385 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7392 return DAG.UnrollVectorOp(
N);
7397 EVT ResultVT =
N->getValueType(0);
7399 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7402 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7408 {WideArg,
Test},
N->getFlags());
7414 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7416 EVT OpVT =
N->getOperand(0).getValueType();
7419 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7424 EVT VT =
N->getValueType(0);
7430 "Unexpected type action");
7431 InOp = GetWidenedVector(InOp);
7433 unsigned Opcode =
N->getOpcode();
7439 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7441 if (
N->isStrictFPOpcode()) {
7443 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7446 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7447 {
N->getOperand(0), InOp });
7453 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7455 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7457 return DAG.getExtractSubvector(dl, VT, Res, 0);
7465 if (
N->isStrictFPOpcode()) {
7468 for (
unsigned i=0; i < NumElts; ++i) {
7469 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7470 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7474 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7476 for (
unsigned i = 0; i < NumElts; ++i)
7477 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7478 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7481 return DAG.getBuildVector(VT, dl,
Ops);
7485 EVT DstVT =
N->getValueType(0);
7486 SDValue Src = GetWidenedVector(
N->getOperand(0));
7487 EVT SrcVT = Src.getValueType();
7494 if (TLI.isTypeLegal(WideDstVT)) {
7496 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7499 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7503 return DAG.UnrollVectorOp(
N);
7507 EVT VT =
N->getValueType(0);
7508 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7516 if (!VT.
isVector() && VT != MVT::x86mmx &&
7520 if (TLI.isTypeLegal(NewVT)) {
7522 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7534 ElementCount NewNumElts =
7536 .divideCoefficientBy(EltSize);
7538 if (TLI.isTypeLegal(NewVT)) {
7540 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7545 return CreateStackStoreLoad(InOp, VT);
7553 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7554 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7559 EVT VT =
N->getValueType(0);
7561 EVT InVT =
N->getOperand(0).getValueType();
7566 unsigned NumOperands =
N->getNumOperands();
7567 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7569 for (i = 1; i < NumOperands; ++i)
7570 if (!
N->getOperand(i).isUndef())
7573 if (i == NumOperands)
7574 return GetWidenedVector(
N->getOperand(0));
7584 for (
unsigned i=0; i < NumOperands; ++i) {
7588 "Unexpected type action");
7589 InOp = GetWidenedVector(InOp);
7590 for (
unsigned j = 0;
j < NumInElts; ++
j)
7591 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7593 return DAG.getBuildVector(VT, dl,
Ops);
7596SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7597 EVT VT =
N->getValueType(0);
7602 SubVec = GetWidenedVector(SubVec);
7607 bool IndicesValid =
false;
7610 IndicesValid =
true;
7614 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7615 Attribute::VScaleRange);
7620 IndicesValid =
true;
7626 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7632 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7639 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7646 Align Alignment = DAG.getReducedAlign(VT,
false);
7648 MachineFunction &MF = DAG.getMachineFunction();
7661 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7669 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7670 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7675 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7680 unsigned Idx =
N->getConstantOperandVal(2);
7686 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7692SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7693 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7695 N->getValueType(0), InOp,
N->getOperand(1));
7698SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7699 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7701 N->getValueType(0), InOp,
N->getOperand(1));
7704SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7705 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7706 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7714 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7715 return TLI.scalarizeVectorStore(ST, DAG);
7717 if (
ST->isTruncatingStore())
7718 return TLI.scalarizeVectorStore(ST, DAG);
7728 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7729 EVT WideMaskVT = getSetCCResultType(WideVT);
7731 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7732 TLI.isTypeLegal(WideMaskVT)) {
7735 StVal = GetWidenedVector(StVal);
7737 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7739 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7740 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7741 ST->getAddressingMode());
7745 if (GenWidenVectorStores(StChain, ST)) {
7746 if (StChain.
size() == 1)
7755 SDValue WideStVal = GetWidenedVector(StVal);
7759 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7760 ST->getOffset(), Mask,
ST->getMemoryVT(),
7761 ST->getMemOperand(),
ST->getAddressingMode(),
7762 ST->isTruncatingStore());
7768SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7769 assert((OpNo == 1 || OpNo == 3) &&
7770 "Can widen only data or mask operand of vp_store");
7778 StVal = GetWidenedVector(StVal);
7784 "Unable to widen VP store");
7785 Mask = GetWidenedVector(Mask);
7787 Mask = GetWidenedVector(Mask);
7793 "Unable to widen VP store");
7794 StVal = GetWidenedVector(StVal);
7797 assert(
Mask.getValueType().getVectorElementCount() ==
7799 "Mask and data vectors should have the same number of elements");
7800 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7801 ST->getOffset(), Mask,
ST->getVectorLength(),
7802 ST->getMemoryVT(),
ST->getMemOperand(),
7803 ST->getAddressingMode(),
ST->isTruncatingStore(),
7804 ST->isCompressingStore());
7809 assert((OpNo == 1 || OpNo == 4) &&
7810 "Can widen only data or mask operand of vp_strided_store");
7819 "Unable to widen VP strided store");
7823 "Unable to widen VP strided store");
7825 StVal = GetWidenedVector(StVal);
7826 Mask = GetWidenedVector(Mask);
7829 Mask.getValueType().getVectorElementCount() &&
7830 "Data and mask vectors should have the same number of elements");
7832 return DAG.getStridedStoreVP(
7839SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7840 assert((OpNo == 1 || OpNo == 4) &&
7841 "Can widen only data or mask operand of mstore");
7844 EVT MaskVT =
Mask.getValueType();
7849 EVT WideVT, WideMaskVT;
7852 StVal = GetWidenedVector(StVal);
7859 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7866 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7867 TLI.isTypeLegal(WideMaskVT)) {
7868 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7869 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7878 Mask = ModifyToType(Mask, WideMaskVT,
true);
7881 Mask = ModifyToType(Mask, WideMaskVT,
true);
7883 StVal = ModifyToType(StVal, WideVT);
7886 assert(
Mask.getValueType().getVectorElementCount() ==
7888 "Mask and data vectors should have the same number of elements");
7895SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7896 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7898 SDValue DataOp = MG->getPassThru();
7900 SDValue Scale = MG->getScale();
7908 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7909 MG->getMemOperand(), MG->getIndexType(),
7910 MG->getExtensionType());
7916SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7925 DataOp = GetWidenedVector(DataOp);
7929 EVT IndexVT =
Index.getValueType();
7932 Index = ModifyToType(Index, WideIndexVT);
7935 EVT MaskVT =
Mask.getValueType();
7938 Mask = ModifyToType(Mask, WideMaskVT,
true);
7943 }
else if (OpNo == 4) {
7945 Index = GetWidenedVector(Index);
7951 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7956SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7965 DataOp = GetWidenedVector(DataOp);
7966 Index = GetWidenedVector(Index);
7968 Mask = GetWidenedMask(Mask, WideEC);
7971 }
else if (OpNo == 3) {
7973 Index = GetWidenedVector(Index);
7980 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7985 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7986 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7988 EVT VT =
N->getValueType(0);
8003 SVT, InOp0, InOp1,
N->getOperand(2));
8009 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8011 EVT OpVT =
N->getOperand(0).getValueType();
8014 return DAG.getNode(ExtendCode, dl, VT, CC);
8024 EVT VT =
N->getValueType(0);
8026 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8033 for (
unsigned i = 0; i != NumElts; ++i) {
8034 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8035 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8037 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8038 {Chain, LHSElem, RHSElem, CC});
8039 Chains[i] = Scalars[i].getValue(1);
8040 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8041 DAG.getBoolConstant(
true, dl, EltVT, VT),
8042 DAG.getBoolConstant(
false, dl, EltVT, VT));
8046 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8048 return DAG.getBuildVector(VT, dl, Scalars);
8072 SDValue Op = GetWidenedVector(
N->getOperand(0));
8073 EVT VT =
N->getValueType(0);
8074 EVT OrigVT =
N->getOperand(0).getValueType();
8075 EVT WideVT =
Op.getValueType();
8077 SDNodeFlags
Flags =
N->getFlags();
8079 unsigned Opc =
N->getOpcode();
8081 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8082 assert(NeutralElem &&
"Neutral element must exist");
8092 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8099 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8100 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8106 unsigned GCD = std::gcd(OrigElts, WideElts);
8109 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8110 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8111 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8112 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8115 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8116 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8118 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8127 EVT VT =
N->getValueType(0);
8129 EVT WideVT =
Op.getValueType();
8131 SDNodeFlags
Flags =
N->getFlags();
8133 unsigned Opc =
N->getOpcode();
8135 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8145 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8148 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8149 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8155 unsigned GCD = std::gcd(OrigElts, WideElts);
8158 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8159 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8160 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8161 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8164 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8165 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8167 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8171 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8174 SDValue Op = GetWidenedVector(
N->getOperand(1));
8176 Op.getValueType().getVectorElementCount());
8178 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8179 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8187 EVT VT =
N->getValueType(0);
8191 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8192 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8197 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8203 EVT SrcVT =
Source.getValueType();
8207 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8208 {Source, Mask, N->getOperand(2)},
N->getFlags());
8211SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8214 EVT OrigMaskVT =
Mask.getValueType();
8215 SDValue WideMask = GetWidenedVector(Mask);
8221 if (OrigElts != WideElts) {
8222 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8224 Mask, DAG.getVectorIdxConstant(0,
DL));
8245 unsigned WidenEx = 0) {
8250 unsigned AlignInBits =
Align*8;
8252 EVT RetVT = WidenEltVT;
8257 if (Width == WidenEltWidth)
8268 (WidenWidth % MemVTWidth) == 0 &&
8270 (MemVTWidth <= Width ||
8271 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8272 if (MemVTWidth == WidenWidth)
8291 (WidenWidth % MemVTWidth) == 0 &&
8293 (MemVTWidth <= Width ||
8294 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8303 return std::nullopt;
8314 unsigned Start,
unsigned End) {
8315 SDLoc dl(LdOps[Start]);
8316 EVT LdTy = LdOps[Start].getValueType();
8324 for (
unsigned i = Start + 1; i != End; ++i) {
8325 EVT NewLdTy = LdOps[i].getValueType();
8326 if (NewLdTy != LdTy) {
8345 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8346 EVT LdVT =
LD->getMemoryVT();
8356 AAMDNodes AAInfo =
LD->getAAInfo();
8360 TypeSize WidthDiff = WidenWidth - LdWidth;
8367 std::optional<EVT> FirstVT =
8368 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8375 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8380 std::optional<EVT> NewVT = FirstVT;
8381 TypeSize RemainingWidth = LdWidth;
8382 TypeSize NewVTWidth = FirstVTWidth;
8384 RemainingWidth -= NewVTWidth;
8391 NewVTWidth = NewVT->getSizeInBits();
8397 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8398 LD->getBaseAlign(), MMOFlags, AAInfo);
8410 uint64_t ScaledOffset = 0;
8411 MachinePointerInfo MPI =
LD->getPointerInfo();
8417 for (EVT MemVT : MemVTs) {
8418 Align NewAlign = ScaledOffset == 0
8419 ?
LD->getBaseAlign()
8422 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8430 unsigned End = LdOps.
size();
8441 EVT LdTy = LdOps[i].getValueType();
8444 for (--i; i >= 0; --i) {
8445 LdTy = LdOps[i].getValueType();
8452 ConcatOps[--Idx] = LdOps[i];
8453 for (--i; i >= 0; --i) {
8454 EVT NewLdTy = LdOps[i].getValueType();
8455 if (NewLdTy != LdTy) {
8465 for (;
j != End-Idx; ++
j)
8466 WidenOps[j] = ConcatOps[Idx+j];
8468 WidenOps[j] = DAG.getUNDEF(LdTy);
8475 ConcatOps[--Idx] = LdOps[i];
8480 ArrayRef(&ConcatOps[Idx], End - Idx));
8486 SDValue UndefVal = DAG.getUNDEF(LdTy);
8489 for (; i != End-Idx; ++i)
8490 WidenOps[i] = ConcatOps[Idx+i];
8492 WidenOps[i] = UndefVal;
8503 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8504 EVT LdVT =
LD->getMemoryVT();
8513 AAMDNodes AAInfo =
LD->getAAInfo();
8527 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8528 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8534 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8535 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8536 LD->getBaseAlign(), MMOFlags, AAInfo);
8541 SDValue UndefVal = DAG.getUNDEF(EltVT);
8542 for (; i != WidenNumElts; ++i)
8545 return DAG.getBuildVector(WidenVT, dl,
Ops);
8556 AAMDNodes AAInfo =
ST->getAAInfo();
8557 SDValue ValOp = GetWidenedVector(
ST->getValue());
8560 EVT StVT =
ST->getMemoryVT();
8568 "Mismatch between store and value types");
8572 MachinePointerInfo MPI =
ST->getPointerInfo();
8573 uint64_t ScaledOffset = 0;
8582 std::optional<EVT> NewVT =
8587 TypeSize NewVTWidth = NewVT->getSizeInBits();
8590 StWidth -= NewVTWidth;
8591 MemVTs.
back().second++;
8595 for (
const auto &Pair : MemVTs) {
8596 EVT NewVT = Pair.first;
8597 unsigned Count = Pair.second;
8603 Align NewAlign = ScaledOffset == 0
8604 ?
ST->getBaseAlign()
8606 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8607 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8623 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8624 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8625 ST->getBaseAlign(), MMOFlags, AAInfo);
8642 bool FillWithZeroes) {
8647 "input and widen element type must match");
8649 "cannot modify scalable vectors in this way");
8661 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8664 for (
unsigned i = 1; i != NumConcat; ++i)
8671 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8674 "Scalable vectors should have been handled already.");
8682 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8684 for (Idx = 0; Idx < MinNumElts; ++Idx)
8685 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8687 SDValue UndefVal = DAG.getUNDEF(EltVT);
8688 for (; Idx < WidenNumElts; ++Idx)
8689 Ops[Idx] = UndefVal;
8691 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8692 if (!FillWithZeroes)
8696 "We expect to never want to FillWithZeroes for non-integral types.");
8699 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8700 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8702 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8703 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 a 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.
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 getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
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.
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, IMM) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by IMM elements and retu...
@ 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, IMM) - Shifts CONCAT_VECTORS(VEC1, VEC2) right by IMM elements and re...
@ 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.