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);
203 R = ScalarizeVecRes_BinOp(
N);
208 R = ScalarizeVecRes_CMP(
N);
214 R = ScalarizeVecRes_TernaryOp(
N);
217#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
218 case ISD::STRICT_##DAGN:
219#include "llvm/IR/ConstrainedOps.def"
220 R = ScalarizeVecRes_StrictFPOp(
N);
225 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
234 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
244 R = ScalarizeVecRes_FIX(
N);
250 SetScalarizedVector(
SDValue(
N, ResNo), R);
254 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
255 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
256 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
265 if (getTypeAction(
LHS.getValueType()) ==
267 LHS = GetScalarizedVector(
LHS);
268 RHS = GetScalarizedVector(
RHS);
270 EVT VT =
LHS.getValueType().getVectorElementType();
271 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
272 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
275 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
276 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
280 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
281 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
282 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
283 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
288 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
289 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
296DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
298 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
299 "Unexpected vector type!");
300 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
302 EVT VT0 =
N->getValueType(0);
303 EVT VT1 =
N->getValueType(1);
307 DAG.getNode(
N->getOpcode(), dl,
308 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
312 unsigned OtherNo = 1 - ResNo;
313 EVT OtherVT =
N->getValueType(OtherNo);
315 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
319 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
322 return SDValue(ScalarNode, ResNo);
327 unsigned NumOpers =
N->getNumOperands();
329 EVT ValueVTs[] = {VT, MVT::Other};
338 for (
unsigned i = 1; i < NumOpers; ++i) {
344 Oper = GetScalarizedVector(Oper);
353 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
354 Opers,
N->getFlags());
365 EVT ResVT =
N->getValueType(0);
366 EVT OvVT =
N->getValueType(1);
370 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
371 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
374 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
375 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
376 ScalarLHS = ElemsLHS[0];
377 ScalarRHS = ElemsRHS[0];
380 SDVTList ScalarVTs = DAG.getVTList(
382 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
383 {ScalarLHS, ScalarRHS},
N->getFlags())
387 unsigned OtherNo = 1 - ResNo;
388 EVT OtherVT =
N->getValueType(OtherNo);
390 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
394 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
397 return SDValue(ScalarNode, ResNo);
402 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
403 return GetScalarizedVector(
Op);
406SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
408 SDValue SourceValue =
N->getOperand(0);
409 SDValue SinkValue =
N->getOperand(1);
410 SDValue EltSizeInBytes =
N->getOperand(2);
411 SDValue LaneOffset =
N->getOperand(3);
419 if (IsReadAfterWrite)
427 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
432 return DAG.getNode(
ISD::OR,
DL, CmpVT, Cmp,
439 Op = GetScalarizedVector(
Op);
440 EVT NewVT =
N->getValueType(0).getVectorElementType();
445SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
455SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
457 N->getValueType(0).getVectorElementType(),
458 N->getOperand(0),
N->getOperand(1));
464 EVT OpVT =
Op.getValueType();
468 Op = GetScalarizedVector(
Op);
471 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
474 N->getValueType(0).getVectorElementType(),
Op,
478SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
479 SDValue Op = GetScalarizedVector(
N->getOperand(0));
480 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
484SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
489 if (
Op.getValueType() != EltVT)
497 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
498 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
508 assert(
N->isUnindexed() &&
"Indexed vector load?");
512 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
513 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
514 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
515 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
527 EVT OpVT =
Op.getValueType();
537 Op = GetScalarizedVector(
Op);
540 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
542 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
548 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
549 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
550 LHS, DAG.getValueType(ExtVT));
557 EVT OpVT =
Op.getValueType();
562 Op = GetScalarizedVector(
Op);
564 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
567 switch (
N->getOpcode()) {
579SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
582 EVT OpVT =
Op.getValueType();
592 Op = GetScalarizedVector(
Op);
595 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
598 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
599 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
600 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
603SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
615 EVT OpVT =
Cond.getValueType();
624 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
627 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
629 TLI.getBooleanContents(
false,
false);
636 if (TLI.getBooleanContents(
false,
false) !=
637 TLI.getBooleanContents(
false,
true)) {
641 EVT OpVT =
Cond->getOperand(0).getValueType();
643 VecBool = TLI.getBooleanContents(OpVT);
648 EVT CondVT =
Cond.getValueType();
649 if (ScalarBool != VecBool) {
650 switch (ScalarBool) {
658 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
665 Cond, DAG.getValueType(MVT::i1));
671 auto BoolVT = getSetCCResultType(CondVT);
672 if (BoolVT.bitsLT(CondVT))
675 return DAG.getSelect(SDLoc(
N),
677 GetScalarizedVector(
N->getOperand(2)));
681 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
682 return DAG.getSelect(SDLoc(
N),
683 LHS.getValueType(),
N->getOperand(0),
LHS,
684 GetScalarizedVector(
N->getOperand(2)));
688 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
690 N->getOperand(0),
N->getOperand(1),
691 LHS, GetScalarizedVector(
N->getOperand(3)),
696 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
699SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
703 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
705 return GetScalarizedVector(
N->getOperand(
Op));
708SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
710 EVT SrcVT = Src.getValueType();
715 Src = GetScalarizedVector(Src);
719 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
721 EVT DstVT =
N->getValueType(0).getVectorElementType();
722 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
726 assert(
N->getValueType(0).isVector() &&
727 N->getOperand(0).getValueType().isVector() &&
728 "Operand types must be vectors");
731 EVT OpVT =
LHS.getValueType();
732 EVT NVT =
N->getValueType(0).getVectorElementType();
737 LHS = GetScalarizedVector(
LHS);
738 RHS = GetScalarizedVector(
RHS);
741 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
742 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
752 return DAG.getNode(ExtendCode,
DL, NVT, Res);
763 Arg = GetScalarizedVector(Arg);
766 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
775 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
782bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
787 switch (
N->getOpcode()) {
790 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
797 Res = ScalarizeVecOp_BITCAST(
N);
800 Res = ScalarizeVecOp_FAKE_USE(
N);
814 Res = ScalarizeVecOp_UnaryOp(
N);
818 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
824 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
827 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
830 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
833 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
836 Res = ScalarizeVecOp_VSELECT(
N);
839 Res = ScalarizeVecOp_VSETCC(
N);
843 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
849 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
852 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
855 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
858 Res = ScalarizeVecOp_FP_EXTEND(
N);
875 Res = ScalarizeVecOp_VECREDUCE(
N);
879 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
883 Res = ScalarizeVecOp_CMP(
N);
888 if (!Res.
getNode())
return false;
896 "Invalid operand expansion");
898 ReplaceValueWith(
SDValue(
N, 0), Res);
905 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
907 N->getValueType(0), Elt);
912 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
913 "Fake Use: Unexpected vector type!");
914 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
915 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
921 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
922 "Unexpected vector type!");
923 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
925 N->getValueType(0).getScalarType(), Elt);
933SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
934 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
935 "Unexpected vector type!");
936 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
938 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
939 Elt,
N->getOperand(1));
947SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
948 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
949 "Unexpected vector type!");
950 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
952 {
N->getValueType(0).getScalarType(), MVT::Other },
953 {
N->getOperand(0), Elt });
963 ReplaceValueWith(
SDValue(
N, 0), Res);
968SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
970 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
971 Ops[i] = GetScalarizedVector(
N->getOperand(i));
972 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
977SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
981 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
982 SDValue ContainingVec =
N->getOperand(0);
990SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
991 EVT VT =
N->getValueType(0);
992 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1004 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1005 EVT VT =
N->getValueType(0);
1007 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1015 assert(
N->getValueType(0).isVector() &&
1016 N->getOperand(0).getValueType().isVector() &&
1017 "Operand types must be vectors");
1018 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1020 EVT VT =
N->getValueType(0);
1021 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1022 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1024 EVT OpVT =
N->getOperand(0).getValueType();
1036 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1042SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1044 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1045 assert(
N->getValueType(0).isVector() &&
1046 N->getOperand(1).getValueType().isVector() &&
1047 "Operand types must be vectors");
1048 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1050 EVT VT =
N->getValueType(0);
1052 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1053 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1056 EVT OpVT =
N->getOperand(1).getValueType();
1060 {Ch, LHS, RHS, CC});
1069 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1074 ReplaceValueWith(
SDValue(
N, 0), Res);
1081 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1082 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1085 if (
N->isTruncatingStore())
1086 return DAG.getTruncStore(
1087 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1088 N->getBasePtr(),
N->getPointerInfo(),
1089 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1090 N->getMemOperand()->getFlags(),
N->getAAInfo());
1092 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1093 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1094 N->getMemOperand()->getFlags(),
N->getAAInfo());
1099SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1100 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1101 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1103 N->getValueType(0).getVectorElementType(), Elt,
1108SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1110 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1111 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1114 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1124 ReplaceValueWith(
SDValue(
N, 0), Res);
1131 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1133 N->getValueType(0).getVectorElementType(), Elt);
1139SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1140 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1143 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1144 {
N->getOperand(0), Elt});
1153 ReplaceValueWith(
SDValue(
N, 0), Res);
1158 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1165SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1171 SDValue Op = GetScalarizedVector(VecOp);
1172 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1173 AccOp,
Op,
N->getFlags());
1177 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1178 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1193void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1198 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1201 switch (
N->getOpcode()) {
1204 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1213 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1220 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1236 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1239 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1248 case ISD::VP_LOAD_FF:
1251 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1258 case ISD::VP_GATHER:
1262 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1266 SplitVecRes_SETCC(
N,
Lo,
Hi);
1269 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1275 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1278 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1281 SplitVecRes_VECTOR_INTERLEAVE(
N);
1284 SplitVecRes_VAARG(
N,
Lo,
Hi);
1290 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1296 case ISD::VP_BITREVERSE:
1304 case ISD::VP_CTLZ_ZERO_UNDEF:
1306 case ISD::VP_CTTZ_ZERO_UNDEF:
1321 case ISD::VP_FFLOOR:
1326 case ISD::VP_FNEARBYINT:
1331 case ISD::VP_FP_EXTEND:
1333 case ISD::VP_FP_ROUND:
1335 case ISD::VP_FP_TO_SINT:
1337 case ISD::VP_FP_TO_UINT:
1343 case ISD::VP_LLRINT:
1345 case ISD::VP_FROUND:
1347 case ISD::VP_FROUNDEVEN:
1356 case ISD::VP_FROUNDTOZERO:
1358 case ISD::VP_SINT_TO_FP:
1360 case ISD::VP_TRUNCATE:
1362 case ISD::VP_UINT_TO_FP:
1365 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1368 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1374 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1380 case ISD::VP_SIGN_EXTEND:
1381 case ISD::VP_ZERO_EXTEND:
1382 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1401 case ISD::VP_FMINNUM:
1404 case ISD::VP_FMAXNUM:
1406 case ISD::VP_FMINIMUM:
1408 case ISD::VP_FMAXIMUM:
1417 case ISD::OR:
case ISD::VP_OR:
1437 case ISD::VP_FCOPYSIGN:
1438 SplitVecRes_BinOp(
N,
Lo,
Hi);
1445 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1449 SplitVecRes_CMP(
N,
Lo,
Hi);
1452#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1453 case ISD::STRICT_##DAGN:
1454#include "llvm/IR/ConstrainedOps.def"
1455 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1460 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1469 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1479 SplitVecRes_FIX(
N,
Lo,
Hi);
1481 case ISD::EXPERIMENTAL_VP_SPLICE:
1482 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1484 case ISD::EXPERIMENTAL_VP_REVERSE:
1485 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1491 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1494 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1503void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1505 uint64_t *ScaledOffset) {
1510 SDValue BytesIncrement = DAG.getVScale(
1513 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1515 *ScaledOffset += IncrementSize;
1525std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1526 return SplitMask(Mask, SDLoc(Mask));
1529std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1532 EVT MaskVT =
Mask.getValueType();
1534 GetSplitVector(Mask, MaskLo, MaskHi);
1536 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1537 return std::make_pair(MaskLo, MaskHi);
1542 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1544 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1547 const SDNodeFlags
Flags =
N->getFlags();
1548 unsigned Opcode =
N->getOpcode();
1549 if (
N->getNumOperands() == 2) {
1550 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1551 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1555 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1556 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1559 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1562 std::tie(EVLLo, EVLHi) =
1563 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1566 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1568 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1574 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1576 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1578 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1581 const SDNodeFlags
Flags =
N->getFlags();
1582 unsigned Opcode =
N->getOpcode();
1583 if (
N->getNumOperands() == 3) {
1584 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1585 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1589 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1590 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1593 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1596 std::tie(EVLLo, EVLHi) =
1597 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1600 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1602 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1606 LLVMContext &Ctxt = *DAG.getContext();
1612 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1614 GetSplitVector(
LHS, LHSLo, LHSHi);
1615 GetSplitVector(
RHS, RHSLo, RHSHi);
1617 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1618 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1622 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1623 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1628 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1630 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1634 unsigned Opcode =
N->getOpcode();
1635 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1637 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1646 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1653 switch (getTypeAction(InVT)) {
1668 GetExpandedOp(InOp,
Lo,
Hi);
1669 if (DAG.getDataLayout().isBigEndian())
1679 GetSplitVector(InOp,
Lo,
Hi);
1688 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1697 if (DAG.getDataLayout().isBigEndian())
1700 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1702 if (DAG.getDataLayout().isBigEndian())
1708void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1714 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1717 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1722 unsigned LaneOffset =
1725 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1727 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1734 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1737 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1740 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1745 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1747 unsigned NumSubvectors =
N->getNumOperands() / 2;
1748 if (NumSubvectors == 1) {
1749 Lo =
N->getOperand(0);
1750 Hi =
N->getOperand(1);
1755 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1764void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1771 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1786 GetSplitVector(Vec,
Lo,
Hi);
1789 EVT LoVT =
Lo.getValueType();
1799 if (IdxVal + SubElems <= LoElems) {
1807 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1809 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1815 SDValue WideSubVec = GetWidenedVector(SubVec);
1817 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1825 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1827 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1828 auto &MF = DAG.getMachineFunction();
1832 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1837 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1838 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1842 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1847 MachinePointerInfo MPI =
Load->getPointerInfo();
1848 IncrementPointer(Load, LoVT, MPI, StackPtr);
1851 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1860 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1865 EVT RHSVT =
RHS.getValueType();
1868 GetSplitVector(
RHS, RHSLo, RHSHi);
1870 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1885 SDValue FpValue =
N->getOperand(0);
1887 GetSplitVector(FpValue, ArgLo, ArgHi);
1889 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1891 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1900 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1904 std::tie(LoVT, HiVT) =
1908 DAG.getValueType(LoVT));
1910 DAG.getValueType(HiVT));
1915 unsigned Opcode =
N->getOpcode();
1922 GetSplitVector(N0, InLo, InHi);
1924 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1929 EVT OutLoVT, OutHiVT;
1930 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1932 assert((2 * OutNumElements) <= InNumElements &&
1933 "Illegal extend vector in reg split");
1942 SmallVector<int, 8> SplitHi(InNumElements, -1);
1943 for (
unsigned i = 0; i != OutNumElements; ++i)
1944 SplitHi[i] = i + OutNumElements;
1945 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1947 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1948 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1953 unsigned NumOps =
N->getNumOperands();
1957 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1967 for (
unsigned i = 1; i <
NumOps; ++i) {
1972 EVT InVT =
Op.getValueType();
1977 GetSplitVector(
Op, OpLo, OpHi);
1979 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
1986 EVT LoValueVTs[] = {LoVT, MVT::Other};
1987 EVT HiValueVTs[] = {HiVT, MVT::Other};
1988 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1990 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
1996 Lo.getValue(1),
Hi.getValue(1));
2000 ReplaceValueWith(
SDValue(
N, 1), Chain);
2003SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2005 EVT VT =
N->getValueType(0);
2016 else if (NE > ResNE)
2020 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2024 for (i = 0; i !=
NE; ++i) {
2025 Operands[0] = Chain;
2026 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2027 SDValue Operand =
N->getOperand(j);
2031 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2033 Operands[
j] = Operand;
2037 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2045 for (; i < ResNE; ++i)
2050 ReplaceValueWith(
SDValue(
N, 1), Chain);
2054 return DAG.getBuildVector(VecVT, dl, Scalars);
2057void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2060 EVT ResVT =
N->getValueType(0);
2061 EVT OvVT =
N->getValueType(1);
2062 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2063 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2064 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2066 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2068 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2069 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2071 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2072 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2075 unsigned Opcode =
N->getOpcode();
2076 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2077 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2079 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2081 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2087 unsigned OtherNo = 1 - ResNo;
2088 EVT OtherVT =
N->getValueType(OtherNo);
2090 SetSplitVector(
SDValue(
N, OtherNo),
2096 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2100void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2106 GetSplitVector(Vec,
Lo,
Hi);
2109 unsigned IdxVal = CIdx->getZExtValue();
2110 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2111 if (IdxVal < LoNumElts) {
2113 Lo.getValueType(),
Lo, Elt, Idx);
2116 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2136 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2138 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2139 auto &MF = DAG.getMachineFunction();
2143 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2148 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2149 Store = DAG.getTruncStore(
2155 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2158 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2162 MachinePointerInfo MPI =
Load->getPointerInfo();
2163 IncrementPointer(Load, LoVT, MPI, StackPtr);
2165 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2168 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2169 if (LoVT !=
Lo.getValueType())
2171 if (HiVT !=
Hi.getValueType())
2179 assert(
N->getValueType(0).isScalableVector() &&
2180 "Only scalable vectors are supported for STEP_VECTOR");
2181 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2202 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2203 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2205 Hi = DAG.getPOISON(HiVT);
2217 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2223 EVT MemoryVT =
LD->getMemoryVT();
2225 AAMDNodes AAInfo =
LD->getAAInfo();
2227 EVT LoMemVT, HiMemVT;
2228 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2232 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2233 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2234 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2239 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2242 MachinePointerInfo MPI;
2243 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2246 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2255 ReplaceValueWith(
SDValue(LD, 1), Ch);
2260 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2263 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2269 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2270 Align Alignment =
LD->getBaseAlign();
2273 EVT MemoryVT =
LD->getMemoryVT();
2275 EVT LoMemVT, HiMemVT;
2276 bool HiIsEmpty =
false;
2277 std::tie(LoMemVT, HiMemVT) =
2278 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2283 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2286 GetSplitVector(Mask, MaskLo, MaskHi);
2288 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2293 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2295 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2301 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2302 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2310 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2311 LD->isExpandingLoad());
2313 MachinePointerInfo MPI;
2315 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2317 MPI =
LD->getPointerInfo().getWithOffset(
2320 MMO = DAG.getMachineFunction().getMachineMemOperand(
2322 Alignment,
LD->getAAInfo(),
LD->getRanges());
2324 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2325 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2326 LD->isExpandingLoad());
2336 ReplaceValueWith(
SDValue(LD, 1), Ch);
2342 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2346 Align Alignment =
LD->getBaseAlign();
2353 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2356 GetSplitVector(Mask, MaskLo, MaskHi);
2358 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2362 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2364 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2369 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2372 Hi = DAG.getPOISON(HiVT);
2374 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2375 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2381 "Indexed VP strided load during type legalization!");
2383 "Unexpected indexed variable-length load offset");
2388 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2390 EVT LoMemVT, HiMemVT;
2391 bool HiIsEmpty =
false;
2392 std::tie(LoMemVT, HiMemVT) =
2393 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2398 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2401 GetSplitVector(Mask, LoMask, HiMask);
2403 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2407 std::tie(LoEVL, HiEVL) =
2411 Lo = DAG.getStridedLoadVP(
2438 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2445 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2456 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2464 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2469 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2479 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2482 GetSplitVector(Mask, MaskLo, MaskHi);
2484 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2488 EVT LoMemVT, HiMemVT;
2489 bool HiIsEmpty =
false;
2490 std::tie(LoMemVT, HiMemVT) =
2491 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2493 SDValue PassThruLo, PassThruHi;
2495 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2497 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2499 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2503 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2513 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2516 MachinePointerInfo MPI;
2523 MMO = DAG.getMachineFunction().getMachineMemOperand(
2527 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2539 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2547 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2555 }
Ops = [&]() -> Operands {
2557 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2560 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2563 EVT MemoryVT =
N->getMemoryVT();
2564 Align Alignment =
N->getBaseAlign();
2569 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2571 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2574 EVT LoMemVT, HiMemVT;
2576 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2579 if (getTypeAction(
Ops.Index.getValueType()) ==
2581 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2583 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2586 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2588 Alignment,
N->getAAInfo(),
N->getRanges());
2591 SDValue PassThru = MGT->getPassThru();
2592 SDValue PassThruLo, PassThruHi;
2595 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2597 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2602 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2603 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2604 OpsLo, MMO, IndexTy, ExtType);
2606 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2607 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2608 OpsHi, MMO, IndexTy, ExtType);
2612 std::tie(EVLLo, EVLHi) =
2613 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2615 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2616 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2617 MMO, VPGT->getIndexType());
2619 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2620 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2621 MMO, VPGT->getIndexType());
2631 ReplaceValueWith(
SDValue(
N, 1), Ch);
2645 EVT VecVT =
N->getValueType(0);
2647 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2648 bool HasCustomLowering =
false;
2655 HasCustomLowering =
true;
2661 SDValue Passthru =
N->getOperand(2);
2662 if (!HasCustomLowering) {
2663 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2664 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2671 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2672 std::tie(LoMask, HiMask) = SplitMask(Mask);
2674 SDValue UndefPassthru = DAG.getUNDEF(LoVT);
2679 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2680 MachineFunction &MF = DAG.getMachineFunction();
2692 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2694 SDValue Chain = DAG.getEntryNode();
2695 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2699 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2704 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2708 assert(
N->getValueType(0).isVector() &&
2709 N->getOperand(0).getValueType().isVector() &&
2710 "Operand types must be vectors");
2714 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2718 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2720 GetSplitVector(
N->getOperand(0), LL, LH);
2722 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2724 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2726 GetSplitVector(
N->getOperand(1), RL, RH);
2728 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2731 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2732 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2734 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2735 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2736 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2737 std::tie(EVLLo, EVLHi) =
2738 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2739 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2741 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2751 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2755 EVT InVT =
N->getOperand(0).getValueType();
2757 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2759 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2761 const SDNodeFlags
Flags =
N->getFlags();
2762 unsigned Opcode =
N->getOpcode();
2763 if (
N->getNumOperands() <= 2) {
2765 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2766 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2768 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2769 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2774 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2775 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2778 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2781 std::tie(EVLLo, EVLHi) =
2782 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2785 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2791 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2795 EVT InVT =
N->getOperand(0).getValueType();
2797 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2799 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2802 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2803 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2804 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2805 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2808void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2813 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2814 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2818 EVT InVT =
N->getOperand(0).getValueType();
2820 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2822 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2824 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2825 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2827 SDNode *HiNode =
Hi.getNode();
2828 SDNode *LoNode =
Lo.getNode();
2831 unsigned OtherNo = 1 - ResNo;
2832 EVT OtherVT =
N->getValueType(OtherNo);
2840 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2847 EVT SrcVT =
N->getOperand(0).getValueType();
2848 EVT DestVT =
N->getValueType(0);
2850 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2867 LLVMContext &Ctx = *DAG.getContext();
2871 EVT SplitLoVT, SplitHiVT;
2872 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2873 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2874 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2875 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2876 N->dump(&DAG);
dbgs() <<
"\n");
2877 if (!
N->isVPOpcode()) {
2880 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2882 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2884 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2885 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2891 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2892 N->getOperand(1),
N->getOperand(2));
2894 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2897 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2900 std::tie(EVLLo, EVLHi) =
2901 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2903 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2904 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2909 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2917 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2918 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2924 return N.getResNo() == 0 &&
2928 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2930 ArrayRef<int>
Mask) {
2933 "Expected build vector node.");
2936 for (
unsigned I = 0;
I < NewElts; ++
I) {
2939 unsigned Idx =
Mask[
I];
2941 Ops[
I] = Input2.getOperand(Idx - NewElts);
2943 Ops[
I] = Input1.getOperand(Idx);
2948 return DAG.getBuildVector(NewVT,
DL,
Ops);
2954 SmallVector<int> OrigMask(
N->getMask());
2956 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2957 &
DL](SmallVectorImpl<int> &
Mask) {
2959 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2960 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2971 for (
auto &
P : ShufflesIdxs) {
2972 if (
P.second.size() < 2)
2976 for (
int &Idx : Mask) {
2979 unsigned SrcRegIdx = Idx / NewElts;
2980 if (Inputs[SrcRegIdx].
isUndef()) {
2988 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2993 Idx = MaskElt % NewElts +
2994 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3000 Inputs[
P.second[0]] =
P.first.first;
3001 Inputs[
P.second[1]] =
P.first.second;
3004 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3007 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3008 for (
int &Idx : Mask) {
3011 unsigned SrcRegIdx = Idx / NewElts;
3012 if (Inputs[SrcRegIdx].
isUndef()) {
3019 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3020 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3023 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3025 if (UsedSubVector.count() > 1) {
3027 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3028 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3030 if (Pairs.
empty() || Pairs.
back().size() == 2)
3032 if (UsedSubVector.test(2 *
I)) {
3033 Pairs.
back().emplace_back(
I, 0);
3035 assert(UsedSubVector.test(2 *
I + 1) &&
3036 "Expected to be used one of the subvectors.");
3037 Pairs.
back().emplace_back(
I, 1);
3040 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3042 for (
int &Idx : Mask) {
3045 unsigned SrcRegIdx = Idx / NewElts;
3047 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3048 return Idxs.front().first == SrcRegIdx ||
3049 Idxs.back().first == SrcRegIdx;
3051 if (It == Pairs.
end())
3053 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3054 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3057 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3058 Inputs[Idxs.front().first] = DAG.
getNode(
3060 Inputs[Idxs.front().first].getValueType(),
3061 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3062 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3071 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3075 if (Shuffle->getOperand(0).getValueType() != NewVT)
3078 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3079 !Shuffle->isSplat()) {
3081 }
else if (!Inputs[
I].hasOneUse() &&
3082 !Shuffle->getOperand(1).isUndef()) {
3084 for (
int &Idx : Mask) {
3087 unsigned SrcRegIdx = Idx / NewElts;
3090 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3095 int OpIdx = MaskElt / NewElts;
3109 if (Shuffle->getOperand(
OpIdx).isUndef())
3111 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3112 if (It == std::end(Inputs))
3114 int FoundOp = std::distance(std::begin(Inputs), It);
3117 for (
int &Idx : Mask) {
3120 unsigned SrcRegIdx = Idx / NewElts;
3123 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3128 int MaskIdx = MaskElt / NewElts;
3129 if (
OpIdx == MaskIdx)
3130 Idx = MaskElt % NewElts + FoundOp * NewElts;
3141 for (
int &Idx : Mask) {
3144 unsigned SrcRegIdx = Idx / NewElts;
3147 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3148 int OpIdx = MaskElt / NewElts;
3151 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3157 TryPeekThroughShufflesInputs(OrigMask);
3159 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3160 NewElts](SmallVectorImpl<int> &
Mask) {
3161 SetVector<SDValue> UniqueInputs;
3162 SetVector<SDValue> UniqueConstantInputs;
3163 for (
const auto &
I : Inputs) {
3165 UniqueConstantInputs.
insert(
I);
3166 else if (!
I.isUndef())
3171 if (UniqueInputs.
size() != std::size(Inputs)) {
3172 auto &&UniqueVec = UniqueInputs.
takeVector();
3173 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3174 unsigned ConstNum = UniqueConstantVec.size();
3175 for (
int &Idx : Mask) {
3178 unsigned SrcRegIdx = Idx / NewElts;
3179 if (Inputs[SrcRegIdx].
isUndef()) {
3183 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3184 if (It != UniqueConstantVec.end()) {
3185 Idx = (Idx % NewElts) +
3186 NewElts * std::distance(UniqueConstantVec.begin(), It);
3187 assert(Idx >= 0 &&
"Expected defined mask idx.");
3190 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3191 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3192 Idx = (Idx % NewElts) +
3193 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3194 assert(Idx >= 0 &&
"Expected defined mask idx.");
3196 copy(UniqueConstantVec, std::begin(Inputs));
3197 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3200 MakeUniqueInputs(OrigMask);
3202 copy(Inputs, std::begin(OrigInputs));
3208 unsigned FirstMaskIdx =
High * NewElts;
3211 assert(!Output &&
"Expected default initialized initial value.");
3212 TryPeekThroughShufflesInputs(Mask);
3213 MakeUniqueInputs(Mask);
3215 copy(Inputs, std::begin(TmpInputs));
3218 bool SecondIteration =
false;
3219 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3224 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3225 SecondIteration =
true;
3226 return SecondIteration;
3229 Mask, std::size(Inputs), std::size(Inputs),
3231 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3232 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3233 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3235 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3237 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3238 DAG.getUNDEF(NewVT), Mask);
3239 Inputs[Idx] = Output;
3241 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3242 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3243 unsigned Idx2,
bool ) {
3244 if (AccumulateResults(Idx1)) {
3247 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3249 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3250 Inputs[Idx2], Mask);
3254 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3256 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3257 TmpInputs[Idx2], Mask);
3259 Inputs[Idx1] = Output;
3261 copy(OrigInputs, std::begin(Inputs));
3266 EVT OVT =
N->getValueType(0);
3273 const Align Alignment =
3274 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3276 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3277 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3282 ReplaceValueWith(
SDValue(
N, 1), Chain);
3287 EVT DstVTLo, DstVTHi;
3288 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3292 EVT SrcVT =
N->getOperand(0).getValueType();
3294 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3296 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3298 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3299 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3305 GetSplitVector(
N->getOperand(0), InLo, InHi);
3316 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3317 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3322 EVT VT =
N->getValueType(0);
3329 Align Alignment = DAG.getReducedAlign(VT,
false);
3334 EVT PtrVT =
StackPtr.getValueType();
3335 auto &MF = DAG.getMachineFunction();
3339 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3342 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3348 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3349 DAG.getConstant(1,
DL, PtrVT));
3351 DAG.getConstant(EltWidth,
DL, PtrVT));
3353 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3355 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3356 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3357 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3360 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3362 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3367 EVT VT =
N->getValueType(0);
3379 EVL1 = ZExtPromotedInteger(EVL1);
3381 Align Alignment = DAG.getReducedAlign(VT,
false);
3386 EVT PtrVT =
StackPtr.getValueType();
3387 auto &MF = DAG.getMachineFunction();
3391 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3394 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3398 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3400 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3401 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3402 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3406 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3411 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3412 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3414 uint64_t TrailingElts = -
Imm;
3416 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3425 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3429 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3431 DAG.getVectorIdxConstant(0,
DL));
3437void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3445 GetSplitVector(Acc, AccLo, AccHi);
3446 unsigned Opcode =
N->getOpcode();
3458 GetSplitVector(Input1, Input1Lo, Input1Hi);
3459 GetSplitVector(Input2, Input2Lo, Input2Hi);
3462 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3463 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3466void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3474 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3482void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3483 unsigned Factor =
N->getNumOperands();
3486 for (
unsigned i = 0; i != Factor; ++i) {
3488 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3490 Ops[i * 2 + 1] = OpHi;
3501 for (
unsigned i = 0; i != Factor; ++i)
3505void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3506 unsigned Factor =
N->getNumOperands();
3509 for (
unsigned i = 0; i != Factor; ++i) {
3511 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3513 Ops[i + Factor] = OpHi;
3524 for (
unsigned i = 0; i != Factor; ++i) {
3525 unsigned IdxLo = 2 * i;
3526 unsigned IdxHi = 2 * i + 1;
3527 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3528 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3540bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3545 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3548 switch (
N->getOpcode()) {
3551 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3561 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3567 case ISD::VP_TRUNCATE:
3569 Res = SplitVecOp_TruncateHelper(
N);
3572 case ISD::VP_FP_ROUND:
3581 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3588 case ISD::VP_SCATTER:
3592 case ISD::VP_GATHER:
3596 Res = SplitVecOp_VSELECT(
N, OpNo);
3599 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3605 case ISD::VP_SINT_TO_FP:
3606 case ISD::VP_UINT_TO_FP:
3607 if (
N->getValueType(0).bitsLT(
3608 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3609 Res = SplitVecOp_TruncateHelper(
N);
3611 Res = SplitVecOp_UnaryOp(
N);
3615 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3619 case ISD::VP_FP_TO_SINT:
3620 case ISD::VP_FP_TO_UINT:
3633 Res = SplitVecOp_UnaryOp(
N);
3636 Res = SplitVecOp_FPOpDifferentTypes(
N);
3641 Res = SplitVecOp_CMP(
N);
3645 Res = SplitVecOp_FAKE_USE(
N);
3650 Res = SplitVecOp_ExtVecInRegOp(
N);
3668 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3672 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3674 case ISD::VP_REDUCE_FADD:
3675 case ISD::VP_REDUCE_SEQ_FADD:
3676 case ISD::VP_REDUCE_FMUL:
3677 case ISD::VP_REDUCE_SEQ_FMUL:
3678 case ISD::VP_REDUCE_ADD:
3679 case ISD::VP_REDUCE_MUL:
3680 case ISD::VP_REDUCE_AND:
3681 case ISD::VP_REDUCE_OR:
3682 case ISD::VP_REDUCE_XOR:
3683 case ISD::VP_REDUCE_SMAX:
3684 case ISD::VP_REDUCE_SMIN:
3685 case ISD::VP_REDUCE_UMAX:
3686 case ISD::VP_REDUCE_UMIN:
3687 case ISD::VP_REDUCE_FMAX:
3688 case ISD::VP_REDUCE_FMIN:
3689 case ISD::VP_REDUCE_FMAXIMUM:
3690 case ISD::VP_REDUCE_FMINIMUM:
3691 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3693 case ISD::VP_CTTZ_ELTS:
3694 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3695 Res = SplitVecOp_VP_CttzElements(
N);
3698 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3704 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3709 if (!Res.
getNode())
return false;
3716 if (
N->isStrictFPOpcode())
3718 "Invalid operand expansion");
3721 "Invalid operand expansion");
3723 ReplaceValueWith(
SDValue(
N, 0), Res);
3727SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3730 assert(OpNo == 0 &&
"Illegal operand must be mask");
3737 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3740 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3741 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3742 "Lo and Hi have differing types");
3745 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3746 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3748 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3749 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3750 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3751 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3761SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3764 assert(OpNo == 1 &&
"Illegal operand must be mask");
3769 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3771 EVT VecVT =
N->getValueType(0);
3775SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3776 EVT ResVT =
N->getValueType(0);
3782 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3783 GetSplitVector(VecOp,
Lo,
Hi);
3785 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3790 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3791 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3795 EVT ResVT =
N->getValueType(0);
3801 SDNodeFlags
Flags =
N->getFlags();
3804 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3805 GetSplitVector(VecOp,
Lo,
Hi);
3807 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3813 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3816SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3817 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3818 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3820 unsigned Opc =
N->getOpcode();
3821 EVT ResVT =
N->getValueType(0);
3827 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3828 GetSplitVector(VecOp,
Lo,
Hi);
3831 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3834 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3836 const SDNodeFlags
Flags =
N->getFlags();
3840 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3845 EVT ResVT =
N->getValueType(0);
3848 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3849 EVT InVT =
Lo.getValueType();
3854 if (
N->isStrictFPOpcode()) {
3855 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3856 {N->getOperand(0), Lo});
3857 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3858 {N->getOperand(0), Hi});
3867 ReplaceValueWith(
SDValue(
N, 1), Ch);
3868 }
else if (
N->getNumOperands() == 3) {
3869 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3870 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3871 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3872 std::tie(EVLLo, EVLHi) =
3873 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3874 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3875 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3877 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3878 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3887 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3897 EVT ResVT =
N->getValueType(0);
3899 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3903 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3909 Lo = BitConvertToInteger(
Lo);
3910 Hi = BitConvertToInteger(
Hi);
3912 if (DAG.getDataLayout().isBigEndian())
3920 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3922 EVT ResVT =
N->getValueType(0);
3930 GetSplitVector(SubVec,
Lo,
Hi);
3939 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3941 return SecondInsertion;
3944SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3951 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3953 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
3955 ElementCount IdxVal =
3959 EVT SrcVT =
N->getOperand(0).getValueType();
3978 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
3979 LoEltsMin - IdxValMin);
3980 DAG.ExtractVectorElements(
Hi, Elts, 0,
3983 return DAG.getBuildVector(SubVT, dl, Elts);
3987 ElementCount ExtractIdx = IdxVal - LoElts;
3989 return DAG.getExtractSubvector(dl, SubVT,
Hi,
3992 EVT HiVT =
Hi.getValueType();
3994 "Only fixed-vector extracts are supported in this case");
4004 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4005 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4011 "Extracting scalable subvector from fixed-width unsupported");
4019 "subvector from a scalable predicate vector");
4025 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4027 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4028 auto &MF = DAG.getMachineFunction();
4032 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4036 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4039 SubVT, dl, Store, StackPtr,
4043SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4049 uint64_t IdxVal =
Index->getZExtValue();
4052 GetSplitVector(Vec,
Lo,
Hi);
4054 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4056 if (IdxVal < LoElts)
4057 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4060 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4065 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4077 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4083 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4085 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4086 auto &MF = DAG.getMachineFunction();
4089 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4093 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4097 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4099 return DAG.getExtLoad(
4110 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4118 SplitVecRes_Gather(
N,
Lo,
Hi);
4121 ReplaceValueWith(
SDValue(
N, 0), Res);
4126 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4130 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4132 SDValue EVL =
N->getVectorLength();
4134 Align Alignment =
N->getBaseAlign();
4140 GetSplitVector(
Data, DataLo, DataHi);
4142 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4147 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4150 GetSplitVector(Mask, MaskLo, MaskHi);
4152 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4155 EVT MemoryVT =
N->getMemoryVT();
4156 EVT LoMemVT, HiMemVT;
4157 bool HiIsEmpty =
false;
4158 std::tie(LoMemVT, HiMemVT) =
4159 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4163 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4166 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4171 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4172 N->getAddressingMode(),
N->isTruncatingStore(),
4173 N->isCompressingStore());
4179 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4180 N->isCompressingStore());
4182 MachinePointerInfo MPI;
4186 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4191 MMO = DAG.getMachineFunction().getMachineMemOperand(
4193 Alignment,
N->getAAInfo(),
N->getRanges());
4195 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4196 N->getAddressingMode(),
N->isTruncatingStore(),
4197 N->isCompressingStore());
4206 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4207 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4214 GetSplitVector(
Data, LoData, HiData);
4216 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4218 EVT LoMemVT, HiMemVT;
4219 bool HiIsEmpty =
false;
4220 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4226 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4227 else if (getTypeAction(
Mask.getValueType()) ==
4229 GetSplitVector(Mask, LoMask, HiMask);
4231 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4234 std::tie(LoEVL, HiEVL) =
4235 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4239 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4240 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4241 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4252 EVT PtrVT =
N->getBasePtr().getValueType();
4255 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4258 Align Alignment =
N->getBaseAlign();
4263 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4264 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4266 Alignment,
N->getAAInfo(),
N->getRanges());
4269 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4270 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4271 N->isCompressingStore());
4280 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4284 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4287 Align Alignment =
N->getBaseAlign();
4293 GetSplitVector(
Data, DataLo, DataHi);
4295 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4300 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4303 GetSplitVector(Mask, MaskLo, MaskHi);
4305 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4308 EVT MemoryVT =
N->getMemoryVT();
4309 EVT LoMemVT, HiMemVT;
4310 bool HiIsEmpty =
false;
4311 std::tie(LoMemVT, HiMemVT) =
4312 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4315 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4320 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4321 N->getAddressingMode(),
N->isTruncatingStore(),
4322 N->isCompressingStore());
4330 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4331 N->isCompressingStore());
4333 MachinePointerInfo MPI;
4337 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4342 MMO = DAG.getMachineFunction().getMachineMemOperand(
4344 Alignment,
N->getAAInfo(),
N->getRanges());
4346 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4347 N->getAddressingMode(),
N->isTruncatingStore(),
4348 N->isCompressingStore());
4361 EVT MemoryVT =
N->getMemoryVT();
4362 Align Alignment =
N->getBaseAlign();
4369 }
Ops = [&]() -> Operands {
4371 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4375 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4380 EVT LoMemVT, HiMemVT;
4381 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4386 GetSplitVector(
Ops.Data, DataLo, DataHi);
4388 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4393 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4395 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4399 if (getTypeAction(
Ops.Index.getValueType()) ==
4401 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4403 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4407 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4409 Alignment,
N->getAAInfo(),
N->getRanges());
4412 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4414 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4415 MSC->getIndexType(), MSC->isTruncatingStore());
4420 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4421 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4422 MMO, MSC->getIndexType(),
4423 MSC->isTruncatingStore());
4427 std::tie(EVLLo, EVLHi) =
4428 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4430 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4431 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4432 VPSC->getIndexType());
4437 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4438 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4439 VPSC->getIndexType());
4443 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4444 assert(OpNo == 1 &&
"Can only split the stored value");
4447 bool isTruncating =
N->isTruncatingStore();
4450 EVT MemoryVT =
N->getMemoryVT();
4451 Align Alignment =
N->getBaseAlign();
4453 AAMDNodes AAInfo =
N->getAAInfo();
4455 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4457 EVT LoMemVT, HiMemVT;
4458 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4462 return TLI.scalarizeVectorStore(
N, DAG);
4465 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4466 Alignment, MMOFlags, AAInfo);
4468 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4471 MachinePointerInfo MPI;
4472 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4475 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4476 HiMemVT, Alignment, MMOFlags, AAInfo);
4478 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4494 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4500 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4521 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4522 SDValue InVec =
N->getOperand(OpNo);
4524 EVT OutVT =
N->getValueType(0);
4532 EVT LoOutVT, HiOutVT;
4533 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4534 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4539 if (isTypeLegal(LoOutVT) ||
4540 InElementSize <= OutElementSize * 2)
4541 return SplitVecOp_UnaryOp(
N);
4550 return SplitVecOp_UnaryOp(
N);
4554 GetSplitVector(InVec, InLoVec, InHiVec);
4560 EVT HalfElementVT = IsFloat ?
4562 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4569 if (
N->isStrictFPOpcode()) {
4570 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4571 {N->getOperand(0), InLoVec});
4572 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4573 {N->getOperand(0), InHiVec});
4579 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4580 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4584 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4592 if (
N->isStrictFPOpcode()) {
4596 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4604 DAG.getTargetConstant(
4605 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4612 assert(
N->getValueType(0).isVector() &&
4613 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4614 "Operand types must be vectors");
4616 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4618 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4619 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4621 EVT VT =
N->getValueType(0);
4627 }
else if (isStrict) {
4628 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4629 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4630 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4631 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4634 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4636 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4637 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4638 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4639 std::tie(EVLLo, EVLHi) =
4640 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4641 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4642 N->getOperand(2), MaskLo, EVLLo);
4643 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4644 N->getOperand(2), MaskHi, EVLHi);
4653 EVT ResVT =
N->getValueType(0);
4656 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4657 EVT InVT =
Lo.getValueType();
4662 if (
N->isStrictFPOpcode()) {
4663 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4664 {N->getOperand(0), Lo, N->getOperand(2)});
4665 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4666 {N->getOperand(0), Hi, N->getOperand(2)});
4670 Lo.getValue(1),
Hi.getValue(1));
4671 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4672 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4673 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4674 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4675 std::tie(EVLLo, EVLHi) =
4676 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4677 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4678 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4692SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4695 EVT LHSLoVT, LHSHiVT;
4696 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4698 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4699 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4702 std::tie(LHSLo, LHSHi) =
4703 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4706 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4709 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4715 LLVMContext &Ctxt = *DAG.getContext();
4718 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4719 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4720 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4722 EVT ResVT =
N->getValueType(0);
4727 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4728 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4734 EVT ResVT =
N->getValueType(0);
4737 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4738 EVT InVT =
Lo.getValueType();
4744 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4745 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4752 EVT ResVT =
N->getValueType(0);
4756 GetSplitVector(VecOp,
Lo,
Hi);
4758 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4759 auto [EVLLo, EVLHi] =
4761 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4767 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4769 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4770 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4773SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4784 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4785 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4786 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4787 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4788 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4789 OpsLo, MMO, IndexType);
4790 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4791 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4795SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4798 "Accumulator should already be a legal type, and shouldn't need "
4799 "further splitting");
4802 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4803 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4804 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4805 unsigned Opcode =
N->getOpcode();
4808 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4809 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4816void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4817 unsigned WidenResNo) {
4818 unsigned NumResults =
N->getNumValues();
4819 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4820 if (ResNo == WidenResNo)
4822 EVT ResVT =
N->getValueType(ResNo);
4828 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4829 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4834void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4835 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4838 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4843 auto unrollExpandedOp = [&]() {
4848 EVT VT =
N->getValueType(0);
4849 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4850 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4851 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
4853 if (
N->getNumValues() > 1)
4854 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4860 switch (
N->getOpcode()) {
4863 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4871 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4875 Res = WidenVecRes_ADDRSPACECAST(
N);
4882 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4886 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4890 Res = WidenVecRes_ScalarOp(
N);
4895 case ISD::VP_SELECT:
4897 Res = WidenVecRes_Select(
N);
4901 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4903 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4910 case ISD::VP_LOAD_FF:
4913 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4917 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4925 case ISD::VP_GATHER:
4929 Res = WidenVecRes_VECTOR_REVERSE(
N);
4932 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4942 case ISD::OR:
case ISD::VP_OR:
4950 case ISD::VP_FMINNUM:
4953 case ISD::VP_FMAXNUM:
4955 case ISD::VP_FMINIMUM:
4957 case ISD::VP_FMAXIMUM:
4990 case ISD::VP_FCOPYSIGN:
4991 Res = WidenVecRes_Binary(
N);
4996 Res = WidenVecRes_CMP(
N);
5002 if (unrollExpandedOp())
5017 Res = WidenVecRes_BinaryCanTrap(
N);
5026 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5029#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5030 case ISD::STRICT_##DAGN:
5031#include "llvm/IR/ConstrainedOps.def"
5032 Res = WidenVecRes_StrictFP(
N);
5041 Res = WidenVecRes_OverflowOp(
N, ResNo);
5045 Res = WidenVecRes_FCOPYSIGN(
N);
5050 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5055 if (!unrollExpandedOp())
5056 Res = WidenVecRes_ExpOp(
N);
5062 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5067 case ISD::VP_FP_EXTEND:
5069 case ISD::VP_FP_ROUND:
5071 case ISD::VP_FP_TO_SINT:
5073 case ISD::VP_FP_TO_UINT:
5075 case ISD::VP_SIGN_EXTEND:
5077 case ISD::VP_SINT_TO_FP:
5078 case ISD::VP_TRUNCATE:
5081 case ISD::VP_UINT_TO_FP:
5083 case ISD::VP_ZERO_EXTEND:
5084 Res = WidenVecRes_Convert(
N);
5089 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5095 case ISD::VP_LLRINT:
5098 Res = WidenVecRes_XROUND(
N);
5124 if (unrollExpandedOp())
5134 case ISD::VP_BITREVERSE:
5140 case ISD::VP_CTLZ_ZERO_UNDEF:
5146 case ISD::VP_CTTZ_ZERO_UNDEF:
5151 case ISD::VP_FFLOOR:
5153 case ISD::VP_FNEARBYINT:
5154 case ISD::VP_FROUND:
5155 case ISD::VP_FROUNDEVEN:
5156 case ISD::VP_FROUNDTOZERO:
5161 Res = WidenVecRes_Unary(
N);
5168 Res = WidenVecRes_Ternary(
N);
5174 if (!unrollExpandedOp())
5175 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5182 SetWidenedVector(
SDValue(
N, ResNo), Res);
5188 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5189 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5190 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5191 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5192 if (
N->getNumOperands() == 3)
5193 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5195 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5196 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5200 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5201 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5207 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5208 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5209 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5210 if (
N->getNumOperands() == 2)
5211 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5214 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5215 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5219 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5220 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5224 LLVMContext &Ctxt = *DAG.getContext();
5229 EVT OpVT =
LHS.getValueType();
5231 LHS = GetWidenedVector(
LHS);
5232 RHS = GetWidenedVector(
RHS);
5233 OpVT =
LHS.getValueType();
5236 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5239 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5245SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5248 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5249 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5250 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5252 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5261 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5264 if (ConcatEnd == 1) {
5265 VT = ConcatOps[0].getValueType();
5267 return ConcatOps[0];
5270 SDLoc dl(ConcatOps[0]);
5277 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5278 int Idx = ConcatEnd - 1;
5279 VT = ConcatOps[Idx--].getValueType();
5280 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5293 unsigned NumToInsert = ConcatEnd - Idx - 1;
5294 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5296 ConcatOps[Idx+1] = VecOp;
5297 ConcatEnd = Idx + 2;
5303 unsigned RealVals = ConcatEnd - Idx - 1;
5304 unsigned SubConcatEnd = 0;
5305 unsigned SubConcatIdx = Idx + 1;
5306 while (SubConcatEnd < RealVals)
5307 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5308 while (SubConcatEnd < OpsToConcat)
5309 SubConcatOps[SubConcatEnd++] = undefVec;
5311 NextVT, SubConcatOps);
5312 ConcatEnd = SubConcatIdx + 1;
5317 if (ConcatEnd == 1) {
5318 VT = ConcatOps[0].getValueType();
5320 return ConcatOps[0];
5325 if (
NumOps != ConcatEnd ) {
5327 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5328 ConcatOps[j] = UndefVal;
5336 unsigned Opcode =
N->getOpcode();
5338 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5342 const SDNodeFlags
Flags =
N->getFlags();
5343 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5344 NumElts = NumElts / 2;
5348 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5350 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5351 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5352 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5360 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5363 TLI.isTypeLegal(WideMaskVT)) {
5364 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5365 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5366 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5368 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5369 N->getValueType(0).getVectorElementCount());
5370 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5384 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5385 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5386 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5389 unsigned ConcatEnd = 0;
5397 while (CurNumElts != 0) {
5398 while (CurNumElts >= NumElts) {
5399 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5400 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5401 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5403 CurNumElts -= NumElts;
5406 NumElts = NumElts / 2;
5408 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5411 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5412 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5413 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5414 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5425 switch (
N->getOpcode()) {
5428 return WidenVecRes_STRICT_FSETCC(
N);
5435 return WidenVecRes_Convert_StrictFP(
N);
5442 unsigned Opcode =
N->getOpcode();
5444 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5448 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5449 NumElts = NumElts / 2;
5460 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5464 unsigned ConcatEnd = 0;
5471 for (
unsigned i = 1; i < NumOpers; ++i) {
5477 Oper = GetWidenedVector(Oper);
5483 DAG.getUNDEF(WideOpVT), Oper,
5484 DAG.getVectorIdxConstant(0, dl));
5496 while (CurNumElts != 0) {
5497 while (CurNumElts >= NumElts) {
5500 for (
unsigned i = 0; i < NumOpers; ++i) {
5503 EVT OpVT =
Op.getValueType();
5508 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5514 EVT OperVT[] = {VT, MVT::Other};
5516 ConcatOps[ConcatEnd++] = Oper;
5519 CurNumElts -= NumElts;
5522 NumElts = NumElts / 2;
5524 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5527 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5530 for (
unsigned i = 0; i < NumOpers; ++i) {
5533 EVT OpVT =
Op.getValueType();
5541 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5543 ConcatOps[ConcatEnd++] = Oper;
5552 if (Chains.
size() == 1)
5553 NewChain = Chains[0];
5556 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5561SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5563 EVT ResVT =
N->getValueType(0);
5564 EVT OvVT =
N->getValueType(1);
5565 EVT WideResVT, WideOvVT;
5570 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5575 WideLHS = GetWidenedVector(
N->getOperand(0));
5576 WideRHS = GetWidenedVector(
N->getOperand(1));
5578 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5586 N->getOperand(0), Zero);
5589 N->getOperand(1), Zero);
5592 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5593 SDNode *WideNode = DAG.getNode(
5594 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5597 unsigned OtherNo = 1 - ResNo;
5598 EVT OtherVT =
N->getValueType(OtherNo);
5605 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5608 return SDValue(WideNode, ResNo);
5612 LLVMContext &Ctx = *DAG.getContext();
5616 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5621 unsigned Opcode =
N->getOpcode();
5622 const SDNodeFlags
Flags =
N->getFlags();
5628 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5630 InOp = ZExtPromotedInteger(InOp);
5641 InOp = GetWidenedVector(
N->getOperand(0));
5644 if (InVTEC == WidenEC) {
5645 if (
N->getNumOperands() == 1)
5646 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5647 if (
N->getNumOperands() == 3) {
5648 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5651 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5653 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5679 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5683 if (TLI.isTypeLegal(InWidenVT)) {
5691 unsigned NumConcat =
5696 if (
N->getNumOperands() == 1)
5697 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5698 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5702 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5704 if (
N->getNumOperands() == 1)
5705 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5706 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5715 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5716 for (
unsigned i=0; i < MinElts; ++i) {
5717 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5718 if (
N->getNumOperands() == 1)
5721 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5724 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5729 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5733 EVT SrcVT = Src.getValueType();
5737 Src = GetWidenedVector(Src);
5738 SrcVT = Src.getValueType();
5745 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5750 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5754 EVT SrcVT = Src.getValueType();
5758 Src = GetWidenedVector(Src);
5759 SrcVT = Src.getValueType();
5766 if (
N->getNumOperands() == 1)
5767 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5769 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5770 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5774 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5777SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5782 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5788 unsigned Opcode =
N->getOpcode();
5794 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5799 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5800 for (
unsigned i=0; i < MinElts; ++i) {
5801 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5802 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5806 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5808 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5811SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5812 unsigned Opcode =
N->getOpcode();
5816 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5825 InOp = GetWidenedVector(InOp);
5832 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5839 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5840 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5857 while (
Ops.size() != WidenNumElts)
5858 Ops.push_back(DAG.getPOISON(WidenSVT));
5860 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5866 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5867 return WidenVecRes_BinaryCanTrap(
N);
5870 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5877SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5879 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5882 SDValue Arg = GetWidenedVector(FpValue);
5883 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5888 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5889 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5891 EVT ExpVT =
RHS.getValueType();
5896 ExpOp = ModifyToType(
RHS, WideExpVT);
5899 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5904 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5905 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5906 if (
N->getNumOperands() == 1)
5907 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5909 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5910 N->getOperand(1),
N->getFlags());
5912 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5913 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5917 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5918 {InOp,
Mask,
N->getOperand(2)});
5922 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5925 .getVectorElementType(),
5927 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5928 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5929 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5932SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5934 EVT VT0 =
N->getValueType(0);
5935 EVT VT1 =
N->getValueType(1);
5939 "expected both results to be vectors of matching element count");
5941 LLVMContext &Ctx = *DAG.getContext();
5942 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5944 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5951 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5954 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5955 return SDValue(WidenNode, ResNo);
5958SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5959 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5960 return GetWidenedVector(WidenVec);
5964 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5965 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5968 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5969 AddrSpaceCastN->getSrcAddressSpace(),
5970 AddrSpaceCastN->getDestAddressSpace());
5976 EVT VT =
N->getValueType(0);
5977 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5980 switch (getTypeAction(InVT)) {
5994 SDValue NInOp = GetPromotedInteger(InOp);
5996 if (WidenVT.
bitsEq(NInVT)) {
5999 if (DAG.getDataLayout().isBigEndian()) {
6002 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6021 InOp = GetWidenedVector(InOp);
6023 if (WidenVT.
bitsEq(InVT))
6033 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6038 unsigned NewNumParts = WidenSize / InSize;
6051 EVT OrigInVT =
N->getOperand(0).getValueType();
6056 if (TLI.isTypeLegal(NewInVT)) {
6064 if (WidenSize % InSize == 0) {
6071 DAG.ExtractVectorElements(InOp,
Ops);
6072 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6084 return CreateStackStoreLoad(InOp, WidenVT);
6087SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6089 N->getOpcode(), SDLoc(
N),
6090 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6091 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6097 EVT VT =
N->getValueType(0);
6101 EVT EltVT =
N->getOperand(0).getValueType();
6104 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6108 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6109 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6111 return DAG.getBuildVector(WidenVT, dl, NewOps);
6115 EVT InVT =
N->getOperand(0).getValueType();
6116 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6118 unsigned NumOperands =
N->getNumOperands();
6120 bool InputWidened =
false;
6124 if (WidenNumElts % NumInElts == 0) {
6126 unsigned NumConcat = WidenNumElts / NumInElts;
6127 SDValue UndefVal = DAG.getPOISON(InVT);
6129 for (
unsigned i=0; i < NumOperands; ++i)
6130 Ops[i] =
N->getOperand(i);
6131 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6136 InputWidened =
true;
6137 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6140 for (i=1; i < NumOperands; ++i)
6141 if (!
N->getOperand(i).isUndef())
6144 if (i == NumOperands)
6147 return GetWidenedVector(
N->getOperand(0));
6149 if (NumOperands == 2) {
6151 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6156 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6157 for (
unsigned i = 0; i < NumInElts; ++i) {
6159 MaskOps[i + NumInElts] = i + WidenNumElts;
6161 return DAG.getVectorShuffle(WidenVT, dl,
6162 GetWidenedVector(
N->getOperand(0)),
6163 GetWidenedVector(
N->getOperand(1)),
6170 "Cannot use build vectors to widen CONCAT_VECTOR result");
6178 for (
unsigned i=0; i < NumOperands; ++i) {
6181 InOp = GetWidenedVector(InOp);
6182 for (
unsigned j = 0;
j < NumInElts; ++
j)
6183 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6185 SDValue UndefVal = DAG.getPOISON(EltVT);
6186 for (; Idx < WidenNumElts; ++Idx)
6187 Ops[Idx] = UndefVal;
6188 return DAG.getBuildVector(WidenVT, dl,
Ops);
6191SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6192 EVT VT =
N->getValueType(0);
6193 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6194 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6201SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6202 EVT VT =
N->getValueType(0);
6204 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6209 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6211 InOp = GetWidenedVector(InOp);
6217 if (IdxVal == 0 && InVT == WidenVT)
6224 assert(IdxVal % VTNumElts == 0 &&
6225 "Expected Idx to be a multiple of subvector minimum vector length");
6226 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6239 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6240 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6241 "down type's element count");
6248 for (;
I < VTNumElts / GCD; ++
I)
6250 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6251 for (;
I < WidenNumElts / GCD; ++
I)
6259 Align Alignment = DAG.getReducedAlign(InVT,
false);
6261 MachineFunction &MF = DAG.getMachineFunction();
6273 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6280 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6281 return DAG.getMaskedLoad(
6282 WidenVT, dl, Ch, StackPtr, DAG.getUNDEF(
StackPtr.getValueType()), Mask,
6290 for (i = 0; i < VTNumElts; ++i)
6291 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6293 SDValue UndefVal = DAG.getPOISON(EltVT);
6294 for (; i < WidenNumElts; ++i)
6296 return DAG.getBuildVector(WidenVT, dl,
Ops);
6302 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6307SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6308 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6311 N->getOperand(1),
N->getOperand(2));
6324 if (!
LD->getMemoryVT().isByteSized()) {
6326 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6328 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6337 EVT VT =
LD->getValueType(0);
6338 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6339 EVT WideMaskVT = getSetCCResultType(WideVT);
6342 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6343 TLI.isTypeLegal(WideMaskVT)) {
6346 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6350 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6351 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6363 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6365 Result = GenWidenVectorLoads(LdChain, LD);
6372 if (LdChain.
size() == 1)
6373 NewChain = LdChain[0];
6379 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6390 SDValue NewLoad = DAG.getMaskedLoad(
6391 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6392 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6393 LD->getAddressingMode(),
LD->getExtensionType());
6403 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6405 SDValue EVL =
N->getVectorLength();
6412 "Unable to widen binary VP op");
6413 Mask = GetWidenedVector(Mask);
6414 assert(
Mask.getValueType().getVectorElementCount() ==
6415 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6416 .getVectorElementCount() &&
6417 "Unable to widen vector load");
6420 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6421 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6422 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6430 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6432 SDValue EVL =
N->getVectorLength();
6438 "Unable to widen binary VP op");
6439 Mask = GetWidenedVector(Mask);
6440 assert(
Mask.getValueType().getVectorElementCount() ==
6441 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6442 .getVectorElementCount() &&
6443 "Unable to widen vector load");
6445 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6446 Mask, EVL,
N->getMemOperand());
6459 "Unable to widen VP strided load");
6460 Mask = GetWidenedVector(Mask);
6462 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6463 assert(
Mask.getValueType().getVectorElementCount() ==
6465 "Data and mask vectors should have the same number of elements");
6467 SDValue Res = DAG.getStridedLoadVP(
6468 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6469 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6470 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6471 N->isExpandingLoad());
6479SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6484 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6486 Mask.getValueType().getVectorElementType(),
6489 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6490 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6491 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6493 WideMask, WidePassthru);
6497 EVT VT =
N->getValueType(0);
6498 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6500 EVT MaskVT =
Mask.getValueType();
6501 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6510 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6511 TLI.isTypeLegal(WideMaskVT) &&
6517 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6518 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6522 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6523 N->getMemoryVT(),
N->getMemOperand());
6527 if (!
N->getPassThru()->isUndef()) {
6530 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6541 Mask = ModifyToType(Mask, WideMaskVT,
true);
6543 SDValue Res = DAG.getMaskedLoad(
6544 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6545 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6546 ExtType,
N->isExpandingLoad());
6555 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6557 EVT MaskVT =
Mask.getValueType();
6558 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6567 Mask = ModifyToType(Mask, WideMaskVT,
true);
6572 Index.getValueType().getScalarType(),
6574 Index = ModifyToType(Index, WideIndexVT);
6580 N->getMemoryVT().getScalarType(), NumElts);
6581 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6582 WideMemVT, dl,
Ops,
N->getMemOperand(),
6583 N->getIndexType(),
N->getExtensionType());
6592 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6600 N->getMemoryVT().getScalarType(), WideEC);
6601 Mask = GetWidenedMask(Mask, WideEC);
6604 Mask,
N->getVectorLength()};
6605 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6606 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6615 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6616 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6644 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6645 return N->getOperand(OpNo).getValueType();
6653 N =
N.getOperand(0);
6655 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6656 if (!
N->getOperand(i)->isUndef())
6658 N =
N.getOperand(0);
6662 N =
N.getOperand(0);
6664 N =
N.getOperand(0);
6691 { MaskVT, MVT::Other },
Ops);
6692 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6699 LLVMContext &Ctx = *DAG.getContext();
6702 if (MaskScalarBits < ToMaskScalBits) {
6706 }
else if (MaskScalarBits > ToMaskScalBits) {
6712 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6714 "Mask should have the right element size by now.");
6717 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6719 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6722 EVT SubVT =
Mask->getValueType(0);
6728 assert((
Mask->getValueType(0) == ToMaskVT) &&
6729 "A mask of ToMaskVT should have been produced by now.");
6739 LLVMContext &Ctx = *DAG.getContext();
6750 EVT CondVT =
Cond->getValueType(0);
6754 EVT VSelVT =
N->getValueType(0);
6766 EVT FinalVT = VSelVT;
6777 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6778 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6785 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6793 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6796 EVT ToMaskVT = VSelVT;
6803 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6819 if (ScalarBits0 != ScalarBits1) {
6820 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6821 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6833 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6834 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6835 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6838 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6846 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6851 unsigned Opcode =
N->getOpcode();
6853 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6854 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6855 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6857 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6863 Cond1 = GetWidenedVector(Cond1);
6871 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6872 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6877 Cond1 = ModifyToType(Cond1, CondWidenVT);
6880 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6881 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6883 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6884 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6886 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6890 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6891 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6894 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6898 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6899 return DAG.getUNDEF(WidenVT);
6903 EVT VT =
N->getValueType(0);
6906 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6910 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6911 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6914 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6915 for (
unsigned i = 0; i != NumElts; ++i) {
6916 int Idx =
N->getMaskElt(i);
6917 if (Idx < (
int)NumElts)
6920 NewMask[i] = Idx - NumElts + WidenNumElts;
6922 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6926 EVT VT =
N->getValueType(0);
6930 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6931 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6937 unsigned IdxVal = WidenNumElts - VTNumElts;
6950 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6953 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6954 "down type's element count");
6957 for (; i < VTNumElts / GCD; ++i)
6959 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6960 for (; i < WidenNumElts / GCD; ++i)
6968 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6969 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6971 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6975SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6976 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6981 assert(
N->getValueType(0).isVector() &&
6982 N->getOperand(0).getValueType().isVector() &&
6983 "Operands must be vectors");
6984 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6997 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
6998 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7005 InOp1 = GetWidenedVector(InOp1);
7006 InOp2 = GetWidenedVector(InOp2);
7009 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7020 "Input not widened to expected type!");
7022 if (
N->getOpcode() == ISD::VP_SETCC) {
7025 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7026 N->getOperand(2), Mask,
N->getOperand(4));
7028 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7033 assert(
N->getValueType(0).isVector() &&
7034 N->getOperand(1).getValueType().isVector() &&
7035 "Operands must be vectors");
7036 EVT VT =
N->getValueType(0);
7037 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7047 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7052 for (
unsigned i = 0; i != NumElts; ++i) {
7053 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7054 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7056 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7057 {Chain, LHSElem, RHSElem, CC});
7058 Chains[i] = Scalars[i].getValue(1);
7059 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7060 DAG.getBoolConstant(
true, dl, EltVT, VT),
7061 DAG.getBoolConstant(
false, dl, EltVT, VT));
7065 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7067 return DAG.getBuildVector(WidenVT, dl, Scalars);
7073bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7074 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7078 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7081 switch (
N->getOpcode()) {
7084 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7092 Res = WidenVecOp_FAKE_USE(
N);
7098 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7099 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7100 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7101 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7106 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7108 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7109 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7111 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7112 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7122 Res = WidenVecOp_UnrollVectorOp(
N);
7129 Res = WidenVecOp_EXTEND(
N);
7134 Res = WidenVecOp_CMP(
N);
7150 Res = WidenVecOp_Convert(
N);
7155 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7173 Res = WidenVecOp_VECREDUCE(
N);
7177 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7179 case ISD::VP_REDUCE_FADD:
7180 case ISD::VP_REDUCE_SEQ_FADD:
7181 case ISD::VP_REDUCE_FMUL:
7182 case ISD::VP_REDUCE_SEQ_FMUL:
7183 case ISD::VP_REDUCE_ADD:
7184 case ISD::VP_REDUCE_MUL:
7185 case ISD::VP_REDUCE_AND:
7186 case ISD::VP_REDUCE_OR:
7187 case ISD::VP_REDUCE_XOR:
7188 case ISD::VP_REDUCE_SMAX:
7189 case ISD::VP_REDUCE_SMIN:
7190 case ISD::VP_REDUCE_UMAX:
7191 case ISD::VP_REDUCE_UMIN:
7192 case ISD::VP_REDUCE_FMAX:
7193 case ISD::VP_REDUCE_FMIN:
7194 case ISD::VP_REDUCE_FMAXIMUM:
7195 case ISD::VP_REDUCE_FMINIMUM:
7196 Res = WidenVecOp_VP_REDUCE(
N);
7198 case ISD::VP_CTTZ_ELTS:
7199 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7200 Res = WidenVecOp_VP_CttzElements(
N);
7205 if (!Res.
getNode())
return false;
7213 if (
N->isStrictFPOpcode())
7215 "Invalid operand expansion");
7218 "Invalid operand expansion");
7220 ReplaceValueWith(
SDValue(
N, 0), Res);
7226 EVT VT =
N->getValueType(0);
7231 "Unexpected type action");
7232 InOp = GetWidenedVector(InOp);
7235 "Input wasn't widened!");
7243 EVT FixedEltVT = FixedVT.getVectorElementType();
7244 if (TLI.isTypeLegal(FixedVT) &&
7246 FixedEltVT == InEltVT) {
7248 "Not enough elements in the fixed type for the operand!");
7250 "We can't have the same type as we started with!");
7252 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7254 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7263 return WidenVecOp_Convert(
N);
7268 switch (
N->getOpcode()) {
7283 EVT OpVT =
N->getOperand(0).getValueType();
7284 EVT ResVT =
N->getValueType(0);
7291 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7292 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7298 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7299 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7301 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7308 return DAG.UnrollVectorOp(
N);
7313 EVT ResultVT =
N->getValueType(0);
7315 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7318 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7324 {WideArg,
Test},
N->getFlags());
7330 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7332 EVT OpVT =
N->getOperand(0).getValueType();
7335 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7340 EVT VT =
N->getValueType(0);
7346 "Unexpected type action");
7347 InOp = GetWidenedVector(InOp);
7349 unsigned Opcode =
N->getOpcode();
7355 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7357 if (
N->isStrictFPOpcode()) {
7359 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7362 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7363 {
N->getOperand(0), InOp });
7369 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7371 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7373 return DAG.getExtractSubvector(dl, VT, Res, 0);
7381 if (
N->isStrictFPOpcode()) {
7384 for (
unsigned i=0; i < NumElts; ++i) {
7385 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7386 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7390 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7392 for (
unsigned i = 0; i < NumElts; ++i)
7393 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7394 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7397 return DAG.getBuildVector(VT, dl,
Ops);
7401 EVT DstVT =
N->getValueType(0);
7402 SDValue Src = GetWidenedVector(
N->getOperand(0));
7403 EVT SrcVT = Src.getValueType();
7410 if (TLI.isTypeLegal(WideDstVT)) {
7412 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7415 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7419 return DAG.UnrollVectorOp(
N);
7423 EVT VT =
N->getValueType(0);
7424 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7432 if (!VT.
isVector() && VT != MVT::x86mmx &&
7436 if (TLI.isTypeLegal(NewVT)) {
7438 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7450 ElementCount NewNumElts =
7452 .divideCoefficientBy(EltSize);
7454 if (TLI.isTypeLegal(NewVT)) {
7456 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7461 return CreateStackStoreLoad(InOp, VT);
7469 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7470 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7475 EVT VT =
N->getValueType(0);
7477 EVT InVT =
N->getOperand(0).getValueType();
7482 unsigned NumOperands =
N->getNumOperands();
7483 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7485 for (i = 1; i < NumOperands; ++i)
7486 if (!
N->getOperand(i).isUndef())
7489 if (i == NumOperands)
7490 return GetWidenedVector(
N->getOperand(0));
7500 for (
unsigned i=0; i < NumOperands; ++i) {
7504 "Unexpected type action");
7505 InOp = GetWidenedVector(InOp);
7506 for (
unsigned j = 0;
j < NumInElts; ++
j)
7507 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7509 return DAG.getBuildVector(VT, dl,
Ops);
7512SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7513 EVT VT =
N->getValueType(0);
7518 SubVec = GetWidenedVector(SubVec);
7523 bool IndicesValid =
false;
7526 IndicesValid =
true;
7530 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7531 Attribute::VScaleRange);
7536 IndicesValid =
true;
7542 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7548 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7555 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7562 Align Alignment = DAG.getReducedAlign(VT,
false);
7564 MachineFunction &MF = DAG.getMachineFunction();
7577 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7585 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7586 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7591 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7596 unsigned Idx =
N->getConstantOperandVal(2);
7602 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7608SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7609 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7611 N->getValueType(0), InOp,
N->getOperand(1));
7614SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7615 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7617 N->getValueType(0), InOp,
N->getOperand(1));
7620SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7621 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7622 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7630 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7631 return TLI.scalarizeVectorStore(ST, DAG);
7633 if (
ST->isTruncatingStore())
7634 return TLI.scalarizeVectorStore(ST, DAG);
7644 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7645 EVT WideMaskVT = getSetCCResultType(WideVT);
7647 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7648 TLI.isTypeLegal(WideMaskVT)) {
7651 StVal = GetWidenedVector(StVal);
7653 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7655 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7656 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7657 ST->getAddressingMode());
7661 if (GenWidenVectorStores(StChain, ST)) {
7662 if (StChain.
size() == 1)
7671 SDValue WideStVal = GetWidenedVector(StVal);
7675 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7676 ST->getOffset(), Mask,
ST->getMemoryVT(),
7677 ST->getMemOperand(),
ST->getAddressingMode(),
7678 ST->isTruncatingStore());
7684SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7685 assert((OpNo == 1 || OpNo == 3) &&
7686 "Can widen only data or mask operand of vp_store");
7694 StVal = GetWidenedVector(StVal);
7700 "Unable to widen VP store");
7701 Mask = GetWidenedVector(Mask);
7703 Mask = GetWidenedVector(Mask);
7709 "Unable to widen VP store");
7710 StVal = GetWidenedVector(StVal);
7713 assert(
Mask.getValueType().getVectorElementCount() ==
7715 "Mask and data vectors should have the same number of elements");
7716 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7717 ST->getOffset(), Mask,
ST->getVectorLength(),
7718 ST->getMemoryVT(),
ST->getMemOperand(),
7719 ST->getAddressingMode(),
ST->isTruncatingStore(),
7720 ST->isCompressingStore());
7725 assert((OpNo == 1 || OpNo == 4) &&
7726 "Can widen only data or mask operand of vp_strided_store");
7735 "Unable to widen VP strided store");
7739 "Unable to widen VP strided store");
7741 StVal = GetWidenedVector(StVal);
7742 Mask = GetWidenedVector(Mask);
7745 Mask.getValueType().getVectorElementCount() &&
7746 "Data and mask vectors should have the same number of elements");
7748 return DAG.getStridedStoreVP(
7755SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7756 assert((OpNo == 1 || OpNo == 4) &&
7757 "Can widen only data or mask operand of mstore");
7760 EVT MaskVT =
Mask.getValueType();
7765 EVT WideVT, WideMaskVT;
7768 StVal = GetWidenedVector(StVal);
7775 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7782 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7783 TLI.isTypeLegal(WideMaskVT)) {
7784 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7785 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7794 Mask = ModifyToType(Mask, WideMaskVT,
true);
7797 Mask = ModifyToType(Mask, WideMaskVT,
true);
7799 StVal = ModifyToType(StVal, WideVT);
7802 assert(
Mask.getValueType().getVectorElementCount() ==
7804 "Mask and data vectors should have the same number of elements");
7811SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7812 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7814 SDValue DataOp = MG->getPassThru();
7816 SDValue Scale = MG->getScale();
7824 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7825 MG->getMemOperand(), MG->getIndexType(),
7826 MG->getExtensionType());
7832SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7841 DataOp = GetWidenedVector(DataOp);
7845 EVT IndexVT =
Index.getValueType();
7848 Index = ModifyToType(Index, WideIndexVT);
7851 EVT MaskVT =
Mask.getValueType();
7854 Mask = ModifyToType(Mask, WideMaskVT,
true);
7859 }
else if (OpNo == 4) {
7861 Index = GetWidenedVector(Index);
7867 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7872SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7881 DataOp = GetWidenedVector(DataOp);
7882 Index = GetWidenedVector(Index);
7884 Mask = GetWidenedMask(Mask, WideEC);
7887 }
else if (OpNo == 3) {
7889 Index = GetWidenedVector(Index);
7896 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7901 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7902 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7904 EVT VT =
N->getValueType(0);
7919 SVT, InOp0, InOp1,
N->getOperand(2));
7925 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7927 EVT OpVT =
N->getOperand(0).getValueType();
7930 return DAG.getNode(ExtendCode, dl, VT, CC);
7940 EVT VT =
N->getValueType(0);
7942 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7949 for (
unsigned i = 0; i != NumElts; ++i) {
7950 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7951 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7953 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7954 {Chain, LHSElem, RHSElem, CC});
7955 Chains[i] = Scalars[i].getValue(1);
7956 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7957 DAG.getBoolConstant(
true, dl, EltVT, VT),
7958 DAG.getBoolConstant(
false, dl, EltVT, VT));
7962 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7964 return DAG.getBuildVector(VT, dl, Scalars);
7988 SDValue Op = GetWidenedVector(
N->getOperand(0));
7989 EVT VT =
N->getValueType(0);
7990 EVT OrigVT =
N->getOperand(0).getValueType();
7991 EVT WideVT =
Op.getValueType();
7993 SDNodeFlags
Flags =
N->getFlags();
7995 unsigned Opc =
N->getOpcode();
7997 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7998 assert(NeutralElem &&
"Neutral element must exist");
8008 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8015 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8016 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8022 unsigned GCD = std::gcd(OrigElts, WideElts);
8025 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8026 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8027 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8028 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8031 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8032 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8034 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8043 EVT VT =
N->getValueType(0);
8045 EVT WideVT =
Op.getValueType();
8047 SDNodeFlags
Flags =
N->getFlags();
8049 unsigned Opc =
N->getOpcode();
8051 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8061 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8064 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8065 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8071 unsigned GCD = std::gcd(OrigElts, WideElts);
8074 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8075 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8076 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8077 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8080 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8081 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8083 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8087 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8090 SDValue Op = GetWidenedVector(
N->getOperand(1));
8092 Op.getValueType().getVectorElementCount());
8094 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8095 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8103 EVT VT =
N->getValueType(0);
8107 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8108 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8113 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8119 EVT SrcVT =
Source.getValueType();
8123 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8124 {Source, Mask, N->getOperand(2)},
N->getFlags());
8141 unsigned WidenEx = 0) {
8146 unsigned AlignInBits =
Align*8;
8148 EVT RetVT = WidenEltVT;
8153 if (Width == WidenEltWidth)
8164 (WidenWidth % MemVTWidth) == 0 &&
8166 (MemVTWidth <= Width ||
8167 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8168 if (MemVTWidth == WidenWidth)
8187 (WidenWidth % MemVTWidth) == 0 &&
8189 (MemVTWidth <= Width ||
8190 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8199 return std::nullopt;
8210 unsigned Start,
unsigned End) {
8211 SDLoc dl(LdOps[Start]);
8212 EVT LdTy = LdOps[Start].getValueType();
8220 for (
unsigned i = Start + 1; i != End; ++i) {
8221 EVT NewLdTy = LdOps[i].getValueType();
8222 if (NewLdTy != LdTy) {
8241 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8242 EVT LdVT =
LD->getMemoryVT();
8252 AAMDNodes AAInfo =
LD->getAAInfo();
8256 TypeSize WidthDiff = WidenWidth - LdWidth;
8263 std::optional<EVT> FirstVT =
8264 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8271 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8276 std::optional<EVT> NewVT = FirstVT;
8277 TypeSize RemainingWidth = LdWidth;
8278 TypeSize NewVTWidth = FirstVTWidth;
8280 RemainingWidth -= NewVTWidth;
8287 NewVTWidth = NewVT->getSizeInBits();
8293 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8294 LD->getBaseAlign(), MMOFlags, AAInfo);
8298 if (MemVTs.
empty()) {
8300 if (!FirstVT->isVector()) {
8307 if (FirstVT == WidenVT)
8312 unsigned NumConcat =
8315 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8316 ConcatOps[0] = LdOp;
8317 for (
unsigned i = 1; i != NumConcat; ++i)
8318 ConcatOps[i] = UndefVal;
8326 uint64_t ScaledOffset = 0;
8327 MachinePointerInfo MPI =
LD->getPointerInfo();
8333 for (EVT MemVT : MemVTs) {
8334 Align NewAlign = ScaledOffset == 0
8335 ?
LD->getBaseAlign()
8338 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8346 unsigned End = LdOps.
size();
8357 EVT LdTy = LdOps[i].getValueType();
8360 for (--i; i >= 0; --i) {
8361 LdTy = LdOps[i].getValueType();
8368 ConcatOps[--Idx] = LdOps[i];
8369 for (--i; i >= 0; --i) {
8370 EVT NewLdTy = LdOps[i].getValueType();
8371 if (NewLdTy != LdTy) {
8381 for (;
j != End-Idx; ++
j)
8382 WidenOps[j] = ConcatOps[Idx+j];
8384 WidenOps[j] = DAG.getUNDEF(LdTy);
8391 ConcatOps[--Idx] = LdOps[i];
8396 ArrayRef(&ConcatOps[Idx], End - Idx));
8402 SDValue UndefVal = DAG.getUNDEF(LdTy);
8405 for (; i != End-Idx; ++i)
8406 WidenOps[i] = ConcatOps[Idx+i];
8408 WidenOps[i] = UndefVal;
8419 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8420 EVT LdVT =
LD->getMemoryVT();
8429 AAMDNodes AAInfo =
LD->getAAInfo();
8443 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8444 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8450 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8451 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8452 LD->getBaseAlign(), MMOFlags, AAInfo);
8457 SDValue UndefVal = DAG.getUNDEF(EltVT);
8458 for (; i != WidenNumElts; ++i)
8461 return DAG.getBuildVector(WidenVT, dl,
Ops);
8472 AAMDNodes AAInfo =
ST->getAAInfo();
8473 SDValue ValOp = GetWidenedVector(
ST->getValue());
8476 EVT StVT =
ST->getMemoryVT();
8484 "Mismatch between store and value types");
8488 MachinePointerInfo MPI =
ST->getPointerInfo();
8489 uint64_t ScaledOffset = 0;
8498 std::optional<EVT> NewVT =
8503 TypeSize NewVTWidth = NewVT->getSizeInBits();
8506 StWidth -= NewVTWidth;
8507 MemVTs.
back().second++;
8511 for (
const auto &Pair : MemVTs) {
8512 EVT NewVT = Pair.first;
8513 unsigned Count = Pair.second;
8519 Align NewAlign = ScaledOffset == 0
8520 ?
ST->getBaseAlign()
8522 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8523 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8539 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8540 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8541 ST->getBaseAlign(), MMOFlags, AAInfo);
8558 bool FillWithZeroes) {
8563 "input and widen element type must match");
8565 "cannot modify scalable vectors in this way");
8577 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8580 for (
unsigned i = 1; i != NumConcat; ++i)
8587 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8590 "Scalable vectors should have been handled already.");
8598 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8600 for (Idx = 0; Idx < MinNumElts; ++Idx)
8601 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8603 SDValue UndefVal = DAG.getUNDEF(EltVT);
8604 for (; Idx < WidenNumElts; ++Idx)
8605 Ops[Idx] = UndefVal;
8607 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8608 if (!FillWithZeroes)
8612 "We expect to never want to FillWithZeroes for non-integral types.");
8615 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8616 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8618 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8619 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...
@ 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.
@ 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],...
@ 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.
@ VECTOR_SPLICE
VECTOR_SPLICE(VEC1, VEC2, IMM) - Returns a subvector of the same type as VEC1/VEC2 from CONCAT_VECTOR...
@ 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.
EVT changeElementType(EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
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.
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 changeVectorElementType(EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
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.