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);
1224 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1240 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1243 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1252 case ISD::VP_LOAD_FF:
1255 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1262 case ISD::VP_GATHER:
1266 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1270 SplitVecRes_SETCC(
N,
Lo,
Hi);
1273 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1280 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1283 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1286 SplitVecRes_VECTOR_INTERLEAVE(
N);
1289 SplitVecRes_VAARG(
N,
Lo,
Hi);
1295 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1301 case ISD::VP_BITREVERSE:
1309 case ISD::VP_CTLZ_ZERO_UNDEF:
1311 case ISD::VP_CTTZ_ZERO_UNDEF:
1326 case ISD::VP_FFLOOR:
1331 case ISD::VP_FNEARBYINT:
1336 case ISD::VP_FP_EXTEND:
1338 case ISD::VP_FP_ROUND:
1340 case ISD::VP_FP_TO_SINT:
1342 case ISD::VP_FP_TO_UINT:
1348 case ISD::VP_LLRINT:
1350 case ISD::VP_FROUND:
1352 case ISD::VP_FROUNDEVEN:
1361 case ISD::VP_FROUNDTOZERO:
1363 case ISD::VP_SINT_TO_FP:
1365 case ISD::VP_TRUNCATE:
1367 case ISD::VP_UINT_TO_FP:
1370 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1373 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1379 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1385 case ISD::VP_SIGN_EXTEND:
1386 case ISD::VP_ZERO_EXTEND:
1387 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1409 case ISD::VP_FMINNUM:
1412 case ISD::VP_FMAXNUM:
1414 case ISD::VP_FMINIMUM:
1416 case ISD::VP_FMAXIMUM:
1425 case ISD::OR:
case ISD::VP_OR:
1445 case ISD::VP_FCOPYSIGN:
1446 SplitVecRes_BinOp(
N,
Lo,
Hi);
1453 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1457 SplitVecRes_CMP(
N,
Lo,
Hi);
1460#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1461 case ISD::STRICT_##DAGN:
1462#include "llvm/IR/ConstrainedOps.def"
1463 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1468 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1477 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1487 SplitVecRes_FIX(
N,
Lo,
Hi);
1489 case ISD::EXPERIMENTAL_VP_SPLICE:
1490 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1492 case ISD::EXPERIMENTAL_VP_REVERSE:
1493 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1499 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1502 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1511void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1513 uint64_t *ScaledOffset) {
1518 SDValue BytesIncrement = DAG.getVScale(
1521 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1523 *ScaledOffset += IncrementSize;
1533std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1534 return SplitMask(Mask, SDLoc(Mask));
1537std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1540 EVT MaskVT =
Mask.getValueType();
1542 GetSplitVector(Mask, MaskLo, MaskHi);
1544 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1545 return std::make_pair(MaskLo, MaskHi);
1550 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1552 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1555 const SDNodeFlags
Flags =
N->getFlags();
1556 unsigned Opcode =
N->getOpcode();
1557 if (
N->getNumOperands() == 2) {
1558 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1559 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1563 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1564 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1567 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1570 std::tie(EVLLo, EVLHi) =
1571 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1574 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1576 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1582 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1584 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1586 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1589 const SDNodeFlags
Flags =
N->getFlags();
1590 unsigned Opcode =
N->getOpcode();
1591 if (
N->getNumOperands() == 3) {
1592 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1593 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1597 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1598 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1601 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1604 std::tie(EVLLo, EVLHi) =
1605 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1608 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1610 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1614 LLVMContext &Ctxt = *DAG.getContext();
1620 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1622 GetSplitVector(
LHS, LHSLo, LHSHi);
1623 GetSplitVector(
RHS, RHSLo, RHSHi);
1625 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1626 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1630 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1631 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1636 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1638 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1642 unsigned Opcode =
N->getOpcode();
1643 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1645 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1654 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1661 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.getPOISON(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)
2053 Scalars.
push_back(DAG.getPOISON(EltVT));
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.getPOISON(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.getPOISON(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.getPOISON(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.getPOISON(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);
3406 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3408 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3410 DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr, PoisonPtr, TrueMask,
3414 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3419 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3420 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3422 uint64_t TrailingElts = -
Imm;
3424 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3433 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3437 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3439 DAG.getVectorIdxConstant(0,
DL));
3445void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3453 GetSplitVector(Acc, AccLo, AccHi);
3454 unsigned Opcode =
N->getOpcode();
3466 GetSplitVector(Input1, Input1Lo, Input1Hi);
3467 GetSplitVector(Input2, Input2Lo, Input2Hi);
3470 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3471 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3474void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3482 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3490void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3491 unsigned Factor =
N->getNumOperands();
3494 for (
unsigned i = 0; i != Factor; ++i) {
3496 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3498 Ops[i * 2 + 1] = OpHi;
3509 for (
unsigned i = 0; i != Factor; ++i)
3513void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3514 unsigned Factor =
N->getNumOperands();
3517 for (
unsigned i = 0; i != Factor; ++i) {
3519 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3521 Ops[i + Factor] = OpHi;
3532 for (
unsigned i = 0; i != Factor; ++i) {
3533 unsigned IdxLo = 2 * i;
3534 unsigned IdxHi = 2 * i + 1;
3535 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3536 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3548bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3553 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3556 switch (
N->getOpcode()) {
3559 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3569 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3575 case ISD::VP_TRUNCATE:
3577 Res = SplitVecOp_TruncateHelper(
N);
3580 case ISD::VP_FP_ROUND:
3589 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3596 case ISD::VP_SCATTER:
3600 case ISD::VP_GATHER:
3604 Res = SplitVecOp_VSELECT(
N, OpNo);
3607 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3613 case ISD::VP_SINT_TO_FP:
3614 case ISD::VP_UINT_TO_FP:
3615 if (
N->getValueType(0).bitsLT(
3616 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3617 Res = SplitVecOp_TruncateHelper(
N);
3619 Res = SplitVecOp_UnaryOp(
N);
3623 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3627 case ISD::VP_FP_TO_SINT:
3628 case ISD::VP_FP_TO_UINT:
3641 Res = SplitVecOp_UnaryOp(
N);
3644 Res = SplitVecOp_FPOpDifferentTypes(
N);
3649 Res = SplitVecOp_CMP(
N);
3653 Res = SplitVecOp_FAKE_USE(
N);
3658 Res = SplitVecOp_ExtVecInRegOp(
N);
3676 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3680 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3682 case ISD::VP_REDUCE_FADD:
3683 case ISD::VP_REDUCE_SEQ_FADD:
3684 case ISD::VP_REDUCE_FMUL:
3685 case ISD::VP_REDUCE_SEQ_FMUL:
3686 case ISD::VP_REDUCE_ADD:
3687 case ISD::VP_REDUCE_MUL:
3688 case ISD::VP_REDUCE_AND:
3689 case ISD::VP_REDUCE_OR:
3690 case ISD::VP_REDUCE_XOR:
3691 case ISD::VP_REDUCE_SMAX:
3692 case ISD::VP_REDUCE_SMIN:
3693 case ISD::VP_REDUCE_UMAX:
3694 case ISD::VP_REDUCE_UMIN:
3695 case ISD::VP_REDUCE_FMAX:
3696 case ISD::VP_REDUCE_FMIN:
3697 case ISD::VP_REDUCE_FMAXIMUM:
3698 case ISD::VP_REDUCE_FMINIMUM:
3699 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3701 case ISD::VP_CTTZ_ELTS:
3702 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3703 Res = SplitVecOp_VP_CttzElements(
N);
3706 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3712 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3717 if (!Res.
getNode())
return false;
3724 if (
N->isStrictFPOpcode())
3726 "Invalid operand expansion");
3729 "Invalid operand expansion");
3731 ReplaceValueWith(
SDValue(
N, 0), Res);
3735SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3738 assert(OpNo == 0 &&
"Illegal operand must be mask");
3745 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3748 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3749 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3750 "Lo and Hi have differing types");
3753 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3754 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3756 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3757 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3758 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3759 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3769SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3772 assert(OpNo == 1 &&
"Illegal operand must be mask");
3777 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3779 EVT VecVT =
N->getValueType(0);
3783SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3784 EVT ResVT =
N->getValueType(0);
3790 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3791 GetSplitVector(VecOp,
Lo,
Hi);
3793 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3798 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3799 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3803 EVT ResVT =
N->getValueType(0);
3809 SDNodeFlags
Flags =
N->getFlags();
3812 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3813 GetSplitVector(VecOp,
Lo,
Hi);
3815 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3821 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3824SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3825 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3826 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3828 unsigned Opc =
N->getOpcode();
3829 EVT ResVT =
N->getValueType(0);
3835 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3836 GetSplitVector(VecOp,
Lo,
Hi);
3839 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3842 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3844 const SDNodeFlags
Flags =
N->getFlags();
3848 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3853 EVT ResVT =
N->getValueType(0);
3856 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3857 EVT InVT =
Lo.getValueType();
3862 if (
N->isStrictFPOpcode()) {
3863 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3864 {N->getOperand(0), Lo});
3865 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3866 {N->getOperand(0), Hi});
3875 ReplaceValueWith(
SDValue(
N, 1), Ch);
3876 }
else if (
N->getNumOperands() == 3) {
3877 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3878 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3879 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3880 std::tie(EVLLo, EVLHi) =
3881 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3882 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3883 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3885 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3886 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3895 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3905 EVT ResVT =
N->getValueType(0);
3907 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3911 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3917 Lo = BitConvertToInteger(
Lo);
3918 Hi = BitConvertToInteger(
Hi);
3920 if (DAG.getDataLayout().isBigEndian())
3928 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3930 EVT ResVT =
N->getValueType(0);
3938 GetSplitVector(SubVec,
Lo,
Hi);
3947 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3949 return SecondInsertion;
3952SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3959 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3961 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
3963 ElementCount IdxVal =
3967 EVT SrcVT =
N->getOperand(0).getValueType();
3986 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
3987 LoEltsMin - IdxValMin);
3988 DAG.ExtractVectorElements(
Hi, Elts, 0,
3991 return DAG.getBuildVector(SubVT, dl, Elts);
3995 ElementCount ExtractIdx = IdxVal - LoElts;
3997 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4000 EVT HiVT =
Hi.getValueType();
4002 "Only fixed-vector extracts are supported in this case");
4012 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4013 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4019 "Extracting scalable subvector from fixed-width unsupported");
4027 "subvector from a scalable predicate vector");
4033 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4035 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4036 auto &MF = DAG.getMachineFunction();
4040 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4044 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4047 SubVT, dl, Store, StackPtr,
4051SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4057 uint64_t IdxVal =
Index->getZExtValue();
4060 GetSplitVector(Vec,
Lo,
Hi);
4062 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4064 if (IdxVal < LoElts)
4065 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4068 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4073 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4085 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4091 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4093 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4094 auto &MF = DAG.getMachineFunction();
4097 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4101 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4105 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4107 return DAG.getExtLoad(
4118 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4126 SplitVecRes_Gather(
N,
Lo,
Hi);
4129 ReplaceValueWith(
SDValue(
N, 0), Res);
4134 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4138 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4140 SDValue EVL =
N->getVectorLength();
4142 Align Alignment =
N->getBaseAlign();
4148 GetSplitVector(
Data, DataLo, DataHi);
4150 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4155 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4158 GetSplitVector(Mask, MaskLo, MaskHi);
4160 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4163 EVT MemoryVT =
N->getMemoryVT();
4164 EVT LoMemVT, HiMemVT;
4165 bool HiIsEmpty =
false;
4166 std::tie(LoMemVT, HiMemVT) =
4167 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4171 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4174 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4179 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4180 N->getAddressingMode(),
N->isTruncatingStore(),
4181 N->isCompressingStore());
4187 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4188 N->isCompressingStore());
4190 MachinePointerInfo MPI;
4194 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4199 MMO = DAG.getMachineFunction().getMachineMemOperand(
4201 Alignment,
N->getAAInfo(),
N->getRanges());
4203 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4204 N->getAddressingMode(),
N->isTruncatingStore(),
4205 N->isCompressingStore());
4214 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4215 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4222 GetSplitVector(
Data, LoData, HiData);
4224 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4226 EVT LoMemVT, HiMemVT;
4227 bool HiIsEmpty =
false;
4228 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4234 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4235 else if (getTypeAction(
Mask.getValueType()) ==
4237 GetSplitVector(Mask, LoMask, HiMask);
4239 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4242 std::tie(LoEVL, HiEVL) =
4243 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4247 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4248 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4249 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4260 EVT PtrVT =
N->getBasePtr().getValueType();
4263 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4266 Align Alignment =
N->getBaseAlign();
4271 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4272 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4274 Alignment,
N->getAAInfo(),
N->getRanges());
4277 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4278 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4279 N->isCompressingStore());
4288 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4292 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4295 Align Alignment =
N->getBaseAlign();
4301 GetSplitVector(
Data, DataLo, DataHi);
4303 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4308 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4311 GetSplitVector(Mask, MaskLo, MaskHi);
4313 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4316 EVT MemoryVT =
N->getMemoryVT();
4317 EVT LoMemVT, HiMemVT;
4318 bool HiIsEmpty =
false;
4319 std::tie(LoMemVT, HiMemVT) =
4320 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4323 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4328 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4329 N->getAddressingMode(),
N->isTruncatingStore(),
4330 N->isCompressingStore());
4338 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4339 N->isCompressingStore());
4341 MachinePointerInfo MPI;
4345 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4350 MMO = DAG.getMachineFunction().getMachineMemOperand(
4352 Alignment,
N->getAAInfo(),
N->getRanges());
4354 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4355 N->getAddressingMode(),
N->isTruncatingStore(),
4356 N->isCompressingStore());
4369 EVT MemoryVT =
N->getMemoryVT();
4370 Align Alignment =
N->getBaseAlign();
4377 }
Ops = [&]() -> Operands {
4379 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4383 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4388 EVT LoMemVT, HiMemVT;
4389 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4394 GetSplitVector(
Ops.Data, DataLo, DataHi);
4396 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4401 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4403 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4407 if (getTypeAction(
Ops.Index.getValueType()) ==
4409 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4411 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4415 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4417 Alignment,
N->getAAInfo(),
N->getRanges());
4420 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4422 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4423 MSC->getIndexType(), MSC->isTruncatingStore());
4428 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4429 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4430 MMO, MSC->getIndexType(),
4431 MSC->isTruncatingStore());
4435 std::tie(EVLLo, EVLHi) =
4436 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4438 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4439 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4440 VPSC->getIndexType());
4445 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4446 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4447 VPSC->getIndexType());
4451 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4452 assert(OpNo == 1 &&
"Can only split the stored value");
4455 bool isTruncating =
N->isTruncatingStore();
4458 EVT MemoryVT =
N->getMemoryVT();
4459 Align Alignment =
N->getBaseAlign();
4461 AAMDNodes AAInfo =
N->getAAInfo();
4463 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4465 EVT LoMemVT, HiMemVT;
4466 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4470 return TLI.scalarizeVectorStore(
N, DAG);
4473 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4474 Alignment, MMOFlags, AAInfo);
4476 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4479 MachinePointerInfo MPI;
4480 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4483 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4484 HiMemVT, Alignment, MMOFlags, AAInfo);
4486 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4502 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4508 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4529 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4530 SDValue InVec =
N->getOperand(OpNo);
4532 EVT OutVT =
N->getValueType(0);
4540 EVT LoOutVT, HiOutVT;
4541 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4542 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4547 if (isTypeLegal(LoOutVT) ||
4548 InElementSize <= OutElementSize * 2)
4549 return SplitVecOp_UnaryOp(
N);
4558 return SplitVecOp_UnaryOp(
N);
4562 GetSplitVector(InVec, InLoVec, InHiVec);
4568 EVT HalfElementVT = IsFloat ?
4570 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4577 if (
N->isStrictFPOpcode()) {
4578 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4579 {N->getOperand(0), InLoVec});
4580 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4581 {N->getOperand(0), InHiVec});
4587 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4588 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4592 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4600 if (
N->isStrictFPOpcode()) {
4604 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4612 DAG.getTargetConstant(
4613 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4620 assert(
N->getValueType(0).isVector() &&
4621 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4622 "Operand types must be vectors");
4624 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4626 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4627 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4629 EVT VT =
N->getValueType(0);
4636 }
else if (isStrict) {
4637 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4638 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4639 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4640 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4643 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4645 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4646 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4647 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4648 std::tie(EVLLo, EVLHi) =
4649 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4650 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4651 N->getOperand(2), MaskLo, EVLLo);
4652 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4653 N->getOperand(2), MaskHi, EVLHi);
4662 EVT ResVT =
N->getValueType(0);
4665 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4666 EVT InVT =
Lo.getValueType();
4671 if (
N->isStrictFPOpcode()) {
4672 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4673 {N->getOperand(0), Lo, N->getOperand(2)});
4674 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4675 {N->getOperand(0), Hi, N->getOperand(2)});
4679 Lo.getValue(1),
Hi.getValue(1));
4680 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4681 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4682 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4683 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4684 std::tie(EVLLo, EVLHi) =
4685 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4686 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4687 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4701SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4704 EVT LHSLoVT, LHSHiVT;
4705 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4707 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4708 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4711 std::tie(LHSLo, LHSHi) =
4712 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4715 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4718 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4724 LLVMContext &Ctxt = *DAG.getContext();
4727 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4728 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4729 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4731 EVT ResVT =
N->getValueType(0);
4736 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4737 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4743 EVT ResVT =
N->getValueType(0);
4746 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4747 EVT InVT =
Lo.getValueType();
4753 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4754 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4761 EVT ResVT =
N->getValueType(0);
4765 GetSplitVector(VecOp,
Lo,
Hi);
4767 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4768 auto [EVLLo, EVLHi] =
4770 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4776 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4778 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4779 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4782SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4793 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4794 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4795 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4796 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4797 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4798 OpsLo, MMO, IndexType);
4799 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4800 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4804SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4807 "Accumulator should already be a legal type, and shouldn't need "
4808 "further splitting");
4811 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4812 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4813 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4814 unsigned Opcode =
N->getOpcode();
4817 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4818 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4825void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4826 unsigned WidenResNo) {
4827 unsigned NumResults =
N->getNumValues();
4828 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4829 if (ResNo == WidenResNo)
4831 EVT ResVT =
N->getValueType(ResNo);
4837 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4838 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4843void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4844 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4847 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4852 auto unrollExpandedOp = [&]() {
4857 EVT VT =
N->getValueType(0);
4858 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4859 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4860 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
4862 if (
N->getNumValues() > 1)
4863 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4869 switch (
N->getOpcode()) {
4872 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4880 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4884 Res = WidenVecRes_ADDRSPACECAST(
N);
4891 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4898 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4902 Res = WidenVecRes_ScalarOp(
N);
4907 case ISD::VP_SELECT:
4909 Res = WidenVecRes_Select(
N);
4913 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4915 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4922 case ISD::VP_LOAD_FF:
4925 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4929 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4937 case ISD::VP_GATHER:
4941 Res = WidenVecRes_VECTOR_REVERSE(
N);
4944 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4954 case ISD::OR:
case ISD::VP_OR:
4965 case ISD::VP_FMINNUM:
4968 case ISD::VP_FMAXNUM:
4970 case ISD::VP_FMINIMUM:
4972 case ISD::VP_FMAXIMUM:
5005 case ISD::VP_FCOPYSIGN:
5006 Res = WidenVecRes_Binary(
N);
5011 Res = WidenVecRes_CMP(
N);
5017 if (unrollExpandedOp())
5032 Res = WidenVecRes_BinaryCanTrap(
N);
5041 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5044#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5045 case ISD::STRICT_##DAGN:
5046#include "llvm/IR/ConstrainedOps.def"
5047 Res = WidenVecRes_StrictFP(
N);
5056 Res = WidenVecRes_OverflowOp(
N, ResNo);
5060 Res = WidenVecRes_FCOPYSIGN(
N);
5065 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5070 if (!unrollExpandedOp())
5071 Res = WidenVecRes_ExpOp(
N);
5077 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5082 case ISD::VP_FP_EXTEND:
5084 case ISD::VP_FP_ROUND:
5086 case ISD::VP_FP_TO_SINT:
5088 case ISD::VP_FP_TO_UINT:
5090 case ISD::VP_SIGN_EXTEND:
5092 case ISD::VP_SINT_TO_FP:
5093 case ISD::VP_TRUNCATE:
5096 case ISD::VP_UINT_TO_FP:
5098 case ISD::VP_ZERO_EXTEND:
5099 Res = WidenVecRes_Convert(
N);
5104 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5110 case ISD::VP_LLRINT:
5113 Res = WidenVecRes_XROUND(
N);
5139 if (unrollExpandedOp())
5149 case ISD::VP_BITREVERSE:
5155 case ISD::VP_CTLZ_ZERO_UNDEF:
5161 case ISD::VP_CTTZ_ZERO_UNDEF:
5166 case ISD::VP_FFLOOR:
5168 case ISD::VP_FNEARBYINT:
5169 case ISD::VP_FROUND:
5170 case ISD::VP_FROUNDEVEN:
5171 case ISD::VP_FROUNDTOZERO:
5176 Res = WidenVecRes_Unary(
N);
5183 Res = WidenVecRes_Ternary(
N);
5189 if (!unrollExpandedOp())
5190 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5197 SetWidenedVector(
SDValue(
N, ResNo), Res);
5203 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5204 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5205 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5206 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5207 if (
N->getNumOperands() == 3)
5208 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5210 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5211 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5215 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5216 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5222 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5223 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5224 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5225 if (
N->getNumOperands() == 2)
5226 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5229 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5230 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5234 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5235 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5239 LLVMContext &Ctxt = *DAG.getContext();
5244 EVT OpVT =
LHS.getValueType();
5246 LHS = GetWidenedVector(
LHS);
5247 RHS = GetWidenedVector(
RHS);
5248 OpVT =
LHS.getValueType();
5251 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5254 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5260SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5263 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5264 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5265 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5267 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5276 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5279 if (ConcatEnd == 1) {
5280 VT = ConcatOps[0].getValueType();
5282 return ConcatOps[0];
5285 SDLoc dl(ConcatOps[0]);
5292 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5293 int Idx = ConcatEnd - 1;
5294 VT = ConcatOps[Idx--].getValueType();
5295 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5308 unsigned NumToInsert = ConcatEnd - Idx - 1;
5309 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5311 ConcatOps[Idx+1] = VecOp;
5312 ConcatEnd = Idx + 2;
5318 unsigned RealVals = ConcatEnd - Idx - 1;
5319 unsigned SubConcatEnd = 0;
5320 unsigned SubConcatIdx = Idx + 1;
5321 while (SubConcatEnd < RealVals)
5322 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5323 while (SubConcatEnd < OpsToConcat)
5324 SubConcatOps[SubConcatEnd++] = undefVec;
5326 NextVT, SubConcatOps);
5327 ConcatEnd = SubConcatIdx + 1;
5332 if (ConcatEnd == 1) {
5333 VT = ConcatOps[0].getValueType();
5335 return ConcatOps[0];
5340 if (
NumOps != ConcatEnd ) {
5342 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5343 ConcatOps[j] = UndefVal;
5351 unsigned Opcode =
N->getOpcode();
5353 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5357 const SDNodeFlags
Flags =
N->getFlags();
5358 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5359 NumElts = NumElts / 2;
5363 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5365 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5366 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5367 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5375 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5378 TLI.isTypeLegal(WideMaskVT)) {
5379 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5380 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5381 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5383 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5384 N->getValueType(0).getVectorElementCount());
5385 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5399 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5400 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5401 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5404 unsigned ConcatEnd = 0;
5412 while (CurNumElts != 0) {
5413 while (CurNumElts >= NumElts) {
5414 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5415 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5416 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5418 CurNumElts -= NumElts;
5421 NumElts = NumElts / 2;
5423 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5426 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5427 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5428 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5429 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5440 switch (
N->getOpcode()) {
5443 return WidenVecRes_STRICT_FSETCC(
N);
5450 return WidenVecRes_Convert_StrictFP(
N);
5457 unsigned Opcode =
N->getOpcode();
5459 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5463 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5464 NumElts = NumElts / 2;
5475 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5479 unsigned ConcatEnd = 0;
5486 for (
unsigned i = 1; i < NumOpers; ++i) {
5492 Oper = GetWidenedVector(Oper);
5498 DAG.getPOISON(WideOpVT), Oper,
5499 DAG.getVectorIdxConstant(0, dl));
5511 while (CurNumElts != 0) {
5512 while (CurNumElts >= NumElts) {
5515 for (
unsigned i = 0; i < NumOpers; ++i) {
5518 EVT OpVT =
Op.getValueType();
5523 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5529 EVT OperVT[] = {VT, MVT::Other};
5531 ConcatOps[ConcatEnd++] = Oper;
5534 CurNumElts -= NumElts;
5537 NumElts = NumElts / 2;
5539 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5542 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5545 for (
unsigned i = 0; i < NumOpers; ++i) {
5548 EVT OpVT =
Op.getValueType();
5556 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5558 ConcatOps[ConcatEnd++] = Oper;
5567 if (Chains.
size() == 1)
5568 NewChain = Chains[0];
5571 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5576SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5578 EVT ResVT =
N->getValueType(0);
5579 EVT OvVT =
N->getValueType(1);
5580 EVT WideResVT, WideOvVT;
5585 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5590 WideLHS = GetWidenedVector(
N->getOperand(0));
5591 WideRHS = GetWidenedVector(
N->getOperand(1));
5593 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5602 N->getOperand(0), Zero);
5604 N->getOperand(1), Zero);
5607 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5608 SDNode *WideNode = DAG.getNode(
5609 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5612 unsigned OtherNo = 1 - ResNo;
5613 EVT OtherVT =
N->getValueType(OtherNo);
5620 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5623 return SDValue(WideNode, ResNo);
5627 LLVMContext &Ctx = *DAG.getContext();
5631 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5636 unsigned Opcode =
N->getOpcode();
5637 const SDNodeFlags
Flags =
N->getFlags();
5643 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5645 InOp = ZExtPromotedInteger(InOp);
5656 InOp = GetWidenedVector(
N->getOperand(0));
5659 if (InVTEC == WidenEC) {
5660 if (
N->getNumOperands() == 1)
5661 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5662 if (
N->getNumOperands() == 3) {
5663 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5666 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5668 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5694 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5698 if (TLI.isTypeLegal(InWidenVT)) {
5706 unsigned NumConcat =
5711 if (
N->getNumOperands() == 1)
5712 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5713 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5717 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5719 if (
N->getNumOperands() == 1)
5720 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5721 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5730 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5731 for (
unsigned i=0; i < MinElts; ++i) {
5732 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5733 if (
N->getNumOperands() == 1)
5736 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5739 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5744 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5748 EVT SrcVT = Src.getValueType();
5752 Src = GetWidenedVector(Src);
5753 SrcVT = Src.getValueType();
5760 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5765 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5769 EVT SrcVT = Src.getValueType();
5773 Src = GetWidenedVector(Src);
5774 SrcVT = Src.getValueType();
5781 if (
N->getNumOperands() == 1)
5782 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5784 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5785 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5789 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5792SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5797 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5803 unsigned Opcode =
N->getOpcode();
5809 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5814 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5815 for (
unsigned i=0; i < MinElts; ++i) {
5816 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5817 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5821 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5823 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5826SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5827 unsigned Opcode =
N->getOpcode();
5831 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5840 InOp = GetWidenedVector(InOp);
5847 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5854 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5855 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5872 while (
Ops.size() != WidenNumElts)
5873 Ops.push_back(DAG.getPOISON(WidenSVT));
5875 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5881 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5882 return WidenVecRes_BinaryCanTrap(
N);
5885 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5892SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5894 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5897 SDValue Arg = GetWidenedVector(FpValue);
5898 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5903 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5904 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5906 EVT ExpVT =
RHS.getValueType();
5911 ExpOp = ModifyToType(
RHS, WideExpVT);
5914 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5919 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5920 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5921 if (
N->getNumOperands() == 1)
5922 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5924 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5925 N->getOperand(1),
N->getFlags());
5927 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5928 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5932 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5933 {InOp,
Mask,
N->getOperand(2)});
5937 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5940 .getVectorElementType(),
5942 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5943 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5944 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5947SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5949 EVT VT0 =
N->getValueType(0);
5950 EVT VT1 =
N->getValueType(1);
5954 "expected both results to be vectors of matching element count");
5956 LLVMContext &Ctx = *DAG.getContext();
5957 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5959 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5966 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5969 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5970 return SDValue(WidenNode, ResNo);
5973SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5974 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5975 return GetWidenedVector(WidenVec);
5979 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5980 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5983 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5984 AddrSpaceCastN->getSrcAddressSpace(),
5985 AddrSpaceCastN->getDestAddressSpace());
5991 EVT VT =
N->getValueType(0);
5992 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5995 switch (getTypeAction(InVT)) {
6009 SDValue NInOp = GetPromotedInteger(InOp);
6011 if (WidenVT.
bitsEq(NInVT)) {
6014 if (DAG.getDataLayout().isBigEndian()) {
6017 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.getPOISON(
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.getPOISON(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.getPOISON(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.getPOISON(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) {
7706 EVT ResVT =
N->getValueType(0);
7709 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
7715 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
7723 "Widened input size must be a multiple of result element size");
7726 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
7728 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
7729 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
7737 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7738 return TLI.scalarizeVectorStore(ST, DAG);
7740 if (
ST->isTruncatingStore())
7741 return TLI.scalarizeVectorStore(ST, DAG);
7751 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7752 EVT WideMaskVT = getSetCCResultType(WideVT);
7754 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7755 TLI.isTypeLegal(WideMaskVT)) {
7758 StVal = GetWidenedVector(StVal);
7760 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7762 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7763 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7764 ST->getAddressingMode());
7768 if (GenWidenVectorStores(StChain, ST)) {
7769 if (StChain.
size() == 1)
7778 SDValue WideStVal = GetWidenedVector(StVal);
7782 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7783 ST->getOffset(), Mask,
ST->getMemoryVT(),
7784 ST->getMemOperand(),
ST->getAddressingMode(),
7785 ST->isTruncatingStore());
7791SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7792 assert((OpNo == 1 || OpNo == 3) &&
7793 "Can widen only data or mask operand of vp_store");
7801 StVal = GetWidenedVector(StVal);
7807 "Unable to widen VP store");
7808 Mask = GetWidenedVector(Mask);
7810 Mask = GetWidenedVector(Mask);
7816 "Unable to widen VP store");
7817 StVal = GetWidenedVector(StVal);
7820 assert(
Mask.getValueType().getVectorElementCount() ==
7822 "Mask and data vectors should have the same number of elements");
7823 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7824 ST->getOffset(), Mask,
ST->getVectorLength(),
7825 ST->getMemoryVT(),
ST->getMemOperand(),
7826 ST->getAddressingMode(),
ST->isTruncatingStore(),
7827 ST->isCompressingStore());
7832 assert((OpNo == 1 || OpNo == 4) &&
7833 "Can widen only data or mask operand of vp_strided_store");
7842 "Unable to widen VP strided store");
7846 "Unable to widen VP strided store");
7848 StVal = GetWidenedVector(StVal);
7849 Mask = GetWidenedVector(Mask);
7852 Mask.getValueType().getVectorElementCount() &&
7853 "Data and mask vectors should have the same number of elements");
7855 return DAG.getStridedStoreVP(
7862SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7863 assert((OpNo == 1 || OpNo == 4) &&
7864 "Can widen only data or mask operand of mstore");
7867 EVT MaskVT =
Mask.getValueType();
7872 EVT WideVT, WideMaskVT;
7875 StVal = GetWidenedVector(StVal);
7882 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7889 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7890 TLI.isTypeLegal(WideMaskVT)) {
7891 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7892 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7901 Mask = ModifyToType(Mask, WideMaskVT,
true);
7904 Mask = ModifyToType(Mask, WideMaskVT,
true);
7906 StVal = ModifyToType(StVal, WideVT);
7909 assert(
Mask.getValueType().getVectorElementCount() ==
7911 "Mask and data vectors should have the same number of elements");
7918SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7919 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7921 SDValue DataOp = MG->getPassThru();
7923 SDValue Scale = MG->getScale();
7931 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7932 MG->getMemOperand(), MG->getIndexType(),
7933 MG->getExtensionType());
7939SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7948 DataOp = GetWidenedVector(DataOp);
7952 EVT IndexVT =
Index.getValueType();
7955 Index = ModifyToType(Index, WideIndexVT);
7958 EVT MaskVT =
Mask.getValueType();
7961 Mask = ModifyToType(Mask, WideMaskVT,
true);
7966 }
else if (OpNo == 4) {
7968 Index = GetWidenedVector(Index);
7974 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7979SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7988 DataOp = GetWidenedVector(DataOp);
7989 Index = GetWidenedVector(Index);
7991 Mask = GetWidenedMask(Mask, WideEC);
7994 }
else if (OpNo == 3) {
7996 Index = GetWidenedVector(Index);
8003 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8008 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8009 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8011 EVT VT =
N->getValueType(0);
8026 SVT, InOp0, InOp1,
N->getOperand(2));
8032 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8034 EVT OpVT =
N->getOperand(0).getValueType();
8037 return DAG.getNode(ExtendCode, dl, VT, CC);
8047 EVT VT =
N->getValueType(0);
8049 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8056 for (
unsigned i = 0; i != NumElts; ++i) {
8057 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8058 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8060 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8061 {Chain, LHSElem, RHSElem, CC});
8062 Chains[i] = Scalars[i].getValue(1);
8063 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8064 DAG.getBoolConstant(
true, dl, EltVT, VT),
8065 DAG.getBoolConstant(
false, dl, EltVT, VT));
8069 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8071 return DAG.getBuildVector(VT, dl, Scalars);
8095 SDValue Op = GetWidenedVector(
N->getOperand(0));
8096 EVT VT =
N->getValueType(0);
8097 EVT OrigVT =
N->getOperand(0).getValueType();
8098 EVT WideVT =
Op.getValueType();
8100 SDNodeFlags
Flags =
N->getFlags();
8102 unsigned Opc =
N->getOpcode();
8104 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8105 assert(NeutralElem &&
"Neutral element must exist");
8115 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8122 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8123 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8129 unsigned GCD = std::gcd(OrigElts, WideElts);
8132 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8133 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8134 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8135 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8138 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8139 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8141 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8150 EVT VT =
N->getValueType(0);
8152 EVT WideVT =
Op.getValueType();
8154 SDNodeFlags
Flags =
N->getFlags();
8156 unsigned Opc =
N->getOpcode();
8158 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8168 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8171 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8172 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8178 unsigned GCD = std::gcd(OrigElts, WideElts);
8181 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8182 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8183 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8184 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8187 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8188 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8190 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8194 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8197 SDValue Op = GetWidenedVector(
N->getOperand(1));
8199 Op.getValueType().getVectorElementCount());
8201 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8202 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8210 EVT VT =
N->getValueType(0);
8214 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8215 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8220 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8226 EVT SrcVT =
Source.getValueType();
8230 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8231 {Source, Mask, N->getOperand(2)},
N->getFlags());
8234SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8237 EVT OrigMaskVT =
Mask.getValueType();
8238 SDValue WideMask = GetWidenedVector(Mask);
8244 if (OrigElts != WideElts) {
8245 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8247 Mask, DAG.getVectorIdxConstant(0,
DL));
8268 unsigned WidenEx = 0) {
8273 unsigned AlignInBits =
Align*8;
8275 EVT RetVT = WidenEltVT;
8280 if (Width == WidenEltWidth)
8291 (WidenWidth % MemVTWidth) == 0 &&
8293 (MemVTWidth <= Width ||
8294 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8295 if (MemVTWidth == WidenWidth)
8314 (WidenWidth % MemVTWidth) == 0 &&
8316 (MemVTWidth <= Width ||
8317 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8326 return std::nullopt;
8337 unsigned Start,
unsigned End) {
8338 SDLoc dl(LdOps[Start]);
8339 EVT LdTy = LdOps[Start].getValueType();
8347 for (
unsigned i = Start + 1; i != End; ++i) {
8348 EVT NewLdTy = LdOps[i].getValueType();
8349 if (NewLdTy != LdTy) {
8368 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8369 EVT LdVT =
LD->getMemoryVT();
8379 AAMDNodes AAInfo =
LD->getAAInfo();
8383 TypeSize WidthDiff = WidenWidth - LdWidth;
8390 std::optional<EVT> FirstVT =
8391 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8398 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8403 std::optional<EVT> NewVT = FirstVT;
8404 TypeSize RemainingWidth = LdWidth;
8405 TypeSize NewVTWidth = FirstVTWidth;
8407 RemainingWidth -= NewVTWidth;
8414 NewVTWidth = NewVT->getSizeInBits();
8420 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8421 LD->getBaseAlign(), MMOFlags, AAInfo);
8433 uint64_t ScaledOffset = 0;
8434 MachinePointerInfo MPI =
LD->getPointerInfo();
8440 for (EVT MemVT : MemVTs) {
8441 Align NewAlign = ScaledOffset == 0
8442 ?
LD->getBaseAlign()
8445 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8453 unsigned End = LdOps.
size();
8464 EVT LdTy = LdOps[i].getValueType();
8467 for (--i; i >= 0; --i) {
8468 LdTy = LdOps[i].getValueType();
8475 ConcatOps[--Idx] = LdOps[i];
8476 for (--i; i >= 0; --i) {
8477 EVT NewLdTy = LdOps[i].getValueType();
8478 if (NewLdTy != LdTy) {
8488 for (;
j != End-Idx; ++
j)
8489 WidenOps[j] = ConcatOps[Idx+j];
8491 WidenOps[j] = DAG.getPOISON(LdTy);
8498 ConcatOps[--Idx] = LdOps[i];
8503 ArrayRef(&ConcatOps[Idx], End - Idx));
8509 SDValue UndefVal = DAG.getPOISON(LdTy);
8512 for (; i != End-Idx; ++i)
8513 WidenOps[i] = ConcatOps[Idx+i];
8515 WidenOps[i] = UndefVal;
8526 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8527 EVT LdVT =
LD->getMemoryVT();
8536 AAMDNodes AAInfo =
LD->getAAInfo();
8550 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8551 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8557 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8558 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8559 LD->getBaseAlign(), MMOFlags, AAInfo);
8564 SDValue UndefVal = DAG.getPOISON(EltVT);
8565 for (; i != WidenNumElts; ++i)
8568 return DAG.getBuildVector(WidenVT, dl,
Ops);
8579 AAMDNodes AAInfo =
ST->getAAInfo();
8580 SDValue ValOp = GetWidenedVector(
ST->getValue());
8583 EVT StVT =
ST->getMemoryVT();
8591 "Mismatch between store and value types");
8595 MachinePointerInfo MPI =
ST->getPointerInfo();
8596 uint64_t ScaledOffset = 0;
8605 std::optional<EVT> NewVT =
8610 TypeSize NewVTWidth = NewVT->getSizeInBits();
8613 StWidth -= NewVTWidth;
8614 MemVTs.
back().second++;
8618 for (
const auto &Pair : MemVTs) {
8619 EVT NewVT = Pair.first;
8620 unsigned Count = Pair.second;
8626 Align NewAlign = ScaledOffset == 0
8627 ?
ST->getBaseAlign()
8629 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8630 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8646 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8647 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8648 ST->getBaseAlign(), MMOFlags, AAInfo);
8665 bool FillWithZeroes) {
8670 "input and widen element type must match");
8672 "cannot modify scalable vectors in this way");
8685 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
8687 for (
unsigned i = 1; i != NumConcat; ++i)
8694 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8697 "Scalable vectors should have been handled already.");
8705 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8707 for (Idx = 0; Idx < MinNumElts; ++Idx)
8708 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8710 SDValue UndefVal = DAG.getPOISON(EltVT);
8711 for (; Idx < WidenNumElts; ++Idx)
8712 Ops[Idx] = UndefVal;
8714 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8715 if (!FillWithZeroes)
8719 "We expect to never want to FillWithZeroes for non-integral types.");
8722 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8723 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8725 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8726 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 getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by OFFSET elements an...
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.