35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
46 switch (
N->getOpcode()) {
49 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
58 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
69 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
81 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
83 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
89 R = ScalarizeVecRes_VecInregOp(
N);
140 R = ScalarizeVecRes_UnaryOp(
N);
143 R = ScalarizeVecRes_ADDRSPACECAST(
N);
149 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
206 R = ScalarizeVecRes_BinOp(
N);
211 R = ScalarizeVecRes_CMP(
N);
217 R = ScalarizeVecRes_TernaryOp(
N);
220#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
221 case ISD::STRICT_##DAGN:
222#include "llvm/IR/ConstrainedOps.def"
223 R = ScalarizeVecRes_StrictFPOp(
N);
228 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
237 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
247 R = ScalarizeVecRes_FIX(
N);
253 SetScalarizedVector(
SDValue(
N, ResNo), R);
257 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
258 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
259 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
268 if (getTypeAction(
LHS.getValueType()) ==
270 LHS = GetScalarizedVector(
LHS);
271 RHS = GetScalarizedVector(
RHS);
273 EVT VT =
LHS.getValueType().getVectorElementType();
274 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
275 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
278 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
279 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
283 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
284 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
285 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
286 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
291 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
292 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
299DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
301 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
302 "Unexpected vector type!");
303 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
305 EVT VT0 =
N->getValueType(0);
306 EVT VT1 =
N->getValueType(1);
310 DAG.getNode(
N->getOpcode(), dl,
311 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
315 unsigned OtherNo = 1 - ResNo;
316 EVT OtherVT =
N->getValueType(OtherNo);
318 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
322 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
325 return SDValue(ScalarNode, ResNo);
330 unsigned NumOpers =
N->getNumOperands();
332 EVT ValueVTs[] = {VT, MVT::Other};
341 for (
unsigned i = 1; i < NumOpers; ++i) {
347 Oper = GetScalarizedVector(Oper);
356 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
357 Opers,
N->getFlags());
368 EVT ResVT =
N->getValueType(0);
369 EVT OvVT =
N->getValueType(1);
373 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
374 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
377 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
378 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
379 ScalarLHS = ElemsLHS[0];
380 ScalarRHS = ElemsRHS[0];
383 SDVTList ScalarVTs = DAG.getVTList(
385 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
386 {ScalarLHS, ScalarRHS},
N->getFlags())
390 unsigned OtherNo = 1 - ResNo;
391 EVT OtherVT =
N->getValueType(OtherNo);
393 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
397 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
400 return SDValue(ScalarNode, ResNo);
405 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
406 return GetScalarizedVector(
Op);
409SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
411 SDValue SourceValue =
N->getOperand(0);
412 SDValue SinkValue =
N->getOperand(1);
413 SDValue EltSizeInBytes =
N->getOperand(2);
414 SDValue LaneOffset =
N->getOperand(3);
422 if (IsReadAfterWrite)
430 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
435 return DAG.getNode(
ISD::OR,
DL, CmpVT, Cmp,
442 Op = GetScalarizedVector(
Op);
443 EVT NewVT =
N->getValueType(0).getVectorElementType();
448SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
458SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
460 N->getValueType(0).getVectorElementType(),
461 N->getOperand(0),
N->getOperand(1));
467 EVT OpVT =
Op.getValueType();
471 Op = GetScalarizedVector(
Op);
474 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
477 N->getValueType(0).getVectorElementType(),
Op,
481SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
482 SDValue Op = GetScalarizedVector(
N->getOperand(0));
483 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
487SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
492 if (
Op.getValueType() != EltVT)
500 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
501 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
511 assert(
N->isUnindexed() &&
"Indexed vector load?");
515 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
516 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
517 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
518 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
530 EVT OpVT =
Op.getValueType();
540 Op = GetScalarizedVector(
Op);
543 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
545 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
551 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
552 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
553 LHS, DAG.getValueType(ExtVT));
560 EVT OpVT =
Op.getValueType();
565 Op = GetScalarizedVector(
Op);
567 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
570 switch (
N->getOpcode()) {
582SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
585 EVT OpVT =
Op.getValueType();
595 Op = GetScalarizedVector(
Op);
598 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
601 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
602 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
603 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
606SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
618 EVT OpVT =
Cond.getValueType();
627 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
630 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
632 TLI.getBooleanContents(
false,
false);
639 if (TLI.getBooleanContents(
false,
false) !=
640 TLI.getBooleanContents(
false,
true)) {
644 EVT OpVT =
Cond->getOperand(0).getValueType();
646 VecBool = TLI.getBooleanContents(OpVT);
651 EVT CondVT =
Cond.getValueType();
652 if (ScalarBool != VecBool) {
653 switch (ScalarBool) {
661 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
668 Cond, DAG.getValueType(MVT::i1));
674 auto BoolVT = getSetCCResultType(CondVT);
675 if (BoolVT.bitsLT(CondVT))
678 return DAG.getSelect(SDLoc(
N),
680 GetScalarizedVector(
N->getOperand(2)));
684 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
685 return DAG.getSelect(SDLoc(
N),
686 LHS.getValueType(),
N->getOperand(0),
LHS,
687 GetScalarizedVector(
N->getOperand(2)));
691 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
693 N->getOperand(0),
N->getOperand(1),
694 LHS, GetScalarizedVector(
N->getOperand(3)),
699 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
702SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
706 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
708 return GetScalarizedVector(
N->getOperand(
Op));
711SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
713 EVT SrcVT = Src.getValueType();
718 Src = GetScalarizedVector(Src);
722 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
724 EVT DstVT =
N->getValueType(0).getVectorElementType();
725 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
729 assert(
N->getValueType(0).isVector() &&
730 N->getOperand(0).getValueType().isVector() &&
731 "Operand types must be vectors");
734 EVT OpVT =
LHS.getValueType();
735 EVT NVT =
N->getValueType(0).getVectorElementType();
740 LHS = GetScalarizedVector(
LHS);
741 RHS = GetScalarizedVector(
RHS);
744 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
745 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
755 return DAG.getNode(ExtendCode,
DL, NVT, Res);
766 Arg = GetScalarizedVector(Arg);
769 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
778 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
785bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
790 switch (
N->getOpcode()) {
793 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
800 Res = ScalarizeVecOp_BITCAST(
N);
803 Res = ScalarizeVecOp_FAKE_USE(
N);
817 Res = ScalarizeVecOp_UnaryOp(
N);
821 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
827 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
830 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
833 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
836 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
839 Res = ScalarizeVecOp_VSELECT(
N);
842 Res = ScalarizeVecOp_VSETCC(
N);
846 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
852 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
855 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
858 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
861 Res = ScalarizeVecOp_FP_EXTEND(
N);
878 Res = ScalarizeVecOp_VECREDUCE(
N);
882 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
886 Res = ScalarizeVecOp_CMP(
N);
891 if (!Res.
getNode())
return false;
899 "Invalid operand expansion");
901 ReplaceValueWith(
SDValue(
N, 0), Res);
908 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
910 N->getValueType(0), Elt);
915 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
916 "Fake Use: Unexpected vector type!");
917 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
918 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
924 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
925 "Unexpected vector type!");
926 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
928 N->getValueType(0).getScalarType(), Elt);
936SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
937 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
938 "Unexpected vector type!");
939 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
941 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
942 Elt,
N->getOperand(1));
950SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
951 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
952 "Unexpected vector type!");
953 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
955 {
N->getValueType(0).getScalarType(), MVT::Other },
956 {
N->getOperand(0), Elt });
966 ReplaceValueWith(
SDValue(
N, 0), Res);
971SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
973 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
974 Ops[i] = GetScalarizedVector(
N->getOperand(i));
975 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
980SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
984 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
985 SDValue ContainingVec =
N->getOperand(0);
993SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
994 EVT VT =
N->getValueType(0);
995 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1007 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1008 EVT VT =
N->getValueType(0);
1010 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1018 assert(
N->getValueType(0).isVector() &&
1019 N->getOperand(0).getValueType().isVector() &&
1020 "Operand types must be vectors");
1021 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1023 EVT VT =
N->getValueType(0);
1024 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1025 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1027 EVT OpVT =
N->getOperand(0).getValueType();
1039 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1045SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1047 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1048 assert(
N->getValueType(0).isVector() &&
1049 N->getOperand(1).getValueType().isVector() &&
1050 "Operand types must be vectors");
1051 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1053 EVT VT =
N->getValueType(0);
1055 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1056 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1059 EVT OpVT =
N->getOperand(1).getValueType();
1063 {Ch, LHS, RHS, CC});
1072 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1077 ReplaceValueWith(
SDValue(
N, 0), Res);
1084 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1085 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1088 if (
N->isTruncatingStore())
1089 return DAG.getTruncStore(
1090 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1091 N->getBasePtr(),
N->getPointerInfo(),
1092 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1093 N->getMemOperand()->getFlags(),
N->getAAInfo());
1095 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1096 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1097 N->getMemOperand()->getFlags(),
N->getAAInfo());
1102SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1103 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1104 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1106 N->getValueType(0).getVectorElementType(), Elt,
1111SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1113 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1114 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1117 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1127 ReplaceValueWith(
SDValue(
N, 0), Res);
1134 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1136 N->getValueType(0).getVectorElementType(), Elt);
1142SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1143 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1146 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1147 {
N->getOperand(0), Elt});
1156 ReplaceValueWith(
SDValue(
N, 0), Res);
1161 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1168SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1174 SDValue Op = GetScalarizedVector(VecOp);
1175 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1176 AccOp,
Op,
N->getFlags());
1180 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1181 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1196void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1201 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1204 switch (
N->getOpcode()) {
1207 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1216 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1223 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1239 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1242 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1251 case ISD::VP_LOAD_FF:
1254 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1261 case ISD::VP_GATHER:
1265 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1269 SplitVecRes_SETCC(
N,
Lo,
Hi);
1272 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1279 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1282 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1285 SplitVecRes_VECTOR_INTERLEAVE(
N);
1288 SplitVecRes_VAARG(
N,
Lo,
Hi);
1294 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1300 case ISD::VP_BITREVERSE:
1308 case ISD::VP_CTLZ_ZERO_UNDEF:
1310 case ISD::VP_CTTZ_ZERO_UNDEF:
1325 case ISD::VP_FFLOOR:
1330 case ISD::VP_FNEARBYINT:
1335 case ISD::VP_FP_EXTEND:
1337 case ISD::VP_FP_ROUND:
1339 case ISD::VP_FP_TO_SINT:
1341 case ISD::VP_FP_TO_UINT:
1347 case ISD::VP_LLRINT:
1349 case ISD::VP_FROUND:
1351 case ISD::VP_FROUNDEVEN:
1360 case ISD::VP_FROUNDTOZERO:
1362 case ISD::VP_SINT_TO_FP:
1364 case ISD::VP_TRUNCATE:
1366 case ISD::VP_UINT_TO_FP:
1369 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1372 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1378 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1384 case ISD::VP_SIGN_EXTEND:
1385 case ISD::VP_ZERO_EXTEND:
1386 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1408 case ISD::VP_FMINNUM:
1411 case ISD::VP_FMAXNUM:
1413 case ISD::VP_FMINIMUM:
1415 case ISD::VP_FMAXIMUM:
1424 case ISD::OR:
case ISD::VP_OR:
1444 case ISD::VP_FCOPYSIGN:
1445 SplitVecRes_BinOp(
N,
Lo,
Hi);
1452 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1456 SplitVecRes_CMP(
N,
Lo,
Hi);
1459#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1460 case ISD::STRICT_##DAGN:
1461#include "llvm/IR/ConstrainedOps.def"
1462 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1467 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1476 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1486 SplitVecRes_FIX(
N,
Lo,
Hi);
1488 case ISD::EXPERIMENTAL_VP_SPLICE:
1489 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1491 case ISD::EXPERIMENTAL_VP_REVERSE:
1492 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1498 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1501 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1510void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1512 uint64_t *ScaledOffset) {
1517 SDValue BytesIncrement = DAG.getVScale(
1520 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1522 *ScaledOffset += IncrementSize;
1532std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1533 return SplitMask(Mask, SDLoc(Mask));
1536std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1539 EVT MaskVT =
Mask.getValueType();
1541 GetSplitVector(Mask, MaskLo, MaskHi);
1543 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1544 return std::make_pair(MaskLo, MaskHi);
1549 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1551 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1554 const SDNodeFlags
Flags =
N->getFlags();
1555 unsigned Opcode =
N->getOpcode();
1556 if (
N->getNumOperands() == 2) {
1557 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1558 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1562 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1563 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1566 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1569 std::tie(EVLLo, EVLHi) =
1570 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1573 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1575 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1581 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1583 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1585 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1588 const SDNodeFlags
Flags =
N->getFlags();
1589 unsigned Opcode =
N->getOpcode();
1590 if (
N->getNumOperands() == 3) {
1591 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1592 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1596 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1597 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1600 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1603 std::tie(EVLLo, EVLHi) =
1604 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1607 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1609 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1613 LLVMContext &Ctxt = *DAG.getContext();
1619 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1621 GetSplitVector(
LHS, LHSLo, LHSHi);
1622 GetSplitVector(
RHS, RHSLo, RHSHi);
1624 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1625 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1629 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1630 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1635 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1637 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1641 unsigned Opcode =
N->getOpcode();
1642 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1644 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1653 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1660 switch (getTypeAction(InVT)) {
1675 GetExpandedOp(InOp,
Lo,
Hi);
1676 if (DAG.getDataLayout().isBigEndian())
1686 GetSplitVector(InOp,
Lo,
Hi);
1695 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1704 if (DAG.getDataLayout().isBigEndian())
1707 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1709 if (DAG.getDataLayout().isBigEndian())
1715void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1721 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1724 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1729 unsigned LaneOffset =
1732 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1734 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1741 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1744 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1747 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1752 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1754 unsigned NumSubvectors =
N->getNumOperands() / 2;
1755 if (NumSubvectors == 1) {
1756 Lo =
N->getOperand(0);
1757 Hi =
N->getOperand(1);
1762 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1771void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1778 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1793 GetSplitVector(Vec,
Lo,
Hi);
1796 EVT LoVT =
Lo.getValueType();
1806 if (IdxVal + SubElems <= LoElems) {
1814 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1816 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1822 SDValue WideSubVec = GetWidenedVector(SubVec);
1824 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1832 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1834 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1835 auto &MF = DAG.getMachineFunction();
1839 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1844 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1845 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1849 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1854 MachinePointerInfo MPI =
Load->getPointerInfo();
1855 IncrementPointer(Load, LoVT, MPI, StackPtr);
1858 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1867 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1872 EVT RHSVT =
RHS.getValueType();
1875 GetSplitVector(
RHS, RHSLo, RHSHi);
1877 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1892 SDValue FpValue =
N->getOperand(0);
1894 GetSplitVector(FpValue, ArgLo, ArgHi);
1896 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1898 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1907 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1911 std::tie(LoVT, HiVT) =
1915 DAG.getValueType(LoVT));
1917 DAG.getValueType(HiVT));
1922 unsigned Opcode =
N->getOpcode();
1929 GetSplitVector(N0, InLo, InHi);
1931 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1936 EVT OutLoVT, OutHiVT;
1937 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1939 assert((2 * OutNumElements) <= InNumElements &&
1940 "Illegal extend vector in reg split");
1949 SmallVector<int, 8> SplitHi(InNumElements, -1);
1950 for (
unsigned i = 0; i != OutNumElements; ++i)
1951 SplitHi[i] = i + OutNumElements;
1952 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1954 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1955 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1960 unsigned NumOps =
N->getNumOperands();
1964 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1974 for (
unsigned i = 1; i <
NumOps; ++i) {
1979 EVT InVT =
Op.getValueType();
1984 GetSplitVector(
Op, OpLo, OpHi);
1986 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
1993 EVT LoValueVTs[] = {LoVT, MVT::Other};
1994 EVT HiValueVTs[] = {HiVT, MVT::Other};
1995 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1997 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2003 Lo.getValue(1),
Hi.getValue(1));
2007 ReplaceValueWith(
SDValue(
N, 1), Chain);
2010SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2012 EVT VT =
N->getValueType(0);
2023 else if (NE > ResNE)
2027 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2031 for (i = 0; i !=
NE; ++i) {
2032 Operands[0] = Chain;
2033 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2034 SDValue Operand =
N->getOperand(j);
2038 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2040 Operands[
j] = Operand;
2044 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2052 for (; i < ResNE; ++i)
2057 ReplaceValueWith(
SDValue(
N, 1), Chain);
2061 return DAG.getBuildVector(VecVT, dl, Scalars);
2064void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2067 EVT ResVT =
N->getValueType(0);
2068 EVT OvVT =
N->getValueType(1);
2069 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2070 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2071 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2073 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2075 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2076 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2078 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2079 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2082 unsigned Opcode =
N->getOpcode();
2083 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2084 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2086 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2088 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2094 unsigned OtherNo = 1 - ResNo;
2095 EVT OtherVT =
N->getValueType(OtherNo);
2097 SetSplitVector(
SDValue(
N, OtherNo),
2103 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2107void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2113 GetSplitVector(Vec,
Lo,
Hi);
2116 unsigned IdxVal = CIdx->getZExtValue();
2117 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2118 if (IdxVal < LoNumElts) {
2120 Lo.getValueType(),
Lo, Elt, Idx);
2123 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2143 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2145 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2146 auto &MF = DAG.getMachineFunction();
2150 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2155 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2156 Store = DAG.getTruncStore(
2162 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2165 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2169 MachinePointerInfo MPI =
Load->getPointerInfo();
2170 IncrementPointer(Load, LoVT, MPI, StackPtr);
2172 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2175 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2176 if (LoVT !=
Lo.getValueType())
2178 if (HiVT !=
Hi.getValueType())
2186 assert(
N->getValueType(0).isScalableVector() &&
2187 "Only scalable vectors are supported for STEP_VECTOR");
2188 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2209 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2210 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2212 Hi = DAG.getPOISON(HiVT);
2224 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2230 EVT MemoryVT =
LD->getMemoryVT();
2232 AAMDNodes AAInfo =
LD->getAAInfo();
2234 EVT LoMemVT, HiMemVT;
2235 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2239 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2240 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2241 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2246 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2249 MachinePointerInfo MPI;
2250 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2253 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2262 ReplaceValueWith(
SDValue(LD, 1), Ch);
2267 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2270 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2276 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2277 Align Alignment =
LD->getBaseAlign();
2280 EVT MemoryVT =
LD->getMemoryVT();
2282 EVT LoMemVT, HiMemVT;
2283 bool HiIsEmpty =
false;
2284 std::tie(LoMemVT, HiMemVT) =
2285 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2290 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2293 GetSplitVector(Mask, MaskLo, MaskHi);
2295 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2300 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2302 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2308 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2309 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2317 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2318 LD->isExpandingLoad());
2320 MachinePointerInfo MPI;
2322 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2324 MPI =
LD->getPointerInfo().getWithOffset(
2327 MMO = DAG.getMachineFunction().getMachineMemOperand(
2329 Alignment,
LD->getAAInfo(),
LD->getRanges());
2331 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2332 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2333 LD->isExpandingLoad());
2343 ReplaceValueWith(
SDValue(LD, 1), Ch);
2349 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2353 Align Alignment =
LD->getBaseAlign();
2360 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2363 GetSplitVector(Mask, MaskLo, MaskHi);
2365 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2369 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2371 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2376 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2379 Hi = DAG.getPOISON(HiVT);
2381 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2382 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2388 "Indexed VP strided load during type legalization!");
2390 "Unexpected indexed variable-length load offset");
2395 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2397 EVT LoMemVT, HiMemVT;
2398 bool HiIsEmpty =
false;
2399 std::tie(LoMemVT, HiMemVT) =
2400 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2405 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2408 GetSplitVector(Mask, LoMask, HiMask);
2410 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2414 std::tie(LoEVL, HiEVL) =
2418 Lo = DAG.getStridedLoadVP(
2445 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2452 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2463 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2471 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2476 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2486 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2489 GetSplitVector(Mask, MaskLo, MaskHi);
2491 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2495 EVT LoMemVT, HiMemVT;
2496 bool HiIsEmpty =
false;
2497 std::tie(LoMemVT, HiMemVT) =
2498 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2500 SDValue PassThruLo, PassThruHi;
2502 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2504 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2506 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2510 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2520 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2523 MachinePointerInfo MPI;
2530 MMO = DAG.getMachineFunction().getMachineMemOperand(
2534 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2546 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2554 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2562 }
Ops = [&]() -> Operands {
2564 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2567 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2570 EVT MemoryVT =
N->getMemoryVT();
2571 Align Alignment =
N->getBaseAlign();
2576 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2578 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2581 EVT LoMemVT, HiMemVT;
2583 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2586 if (getTypeAction(
Ops.Index.getValueType()) ==
2588 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2590 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2593 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2595 Alignment,
N->getAAInfo(),
N->getRanges());
2598 SDValue PassThru = MGT->getPassThru();
2599 SDValue PassThruLo, PassThruHi;
2602 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2604 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2609 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2610 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2611 OpsLo, MMO, IndexTy, ExtType);
2613 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2614 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2615 OpsHi, MMO, IndexTy, ExtType);
2619 std::tie(EVLLo, EVLHi) =
2620 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2622 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2623 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2624 MMO, VPGT->getIndexType());
2626 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2627 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2628 MMO, VPGT->getIndexType());
2638 ReplaceValueWith(
SDValue(
N, 1), Ch);
2652 EVT VecVT =
N->getValueType(0);
2654 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2655 bool HasCustomLowering =
false;
2662 HasCustomLowering =
true;
2668 SDValue Passthru =
N->getOperand(2);
2669 if (!HasCustomLowering) {
2670 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2671 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2678 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2679 std::tie(LoMask, HiMask) = SplitMask(Mask);
2681 SDValue UndefPassthru = DAG.getUNDEF(LoVT);
2686 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2687 MachineFunction &MF = DAG.getMachineFunction();
2699 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2701 SDValue Chain = DAG.getEntryNode();
2702 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2706 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2711 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2715 assert(
N->getValueType(0).isVector() &&
2716 N->getOperand(0).getValueType().isVector() &&
2717 "Operand types must be vectors");
2721 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2725 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2727 GetSplitVector(
N->getOperand(0), LL, LH);
2729 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2731 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2733 GetSplitVector(
N->getOperand(1), RL, RH);
2735 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2738 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2739 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2741 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2742 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2743 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2744 std::tie(EVLLo, EVLHi) =
2745 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2746 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2748 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2758 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2762 EVT InVT =
N->getOperand(0).getValueType();
2764 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2766 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2768 const SDNodeFlags
Flags =
N->getFlags();
2769 unsigned Opcode =
N->getOpcode();
2770 if (
N->getNumOperands() <= 2) {
2772 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2773 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2775 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2776 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2781 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2782 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2785 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2788 std::tie(EVLLo, EVLHi) =
2789 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2792 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2798 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2802 EVT InVT =
N->getOperand(0).getValueType();
2804 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2806 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2809 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2810 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2811 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2812 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2815void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2820 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2821 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2825 EVT InVT =
N->getOperand(0).getValueType();
2827 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2829 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2831 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2832 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2834 SDNode *HiNode =
Hi.getNode();
2835 SDNode *LoNode =
Lo.getNode();
2838 unsigned OtherNo = 1 - ResNo;
2839 EVT OtherVT =
N->getValueType(OtherNo);
2847 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2854 EVT SrcVT =
N->getOperand(0).getValueType();
2855 EVT DestVT =
N->getValueType(0);
2857 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2874 LLVMContext &Ctx = *DAG.getContext();
2878 EVT SplitLoVT, SplitHiVT;
2879 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2880 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2881 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2882 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2883 N->dump(&DAG);
dbgs() <<
"\n");
2884 if (!
N->isVPOpcode()) {
2887 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2889 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2891 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2892 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2898 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2899 N->getOperand(1),
N->getOperand(2));
2901 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2904 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2907 std::tie(EVLLo, EVLHi) =
2908 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2910 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2911 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2916 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2924 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2925 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2931 return N.getResNo() == 0 &&
2935 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2937 ArrayRef<int>
Mask) {
2940 "Expected build vector node.");
2943 for (
unsigned I = 0;
I < NewElts; ++
I) {
2946 unsigned Idx =
Mask[
I];
2948 Ops[
I] = Input2.getOperand(Idx - NewElts);
2950 Ops[
I] = Input1.getOperand(Idx);
2955 return DAG.getBuildVector(NewVT,
DL,
Ops);
2961 SmallVector<int> OrigMask(
N->getMask());
2963 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2964 &
DL](SmallVectorImpl<int> &
Mask) {
2966 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2967 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2978 for (
auto &
P : ShufflesIdxs) {
2979 if (
P.second.size() < 2)
2983 for (
int &Idx : Mask) {
2986 unsigned SrcRegIdx = Idx / NewElts;
2987 if (Inputs[SrcRegIdx].
isUndef()) {
2995 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3000 Idx = MaskElt % NewElts +
3001 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3007 Inputs[
P.second[0]] =
P.first.first;
3008 Inputs[
P.second[1]] =
P.first.second;
3011 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3014 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3015 for (
int &Idx : Mask) {
3018 unsigned SrcRegIdx = Idx / NewElts;
3019 if (Inputs[SrcRegIdx].
isUndef()) {
3026 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3027 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3030 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3032 if (UsedSubVector.count() > 1) {
3034 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3035 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3037 if (Pairs.
empty() || Pairs.
back().size() == 2)
3039 if (UsedSubVector.test(2 *
I)) {
3040 Pairs.
back().emplace_back(
I, 0);
3042 assert(UsedSubVector.test(2 *
I + 1) &&
3043 "Expected to be used one of the subvectors.");
3044 Pairs.
back().emplace_back(
I, 1);
3047 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3049 for (
int &Idx : Mask) {
3052 unsigned SrcRegIdx = Idx / NewElts;
3054 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3055 return Idxs.front().first == SrcRegIdx ||
3056 Idxs.back().first == SrcRegIdx;
3058 if (It == Pairs.
end())
3060 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3061 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3064 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3065 Inputs[Idxs.front().first] = DAG.
getNode(
3067 Inputs[Idxs.front().first].getValueType(),
3068 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3069 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3078 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3082 if (Shuffle->getOperand(0).getValueType() != NewVT)
3085 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3086 !Shuffle->isSplat()) {
3088 }
else if (!Inputs[
I].hasOneUse() &&
3089 !Shuffle->getOperand(1).isUndef()) {
3091 for (
int &Idx : Mask) {
3094 unsigned SrcRegIdx = Idx / NewElts;
3097 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3102 int OpIdx = MaskElt / NewElts;
3116 if (Shuffle->getOperand(
OpIdx).isUndef())
3118 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3119 if (It == std::end(Inputs))
3121 int FoundOp = std::distance(std::begin(Inputs), It);
3124 for (
int &Idx : Mask) {
3127 unsigned SrcRegIdx = Idx / NewElts;
3130 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3135 int MaskIdx = MaskElt / NewElts;
3136 if (
OpIdx == MaskIdx)
3137 Idx = MaskElt % NewElts + FoundOp * NewElts;
3148 for (
int &Idx : Mask) {
3151 unsigned SrcRegIdx = Idx / NewElts;
3154 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3155 int OpIdx = MaskElt / NewElts;
3158 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3164 TryPeekThroughShufflesInputs(OrigMask);
3166 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3167 NewElts](SmallVectorImpl<int> &
Mask) {
3168 SetVector<SDValue> UniqueInputs;
3169 SetVector<SDValue> UniqueConstantInputs;
3170 for (
const auto &
I : Inputs) {
3172 UniqueConstantInputs.
insert(
I);
3173 else if (!
I.isUndef())
3178 if (UniqueInputs.
size() != std::size(Inputs)) {
3179 auto &&UniqueVec = UniqueInputs.
takeVector();
3180 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3181 unsigned ConstNum = UniqueConstantVec.size();
3182 for (
int &Idx : Mask) {
3185 unsigned SrcRegIdx = Idx / NewElts;
3186 if (Inputs[SrcRegIdx].
isUndef()) {
3190 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3191 if (It != UniqueConstantVec.end()) {
3192 Idx = (Idx % NewElts) +
3193 NewElts * std::distance(UniqueConstantVec.begin(), It);
3194 assert(Idx >= 0 &&
"Expected defined mask idx.");
3197 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3198 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3199 Idx = (Idx % NewElts) +
3200 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3201 assert(Idx >= 0 &&
"Expected defined mask idx.");
3203 copy(UniqueConstantVec, std::begin(Inputs));
3204 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3207 MakeUniqueInputs(OrigMask);
3209 copy(Inputs, std::begin(OrigInputs));
3215 unsigned FirstMaskIdx =
High * NewElts;
3218 assert(!Output &&
"Expected default initialized initial value.");
3219 TryPeekThroughShufflesInputs(Mask);
3220 MakeUniqueInputs(Mask);
3222 copy(Inputs, std::begin(TmpInputs));
3225 bool SecondIteration =
false;
3226 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3231 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3232 SecondIteration =
true;
3233 return SecondIteration;
3236 Mask, std::size(Inputs), std::size(Inputs),
3238 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3239 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3240 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3242 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3244 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3245 DAG.getUNDEF(NewVT), Mask);
3246 Inputs[Idx] = Output;
3248 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3249 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3250 unsigned Idx2,
bool ) {
3251 if (AccumulateResults(Idx1)) {
3254 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3256 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3257 Inputs[Idx2], Mask);
3261 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3263 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3264 TmpInputs[Idx2], Mask);
3266 Inputs[Idx1] = Output;
3268 copy(OrigInputs, std::begin(Inputs));
3273 EVT OVT =
N->getValueType(0);
3280 const Align Alignment =
3281 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3283 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3284 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3289 ReplaceValueWith(
SDValue(
N, 1), Chain);
3294 EVT DstVTLo, DstVTHi;
3295 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3299 EVT SrcVT =
N->getOperand(0).getValueType();
3301 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3303 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3305 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3306 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3312 GetSplitVector(
N->getOperand(0), InLo, InHi);
3323 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3324 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3329 EVT VT =
N->getValueType(0);
3336 Align Alignment = DAG.getReducedAlign(VT,
false);
3341 EVT PtrVT =
StackPtr.getValueType();
3342 auto &MF = DAG.getMachineFunction();
3346 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3349 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3355 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3356 DAG.getConstant(1,
DL, PtrVT));
3358 DAG.getConstant(EltWidth,
DL, PtrVT));
3360 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3362 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3363 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3364 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3367 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3369 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3374 EVT VT =
N->getValueType(0);
3386 EVL1 = ZExtPromotedInteger(EVL1);
3388 Align Alignment = DAG.getReducedAlign(VT,
false);
3393 EVT PtrVT =
StackPtr.getValueType();
3394 auto &MF = DAG.getMachineFunction();
3398 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3401 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3405 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3407 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3408 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3409 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3413 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3418 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3419 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3421 uint64_t TrailingElts = -
Imm;
3423 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3432 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3436 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3438 DAG.getVectorIdxConstant(0,
DL));
3444void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3452 GetSplitVector(Acc, AccLo, AccHi);
3453 unsigned Opcode =
N->getOpcode();
3465 GetSplitVector(Input1, Input1Lo, Input1Hi);
3466 GetSplitVector(Input2, Input2Lo, Input2Hi);
3469 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3470 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3473void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3481 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3489void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3490 unsigned Factor =
N->getNumOperands();
3493 for (
unsigned i = 0; i != Factor; ++i) {
3495 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3497 Ops[i * 2 + 1] = OpHi;
3508 for (
unsigned i = 0; i != Factor; ++i)
3512void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3513 unsigned Factor =
N->getNumOperands();
3516 for (
unsigned i = 0; i != Factor; ++i) {
3518 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3520 Ops[i + Factor] = OpHi;
3531 for (
unsigned i = 0; i != Factor; ++i) {
3532 unsigned IdxLo = 2 * i;
3533 unsigned IdxHi = 2 * i + 1;
3534 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3535 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3547bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3552 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3555 switch (
N->getOpcode()) {
3558 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3568 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3574 case ISD::VP_TRUNCATE:
3576 Res = SplitVecOp_TruncateHelper(
N);
3579 case ISD::VP_FP_ROUND:
3588 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3595 case ISD::VP_SCATTER:
3599 case ISD::VP_GATHER:
3603 Res = SplitVecOp_VSELECT(
N, OpNo);
3606 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3612 case ISD::VP_SINT_TO_FP:
3613 case ISD::VP_UINT_TO_FP:
3614 if (
N->getValueType(0).bitsLT(
3615 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3616 Res = SplitVecOp_TruncateHelper(
N);
3618 Res = SplitVecOp_UnaryOp(
N);
3622 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3626 case ISD::VP_FP_TO_SINT:
3627 case ISD::VP_FP_TO_UINT:
3640 Res = SplitVecOp_UnaryOp(
N);
3643 Res = SplitVecOp_FPOpDifferentTypes(
N);
3648 Res = SplitVecOp_CMP(
N);
3652 Res = SplitVecOp_FAKE_USE(
N);
3657 Res = SplitVecOp_ExtVecInRegOp(
N);
3675 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3679 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3681 case ISD::VP_REDUCE_FADD:
3682 case ISD::VP_REDUCE_SEQ_FADD:
3683 case ISD::VP_REDUCE_FMUL:
3684 case ISD::VP_REDUCE_SEQ_FMUL:
3685 case ISD::VP_REDUCE_ADD:
3686 case ISD::VP_REDUCE_MUL:
3687 case ISD::VP_REDUCE_AND:
3688 case ISD::VP_REDUCE_OR:
3689 case ISD::VP_REDUCE_XOR:
3690 case ISD::VP_REDUCE_SMAX:
3691 case ISD::VP_REDUCE_SMIN:
3692 case ISD::VP_REDUCE_UMAX:
3693 case ISD::VP_REDUCE_UMIN:
3694 case ISD::VP_REDUCE_FMAX:
3695 case ISD::VP_REDUCE_FMIN:
3696 case ISD::VP_REDUCE_FMAXIMUM:
3697 case ISD::VP_REDUCE_FMINIMUM:
3698 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3700 case ISD::VP_CTTZ_ELTS:
3701 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3702 Res = SplitVecOp_VP_CttzElements(
N);
3705 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3711 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3716 if (!Res.
getNode())
return false;
3723 if (
N->isStrictFPOpcode())
3725 "Invalid operand expansion");
3728 "Invalid operand expansion");
3730 ReplaceValueWith(
SDValue(
N, 0), Res);
3734SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3737 assert(OpNo == 0 &&
"Illegal operand must be mask");
3744 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3747 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3748 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3749 "Lo and Hi have differing types");
3752 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3753 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3755 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3756 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3757 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3758 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3768SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3771 assert(OpNo == 1 &&
"Illegal operand must be mask");
3776 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3778 EVT VecVT =
N->getValueType(0);
3782SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3783 EVT ResVT =
N->getValueType(0);
3789 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3790 GetSplitVector(VecOp,
Lo,
Hi);
3792 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3797 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3798 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3802 EVT ResVT =
N->getValueType(0);
3808 SDNodeFlags
Flags =
N->getFlags();
3811 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3812 GetSplitVector(VecOp,
Lo,
Hi);
3814 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3820 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3823SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3824 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3825 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3827 unsigned Opc =
N->getOpcode();
3828 EVT ResVT =
N->getValueType(0);
3834 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3835 GetSplitVector(VecOp,
Lo,
Hi);
3838 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3841 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3843 const SDNodeFlags
Flags =
N->getFlags();
3847 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3852 EVT ResVT =
N->getValueType(0);
3855 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3856 EVT InVT =
Lo.getValueType();
3861 if (
N->isStrictFPOpcode()) {
3862 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3863 {N->getOperand(0), Lo});
3864 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3865 {N->getOperand(0), Hi});
3874 ReplaceValueWith(
SDValue(
N, 1), Ch);
3875 }
else if (
N->getNumOperands() == 3) {
3876 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3877 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3878 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3879 std::tie(EVLLo, EVLHi) =
3880 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3881 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3882 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3884 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3885 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3894 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3904 EVT ResVT =
N->getValueType(0);
3906 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3910 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3916 Lo = BitConvertToInteger(
Lo);
3917 Hi = BitConvertToInteger(
Hi);
3919 if (DAG.getDataLayout().isBigEndian())
3927 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3929 EVT ResVT =
N->getValueType(0);
3937 GetSplitVector(SubVec,
Lo,
Hi);
3946 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3948 return SecondInsertion;
3951SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3958 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3960 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
3962 ElementCount IdxVal =
3966 EVT SrcVT =
N->getOperand(0).getValueType();
3985 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
3986 LoEltsMin - IdxValMin);
3987 DAG.ExtractVectorElements(
Hi, Elts, 0,
3990 return DAG.getBuildVector(SubVT, dl, Elts);
3994 ElementCount ExtractIdx = IdxVal - LoElts;
3996 return DAG.getExtractSubvector(dl, SubVT,
Hi,
3999 EVT HiVT =
Hi.getValueType();
4001 "Only fixed-vector extracts are supported in this case");
4011 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4012 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4018 "Extracting scalable subvector from fixed-width unsupported");
4026 "subvector from a scalable predicate vector");
4032 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4034 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4035 auto &MF = DAG.getMachineFunction();
4039 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4043 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4046 SubVT, dl, Store, StackPtr,
4050SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4056 uint64_t IdxVal =
Index->getZExtValue();
4059 GetSplitVector(Vec,
Lo,
Hi);
4061 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4063 if (IdxVal < LoElts)
4064 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4067 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4072 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4084 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4090 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4092 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4093 auto &MF = DAG.getMachineFunction();
4096 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4100 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4104 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4106 return DAG.getExtLoad(
4117 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4125 SplitVecRes_Gather(
N,
Lo,
Hi);
4128 ReplaceValueWith(
SDValue(
N, 0), Res);
4133 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4137 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4139 SDValue EVL =
N->getVectorLength();
4141 Align Alignment =
N->getBaseAlign();
4147 GetSplitVector(
Data, DataLo, DataHi);
4149 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4154 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4157 GetSplitVector(Mask, MaskLo, MaskHi);
4159 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4162 EVT MemoryVT =
N->getMemoryVT();
4163 EVT LoMemVT, HiMemVT;
4164 bool HiIsEmpty =
false;
4165 std::tie(LoMemVT, HiMemVT) =
4166 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4170 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4173 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4178 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4179 N->getAddressingMode(),
N->isTruncatingStore(),
4180 N->isCompressingStore());
4186 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4187 N->isCompressingStore());
4189 MachinePointerInfo MPI;
4193 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4198 MMO = DAG.getMachineFunction().getMachineMemOperand(
4200 Alignment,
N->getAAInfo(),
N->getRanges());
4202 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4203 N->getAddressingMode(),
N->isTruncatingStore(),
4204 N->isCompressingStore());
4213 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4214 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4221 GetSplitVector(
Data, LoData, HiData);
4223 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4225 EVT LoMemVT, HiMemVT;
4226 bool HiIsEmpty =
false;
4227 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4233 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4234 else if (getTypeAction(
Mask.getValueType()) ==
4236 GetSplitVector(Mask, LoMask, HiMask);
4238 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4241 std::tie(LoEVL, HiEVL) =
4242 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4246 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4247 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4248 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4259 EVT PtrVT =
N->getBasePtr().getValueType();
4262 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4265 Align Alignment =
N->getBaseAlign();
4270 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4271 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4273 Alignment,
N->getAAInfo(),
N->getRanges());
4276 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4277 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4278 N->isCompressingStore());
4287 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4291 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4294 Align Alignment =
N->getBaseAlign();
4300 GetSplitVector(
Data, DataLo, DataHi);
4302 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4307 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4310 GetSplitVector(Mask, MaskLo, MaskHi);
4312 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4315 EVT MemoryVT =
N->getMemoryVT();
4316 EVT LoMemVT, HiMemVT;
4317 bool HiIsEmpty =
false;
4318 std::tie(LoMemVT, HiMemVT) =
4319 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4322 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4327 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4328 N->getAddressingMode(),
N->isTruncatingStore(),
4329 N->isCompressingStore());
4337 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4338 N->isCompressingStore());
4340 MachinePointerInfo MPI;
4344 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4349 MMO = DAG.getMachineFunction().getMachineMemOperand(
4351 Alignment,
N->getAAInfo(),
N->getRanges());
4353 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4354 N->getAddressingMode(),
N->isTruncatingStore(),
4355 N->isCompressingStore());
4368 EVT MemoryVT =
N->getMemoryVT();
4369 Align Alignment =
N->getBaseAlign();
4376 }
Ops = [&]() -> Operands {
4378 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4382 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4387 EVT LoMemVT, HiMemVT;
4388 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4393 GetSplitVector(
Ops.Data, DataLo, DataHi);
4395 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4400 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4402 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4406 if (getTypeAction(
Ops.Index.getValueType()) ==
4408 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4410 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4414 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4416 Alignment,
N->getAAInfo(),
N->getRanges());
4419 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4421 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4422 MSC->getIndexType(), MSC->isTruncatingStore());
4427 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4428 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4429 MMO, MSC->getIndexType(),
4430 MSC->isTruncatingStore());
4434 std::tie(EVLLo, EVLHi) =
4435 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4437 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4438 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4439 VPSC->getIndexType());
4444 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4445 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4446 VPSC->getIndexType());
4450 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4451 assert(OpNo == 1 &&
"Can only split the stored value");
4454 bool isTruncating =
N->isTruncatingStore();
4457 EVT MemoryVT =
N->getMemoryVT();
4458 Align Alignment =
N->getBaseAlign();
4460 AAMDNodes AAInfo =
N->getAAInfo();
4462 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4464 EVT LoMemVT, HiMemVT;
4465 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4469 return TLI.scalarizeVectorStore(
N, DAG);
4472 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4473 Alignment, MMOFlags, AAInfo);
4475 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4478 MachinePointerInfo MPI;
4479 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4482 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4483 HiMemVT, Alignment, MMOFlags, AAInfo);
4485 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4501 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4507 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4528 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4529 SDValue InVec =
N->getOperand(OpNo);
4531 EVT OutVT =
N->getValueType(0);
4539 EVT LoOutVT, HiOutVT;
4540 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4541 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4546 if (isTypeLegal(LoOutVT) ||
4547 InElementSize <= OutElementSize * 2)
4548 return SplitVecOp_UnaryOp(
N);
4557 return SplitVecOp_UnaryOp(
N);
4561 GetSplitVector(InVec, InLoVec, InHiVec);
4567 EVT HalfElementVT = IsFloat ?
4569 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4576 if (
N->isStrictFPOpcode()) {
4577 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4578 {N->getOperand(0), InLoVec});
4579 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4580 {N->getOperand(0), InHiVec});
4586 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4587 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4591 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4599 if (
N->isStrictFPOpcode()) {
4603 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4611 DAG.getTargetConstant(
4612 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4619 assert(
N->getValueType(0).isVector() &&
4620 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4621 "Operand types must be vectors");
4623 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4625 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4626 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4628 EVT VT =
N->getValueType(0);
4635 }
else if (isStrict) {
4636 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4637 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4638 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4639 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4642 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4644 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4645 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4646 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4647 std::tie(EVLLo, EVLHi) =
4648 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4649 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4650 N->getOperand(2), MaskLo, EVLLo);
4651 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4652 N->getOperand(2), MaskHi, EVLHi);
4661 EVT ResVT =
N->getValueType(0);
4664 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4665 EVT InVT =
Lo.getValueType();
4670 if (
N->isStrictFPOpcode()) {
4671 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4672 {N->getOperand(0), Lo, N->getOperand(2)});
4673 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4674 {N->getOperand(0), Hi, N->getOperand(2)});
4678 Lo.getValue(1),
Hi.getValue(1));
4679 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4680 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4681 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4682 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4683 std::tie(EVLLo, EVLHi) =
4684 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4685 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4686 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4700SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4703 EVT LHSLoVT, LHSHiVT;
4704 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4706 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4707 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4710 std::tie(LHSLo, LHSHi) =
4711 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4714 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4717 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4723 LLVMContext &Ctxt = *DAG.getContext();
4726 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4727 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4728 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4730 EVT ResVT =
N->getValueType(0);
4735 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4736 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4742 EVT ResVT =
N->getValueType(0);
4745 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4746 EVT InVT =
Lo.getValueType();
4752 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4753 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4760 EVT ResVT =
N->getValueType(0);
4764 GetSplitVector(VecOp,
Lo,
Hi);
4766 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4767 auto [EVLLo, EVLHi] =
4769 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4775 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4777 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4778 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4781SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4792 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4793 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4794 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4795 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4796 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4797 OpsLo, MMO, IndexType);
4798 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4799 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4803SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4806 "Accumulator should already be a legal type, and shouldn't need "
4807 "further splitting");
4810 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4811 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4812 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4813 unsigned Opcode =
N->getOpcode();
4816 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4817 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4824void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4825 unsigned WidenResNo) {
4826 unsigned NumResults =
N->getNumValues();
4827 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4828 if (ResNo == WidenResNo)
4830 EVT ResVT =
N->getValueType(ResNo);
4836 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4837 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4842void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4843 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4846 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4851 auto unrollExpandedOp = [&]() {
4856 EVT VT =
N->getValueType(0);
4857 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4858 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4859 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
4861 if (
N->getNumValues() > 1)
4862 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4868 switch (
N->getOpcode()) {
4871 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4879 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4883 Res = WidenVecRes_ADDRSPACECAST(
N);
4890 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4894 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4898 Res = WidenVecRes_ScalarOp(
N);
4903 case ISD::VP_SELECT:
4905 Res = WidenVecRes_Select(
N);
4909 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4911 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4918 case ISD::VP_LOAD_FF:
4921 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4925 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4933 case ISD::VP_GATHER:
4937 Res = WidenVecRes_VECTOR_REVERSE(
N);
4940 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4950 case ISD::OR:
case ISD::VP_OR:
4961 case ISD::VP_FMINNUM:
4964 case ISD::VP_FMAXNUM:
4966 case ISD::VP_FMINIMUM:
4968 case ISD::VP_FMAXIMUM:
5001 case ISD::VP_FCOPYSIGN:
5002 Res = WidenVecRes_Binary(
N);
5007 Res = WidenVecRes_CMP(
N);
5013 if (unrollExpandedOp())
5028 Res = WidenVecRes_BinaryCanTrap(
N);
5037 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5040#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5041 case ISD::STRICT_##DAGN:
5042#include "llvm/IR/ConstrainedOps.def"
5043 Res = WidenVecRes_StrictFP(
N);
5052 Res = WidenVecRes_OverflowOp(
N, ResNo);
5056 Res = WidenVecRes_FCOPYSIGN(
N);
5061 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5066 if (!unrollExpandedOp())
5067 Res = WidenVecRes_ExpOp(
N);
5073 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5078 case ISD::VP_FP_EXTEND:
5080 case ISD::VP_FP_ROUND:
5082 case ISD::VP_FP_TO_SINT:
5084 case ISD::VP_FP_TO_UINT:
5086 case ISD::VP_SIGN_EXTEND:
5088 case ISD::VP_SINT_TO_FP:
5089 case ISD::VP_TRUNCATE:
5092 case ISD::VP_UINT_TO_FP:
5094 case ISD::VP_ZERO_EXTEND:
5095 Res = WidenVecRes_Convert(
N);
5100 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5106 case ISD::VP_LLRINT:
5109 Res = WidenVecRes_XROUND(
N);
5135 if (unrollExpandedOp())
5145 case ISD::VP_BITREVERSE:
5151 case ISD::VP_CTLZ_ZERO_UNDEF:
5157 case ISD::VP_CTTZ_ZERO_UNDEF:
5162 case ISD::VP_FFLOOR:
5164 case ISD::VP_FNEARBYINT:
5165 case ISD::VP_FROUND:
5166 case ISD::VP_FROUNDEVEN:
5167 case ISD::VP_FROUNDTOZERO:
5172 Res = WidenVecRes_Unary(
N);
5179 Res = WidenVecRes_Ternary(
N);
5185 if (!unrollExpandedOp())
5186 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5193 SetWidenedVector(
SDValue(
N, ResNo), Res);
5199 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5200 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5201 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5202 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5203 if (
N->getNumOperands() == 3)
5204 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5206 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5207 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5211 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5212 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5218 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5219 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5220 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5221 if (
N->getNumOperands() == 2)
5222 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5225 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5226 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5230 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5231 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5235 LLVMContext &Ctxt = *DAG.getContext();
5240 EVT OpVT =
LHS.getValueType();
5242 LHS = GetWidenedVector(
LHS);
5243 RHS = GetWidenedVector(
RHS);
5244 OpVT =
LHS.getValueType();
5247 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5250 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5256SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5259 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5260 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5261 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5263 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5272 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5275 if (ConcatEnd == 1) {
5276 VT = ConcatOps[0].getValueType();
5278 return ConcatOps[0];
5281 SDLoc dl(ConcatOps[0]);
5288 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5289 int Idx = ConcatEnd - 1;
5290 VT = ConcatOps[Idx--].getValueType();
5291 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5304 unsigned NumToInsert = ConcatEnd - Idx - 1;
5305 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5307 ConcatOps[Idx+1] = VecOp;
5308 ConcatEnd = Idx + 2;
5314 unsigned RealVals = ConcatEnd - Idx - 1;
5315 unsigned SubConcatEnd = 0;
5316 unsigned SubConcatIdx = Idx + 1;
5317 while (SubConcatEnd < RealVals)
5318 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5319 while (SubConcatEnd < OpsToConcat)
5320 SubConcatOps[SubConcatEnd++] = undefVec;
5322 NextVT, SubConcatOps);
5323 ConcatEnd = SubConcatIdx + 1;
5328 if (ConcatEnd == 1) {
5329 VT = ConcatOps[0].getValueType();
5331 return ConcatOps[0];
5336 if (
NumOps != ConcatEnd ) {
5338 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5339 ConcatOps[j] = UndefVal;
5347 unsigned Opcode =
N->getOpcode();
5349 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5353 const SDNodeFlags
Flags =
N->getFlags();
5354 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5355 NumElts = NumElts / 2;
5359 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5361 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5362 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5363 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5371 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5374 TLI.isTypeLegal(WideMaskVT)) {
5375 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5376 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5377 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5379 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5380 N->getValueType(0).getVectorElementCount());
5381 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5395 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5396 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5397 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5400 unsigned ConcatEnd = 0;
5408 while (CurNumElts != 0) {
5409 while (CurNumElts >= NumElts) {
5410 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5411 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5412 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5414 CurNumElts -= NumElts;
5417 NumElts = NumElts / 2;
5419 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5422 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5423 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5424 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5425 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5436 switch (
N->getOpcode()) {
5439 return WidenVecRes_STRICT_FSETCC(
N);
5446 return WidenVecRes_Convert_StrictFP(
N);
5453 unsigned Opcode =
N->getOpcode();
5455 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5459 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5460 NumElts = NumElts / 2;
5471 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5475 unsigned ConcatEnd = 0;
5482 for (
unsigned i = 1; i < NumOpers; ++i) {
5488 Oper = GetWidenedVector(Oper);
5494 DAG.getUNDEF(WideOpVT), Oper,
5495 DAG.getVectorIdxConstant(0, dl));
5507 while (CurNumElts != 0) {
5508 while (CurNumElts >= NumElts) {
5511 for (
unsigned i = 0; i < NumOpers; ++i) {
5514 EVT OpVT =
Op.getValueType();
5519 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5525 EVT OperVT[] = {VT, MVT::Other};
5527 ConcatOps[ConcatEnd++] = Oper;
5530 CurNumElts -= NumElts;
5533 NumElts = NumElts / 2;
5535 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5538 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5541 for (
unsigned i = 0; i < NumOpers; ++i) {
5544 EVT OpVT =
Op.getValueType();
5552 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5554 ConcatOps[ConcatEnd++] = Oper;
5563 if (Chains.
size() == 1)
5564 NewChain = Chains[0];
5567 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5572SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5574 EVT ResVT =
N->getValueType(0);
5575 EVT OvVT =
N->getValueType(1);
5576 EVT WideResVT, WideOvVT;
5581 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5586 WideLHS = GetWidenedVector(
N->getOperand(0));
5587 WideRHS = GetWidenedVector(
N->getOperand(1));
5589 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5597 N->getOperand(0), Zero);
5600 N->getOperand(1), Zero);
5603 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5604 SDNode *WideNode = DAG.getNode(
5605 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5608 unsigned OtherNo = 1 - ResNo;
5609 EVT OtherVT =
N->getValueType(OtherNo);
5616 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5619 return SDValue(WideNode, ResNo);
5623 LLVMContext &Ctx = *DAG.getContext();
5627 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5632 unsigned Opcode =
N->getOpcode();
5633 const SDNodeFlags
Flags =
N->getFlags();
5639 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5641 InOp = ZExtPromotedInteger(InOp);
5652 InOp = GetWidenedVector(
N->getOperand(0));
5655 if (InVTEC == WidenEC) {
5656 if (
N->getNumOperands() == 1)
5657 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5658 if (
N->getNumOperands() == 3) {
5659 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5662 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5664 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5690 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5694 if (TLI.isTypeLegal(InWidenVT)) {
5702 unsigned NumConcat =
5707 if (
N->getNumOperands() == 1)
5708 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5709 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5713 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5715 if (
N->getNumOperands() == 1)
5716 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5717 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5726 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5727 for (
unsigned i=0; i < MinElts; ++i) {
5728 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5729 if (
N->getNumOperands() == 1)
5732 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5735 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5740 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5744 EVT SrcVT = Src.getValueType();
5748 Src = GetWidenedVector(Src);
5749 SrcVT = Src.getValueType();
5756 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5761 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5765 EVT SrcVT = Src.getValueType();
5769 Src = GetWidenedVector(Src);
5770 SrcVT = Src.getValueType();
5777 if (
N->getNumOperands() == 1)
5778 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5780 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5781 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5785 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5788SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5793 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5799 unsigned Opcode =
N->getOpcode();
5805 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5810 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5811 for (
unsigned i=0; i < MinElts; ++i) {
5812 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5813 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5817 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5819 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5822SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5823 unsigned Opcode =
N->getOpcode();
5827 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5836 InOp = GetWidenedVector(InOp);
5843 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5850 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5851 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5868 while (
Ops.size() != WidenNumElts)
5869 Ops.push_back(DAG.getPOISON(WidenSVT));
5871 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5877 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5878 return WidenVecRes_BinaryCanTrap(
N);
5881 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5888SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5890 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5893 SDValue Arg = GetWidenedVector(FpValue);
5894 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5899 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5900 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5902 EVT ExpVT =
RHS.getValueType();
5907 ExpOp = ModifyToType(
RHS, WideExpVT);
5910 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5915 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5916 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5917 if (
N->getNumOperands() == 1)
5918 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5920 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5921 N->getOperand(1),
N->getFlags());
5923 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5924 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5928 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5929 {InOp,
Mask,
N->getOperand(2)});
5933 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5936 .getVectorElementType(),
5938 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5939 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5940 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5943SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5945 EVT VT0 =
N->getValueType(0);
5946 EVT VT1 =
N->getValueType(1);
5950 "expected both results to be vectors of matching element count");
5952 LLVMContext &Ctx = *DAG.getContext();
5953 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5955 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5962 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5965 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5966 return SDValue(WidenNode, ResNo);
5969SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5970 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5971 return GetWidenedVector(WidenVec);
5975 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5976 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5979 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5980 AddrSpaceCastN->getSrcAddressSpace(),
5981 AddrSpaceCastN->getDestAddressSpace());
5987 EVT VT =
N->getValueType(0);
5988 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5991 switch (getTypeAction(InVT)) {
6005 SDValue NInOp = GetPromotedInteger(InOp);
6007 if (WidenVT.
bitsEq(NInVT)) {
6010 if (DAG.getDataLayout().isBigEndian()) {
6013 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6032 InOp = GetWidenedVector(InOp);
6034 if (WidenVT.
bitsEq(InVT))
6044 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6049 unsigned NewNumParts = WidenSize / InSize;
6062 EVT OrigInVT =
N->getOperand(0).getValueType();
6067 if (TLI.isTypeLegal(NewInVT)) {
6075 if (WidenSize % InSize == 0) {
6082 DAG.ExtractVectorElements(InOp,
Ops);
6083 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6095 return CreateStackStoreLoad(InOp, WidenVT);
6098SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6100 N->getOpcode(), SDLoc(
N),
6101 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6102 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6108 EVT VT =
N->getValueType(0);
6112 EVT EltVT =
N->getOperand(0).getValueType();
6115 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6119 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6120 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6122 return DAG.getBuildVector(WidenVT, dl, NewOps);
6126 EVT InVT =
N->getOperand(0).getValueType();
6127 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6129 unsigned NumOperands =
N->getNumOperands();
6131 bool InputWidened =
false;
6135 if (WidenNumElts % NumInElts == 0) {
6137 unsigned NumConcat = WidenNumElts / NumInElts;
6138 SDValue UndefVal = DAG.getPOISON(InVT);
6140 for (
unsigned i=0; i < NumOperands; ++i)
6141 Ops[i] =
N->getOperand(i);
6142 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6147 InputWidened =
true;
6148 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6151 for (i=1; i < NumOperands; ++i)
6152 if (!
N->getOperand(i).isUndef())
6155 if (i == NumOperands)
6158 return GetWidenedVector(
N->getOperand(0));
6160 if (NumOperands == 2) {
6162 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6167 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6168 for (
unsigned i = 0; i < NumInElts; ++i) {
6170 MaskOps[i + NumInElts] = i + WidenNumElts;
6172 return DAG.getVectorShuffle(WidenVT, dl,
6173 GetWidenedVector(
N->getOperand(0)),
6174 GetWidenedVector(
N->getOperand(1)),
6181 "Cannot use build vectors to widen CONCAT_VECTOR result");
6189 for (
unsigned i=0; i < NumOperands; ++i) {
6192 InOp = GetWidenedVector(InOp);
6193 for (
unsigned j = 0;
j < NumInElts; ++
j)
6194 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6196 SDValue UndefVal = DAG.getPOISON(EltVT);
6197 for (; Idx < WidenNumElts; ++Idx)
6198 Ops[Idx] = UndefVal;
6199 return DAG.getBuildVector(WidenVT, dl,
Ops);
6202SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6203 EVT VT =
N->getValueType(0);
6204 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6205 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6212SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6213 EVT VT =
N->getValueType(0);
6215 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6220 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6222 InOp = GetWidenedVector(InOp);
6228 if (IdxVal == 0 && InVT == WidenVT)
6235 assert(IdxVal % VTNumElts == 0 &&
6236 "Expected Idx to be a multiple of subvector minimum vector length");
6237 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6250 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6251 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6252 "down type's element count");
6259 for (;
I < VTNumElts / GCD; ++
I)
6261 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6262 for (;
I < WidenNumElts / GCD; ++
I)
6270 Align Alignment = DAG.getReducedAlign(InVT,
false);
6272 MachineFunction &MF = DAG.getMachineFunction();
6284 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6291 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6292 return DAG.getMaskedLoad(
6293 WidenVT, dl, Ch, StackPtr, DAG.getUNDEF(
StackPtr.getValueType()), Mask,
6301 for (i = 0; i < VTNumElts; ++i)
6302 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6304 SDValue UndefVal = DAG.getPOISON(EltVT);
6305 for (; i < WidenNumElts; ++i)
6307 return DAG.getBuildVector(WidenVT, dl,
Ops);
6313 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6318SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6319 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6322 N->getOperand(1),
N->getOperand(2));
6335 if (!
LD->getMemoryVT().isByteSized()) {
6337 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6339 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6348 EVT VT =
LD->getValueType(0);
6349 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6350 EVT WideMaskVT = getSetCCResultType(WideVT);
6353 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6354 TLI.isTypeLegal(WideMaskVT)) {
6357 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6361 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6362 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6374 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6376 Result = GenWidenVectorLoads(LdChain, LD);
6383 if (LdChain.
size() == 1)
6384 NewChain = LdChain[0];
6390 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6401 SDValue NewLoad = DAG.getMaskedLoad(
6402 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6403 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6404 LD->getAddressingMode(),
LD->getExtensionType());
6414 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6416 SDValue EVL =
N->getVectorLength();
6423 "Unable to widen binary VP op");
6424 Mask = GetWidenedVector(Mask);
6425 assert(
Mask.getValueType().getVectorElementCount() ==
6426 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6427 .getVectorElementCount() &&
6428 "Unable to widen vector load");
6431 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6432 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6433 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6441 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6443 SDValue EVL =
N->getVectorLength();
6449 "Unable to widen binary VP op");
6450 Mask = GetWidenedVector(Mask);
6451 assert(
Mask.getValueType().getVectorElementCount() ==
6452 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6453 .getVectorElementCount() &&
6454 "Unable to widen vector load");
6456 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6457 Mask, EVL,
N->getMemOperand());
6470 "Unable to widen VP strided load");
6471 Mask = GetWidenedVector(Mask);
6473 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6474 assert(
Mask.getValueType().getVectorElementCount() ==
6476 "Data and mask vectors should have the same number of elements");
6478 SDValue Res = DAG.getStridedLoadVP(
6479 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6480 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6481 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6482 N->isExpandingLoad());
6490SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6495 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6497 Mask.getValueType().getVectorElementType(),
6500 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6501 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6502 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6504 WideMask, WidePassthru);
6508 EVT VT =
N->getValueType(0);
6509 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6511 EVT MaskVT =
Mask.getValueType();
6512 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6521 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6522 TLI.isTypeLegal(WideMaskVT) &&
6528 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6529 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6533 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6534 N->getMemoryVT(),
N->getMemOperand());
6538 if (!
N->getPassThru()->isUndef()) {
6541 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6552 Mask = ModifyToType(Mask, WideMaskVT,
true);
6554 SDValue Res = DAG.getMaskedLoad(
6555 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6556 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6557 ExtType,
N->isExpandingLoad());
6566 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6568 EVT MaskVT =
Mask.getValueType();
6569 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6578 Mask = ModifyToType(Mask, WideMaskVT,
true);
6583 Index.getValueType().getScalarType(),
6585 Index = ModifyToType(Index, WideIndexVT);
6591 N->getMemoryVT().getScalarType(), NumElts);
6592 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6593 WideMemVT, dl,
Ops,
N->getMemOperand(),
6594 N->getIndexType(),
N->getExtensionType());
6603 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6611 N->getMemoryVT().getScalarType(), WideEC);
6612 Mask = GetWidenedMask(Mask, WideEC);
6615 Mask,
N->getVectorLength()};
6616 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6617 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6626 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6627 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6655 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6656 return N->getOperand(OpNo).getValueType();
6664 N =
N.getOperand(0);
6666 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6667 if (!
N->getOperand(i)->isUndef())
6669 N =
N.getOperand(0);
6673 N =
N.getOperand(0);
6675 N =
N.getOperand(0);
6702 { MaskVT, MVT::Other },
Ops);
6703 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6710 LLVMContext &Ctx = *DAG.getContext();
6713 if (MaskScalarBits < ToMaskScalBits) {
6717 }
else if (MaskScalarBits > ToMaskScalBits) {
6723 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6725 "Mask should have the right element size by now.");
6728 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6730 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6733 EVT SubVT =
Mask->getValueType(0);
6739 assert((
Mask->getValueType(0) == ToMaskVT) &&
6740 "A mask of ToMaskVT should have been produced by now.");
6750 LLVMContext &Ctx = *DAG.getContext();
6761 EVT CondVT =
Cond->getValueType(0);
6765 EVT VSelVT =
N->getValueType(0);
6777 EVT FinalVT = VSelVT;
6788 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6789 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6796 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6804 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6807 EVT ToMaskVT = VSelVT;
6814 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6830 if (ScalarBits0 != ScalarBits1) {
6831 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6832 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6844 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6845 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6846 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6849 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6857 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6862 unsigned Opcode =
N->getOpcode();
6864 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6865 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6866 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6868 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6874 Cond1 = GetWidenedVector(Cond1);
6882 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6883 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6888 Cond1 = ModifyToType(Cond1, CondWidenVT);
6891 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6892 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6894 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6895 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6897 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6901 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6902 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6905 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6909 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6910 return DAG.getUNDEF(WidenVT);
6914 EVT VT =
N->getValueType(0);
6917 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6921 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6922 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6925 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6926 for (
unsigned i = 0; i != NumElts; ++i) {
6927 int Idx =
N->getMaskElt(i);
6928 if (Idx < (
int)NumElts)
6931 NewMask[i] = Idx - NumElts + WidenNumElts;
6933 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6937 EVT VT =
N->getValueType(0);
6941 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6942 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6948 unsigned IdxVal = WidenNumElts - VTNumElts;
6961 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6964 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6965 "down type's element count");
6968 for (; i < VTNumElts / GCD; ++i)
6970 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6971 for (; i < WidenNumElts / GCD; ++i)
6979 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6980 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6982 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6986SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6987 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6992 assert(
N->getValueType(0).isVector() &&
6993 N->getOperand(0).getValueType().isVector() &&
6994 "Operands must be vectors");
6995 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7008 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7009 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7016 InOp1 = GetWidenedVector(InOp1);
7017 InOp2 = GetWidenedVector(InOp2);
7020 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7031 "Input not widened to expected type!");
7033 if (
N->getOpcode() == ISD::VP_SETCC) {
7036 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7037 N->getOperand(2), Mask,
N->getOperand(4));
7039 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7044 assert(
N->getValueType(0).isVector() &&
7045 N->getOperand(1).getValueType().isVector() &&
7046 "Operands must be vectors");
7047 EVT VT =
N->getValueType(0);
7048 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7058 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7063 for (
unsigned i = 0; i != NumElts; ++i) {
7064 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7065 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7067 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7068 {Chain, LHSElem, RHSElem, CC});
7069 Chains[i] = Scalars[i].getValue(1);
7070 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7071 DAG.getBoolConstant(
true, dl, EltVT, VT),
7072 DAG.getBoolConstant(
false, dl, EltVT, VT));
7076 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7078 return DAG.getBuildVector(WidenVT, dl, Scalars);
7084bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7085 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7089 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7092 switch (
N->getOpcode()) {
7095 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7103 Res = WidenVecOp_FAKE_USE(
N);
7109 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7110 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7111 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7112 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7117 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7119 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7120 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7122 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7123 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7133 Res = WidenVecOp_UnrollVectorOp(
N);
7140 Res = WidenVecOp_EXTEND(
N);
7145 Res = WidenVecOp_CMP(
N);
7161 Res = WidenVecOp_Convert(
N);
7166 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7184 Res = WidenVecOp_VECREDUCE(
N);
7188 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7190 case ISD::VP_REDUCE_FADD:
7191 case ISD::VP_REDUCE_SEQ_FADD:
7192 case ISD::VP_REDUCE_FMUL:
7193 case ISD::VP_REDUCE_SEQ_FMUL:
7194 case ISD::VP_REDUCE_ADD:
7195 case ISD::VP_REDUCE_MUL:
7196 case ISD::VP_REDUCE_AND:
7197 case ISD::VP_REDUCE_OR:
7198 case ISD::VP_REDUCE_XOR:
7199 case ISD::VP_REDUCE_SMAX:
7200 case ISD::VP_REDUCE_SMIN:
7201 case ISD::VP_REDUCE_UMAX:
7202 case ISD::VP_REDUCE_UMIN:
7203 case ISD::VP_REDUCE_FMAX:
7204 case ISD::VP_REDUCE_FMIN:
7205 case ISD::VP_REDUCE_FMAXIMUM:
7206 case ISD::VP_REDUCE_FMINIMUM:
7207 Res = WidenVecOp_VP_REDUCE(
N);
7209 case ISD::VP_CTTZ_ELTS:
7210 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7211 Res = WidenVecOp_VP_CttzElements(
N);
7216 if (!Res.
getNode())
return false;
7224 if (
N->isStrictFPOpcode())
7226 "Invalid operand expansion");
7229 "Invalid operand expansion");
7231 ReplaceValueWith(
SDValue(
N, 0), Res);
7237 EVT VT =
N->getValueType(0);
7242 "Unexpected type action");
7243 InOp = GetWidenedVector(InOp);
7246 "Input wasn't widened!");
7254 EVT FixedEltVT = FixedVT.getVectorElementType();
7255 if (TLI.isTypeLegal(FixedVT) &&
7257 FixedEltVT == InEltVT) {
7259 "Not enough elements in the fixed type for the operand!");
7261 "We can't have the same type as we started with!");
7263 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7265 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7274 return WidenVecOp_Convert(
N);
7279 switch (
N->getOpcode()) {
7294 EVT OpVT =
N->getOperand(0).getValueType();
7295 EVT ResVT =
N->getValueType(0);
7302 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7303 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7309 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7310 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7312 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7319 return DAG.UnrollVectorOp(
N);
7324 EVT ResultVT =
N->getValueType(0);
7326 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7329 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7335 {WideArg,
Test},
N->getFlags());
7341 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7343 EVT OpVT =
N->getOperand(0).getValueType();
7346 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7351 EVT VT =
N->getValueType(0);
7357 "Unexpected type action");
7358 InOp = GetWidenedVector(InOp);
7360 unsigned Opcode =
N->getOpcode();
7366 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7368 if (
N->isStrictFPOpcode()) {
7370 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7373 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7374 {
N->getOperand(0), InOp });
7380 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7382 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7384 return DAG.getExtractSubvector(dl, VT, Res, 0);
7392 if (
N->isStrictFPOpcode()) {
7395 for (
unsigned i=0; i < NumElts; ++i) {
7396 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7397 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7401 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7403 for (
unsigned i = 0; i < NumElts; ++i)
7404 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7405 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7408 return DAG.getBuildVector(VT, dl,
Ops);
7412 EVT DstVT =
N->getValueType(0);
7413 SDValue Src = GetWidenedVector(
N->getOperand(0));
7414 EVT SrcVT = Src.getValueType();
7421 if (TLI.isTypeLegal(WideDstVT)) {
7423 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7426 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7430 return DAG.UnrollVectorOp(
N);
7434 EVT VT =
N->getValueType(0);
7435 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7443 if (!VT.
isVector() && VT != MVT::x86mmx &&
7447 if (TLI.isTypeLegal(NewVT)) {
7449 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7461 ElementCount NewNumElts =
7463 .divideCoefficientBy(EltSize);
7465 if (TLI.isTypeLegal(NewVT)) {
7467 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7472 return CreateStackStoreLoad(InOp, VT);
7480 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7481 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7486 EVT VT =
N->getValueType(0);
7488 EVT InVT =
N->getOperand(0).getValueType();
7493 unsigned NumOperands =
N->getNumOperands();
7494 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7496 for (i = 1; i < NumOperands; ++i)
7497 if (!
N->getOperand(i).isUndef())
7500 if (i == NumOperands)
7501 return GetWidenedVector(
N->getOperand(0));
7511 for (
unsigned i=0; i < NumOperands; ++i) {
7515 "Unexpected type action");
7516 InOp = GetWidenedVector(InOp);
7517 for (
unsigned j = 0;
j < NumInElts; ++
j)
7518 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7520 return DAG.getBuildVector(VT, dl,
Ops);
7523SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7524 EVT VT =
N->getValueType(0);
7529 SubVec = GetWidenedVector(SubVec);
7534 bool IndicesValid =
false;
7537 IndicesValid =
true;
7541 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7542 Attribute::VScaleRange);
7547 IndicesValid =
true;
7553 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7559 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7566 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7573 Align Alignment = DAG.getReducedAlign(VT,
false);
7575 MachineFunction &MF = DAG.getMachineFunction();
7588 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7596 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7597 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7602 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7607 unsigned Idx =
N->getConstantOperandVal(2);
7613 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7619SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7620 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7622 N->getValueType(0), InOp,
N->getOperand(1));
7625SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7626 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7628 N->getValueType(0), InOp,
N->getOperand(1));
7631SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7632 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7633 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7641 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7642 return TLI.scalarizeVectorStore(ST, DAG);
7644 if (
ST->isTruncatingStore())
7645 return TLI.scalarizeVectorStore(ST, DAG);
7655 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7656 EVT WideMaskVT = getSetCCResultType(WideVT);
7658 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7659 TLI.isTypeLegal(WideMaskVT)) {
7662 StVal = GetWidenedVector(StVal);
7664 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7666 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7667 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7668 ST->getAddressingMode());
7672 if (GenWidenVectorStores(StChain, ST)) {
7673 if (StChain.
size() == 1)
7682 SDValue WideStVal = GetWidenedVector(StVal);
7686 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7687 ST->getOffset(), Mask,
ST->getMemoryVT(),
7688 ST->getMemOperand(),
ST->getAddressingMode(),
7689 ST->isTruncatingStore());
7695SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7696 assert((OpNo == 1 || OpNo == 3) &&
7697 "Can widen only data or mask operand of vp_store");
7705 StVal = GetWidenedVector(StVal);
7711 "Unable to widen VP store");
7712 Mask = GetWidenedVector(Mask);
7714 Mask = GetWidenedVector(Mask);
7720 "Unable to widen VP store");
7721 StVal = GetWidenedVector(StVal);
7724 assert(
Mask.getValueType().getVectorElementCount() ==
7726 "Mask and data vectors should have the same number of elements");
7727 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7728 ST->getOffset(), Mask,
ST->getVectorLength(),
7729 ST->getMemoryVT(),
ST->getMemOperand(),
7730 ST->getAddressingMode(),
ST->isTruncatingStore(),
7731 ST->isCompressingStore());
7736 assert((OpNo == 1 || OpNo == 4) &&
7737 "Can widen only data or mask operand of vp_strided_store");
7746 "Unable to widen VP strided store");
7750 "Unable to widen VP strided store");
7752 StVal = GetWidenedVector(StVal);
7753 Mask = GetWidenedVector(Mask);
7756 Mask.getValueType().getVectorElementCount() &&
7757 "Data and mask vectors should have the same number of elements");
7759 return DAG.getStridedStoreVP(
7766SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7767 assert((OpNo == 1 || OpNo == 4) &&
7768 "Can widen only data or mask operand of mstore");
7771 EVT MaskVT =
Mask.getValueType();
7776 EVT WideVT, WideMaskVT;
7779 StVal = GetWidenedVector(StVal);
7786 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7793 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7794 TLI.isTypeLegal(WideMaskVT)) {
7795 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7796 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7805 Mask = ModifyToType(Mask, WideMaskVT,
true);
7808 Mask = ModifyToType(Mask, WideMaskVT,
true);
7810 StVal = ModifyToType(StVal, WideVT);
7813 assert(
Mask.getValueType().getVectorElementCount() ==
7815 "Mask and data vectors should have the same number of elements");
7822SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7823 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7825 SDValue DataOp = MG->getPassThru();
7827 SDValue Scale = MG->getScale();
7835 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7836 MG->getMemOperand(), MG->getIndexType(),
7837 MG->getExtensionType());
7843SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7852 DataOp = GetWidenedVector(DataOp);
7856 EVT IndexVT =
Index.getValueType();
7859 Index = ModifyToType(Index, WideIndexVT);
7862 EVT MaskVT =
Mask.getValueType();
7865 Mask = ModifyToType(Mask, WideMaskVT,
true);
7870 }
else if (OpNo == 4) {
7872 Index = GetWidenedVector(Index);
7878 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7883SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7892 DataOp = GetWidenedVector(DataOp);
7893 Index = GetWidenedVector(Index);
7895 Mask = GetWidenedMask(Mask, WideEC);
7898 }
else if (OpNo == 3) {
7900 Index = GetWidenedVector(Index);
7907 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7912 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7913 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7915 EVT VT =
N->getValueType(0);
7930 SVT, InOp0, InOp1,
N->getOperand(2));
7936 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7938 EVT OpVT =
N->getOperand(0).getValueType();
7941 return DAG.getNode(ExtendCode, dl, VT, CC);
7951 EVT VT =
N->getValueType(0);
7953 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7960 for (
unsigned i = 0; i != NumElts; ++i) {
7961 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7962 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7964 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7965 {Chain, LHSElem, RHSElem, CC});
7966 Chains[i] = Scalars[i].getValue(1);
7967 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7968 DAG.getBoolConstant(
true, dl, EltVT, VT),
7969 DAG.getBoolConstant(
false, dl, EltVT, VT));
7973 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7975 return DAG.getBuildVector(VT, dl, Scalars);
7999 SDValue Op = GetWidenedVector(
N->getOperand(0));
8000 EVT VT =
N->getValueType(0);
8001 EVT OrigVT =
N->getOperand(0).getValueType();
8002 EVT WideVT =
Op.getValueType();
8004 SDNodeFlags
Flags =
N->getFlags();
8006 unsigned Opc =
N->getOpcode();
8008 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8009 assert(NeutralElem &&
"Neutral element must exist");
8019 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8026 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8027 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8033 unsigned GCD = std::gcd(OrigElts, WideElts);
8036 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8037 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8038 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8039 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8042 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8043 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8045 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8054 EVT VT =
N->getValueType(0);
8056 EVT WideVT =
Op.getValueType();
8058 SDNodeFlags
Flags =
N->getFlags();
8060 unsigned Opc =
N->getOpcode();
8062 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8072 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8075 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8076 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8082 unsigned GCD = std::gcd(OrigElts, WideElts);
8085 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8086 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8087 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8088 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8091 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8092 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8094 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8098 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8101 SDValue Op = GetWidenedVector(
N->getOperand(1));
8103 Op.getValueType().getVectorElementCount());
8105 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8106 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8114 EVT VT =
N->getValueType(0);
8118 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8119 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8124 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8130 EVT SrcVT =
Source.getValueType();
8134 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8135 {Source, Mask, N->getOperand(2)},
N->getFlags());
8152 unsigned WidenEx = 0) {
8157 unsigned AlignInBits =
Align*8;
8159 EVT RetVT = WidenEltVT;
8164 if (Width == WidenEltWidth)
8175 (WidenWidth % MemVTWidth) == 0 &&
8177 (MemVTWidth <= Width ||
8178 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8179 if (MemVTWidth == WidenWidth)
8198 (WidenWidth % MemVTWidth) == 0 &&
8200 (MemVTWidth <= Width ||
8201 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8210 return std::nullopt;
8221 unsigned Start,
unsigned End) {
8222 SDLoc dl(LdOps[Start]);
8223 EVT LdTy = LdOps[Start].getValueType();
8231 for (
unsigned i = Start + 1; i != End; ++i) {
8232 EVT NewLdTy = LdOps[i].getValueType();
8233 if (NewLdTy != LdTy) {
8252 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8253 EVT LdVT =
LD->getMemoryVT();
8263 AAMDNodes AAInfo =
LD->getAAInfo();
8267 TypeSize WidthDiff = WidenWidth - LdWidth;
8274 std::optional<EVT> FirstVT =
8275 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8282 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8287 std::optional<EVT> NewVT = FirstVT;
8288 TypeSize RemainingWidth = LdWidth;
8289 TypeSize NewVTWidth = FirstVTWidth;
8291 RemainingWidth -= NewVTWidth;
8298 NewVTWidth = NewVT->getSizeInBits();
8304 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8305 LD->getBaseAlign(), MMOFlags, AAInfo);
8309 if (MemVTs.
empty()) {
8311 if (!FirstVT->isVector()) {
8318 if (FirstVT == WidenVT)
8323 unsigned NumConcat =
8326 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8327 ConcatOps[0] = LdOp;
8328 for (
unsigned i = 1; i != NumConcat; ++i)
8329 ConcatOps[i] = UndefVal;
8337 uint64_t ScaledOffset = 0;
8338 MachinePointerInfo MPI =
LD->getPointerInfo();
8344 for (EVT MemVT : MemVTs) {
8345 Align NewAlign = ScaledOffset == 0
8346 ?
LD->getBaseAlign()
8349 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8357 unsigned End = LdOps.
size();
8368 EVT LdTy = LdOps[i].getValueType();
8371 for (--i; i >= 0; --i) {
8372 LdTy = LdOps[i].getValueType();
8379 ConcatOps[--Idx] = LdOps[i];
8380 for (--i; i >= 0; --i) {
8381 EVT NewLdTy = LdOps[i].getValueType();
8382 if (NewLdTy != LdTy) {
8392 for (;
j != End-Idx; ++
j)
8393 WidenOps[j] = ConcatOps[Idx+j];
8395 WidenOps[j] = DAG.getUNDEF(LdTy);
8402 ConcatOps[--Idx] = LdOps[i];
8407 ArrayRef(&ConcatOps[Idx], End - Idx));
8413 SDValue UndefVal = DAG.getUNDEF(LdTy);
8416 for (; i != End-Idx; ++i)
8417 WidenOps[i] = ConcatOps[Idx+i];
8419 WidenOps[i] = UndefVal;
8430 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8431 EVT LdVT =
LD->getMemoryVT();
8440 AAMDNodes AAInfo =
LD->getAAInfo();
8454 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8455 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8461 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8462 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8463 LD->getBaseAlign(), MMOFlags, AAInfo);
8468 SDValue UndefVal = DAG.getUNDEF(EltVT);
8469 for (; i != WidenNumElts; ++i)
8472 return DAG.getBuildVector(WidenVT, dl,
Ops);
8483 AAMDNodes AAInfo =
ST->getAAInfo();
8484 SDValue ValOp = GetWidenedVector(
ST->getValue());
8487 EVT StVT =
ST->getMemoryVT();
8495 "Mismatch between store and value types");
8499 MachinePointerInfo MPI =
ST->getPointerInfo();
8500 uint64_t ScaledOffset = 0;
8509 std::optional<EVT> NewVT =
8514 TypeSize NewVTWidth = NewVT->getSizeInBits();
8517 StWidth -= NewVTWidth;
8518 MemVTs.
back().second++;
8522 for (
const auto &Pair : MemVTs) {
8523 EVT NewVT = Pair.first;
8524 unsigned Count = Pair.second;
8530 Align NewAlign = ScaledOffset == 0
8531 ?
ST->getBaseAlign()
8533 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8534 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8550 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8551 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8552 ST->getBaseAlign(), MMOFlags, AAInfo);
8569 bool FillWithZeroes) {
8574 "input and widen element type must match");
8576 "cannot modify scalable vectors in this way");
8588 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8591 for (
unsigned i = 1; i != NumConcat; ++i)
8598 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8601 "Scalable vectors should have been handled already.");
8609 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8611 for (Idx = 0; Idx < MinNumElts; ++Idx)
8612 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8614 SDValue UndefVal = DAG.getUNDEF(EltVT);
8615 for (; Idx < WidenNumElts; ++Idx)
8616 Ops[Idx] = UndefVal;
8618 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8619 if (!FillWithZeroes)
8623 "We expect to never want to FillWithZeroes for non-integral types.");
8626 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8627 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8629 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8630 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 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 std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align=0, unsigned WidenEx=0)
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
This file implements the SmallBitVector class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, IMM) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by IMM elements and retu...
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, IMM) - Shifts CONCAT_VECTORS(VEC1, VEC2) right by IMM elements and re...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.