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);
61 case ISD::BITCAST: R = ScalarizeVecRes_BITCAST(
N);
break;
69 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
72 case ISD::ATOMIC_LOAD:
81 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
83 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
89 R = ScalarizeVecRes_VecInregOp(
N);
114 case ISD::FNEARBYINT:
117 case ISD::ARITH_FENCE:
125 case ISD::FROUNDEVEN:
140 R = ScalarizeVecRes_UnaryOp(
N);
142 case ISD::ADDRSPACECAST:
143 R = ScalarizeVecRes_ADDRSPACECAST(
N);
149 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
163 case ISD::FMINNUM_IEEE:
164 case ISD::FMAXNUM_IEEE:
167 case ISD::FMINIMUMNUM:
168 case ISD::FMAXIMUMNUM:
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) {
414 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
425 Op = GetScalarizedVector(
Op);
426 EVT NewVT =
N->getValueType(0).getVectorElementType();
427 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
431SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
441SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
443 N->getValueType(0).getVectorElementType(),
444 N->getOperand(0),
N->getOperand(1));
450 EVT OpVT =
Op.getValueType();
454 Op = GetScalarizedVector(
Op);
457 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
460 N->getValueType(0).getVectorElementType(),
Op,
464SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
465 SDValue Op = GetScalarizedVector(
N->getOperand(0));
466 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
470SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
475 if (
Op.getValueType() != EltVT)
483 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
484 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
494 assert(
N->isUnindexed() &&
"Indexed vector load?");
498 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
499 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
500 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
501 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
513 EVT OpVT =
Op.getValueType();
523 Op = GetScalarizedVector(
Op);
526 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
528 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
534 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
535 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
536 LHS, DAG.getValueType(ExtVT));
543 EVT OpVT =
Op.getValueType();
548 Op = GetScalarizedVector(
Op);
550 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
553 switch (
N->getOpcode()) {
565SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
568 EVT OpVT =
Op.getValueType();
578 Op = GetScalarizedVector(
Op);
581 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
584 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
585 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
586 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
589SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
601 EVT OpVT =
Cond.getValueType();
610 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
613 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
615 TLI.getBooleanContents(
false,
false);
622 if (TLI.getBooleanContents(
false,
false) !=
623 TLI.getBooleanContents(
false,
true)) {
627 EVT OpVT =
Cond->getOperand(0).getValueType();
629 VecBool = TLI.getBooleanContents(OpVT);
634 EVT CondVT =
Cond.getValueType();
635 if (ScalarBool != VecBool) {
636 switch (ScalarBool) {
644 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
651 Cond, DAG.getValueType(MVT::i1));
657 auto BoolVT = getSetCCResultType(CondVT);
658 if (BoolVT.bitsLT(CondVT))
661 return DAG.getSelect(SDLoc(
N),
663 GetScalarizedVector(
N->getOperand(2)));
667 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
668 return DAG.getSelect(SDLoc(
N),
669 LHS.getValueType(),
N->getOperand(0),
LHS,
670 GetScalarizedVector(
N->getOperand(2)));
674 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
676 N->getOperand(0),
N->getOperand(1),
677 LHS, GetScalarizedVector(
N->getOperand(3)),
682 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
685SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
689 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
691 return GetScalarizedVector(
N->getOperand(
Op));
694SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
696 EVT SrcVT = Src.getValueType();
701 Src = GetScalarizedVector(Src);
705 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
707 EVT DstVT =
N->getValueType(0).getVectorElementType();
708 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
712 assert(
N->getValueType(0).isVector() &&
713 N->getOperand(0).getValueType().isVector() &&
714 "Operand types must be vectors");
717 EVT OpVT =
LHS.getValueType();
718 EVT NVT =
N->getValueType(0).getVectorElementType();
723 LHS = GetScalarizedVector(
LHS);
724 RHS = GetScalarizedVector(
RHS);
727 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
728 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
738 return DAG.getNode(ExtendCode,
DL, NVT, Res);
749 Arg = GetScalarizedVector(Arg);
752 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
761 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
768bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
773 switch (
N->getOpcode()) {
776 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
783 Res = ScalarizeVecOp_BITCAST(
N);
786 Res = ScalarizeVecOp_FAKE_USE(
N);
800 Res = ScalarizeVecOp_UnaryOp(
N);
804 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
810 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
813 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
816 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
819 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
822 Res = ScalarizeVecOp_VSELECT(
N);
825 Res = ScalarizeVecOp_VSETCC(
N);
829 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
835 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
838 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
841 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
844 Res = ScalarizeVecOp_FP_EXTEND(
N);
846 case ISD::VECREDUCE_FADD:
847 case ISD::VECREDUCE_FMUL:
848 case ISD::VECREDUCE_ADD:
849 case ISD::VECREDUCE_MUL:
850 case ISD::VECREDUCE_AND:
851 case ISD::VECREDUCE_OR:
852 case ISD::VECREDUCE_XOR:
853 case ISD::VECREDUCE_SMAX:
854 case ISD::VECREDUCE_SMIN:
855 case ISD::VECREDUCE_UMAX:
856 case ISD::VECREDUCE_UMIN:
857 case ISD::VECREDUCE_FMAX:
858 case ISD::VECREDUCE_FMIN:
859 case ISD::VECREDUCE_FMAXIMUM:
860 case ISD::VECREDUCE_FMINIMUM:
861 Res = ScalarizeVecOp_VECREDUCE(
N);
863 case ISD::VECREDUCE_SEQ_FADD:
864 case ISD::VECREDUCE_SEQ_FMUL:
865 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
869 Res = ScalarizeVecOp_CMP(
N);
874 if (!Res.
getNode())
return false;
882 "Invalid operand expansion");
884 ReplaceValueWith(
SDValue(
N, 0), Res);
891 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
892 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
893 N->getValueType(0), Elt);
898 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
899 "Fake Use: Unexpected vector type!");
900 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
901 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
907 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
908 "Unexpected vector type!");
909 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
911 N->getValueType(0).getScalarType(), Elt);
919SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
920 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
921 "Unexpected vector type!");
922 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
924 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
925 Elt,
N->getOperand(1));
933SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
934 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
935 "Unexpected vector type!");
936 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
938 {
N->getValueType(0).getScalarType(), MVT::Other },
939 {
N->getOperand(0), Elt });
949 ReplaceValueWith(
SDValue(
N, 0), Res);
954SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
956 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
957 Ops[i] = GetScalarizedVector(
N->getOperand(i));
958 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
963SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
967 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
968 SDValue ContainingVec =
N->getOperand(0);
976SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
977 EVT VT =
N->getValueType(0);
978 SDValue Res = GetScalarizedVector(
N->getOperand(0));
981 ? DAG.getNode(ISD::FP_EXTEND, SDLoc(
N), VT, Res)
990 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
991 EVT VT =
N->getValueType(0);
993 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1001 assert(
N->getValueType(0).isVector() &&
1002 N->getOperand(0).getValueType().isVector() &&
1003 "Operand types must be vectors");
1004 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1006 EVT VT =
N->getValueType(0);
1007 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1008 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1010 EVT OpVT =
N->getOperand(0).getValueType();
1022 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1028SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1030 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1031 assert(
N->getValueType(0).isVector() &&
1032 N->getOperand(1).getValueType().isVector() &&
1033 "Operand types must be vectors");
1034 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1036 EVT VT =
N->getValueType(0);
1038 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1039 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1042 EVT OpVT =
N->getOperand(1).getValueType();
1046 {Ch, LHS, RHS, CC});
1055 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1060 ReplaceValueWith(
SDValue(
N, 0), Res);
1067 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1068 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1071 if (
N->isTruncatingStore())
1072 return DAG.getTruncStore(
1073 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1074 N->getBasePtr(),
N->getPointerInfo(),
1075 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1076 N->getMemOperand()->getFlags(),
N->getAAInfo());
1078 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1079 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1080 N->getMemOperand()->getFlags(),
N->getAAInfo());
1085SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1086 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1087 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1089 N->getValueType(0).getVectorElementType(), Elt,
1094SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1096 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1097 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1100 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1110 ReplaceValueWith(
SDValue(
N, 0), Res);
1117 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1119 N->getValueType(0).getVectorElementType(), Elt);
1125SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1126 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1129 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1130 {
N->getOperand(0), Elt});
1139 ReplaceValueWith(
SDValue(
N, 0), Res);
1144 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1151SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1157 SDValue Op = GetScalarizedVector(VecOp);
1158 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1159 AccOp,
Op,
N->getFlags());
1163 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1164 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1179void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1184 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1187 switch (
N->getOpcode()) {
1190 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1199 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1206 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1210 case ISD::BITCAST: SplitVecRes_BITCAST(
N,
Lo,
Hi);
break;
1222 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1225 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1234 case ISD::VP_LOAD_FF:
1237 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1244 case ISD::VP_GATHER:
1248 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1252 SplitVecRes_SETCC(
N,
Lo,
Hi);
1255 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1261 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1264 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1267 SplitVecRes_VECTOR_INTERLEAVE(
N);
1270 SplitVecRes_VAARG(
N,
Lo,
Hi);
1276 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1282 case ISD::VP_BITREVERSE:
1290 case ISD::VP_CTLZ_ZERO_UNDEF:
1292 case ISD::VP_CTTZ_ZERO_UNDEF:
1295 case ISD::FABS:
case ISD::VP_FABS:
1307 case ISD::VP_FFLOOR:
1311 case ISD::FNEARBYINT:
1312 case ISD::VP_FNEARBYINT:
1313 case ISD::FNEG:
case ISD::VP_FNEG:
1315 case ISD::ARITH_FENCE:
1316 case ISD::FP_EXTEND:
1317 case ISD::VP_FP_EXTEND:
1319 case ISD::VP_FP_ROUND:
1321 case ISD::VP_FP_TO_SINT:
1323 case ISD::VP_FP_TO_UINT:
1329 case ISD::VP_LLRINT:
1331 case ISD::VP_FROUND:
1332 case ISD::FROUNDEVEN:
1333 case ISD::VP_FROUNDEVEN:
1338 case ISD::FSQRT:
case ISD::VP_SQRT:
1342 case ISD::VP_FROUNDTOZERO:
1344 case ISD::VP_SINT_TO_FP:
1346 case ISD::VP_TRUNCATE:
1348 case ISD::VP_UINT_TO_FP:
1351 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1353 case ISD::ADDRSPACECAST:
1354 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1359 case ISD::FSINCOSPI:
1360 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1366 case ISD::VP_SIGN_EXTEND:
1367 case ISD::VP_ZERO_EXTEND:
1368 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1386 case ISD::FMINNUM_IEEE:
1387 case ISD::VP_FMINNUM:
1389 case ISD::FMAXNUM_IEEE:
1390 case ISD::VP_FMAXNUM:
1392 case ISD::VP_FMINIMUM:
1394 case ISD::VP_FMAXIMUM:
1395 case ISD::FMINIMUMNUM:
1396 case ISD::FMAXIMUMNUM:
1403 case ISD::OR:
case ISD::VP_OR:
1423 case ISD::VP_FCOPYSIGN:
1424 SplitVecRes_BinOp(
N,
Lo,
Hi);
1431 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1435 SplitVecRes_CMP(
N,
Lo,
Hi);
1438#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1439 case ISD::STRICT_##DAGN:
1440#include "llvm/IR/ConstrainedOps.def"
1441 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1446 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1455 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1465 SplitVecRes_FIX(
N,
Lo,
Hi);
1467 case ISD::EXPERIMENTAL_VP_SPLICE:
1468 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1470 case ISD::EXPERIMENTAL_VP_REVERSE:
1471 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1473 case ISD::PARTIAL_REDUCE_UMLA:
1474 case ISD::PARTIAL_REDUCE_SMLA:
1475 case ISD::PARTIAL_REDUCE_SUMLA:
1476 case ISD::PARTIAL_REDUCE_FMLA:
1477 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1479 case ISD::GET_ACTIVE_LANE_MASK:
1480 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1489void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1491 uint64_t *ScaledOffset) {
1496 SDValue BytesIncrement = DAG.getVScale(
1499 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1501 *ScaledOffset += IncrementSize;
1511std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1512 return SplitMask(Mask, SDLoc(Mask));
1515std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1518 EVT MaskVT =
Mask.getValueType();
1520 GetSplitVector(Mask, MaskLo, MaskHi);
1522 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1523 return std::make_pair(MaskLo, MaskHi);
1528 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1530 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1533 const SDNodeFlags
Flags =
N->getFlags();
1534 unsigned Opcode =
N->getOpcode();
1535 if (
N->getNumOperands() == 2) {
1536 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1537 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1541 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1542 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1545 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1548 std::tie(EVLLo, EVLHi) =
1549 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1552 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1554 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1560 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1562 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1564 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1567 const SDNodeFlags
Flags =
N->getFlags();
1568 unsigned Opcode =
N->getOpcode();
1569 if (
N->getNumOperands() == 3) {
1570 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1571 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1575 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1576 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1579 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1582 std::tie(EVLLo, EVLHi) =
1583 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1586 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1588 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1592 LLVMContext &Ctxt = *DAG.getContext();
1598 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1600 GetSplitVector(
LHS, LHSLo, LHSHi);
1601 GetSplitVector(
RHS, RHSLo, RHSHi);
1603 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1604 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1608 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1609 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1614 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1616 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1620 unsigned Opcode =
N->getOpcode();
1621 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1623 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1632 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1639 switch (getTypeAction(InVT)) {
1654 GetExpandedOp(InOp,
Lo,
Hi);
1655 if (DAG.getDataLayout().isBigEndian())
1657 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1658 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1665 GetSplitVector(InOp,
Lo,
Hi);
1666 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1667 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1674 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1675 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, InLo);
1676 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, InHi);
1683 if (DAG.getDataLayout().isBigEndian())
1686 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1688 if (DAG.getDataLayout().isBigEndian())
1690 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1691 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1694void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1698 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1701 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
N->getOperand(2));
1708 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
N->getOperand(2));
1715 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1718 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1721 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1726 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1728 unsigned NumSubvectors =
N->getNumOperands() / 2;
1729 if (NumSubvectors == 1) {
1730 Lo =
N->getOperand(0);
1731 Hi =
N->getOperand(1);
1736 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1745void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1752 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1767 GetSplitVector(Vec,
Lo,
Hi);
1770 EVT LoVT =
Lo.getValueType();
1780 if (IdxVal + SubElems <= LoElems) {
1788 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1790 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1796 SDValue WideSubVec = GetWidenedVector(SubVec);
1798 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1806 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1808 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1809 auto &MF = DAG.getMachineFunction();
1813 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1818 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1819 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1823 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1828 MachinePointerInfo MPI =
Load->getPointerInfo();
1829 IncrementPointer(Load, LoVT, MPI, StackPtr);
1832 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1841 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1846 EVT RHSVT =
RHS.getValueType();
1849 GetSplitVector(
RHS, RHSLo, RHSHi);
1851 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1866 SDValue FpValue =
N->getOperand(0);
1868 GetSplitVector(FpValue, ArgLo, ArgHi);
1870 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1872 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1881 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1885 std::tie(LoVT, HiVT) =
1889 DAG.getValueType(LoVT));
1891 DAG.getValueType(HiVT));
1896 unsigned Opcode =
N->getOpcode();
1903 GetSplitVector(N0, InLo, InHi);
1905 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1910 EVT OutLoVT, OutHiVT;
1911 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1913 assert((2 * OutNumElements) <= InNumElements &&
1914 "Illegal extend vector in reg split");
1923 SmallVector<int, 8> SplitHi(InNumElements, -1);
1924 for (
unsigned i = 0; i != OutNumElements; ++i)
1925 SplitHi[i] = i + OutNumElements;
1926 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1928 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1929 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1934 unsigned NumOps =
N->getNumOperands();
1938 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1948 for (
unsigned i = 1; i <
NumOps; ++i) {
1953 EVT InVT =
Op.getValueType();
1958 GetSplitVector(
Op, OpLo, OpHi);
1960 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
1967 EVT LoValueVTs[] = {LoVT, MVT::Other};
1968 EVT HiValueVTs[] = {HiVT, MVT::Other};
1969 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1971 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
1977 Lo.getValue(1),
Hi.getValue(1));
1981 ReplaceValueWith(
SDValue(
N, 1), Chain);
1984SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
1986 EVT VT =
N->getValueType(0);
1997 else if (NE > ResNE)
2001 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2005 for (i = 0; i !=
NE; ++i) {
2006 Operands[0] = Chain;
2007 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2008 SDValue Operand =
N->getOperand(j);
2012 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2014 Operands[
j] = Operand;
2018 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2026 for (; i < ResNE; ++i)
2031 ReplaceValueWith(
SDValue(
N, 1), Chain);
2035 return DAG.getBuildVector(VecVT, dl, Scalars);
2038void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2041 EVT ResVT =
N->getValueType(0);
2042 EVT OvVT =
N->getValueType(1);
2043 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2044 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2045 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2047 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2049 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2050 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2052 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2053 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2056 unsigned Opcode =
N->getOpcode();
2057 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2058 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2060 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2062 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2068 unsigned OtherNo = 1 - ResNo;
2069 EVT OtherVT =
N->getValueType(OtherNo);
2071 SetSplitVector(
SDValue(
N, OtherNo),
2077 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2081void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2087 GetSplitVector(Vec,
Lo,
Hi);
2090 unsigned IdxVal = CIdx->getZExtValue();
2091 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2092 if (IdxVal < LoNumElts) {
2094 Lo.getValueType(),
Lo, Elt, Idx);
2097 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2117 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2119 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2120 auto &MF = DAG.getMachineFunction();
2124 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2129 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2130 Store = DAG.getTruncStore(
2136 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2139 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2143 MachinePointerInfo MPI =
Load->getPointerInfo();
2144 IncrementPointer(Load, LoVT, MPI, StackPtr);
2146 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2149 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2150 if (LoVT !=
Lo.getValueType())
2152 if (HiVT !=
Hi.getValueType())
2160 assert(
N->getValueType(0).isScalableVector() &&
2161 "Only scalable vectors are supported for STEP_VECTOR");
2162 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2183 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2184 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2186 Hi = DAG.getPOISON(HiVT);
2198 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2204 EVT MemoryVT =
LD->getMemoryVT();
2206 AAMDNodes AAInfo =
LD->getAAInfo();
2208 EVT LoMemVT, HiMemVT;
2209 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2213 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2214 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2215 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2220 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2223 MachinePointerInfo MPI;
2224 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2227 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2236 ReplaceValueWith(
SDValue(LD, 1), Ch);
2241 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2244 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2250 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2251 Align Alignment =
LD->getBaseAlign();
2254 EVT MemoryVT =
LD->getMemoryVT();
2256 EVT LoMemVT, HiMemVT;
2257 bool HiIsEmpty =
false;
2258 std::tie(LoMemVT, HiMemVT) =
2259 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2264 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2267 GetSplitVector(Mask, MaskLo, MaskHi);
2269 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2274 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2276 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2282 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2283 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2291 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2292 LD->isExpandingLoad());
2294 MachinePointerInfo MPI;
2296 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2298 MPI =
LD->getPointerInfo().getWithOffset(
2301 MMO = DAG.getMachineFunction().getMachineMemOperand(
2303 Alignment,
LD->getAAInfo(),
LD->getRanges());
2305 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2306 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2307 LD->isExpandingLoad());
2317 ReplaceValueWith(
SDValue(LD, 1), Ch);
2323 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2327 Align Alignment =
LD->getBaseAlign();
2334 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2337 GetSplitVector(Mask, MaskLo, MaskHi);
2339 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2343 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2345 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2350 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2353 Hi = DAG.getPOISON(HiVT);
2355 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2356 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2362 "Indexed VP strided load during type legalization!");
2364 "Unexpected indexed variable-length load offset");
2369 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2371 EVT LoMemVT, HiMemVT;
2372 bool HiIsEmpty =
false;
2373 std::tie(LoMemVT, HiMemVT) =
2374 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2379 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2382 GetSplitVector(Mask, LoMask, HiMask);
2384 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2388 std::tie(LoEVL, HiEVL) =
2392 Lo = DAG.getStridedLoadVP(
2419 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2426 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2437 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2445 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2450 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2460 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2463 GetSplitVector(Mask, MaskLo, MaskHi);
2465 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2469 EVT LoMemVT, HiMemVT;
2470 bool HiIsEmpty =
false;
2471 std::tie(LoMemVT, HiMemVT) =
2472 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2474 SDValue PassThruLo, PassThruHi;
2476 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2478 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2480 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2484 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2494 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2497 MachinePointerInfo MPI;
2504 MMO = DAG.getMachineFunction().getMachineMemOperand(
2508 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2520 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2528 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2536 }
Ops = [&]() -> Operands {
2538 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2541 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2544 EVT MemoryVT =
N->getMemoryVT();
2545 Align Alignment =
N->getBaseAlign();
2550 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2552 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2555 EVT LoMemVT, HiMemVT;
2557 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2560 if (getTypeAction(
Ops.Index.getValueType()) ==
2562 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2564 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2567 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2569 Alignment,
N->getAAInfo(),
N->getRanges());
2572 SDValue PassThru = MGT->getPassThru();
2573 SDValue PassThruLo, PassThruHi;
2576 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2578 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2583 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2584 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2585 OpsLo, MMO, IndexTy, ExtType);
2587 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2588 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2589 OpsHi, MMO, IndexTy, ExtType);
2593 std::tie(EVLLo, EVLHi) =
2594 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2596 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2597 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2598 MMO, VPGT->getIndexType());
2600 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2601 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2602 MMO, VPGT->getIndexType());
2612 ReplaceValueWith(
SDValue(
N, 1), Ch);
2626 EVT VecVT =
N->getValueType(0);
2628 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2629 bool HasCustomLowering =
false;
2636 HasCustomLowering =
true;
2642 SDValue Passthru =
N->getOperand(2);
2643 if (!HasCustomLowering) {
2644 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2645 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2652 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2653 std::tie(LoMask, HiMask) = SplitMask(Mask);
2655 SDValue UndefPassthru = DAG.getUNDEF(LoVT);
2660 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2661 MachineFunction &MF = DAG.getMachineFunction();
2668 SDValue Offset = DAG.getNode(ISD::VECREDUCE_ADD,
DL, MVT::i32, WideMask);
2669 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2671 SDValue Chain = DAG.getEntryNode();
2672 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2676 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2681 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2685 assert(
N->getValueType(0).isVector() &&
2686 N->getOperand(0).getValueType().isVector() &&
2687 "Operand types must be vectors");
2691 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2695 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2697 GetSplitVector(
N->getOperand(0), LL, LH);
2699 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2701 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2703 GetSplitVector(
N->getOperand(1), RL, RH);
2705 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2708 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2709 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2711 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2712 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2713 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2714 std::tie(EVLLo, EVLHi) =
2715 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2716 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2718 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2728 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2732 EVT InVT =
N->getOperand(0).getValueType();
2734 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2736 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2738 const SDNodeFlags
Flags =
N->getFlags();
2739 unsigned Opcode =
N->getOpcode();
2740 if (
N->getNumOperands() <= 2) {
2742 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2743 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2745 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2746 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2751 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2752 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2755 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2758 std::tie(EVLLo, EVLHi) =
2759 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2762 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2768 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2772 EVT InVT =
N->getOperand(0).getValueType();
2774 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2776 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2779 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2780 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2781 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2782 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2785void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2790 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2791 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2795 EVT InVT =
N->getOperand(0).getValueType();
2797 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2799 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2801 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2802 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2804 SDNode *HiNode =
Hi.getNode();
2805 SDNode *LoNode =
Lo.getNode();
2808 unsigned OtherNo = 1 - ResNo;
2809 EVT OtherVT =
N->getValueType(OtherNo);
2817 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2824 EVT SrcVT =
N->getOperand(0).getValueType();
2825 EVT DestVT =
N->getValueType(0);
2827 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2844 LLVMContext &Ctx = *DAG.getContext();
2848 EVT SplitLoVT, SplitHiVT;
2849 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2850 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2851 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2852 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2853 N->dump(&DAG);
dbgs() <<
"\n");
2854 if (!
N->isVPOpcode()) {
2857 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2859 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2861 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2862 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2868 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2869 N->getOperand(1),
N->getOperand(2));
2871 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2874 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2877 std::tie(EVLLo, EVLHi) =
2878 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2880 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2881 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2886 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2894 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2895 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2901 return N.getResNo() == 0 &&
2905 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2907 ArrayRef<int>
Mask) {
2910 "Expected build vector node.");
2913 for (
unsigned I = 0;
I < NewElts; ++
I) {
2916 unsigned Idx =
Mask[
I];
2918 Ops[
I] = Input2.getOperand(Idx - NewElts);
2920 Ops[
I] = Input1.getOperand(Idx);
2925 return DAG.getBuildVector(NewVT,
DL,
Ops);
2931 SmallVector<int> OrigMask(
N->getMask());
2933 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2934 &
DL](SmallVectorImpl<int> &
Mask) {
2936 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2937 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2948 for (
auto &
P : ShufflesIdxs) {
2949 if (
P.second.size() < 2)
2953 for (
int &Idx : Mask) {
2956 unsigned SrcRegIdx = Idx / NewElts;
2957 if (Inputs[SrcRegIdx].
isUndef()) {
2965 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2970 Idx = MaskElt % NewElts +
2971 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
2977 Inputs[
P.second[0]] =
P.first.first;
2978 Inputs[
P.second[1]] =
P.first.second;
2981 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
2984 SmallBitVector UsedSubVector(2 * std::size(Inputs));
2985 for (
int &Idx : Mask) {
2988 unsigned SrcRegIdx = Idx / NewElts;
2989 if (Inputs[SrcRegIdx].
isUndef()) {
2996 Inputs[SrcRegIdx].getNumOperands() == 2 &&
2997 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3000 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3002 if (UsedSubVector.count() > 1) {
3004 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3005 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3007 if (Pairs.
empty() || Pairs.
back().size() == 2)
3009 if (UsedSubVector.test(2 *
I)) {
3010 Pairs.
back().emplace_back(
I, 0);
3012 assert(UsedSubVector.test(2 *
I + 1) &&
3013 "Expected to be used one of the subvectors.");
3014 Pairs.
back().emplace_back(
I, 1);
3017 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3019 for (
int &Idx : Mask) {
3022 unsigned SrcRegIdx = Idx / NewElts;
3024 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3025 return Idxs.front().first == SrcRegIdx ||
3026 Idxs.back().first == SrcRegIdx;
3028 if (It == Pairs.
end())
3030 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3031 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3034 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3035 Inputs[Idxs.front().first] = DAG.
getNode(
3037 Inputs[Idxs.front().first].getValueType(),
3038 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3039 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3048 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3052 if (Shuffle->getOperand(0).getValueType() != NewVT)
3055 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3056 !Shuffle->isSplat()) {
3058 }
else if (!Inputs[
I].hasOneUse() &&
3059 !Shuffle->getOperand(1).isUndef()) {
3061 for (
int &Idx : Mask) {
3064 unsigned SrcRegIdx = Idx / NewElts;
3067 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3072 int OpIdx = MaskElt / NewElts;
3086 if (Shuffle->getOperand(
OpIdx).isUndef())
3088 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3089 if (It == std::end(Inputs))
3091 int FoundOp = std::distance(std::begin(Inputs), It);
3094 for (
int &Idx : Mask) {
3097 unsigned SrcRegIdx = Idx / NewElts;
3100 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3105 int MaskIdx = MaskElt / NewElts;
3106 if (
OpIdx == MaskIdx)
3107 Idx = MaskElt % NewElts + FoundOp * NewElts;
3118 for (
int &Idx : Mask) {
3121 unsigned SrcRegIdx = Idx / NewElts;
3124 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3125 int OpIdx = MaskElt / NewElts;
3128 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3134 TryPeekThroughShufflesInputs(OrigMask);
3136 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3137 NewElts](SmallVectorImpl<int> &
Mask) {
3138 SetVector<SDValue> UniqueInputs;
3139 SetVector<SDValue> UniqueConstantInputs;
3140 for (
const auto &
I : Inputs) {
3142 UniqueConstantInputs.
insert(
I);
3143 else if (!
I.isUndef())
3148 if (UniqueInputs.
size() != std::size(Inputs)) {
3149 auto &&UniqueVec = UniqueInputs.
takeVector();
3150 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3151 unsigned ConstNum = UniqueConstantVec.size();
3152 for (
int &Idx : Mask) {
3155 unsigned SrcRegIdx = Idx / NewElts;
3156 if (Inputs[SrcRegIdx].
isUndef()) {
3160 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3161 if (It != UniqueConstantVec.end()) {
3162 Idx = (Idx % NewElts) +
3163 NewElts * std::distance(UniqueConstantVec.begin(), It);
3164 assert(Idx >= 0 &&
"Expected defined mask idx.");
3167 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3168 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3169 Idx = (Idx % NewElts) +
3170 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3171 assert(Idx >= 0 &&
"Expected defined mask idx.");
3173 copy(UniqueConstantVec, std::begin(Inputs));
3174 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3177 MakeUniqueInputs(OrigMask);
3179 copy(Inputs, std::begin(OrigInputs));
3185 unsigned FirstMaskIdx =
High * NewElts;
3188 assert(!Output &&
"Expected default initialized initial value.");
3189 TryPeekThroughShufflesInputs(Mask);
3190 MakeUniqueInputs(Mask);
3192 copy(Inputs, std::begin(TmpInputs));
3195 bool SecondIteration =
false;
3196 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3201 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3202 SecondIteration =
true;
3203 return SecondIteration;
3206 Mask, std::size(Inputs), std::size(Inputs),
3208 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3209 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3210 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3212 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3214 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3215 DAG.getUNDEF(NewVT), Mask);
3216 Inputs[Idx] = Output;
3218 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3219 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3220 unsigned Idx2,
bool ) {
3221 if (AccumulateResults(Idx1)) {
3224 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3226 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3227 Inputs[Idx2], Mask);
3231 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3233 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3234 TmpInputs[Idx2], Mask);
3236 Inputs[Idx1] = Output;
3238 copy(OrigInputs, std::begin(Inputs));
3243 EVT OVT =
N->getValueType(0);
3250 const Align Alignment =
3251 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3253 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3254 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3259 ReplaceValueWith(
SDValue(
N, 1), Chain);
3264 EVT DstVTLo, DstVTHi;
3265 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3269 EVT SrcVT =
N->getOperand(0).getValueType();
3271 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3273 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3275 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3276 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3282 GetSplitVector(
N->getOperand(0), InLo, InHi);
3293 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3294 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3299 EVT VT =
N->getValueType(0);
3306 Align Alignment = DAG.getReducedAlign(VT,
false);
3311 EVT PtrVT =
StackPtr.getValueType();
3312 auto &MF = DAG.getMachineFunction();
3316 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3319 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3325 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3326 DAG.getConstant(1,
DL, PtrVT));
3328 DAG.getConstant(EltWidth,
DL, PtrVT));
3330 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3332 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3333 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3334 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3337 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3339 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3344 EVT VT =
N->getValueType(0);
3356 EVL1 = ZExtPromotedInteger(EVL1);
3358 Align Alignment = DAG.getReducedAlign(VT,
false);
3363 EVT PtrVT =
StackPtr.getValueType();
3364 auto &MF = DAG.getMachineFunction();
3368 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3371 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3375 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3377 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3378 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3379 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3383 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3388 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3389 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3391 uint64_t TrailingElts = -
Imm;
3393 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3402 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3406 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3408 DAG.getVectorIdxConstant(0,
DL));
3414void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3422 GetSplitVector(Acc, AccLo, AccHi);
3423 unsigned Opcode =
N->getOpcode();
3435 GetSplitVector(Input1, Input1Lo, Input1Hi);
3436 GetSplitVector(Input2, Input2Lo, Input2Hi);
3439 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3440 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3443void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3451 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3453 Lo = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, LoVT, Op0, Op1);
3456 Hi = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, HiVT, HiStartVal, Op1);
3459void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3460 unsigned Factor =
N->getNumOperands();
3463 for (
unsigned i = 0; i != Factor; ++i) {
3465 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3467 Ops[i * 2 + 1] = OpHi;
3478 for (
unsigned i = 0; i != Factor; ++i)
3482void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
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 + Factor] = OpHi;
3501 for (
unsigned i = 0; i != Factor; ++i) {
3502 unsigned IdxLo = 2 * i;
3503 unsigned IdxHi = 2 * i + 1;
3504 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3505 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3517bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3522 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3525 switch (
N->getOpcode()) {
3528 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3538 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3539 case ISD::BITCAST: Res = SplitVecOp_BITCAST(
N);
break;
3544 case ISD::VP_TRUNCATE:
3546 Res = SplitVecOp_TruncateHelper(
N);
3549 case ISD::VP_FP_ROUND:
3558 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3565 case ISD::VP_SCATTER:
3569 case ISD::VP_GATHER:
3573 Res = SplitVecOp_VSELECT(
N, OpNo);
3576 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3582 case ISD::VP_SINT_TO_FP:
3583 case ISD::VP_UINT_TO_FP:
3584 if (
N->getValueType(0).bitsLT(
3585 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3586 Res = SplitVecOp_TruncateHelper(
N);
3588 Res = SplitVecOp_UnaryOp(
N);
3592 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3596 case ISD::VP_FP_TO_SINT:
3597 case ISD::VP_FP_TO_UINT:
3601 case ISD::FP_EXTEND:
3610 Res = SplitVecOp_UnaryOp(
N);
3613 Res = SplitVecOp_FPOpDifferentTypes(
N);
3618 Res = SplitVecOp_CMP(
N);
3622 Res = SplitVecOp_FAKE_USE(
N);
3627 Res = SplitVecOp_ExtVecInRegOp(
N);
3630 case ISD::VECREDUCE_FADD:
3631 case ISD::VECREDUCE_FMUL:
3632 case ISD::VECREDUCE_ADD:
3633 case ISD::VECREDUCE_MUL:
3634 case ISD::VECREDUCE_AND:
3635 case ISD::VECREDUCE_OR:
3636 case ISD::VECREDUCE_XOR:
3637 case ISD::VECREDUCE_SMAX:
3638 case ISD::VECREDUCE_SMIN:
3639 case ISD::VECREDUCE_UMAX:
3640 case ISD::VECREDUCE_UMIN:
3641 case ISD::VECREDUCE_FMAX:
3642 case ISD::VECREDUCE_FMIN:
3643 case ISD::VECREDUCE_FMAXIMUM:
3644 case ISD::VECREDUCE_FMINIMUM:
3645 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3647 case ISD::VECREDUCE_SEQ_FADD:
3648 case ISD::VECREDUCE_SEQ_FMUL:
3649 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3651 case ISD::VP_REDUCE_FADD:
3652 case ISD::VP_REDUCE_SEQ_FADD:
3653 case ISD::VP_REDUCE_FMUL:
3654 case ISD::VP_REDUCE_SEQ_FMUL:
3655 case ISD::VP_REDUCE_ADD:
3656 case ISD::VP_REDUCE_MUL:
3657 case ISD::VP_REDUCE_AND:
3658 case ISD::VP_REDUCE_OR:
3659 case ISD::VP_REDUCE_XOR:
3660 case ISD::VP_REDUCE_SMAX:
3661 case ISD::VP_REDUCE_SMIN:
3662 case ISD::VP_REDUCE_UMAX:
3663 case ISD::VP_REDUCE_UMIN:
3664 case ISD::VP_REDUCE_FMAX:
3665 case ISD::VP_REDUCE_FMIN:
3666 case ISD::VP_REDUCE_FMAXIMUM:
3667 case ISD::VP_REDUCE_FMINIMUM:
3668 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3670 case ISD::VP_CTTZ_ELTS:
3671 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3672 Res = SplitVecOp_VP_CttzElements(
N);
3674 case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
3675 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3677 case ISD::PARTIAL_REDUCE_UMLA:
3678 case ISD::PARTIAL_REDUCE_SMLA:
3679 case ISD::PARTIAL_REDUCE_SUMLA:
3680 case ISD::PARTIAL_REDUCE_FMLA:
3681 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3686 if (!Res.
getNode())
return false;
3693 if (
N->isStrictFPOpcode())
3695 "Invalid operand expansion");
3698 "Invalid operand expansion");
3700 ReplaceValueWith(
SDValue(
N, 0), Res);
3704SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3707 assert(OpNo == 0 &&
"Illegal operand must be mask");
3714 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3717 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3718 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3719 "Lo and Hi have differing types");
3722 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3723 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3725 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3726 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3727 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3728 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3738SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3741 assert(OpNo == 1 &&
"Illegal operand must be mask");
3746 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3748 EVT VecVT =
N->getValueType(0);
3752SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3753 EVT ResVT =
N->getValueType(0);
3759 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3760 GetSplitVector(VecOp,
Lo,
Hi);
3762 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3767 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3768 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3772 EVT ResVT =
N->getValueType(0);
3778 SDNodeFlags
Flags =
N->getFlags();
3781 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3782 GetSplitVector(VecOp,
Lo,
Hi);
3784 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3790 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3793SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3794 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3795 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3797 unsigned Opc =
N->getOpcode();
3798 EVT ResVT =
N->getValueType(0);
3804 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3805 GetSplitVector(VecOp,
Lo,
Hi);
3808 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3811 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3813 const SDNodeFlags
Flags =
N->getFlags();
3817 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3822 EVT ResVT =
N->getValueType(0);
3825 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3826 EVT InVT =
Lo.getValueType();
3831 if (
N->isStrictFPOpcode()) {
3832 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3833 {N->getOperand(0), Lo});
3834 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3835 {N->getOperand(0), Hi});
3844 ReplaceValueWith(
SDValue(
N, 1), Ch);
3845 }
else if (
N->getNumOperands() == 3) {
3846 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3847 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3848 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3849 std::tie(EVLLo, EVLHi) =
3850 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3851 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3852 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3854 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3855 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3864 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3866 DAG.
getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
Lo);
3867 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other, Chain,
Hi);
3874 EVT ResVT =
N->getValueType(0);
3876 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3880 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3881 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
3882 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
3886 Lo = BitConvertToInteger(
Lo);
3887 Hi = BitConvertToInteger(
Hi);
3889 if (DAG.getDataLayout().isBigEndian())
3892 return DAG.getNode(ISD::BITCAST, dl, ResVT, JoinIntegers(
Lo,
Hi));
3897 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3899 EVT ResVT =
N->getValueType(0);
3907 GetSplitVector(SubVec,
Lo,
Hi);
3916 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3918 return SecondInsertion;
3921SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3928 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3930 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
3932 ElementCount IdxVal =
3936 EVT SrcVT =
N->getOperand(0).getValueType();
3955 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
3956 LoEltsMin - IdxValMin);
3957 DAG.ExtractVectorElements(
Hi, Elts, 0,
3960 return DAG.getBuildVector(SubVT, dl, Elts);
3964 ElementCount ExtractIdx = IdxVal - LoElts;
3966 return DAG.getExtractSubvector(dl, SubVT,
Hi,
3969 EVT HiVT =
Hi.getValueType();
3971 "Only fixed-vector extracts are supported in this case");
3981 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
3982 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
3988 "Extracting scalable subvector from fixed-width unsupported");
3996 "subvector from a scalable predicate vector");
4002 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4004 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4005 auto &MF = DAG.getMachineFunction();
4009 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4013 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4016 SubVT, dl, Store, StackPtr,
4020SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4026 uint64_t IdxVal =
Index->getZExtValue();
4029 GetSplitVector(Vec,
Lo,
Hi);
4031 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4033 if (IdxVal < LoElts)
4034 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4037 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4042 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4054 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4060 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4062 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4063 auto &MF = DAG.getMachineFunction();
4066 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4070 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4074 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4076 return DAG.getExtLoad(
4087 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4095 SplitVecRes_Gather(
N,
Lo,
Hi);
4098 ReplaceValueWith(
SDValue(
N, 0), Res);
4103 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4107 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4109 SDValue EVL =
N->getVectorLength();
4111 Align Alignment =
N->getBaseAlign();
4117 GetSplitVector(
Data, DataLo, DataHi);
4119 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4124 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4127 GetSplitVector(Mask, MaskLo, MaskHi);
4129 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4132 EVT MemoryVT =
N->getMemoryVT();
4133 EVT LoMemVT, HiMemVT;
4134 bool HiIsEmpty =
false;
4135 std::tie(LoMemVT, HiMemVT) =
4136 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4140 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4143 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4148 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4149 N->getAddressingMode(),
N->isTruncatingStore(),
4150 N->isCompressingStore());
4156 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4157 N->isCompressingStore());
4159 MachinePointerInfo MPI;
4163 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4168 MMO = DAG.getMachineFunction().getMachineMemOperand(
4170 Alignment,
N->getAAInfo(),
N->getRanges());
4172 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4173 N->getAddressingMode(),
N->isTruncatingStore(),
4174 N->isCompressingStore());
4183 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4184 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4191 GetSplitVector(
Data, LoData, HiData);
4193 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4195 EVT LoMemVT, HiMemVT;
4196 bool HiIsEmpty =
false;
4197 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4203 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4204 else if (getTypeAction(
Mask.getValueType()) ==
4206 GetSplitVector(Mask, LoMask, HiMask);
4208 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4211 std::tie(LoEVL, HiEVL) =
4212 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4216 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4217 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4218 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4229 EVT PtrVT =
N->getBasePtr().getValueType();
4232 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4235 Align Alignment =
N->getBaseAlign();
4240 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4241 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4243 Alignment,
N->getAAInfo(),
N->getRanges());
4246 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4247 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4248 N->isCompressingStore());
4257 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4261 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4264 Align Alignment =
N->getBaseAlign();
4270 GetSplitVector(
Data, DataLo, DataHi);
4272 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4277 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4280 GetSplitVector(Mask, MaskLo, MaskHi);
4282 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4285 EVT MemoryVT =
N->getMemoryVT();
4286 EVT LoMemVT, HiMemVT;
4287 bool HiIsEmpty =
false;
4288 std::tie(LoMemVT, HiMemVT) =
4289 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4292 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4297 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4298 N->getAddressingMode(),
N->isTruncatingStore(),
4299 N->isCompressingStore());
4307 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4308 N->isCompressingStore());
4310 MachinePointerInfo MPI;
4314 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4319 MMO = DAG.getMachineFunction().getMachineMemOperand(
4321 Alignment,
N->getAAInfo(),
N->getRanges());
4323 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4324 N->getAddressingMode(),
N->isTruncatingStore(),
4325 N->isCompressingStore());
4338 EVT MemoryVT =
N->getMemoryVT();
4339 Align Alignment =
N->getBaseAlign();
4346 }
Ops = [&]() -> Operands {
4348 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4352 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4357 EVT LoMemVT, HiMemVT;
4358 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4363 GetSplitVector(
Ops.Data, DataLo, DataHi);
4365 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4370 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4372 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4376 if (getTypeAction(
Ops.Index.getValueType()) ==
4378 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4380 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4384 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4386 Alignment,
N->getAAInfo(),
N->getRanges());
4389 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4391 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4392 MSC->getIndexType(), MSC->isTruncatingStore());
4397 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4398 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4399 MMO, MSC->getIndexType(),
4400 MSC->isTruncatingStore());
4404 std::tie(EVLLo, EVLHi) =
4405 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4407 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4408 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4409 VPSC->getIndexType());
4414 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4415 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4416 VPSC->getIndexType());
4420 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4421 assert(OpNo == 1 &&
"Can only split the stored value");
4424 bool isTruncating =
N->isTruncatingStore();
4427 EVT MemoryVT =
N->getMemoryVT();
4428 Align Alignment =
N->getBaseAlign();
4430 AAMDNodes AAInfo =
N->getAAInfo();
4432 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4434 EVT LoMemVT, HiMemVT;
4435 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4439 return TLI.scalarizeVectorStore(
N, DAG);
4442 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4443 Alignment, MMOFlags, AAInfo);
4445 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4448 MachinePointerInfo MPI;
4449 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4452 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4453 HiMemVT, Alignment, MMOFlags, AAInfo);
4455 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4471 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4477 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4498 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4499 SDValue InVec =
N->getOperand(OpNo);
4501 EVT OutVT =
N->getValueType(0);
4509 EVT LoOutVT, HiOutVT;
4510 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4511 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4516 if (isTypeLegal(LoOutVT) ||
4517 InElementSize <= OutElementSize * 2)
4518 return SplitVecOp_UnaryOp(
N);
4527 return SplitVecOp_UnaryOp(
N);
4531 GetSplitVector(InVec, InLoVec, InHiVec);
4537 EVT HalfElementVT = IsFloat ?
4539 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4546 if (
N->isStrictFPOpcode()) {
4547 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4548 {N->getOperand(0), InLoVec});
4549 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4550 {N->getOperand(0), InHiVec});
4556 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4557 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4561 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4569 if (
N->isStrictFPOpcode()) {
4573 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4581 DAG.getTargetConstant(
4582 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4589 assert(
N->getValueType(0).isVector() &&
4590 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4591 "Operand types must be vectors");
4593 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4595 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4596 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4598 EVT VT =
N->getValueType(0);
4604 }
else if (isStrict) {
4605 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4606 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4607 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4608 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4611 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4613 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4614 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4615 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4616 std::tie(EVLLo, EVLHi) =
4617 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4618 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4619 N->getOperand(2), MaskLo, EVLLo);
4620 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4621 N->getOperand(2), MaskHi, EVLHi);
4630 EVT ResVT =
N->getValueType(0);
4633 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4634 EVT InVT =
Lo.getValueType();
4639 if (
N->isStrictFPOpcode()) {
4640 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4641 {N->getOperand(0), Lo, N->getOperand(2)});
4642 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4643 {N->getOperand(0), Hi, N->getOperand(2)});
4647 Lo.getValue(1),
Hi.getValue(1));
4648 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4649 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4650 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4651 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4652 std::tie(EVLLo, EVLHi) =
4653 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4654 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4655 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4669SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4672 EVT LHSLoVT, LHSHiVT;
4673 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4675 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4676 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4679 std::tie(LHSLo, LHSHi) =
4680 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4683 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4686 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4692 LLVMContext &Ctxt = *DAG.getContext();
4695 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4696 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4697 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4699 EVT ResVT =
N->getValueType(0);
4704 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4705 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4711 EVT ResVT =
N->getValueType(0);
4714 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4715 EVT InVT =
Lo.getValueType();
4721 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4722 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4729 EVT ResVT =
N->getValueType(0);
4733 GetSplitVector(VecOp,
Lo,
Hi);
4735 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4736 auto [EVLLo, EVLHi] =
4738 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4744 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4746 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4747 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4750SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4761 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4762 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4763 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4764 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4765 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4766 OpsLo, MMO, IndexType);
4767 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4768 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4772SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4775 "Accumulator should already be a legal type, and shouldn't need "
4776 "further splitting");
4779 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4780 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4781 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4782 unsigned Opcode =
N->getOpcode();
4785 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4786 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4793void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4794 unsigned WidenResNo) {
4795 unsigned NumResults =
N->getNumValues();
4796 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4797 if (ResNo == WidenResNo)
4799 EVT ResVT =
N->getValueType(ResNo);
4805 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4806 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4811void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4812 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4815 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4820 auto unrollExpandedOp = [&]() {
4825 EVT VT =
N->getValueType(0);
4826 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4827 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4830 if (
N->getNumValues() > 1)
4831 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4837 switch (
N->getOpcode()) {
4840 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4848 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4851 case ISD::ADDRSPACECAST:
4852 Res = WidenVecRes_ADDRSPACECAST(
N);
4855 case ISD::BITCAST: Res = WidenVecRes_BITCAST(
N);
break;
4859 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4863 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4867 Res = WidenVecRes_ScalarOp(
N);
4872 case ISD::VP_SELECT:
4874 Res = WidenVecRes_Select(
N);
4878 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4880 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4887 case ISD::VP_LOAD_FF:
4890 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4894 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4902 case ISD::VP_GATHER:
4906 Res = WidenVecRes_VECTOR_REVERSE(
N);
4908 case ISD::GET_ACTIVE_LANE_MASK:
4909 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4919 case ISD::OR:
case ISD::VP_OR:
4926 case ISD::FMINNUM_IEEE:
4927 case ISD::VP_FMINNUM:
4929 case ISD::FMAXNUM_IEEE:
4930 case ISD::VP_FMAXNUM:
4932 case ISD::VP_FMINIMUM:
4934 case ISD::VP_FMAXIMUM:
4935 case ISD::FMINIMUMNUM:
4936 case ISD::FMAXIMUMNUM:
4967 case ISD::VP_FCOPYSIGN:
4968 Res = WidenVecRes_Binary(
N);
4973 Res = WidenVecRes_CMP(
N);
4979 if (unrollExpandedOp())
4994 Res = WidenVecRes_BinaryCanTrap(
N);
5003 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5006#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5007 case ISD::STRICT_##DAGN:
5008#include "llvm/IR/ConstrainedOps.def"
5009 Res = WidenVecRes_StrictFP(
N);
5018 Res = WidenVecRes_OverflowOp(
N, ResNo);
5022 Res = WidenVecRes_FCOPYSIGN(
N);
5027 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5032 if (!unrollExpandedOp())
5033 Res = WidenVecRes_ExpOp(
N);
5039 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5043 case ISD::FP_EXTEND:
5044 case ISD::VP_FP_EXTEND:
5046 case ISD::VP_FP_ROUND:
5048 case ISD::VP_FP_TO_SINT:
5050 case ISD::VP_FP_TO_UINT:
5052 case ISD::VP_SIGN_EXTEND:
5054 case ISD::VP_SINT_TO_FP:
5055 case ISD::VP_TRUNCATE:
5058 case ISD::VP_UINT_TO_FP:
5060 case ISD::VP_ZERO_EXTEND:
5061 Res = WidenVecRes_Convert(
N);
5066 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5072 case ISD::VP_LLRINT:
5075 Res = WidenVecRes_XROUND(
N);
5091 case ISD::FNEARBYINT:
5094 case ISD::FROUNDEVEN:
5101 if (unrollExpandedOp())
5111 case ISD::VP_BITREVERSE:
5117 case ISD::VP_CTLZ_ZERO_UNDEF:
5123 case ISD::VP_CTTZ_ZERO_UNDEF:
5124 case ISD::FNEG:
case ISD::VP_FNEG:
5125 case ISD::FABS:
case ISD::VP_FABS:
5128 case ISD::VP_FFLOOR:
5130 case ISD::VP_FNEARBYINT:
5131 case ISD::VP_FROUND:
5132 case ISD::VP_FROUNDEVEN:
5133 case ISD::VP_FROUNDTOZERO:
5135 case ISD::ARITH_FENCE:
5138 Res = WidenVecRes_Unary(
N);
5145 Res = WidenVecRes_Ternary(
N);
5150 case ISD::FSINCOSPI: {
5151 if (!unrollExpandedOp())
5152 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5159 SetWidenedVector(
SDValue(
N, ResNo), Res);
5165 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5166 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5167 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5168 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5169 if (
N->getNumOperands() == 3)
5170 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5172 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5173 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5177 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5178 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5184 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5185 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5186 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5187 if (
N->getNumOperands() == 2)
5188 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5191 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5192 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5196 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5197 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5201 LLVMContext &Ctxt = *DAG.getContext();
5206 EVT OpVT =
LHS.getValueType();
5208 LHS = GetWidenedVector(
LHS);
5209 RHS = GetWidenedVector(
RHS);
5210 OpVT =
LHS.getValueType();
5213 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5216 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5222SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5225 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5226 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5227 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5229 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5238 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5241 if (ConcatEnd == 1) {
5242 VT = ConcatOps[0].getValueType();
5244 return ConcatOps[0];
5247 SDLoc dl(ConcatOps[0]);
5254 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5255 int Idx = ConcatEnd - 1;
5256 VT = ConcatOps[Idx--].getValueType();
5257 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5270 unsigned NumToInsert = ConcatEnd - Idx - 1;
5271 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5273 ConcatOps[Idx+1] = VecOp;
5274 ConcatEnd = Idx + 2;
5280 unsigned RealVals = ConcatEnd - Idx - 1;
5281 unsigned SubConcatEnd = 0;
5282 unsigned SubConcatIdx = Idx + 1;
5283 while (SubConcatEnd < RealVals)
5284 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5285 while (SubConcatEnd < OpsToConcat)
5286 SubConcatOps[SubConcatEnd++] = undefVec;
5288 NextVT, SubConcatOps);
5289 ConcatEnd = SubConcatIdx + 1;
5294 if (ConcatEnd == 1) {
5295 VT = ConcatOps[0].getValueType();
5297 return ConcatOps[0];
5302 if (
NumOps != ConcatEnd ) {
5304 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5305 ConcatOps[j] = UndefVal;
5313 unsigned Opcode =
N->getOpcode();
5315 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5319 const SDNodeFlags
Flags =
N->getFlags();
5320 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5321 NumElts = NumElts / 2;
5325 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5327 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5328 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5329 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5337 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5340 TLI.isTypeLegal(WideMaskVT)) {
5341 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5342 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5343 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5345 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5346 N->getValueType(0).getVectorElementCount());
5347 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5361 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5362 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5363 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5366 unsigned ConcatEnd = 0;
5374 while (CurNumElts != 0) {
5375 while (CurNumElts >= NumElts) {
5376 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5377 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5378 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5380 CurNumElts -= NumElts;
5383 NumElts = NumElts / 2;
5385 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5388 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5389 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5390 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5391 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5402 switch (
N->getOpcode()) {
5405 return WidenVecRes_STRICT_FSETCC(
N);
5412 return WidenVecRes_Convert_StrictFP(
N);
5419 unsigned Opcode =
N->getOpcode();
5421 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5425 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5426 NumElts = NumElts / 2;
5437 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5441 unsigned ConcatEnd = 0;
5448 for (
unsigned i = 1; i < NumOpers; ++i) {
5454 Oper = GetWidenedVector(Oper);
5460 DAG.getUNDEF(WideOpVT), Oper,
5461 DAG.getVectorIdxConstant(0, dl));
5473 while (CurNumElts != 0) {
5474 while (CurNumElts >= NumElts) {
5477 for (
unsigned i = 0; i < NumOpers; ++i) {
5480 EVT OpVT =
Op.getValueType();
5485 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5491 EVT OperVT[] = {VT, MVT::Other};
5493 ConcatOps[ConcatEnd++] = Oper;
5496 CurNumElts -= NumElts;
5499 NumElts = NumElts / 2;
5501 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5504 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5507 for (
unsigned i = 0; i < NumOpers; ++i) {
5510 EVT OpVT =
Op.getValueType();
5518 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5520 ConcatOps[ConcatEnd++] = Oper;
5529 if (Chains.
size() == 1)
5530 NewChain = Chains[0];
5533 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5538SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5540 EVT ResVT =
N->getValueType(0);
5541 EVT OvVT =
N->getValueType(1);
5542 EVT WideResVT, WideOvVT;
5547 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5552 WideLHS = GetWidenedVector(
N->getOperand(0));
5553 WideRHS = GetWidenedVector(
N->getOperand(1));
5555 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5563 N->getOperand(0), Zero);
5566 N->getOperand(1), Zero);
5569 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5570 SDNode *WideNode = DAG.getNode(
5571 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5574 unsigned OtherNo = 1 - ResNo;
5575 EVT OtherVT =
N->getValueType(OtherNo);
5582 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5585 return SDValue(WideNode, ResNo);
5589 LLVMContext &Ctx = *DAG.getContext();
5593 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5598 unsigned Opcode =
N->getOpcode();
5599 const SDNodeFlags
Flags =
N->getFlags();
5605 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5607 InOp = ZExtPromotedInteger(InOp);
5618 InOp = GetWidenedVector(
N->getOperand(0));
5621 if (InVTEC == WidenEC) {
5622 if (
N->getNumOperands() == 1)
5623 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5624 if (
N->getNumOperands() == 3) {
5625 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5628 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5630 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5645 if (TLI.isTypeLegal(InWidenVT)) {
5653 unsigned NumConcat =
5658 if (
N->getNumOperands() == 1)
5659 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5660 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5664 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5666 if (
N->getNumOperands() == 1)
5667 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5668 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5677 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5678 for (
unsigned i=0; i < MinElts; ++i) {
5679 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5680 if (
N->getNumOperands() == 1)
5683 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5686 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5691 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5695 EVT SrcVT = Src.getValueType();
5699 Src = GetWidenedVector(Src);
5700 SrcVT = Src.getValueType();
5707 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5712 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5716 EVT SrcVT = Src.getValueType();
5720 Src = GetWidenedVector(Src);
5721 SrcVT = Src.getValueType();
5728 if (
N->getNumOperands() == 1)
5729 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5731 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5732 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5736 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5739SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5744 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5750 unsigned Opcode =
N->getOpcode();
5756 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5761 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5762 for (
unsigned i=0; i < MinElts; ++i) {
5763 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5764 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5768 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5770 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5773SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5774 unsigned Opcode =
N->getOpcode();
5778 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5787 InOp = GetWidenedVector(InOp);
5794 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5801 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5802 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5819 while (
Ops.size() != WidenNumElts)
5820 Ops.push_back(DAG.getPOISON(WidenSVT));
5822 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5828 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5829 return WidenVecRes_BinaryCanTrap(
N);
5832 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5839SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5841 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5844 SDValue Arg = GetWidenedVector(FpValue);
5845 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5850 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5851 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5853 EVT ExpVT =
RHS.getValueType();
5858 ExpOp = ModifyToType(
RHS, WideExpVT);
5861 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5866 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5867 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5868 if (
N->getNumOperands() == 1)
5869 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5871 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5872 N->getOperand(1),
N->getFlags());
5874 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5875 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5879 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5880 {InOp,
Mask,
N->getOperand(2)});
5884 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5887 .getVectorElementType(),
5889 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5890 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5891 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5894SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5896 EVT VT0 =
N->getValueType(0);
5897 EVT VT1 =
N->getValueType(1);
5901 "expected both results to be vectors of matching element count");
5903 LLVMContext &Ctx = *DAG.getContext();
5904 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5906 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5913 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5916 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5917 return SDValue(WidenNode, ResNo);
5920SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5921 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5922 return GetWidenedVector(WidenVec);
5926 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5927 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5930 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5931 AddrSpaceCastN->getSrcAddressSpace(),
5932 AddrSpaceCastN->getDestAddressSpace());
5938 EVT VT =
N->getValueType(0);
5939 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5942 switch (getTypeAction(InVT)) {
5956 SDValue NInOp = GetPromotedInteger(InOp);
5958 if (WidenVT.
bitsEq(NInVT)) {
5961 if (DAG.getDataLayout().isBigEndian()) {
5964 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
5966 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NInOp);
5983 InOp = GetWidenedVector(InOp);
5985 if (WidenVT.
bitsEq(InVT))
5987 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp);
5995 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6000 unsigned NewNumParts = WidenSize / InSize;
6013 EVT OrigInVT =
N->getOperand(0).getValueType();
6018 if (TLI.isTypeLegal(NewInVT)) {
6026 if (WidenSize % InSize == 0) {
6033 DAG.ExtractVectorElements(InOp,
Ops);
6034 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6042 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec);
6046 return CreateStackStoreLoad(InOp, WidenVT);
6049SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6051 N->getOpcode(), SDLoc(
N),
6052 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6053 N->getOperand(0),
N->getOperand(1),
N->getOperand(2));
6059 EVT VT =
N->getValueType(0);
6063 EVT EltVT =
N->getOperand(0).getValueType();
6066 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6070 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6071 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6073 return DAG.getBuildVector(WidenVT, dl, NewOps);
6077 EVT InVT =
N->getOperand(0).getValueType();
6078 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6080 unsigned NumOperands =
N->getNumOperands();
6082 bool InputWidened =
false;
6086 if (WidenNumElts % NumInElts == 0) {
6088 unsigned NumConcat = WidenNumElts / NumInElts;
6089 SDValue UndefVal = DAG.getPOISON(InVT);
6091 for (
unsigned i=0; i < NumOperands; ++i)
6092 Ops[i] =
N->getOperand(i);
6093 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6098 InputWidened =
true;
6099 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6102 for (i=1; i < NumOperands; ++i)
6103 if (!
N->getOperand(i).isUndef())
6106 if (i == NumOperands)
6109 return GetWidenedVector(
N->getOperand(0));
6111 if (NumOperands == 2) {
6113 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6118 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6119 for (
unsigned i = 0; i < NumInElts; ++i) {
6121 MaskOps[i + NumInElts] = i + WidenNumElts;
6123 return DAG.getVectorShuffle(WidenVT, dl,
6124 GetWidenedVector(
N->getOperand(0)),
6125 GetWidenedVector(
N->getOperand(1)),
6132 "Cannot use build vectors to widen CONCAT_VECTOR result");
6140 for (
unsigned i=0; i < NumOperands; ++i) {
6143 InOp = GetWidenedVector(InOp);
6144 for (
unsigned j = 0;
j < NumInElts; ++
j)
6145 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6147 SDValue UndefVal = DAG.getPOISON(EltVT);
6148 for (; Idx < WidenNumElts; ++Idx)
6149 Ops[Idx] = UndefVal;
6150 return DAG.getBuildVector(WidenVT, dl,
Ops);
6153SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6154 EVT VT =
N->getValueType(0);
6155 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6156 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6163SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6164 EVT VT =
N->getValueType(0);
6166 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6171 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6173 InOp = GetWidenedVector(InOp);
6179 if (IdxVal == 0 && InVT == WidenVT)
6186 assert(IdxVal % VTNumElts == 0 &&
6187 "Expected Idx to be a multiple of subvector minimum vector length");
6188 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6201 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6202 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6203 "down type's element count");
6210 for (;
I < VTNumElts / GCD; ++
I)
6212 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6213 for (;
I < WidenNumElts / GCD; ++
I)
6221 Align Alignment = DAG.getReducedAlign(InVT,
false);
6223 MachineFunction &MF = DAG.getMachineFunction();
6235 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6242 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6243 return DAG.getMaskedLoad(
6244 WidenVT, dl, Ch, StackPtr, DAG.getUNDEF(
StackPtr.getValueType()), Mask,
6252 for (i = 0; i < VTNumElts; ++i)
6253 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6255 SDValue UndefVal = DAG.getPOISON(EltVT);
6256 for (; i < WidenNumElts; ++i)
6258 return DAG.getBuildVector(WidenVT, dl,
Ops);
6264 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6269SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6270 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6273 N->getOperand(1),
N->getOperand(2));
6286 if (!
LD->getMemoryVT().isByteSized()) {
6288 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6290 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6299 EVT VT =
LD->getValueType(0);
6300 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6301 EVT WideMaskVT = getSetCCResultType(WideVT);
6304 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6305 TLI.isTypeLegal(WideMaskVT)) {
6308 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6312 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6313 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6325 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6327 Result = GenWidenVectorLoads(LdChain, LD);
6334 if (LdChain.
size() == 1)
6335 NewChain = LdChain[0];
6341 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6352 SDValue NewLoad = DAG.getMaskedLoad(
6353 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6354 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6355 LD->getAddressingMode(),
LD->getExtensionType());
6365 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6367 SDValue EVL =
N->getVectorLength();
6374 "Unable to widen binary VP op");
6375 Mask = GetWidenedVector(Mask);
6376 assert(
Mask.getValueType().getVectorElementCount() ==
6377 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6378 .getVectorElementCount() &&
6379 "Unable to widen vector load");
6382 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6383 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6384 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6392 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6394 SDValue EVL =
N->getVectorLength();
6400 "Unable to widen binary VP op");
6401 Mask = GetWidenedVector(Mask);
6402 assert(
Mask.getValueType().getVectorElementCount() ==
6403 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6404 .getVectorElementCount() &&
6405 "Unable to widen vector load");
6407 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6408 Mask, EVL,
N->getMemOperand());
6421 "Unable to widen VP strided load");
6422 Mask = GetWidenedVector(Mask);
6424 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6425 assert(
Mask.getValueType().getVectorElementCount() ==
6427 "Data and mask vectors should have the same number of elements");
6429 SDValue Res = DAG.getStridedLoadVP(
6430 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6431 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6432 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6433 N->isExpandingLoad());
6441SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6446 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6448 Mask.getValueType().getVectorElementType(),
6451 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6452 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6453 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6455 WideMask, WidePassthru);
6459 EVT VT =
N->getValueType(0);
6460 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6462 EVT MaskVT =
Mask.getValueType();
6463 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6472 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6473 TLI.isTypeLegal(WideMaskVT) &&
6479 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6480 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6484 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6485 N->getMemoryVT(),
N->getMemOperand());
6489 if (!
N->getPassThru()->isUndef()) {
6492 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6503 Mask = ModifyToType(Mask, WideMaskVT,
true);
6505 SDValue Res = DAG.getMaskedLoad(
6506 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6507 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6508 ExtType,
N->isExpandingLoad());
6517 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6519 EVT MaskVT =
Mask.getValueType();
6520 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6529 Mask = ModifyToType(Mask, WideMaskVT,
true);
6534 Index.getValueType().getScalarType(),
6536 Index = ModifyToType(Index, WideIndexVT);
6542 N->getMemoryVT().getScalarType(), NumElts);
6543 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6544 WideMemVT, dl,
Ops,
N->getMemOperand(),
6545 N->getIndexType(),
N->getExtensionType());
6554 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6562 N->getMemoryVT().getScalarType(), WideEC);
6563 Mask = GetWidenedMask(Mask, WideEC);
6566 Mask,
N->getVectorLength()};
6567 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6568 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6577 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6578 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6606 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6607 return N->getOperand(OpNo).getValueType();
6615 N =
N.getOperand(0);
6617 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6618 if (!
N->getOperand(i)->isUndef())
6620 N =
N.getOperand(0);
6624 N =
N.getOperand(0);
6626 N =
N.getOperand(0);
6653 { MaskVT, MVT::Other },
Ops);
6654 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6661 LLVMContext &Ctx = *DAG.getContext();
6664 if (MaskScalarBits < ToMaskScalBits) {
6668 }
else if (MaskScalarBits > ToMaskScalBits) {
6674 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6676 "Mask should have the right element size by now.");
6679 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6681 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6684 EVT SubVT =
Mask->getValueType(0);
6690 assert((
Mask->getValueType(0) == ToMaskVT) &&
6691 "A mask of ToMaskVT should have been produced by now.");
6701 LLVMContext &Ctx = *DAG.getContext();
6712 EVT CondVT =
Cond->getValueType(0);
6716 EVT VSelVT =
N->getValueType(0);
6728 EVT FinalVT = VSelVT;
6739 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6740 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6747 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6755 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6758 EVT ToMaskVT = VSelVT;
6765 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6781 if (ScalarBits0 != ScalarBits1) {
6782 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6783 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6795 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6796 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6797 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6800 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6808 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6813 unsigned Opcode =
N->getOpcode();
6815 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6816 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6817 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6819 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6825 Cond1 = GetWidenedVector(Cond1);
6833 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6834 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6839 Cond1 = ModifyToType(Cond1, CondWidenVT);
6842 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6843 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6845 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6846 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6848 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6852 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6853 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6856 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6860 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6861 return DAG.getUNDEF(WidenVT);
6865 EVT VT =
N->getValueType(0);
6868 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6872 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6873 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6876 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6877 for (
unsigned i = 0; i != NumElts; ++i) {
6878 int Idx =
N->getMaskElt(i);
6879 if (Idx < (
int)NumElts)
6882 NewMask[i] = Idx - NumElts + WidenNumElts;
6884 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6888 EVT VT =
N->getValueType(0);
6892 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6893 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6899 unsigned IdxVal = WidenNumElts - VTNumElts;
6912 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6915 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6916 "down type's element count");
6919 for (; i < VTNumElts / GCD; ++i)
6921 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6922 for (; i < WidenNumElts / GCD; ++i)
6930 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6931 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6933 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6937SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6938 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6939 return DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, SDLoc(
N), NVT,
N->ops());
6943 assert(
N->getValueType(0).isVector() &&
6944 N->getOperand(0).getValueType().isVector() &&
6945 "Operands must be vectors");
6946 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6959 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
6960 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
6967 InOp1 = GetWidenedVector(InOp1);
6968 InOp2 = GetWidenedVector(InOp2);
6971 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
6982 "Input not widened to expected type!");
6984 if (
N->getOpcode() == ISD::VP_SETCC) {
6987 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6988 N->getOperand(2), Mask,
N->getOperand(4));
6990 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6995 assert(
N->getValueType(0).isVector() &&
6996 N->getOperand(1).getValueType().isVector() &&
6997 "Operands must be vectors");
6998 EVT VT =
N->getValueType(0);
6999 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7009 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7014 for (
unsigned i = 0; i != NumElts; ++i) {
7015 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7016 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7018 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7019 {Chain, LHSElem, RHSElem, CC});
7020 Chains[i] = Scalars[i].getValue(1);
7021 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7022 DAG.getBoolConstant(
true, dl, EltVT, VT),
7023 DAG.getBoolConstant(
false, dl, EltVT, VT));
7027 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7029 return DAG.getBuildVector(WidenVT, dl, Scalars);
7035bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7036 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7040 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7043 switch (
N->getOpcode()) {
7046 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7052 case ISD::BITCAST: Res = WidenVecOp_BITCAST(
N);
break;
7054 Res = WidenVecOp_FAKE_USE(
N);
7060 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7061 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7062 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7063 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7068 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7070 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7071 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7072 case ISD::MSCATTER: Res = WidenVecOp_MSCATTER(
N, OpNo);
break;
7073 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7074 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7084 Res = WidenVecOp_UnrollVectorOp(
N);
7091 Res = WidenVecOp_EXTEND(
N);
7096 Res = WidenVecOp_CMP(
N);
7099 case ISD::FP_EXTEND:
7112 Res = WidenVecOp_Convert(
N);
7117 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7120 case ISD::VECREDUCE_FADD:
7121 case ISD::VECREDUCE_FMUL:
7122 case ISD::VECREDUCE_ADD:
7123 case ISD::VECREDUCE_MUL:
7124 case ISD::VECREDUCE_AND:
7125 case ISD::VECREDUCE_OR:
7126 case ISD::VECREDUCE_XOR:
7127 case ISD::VECREDUCE_SMAX:
7128 case ISD::VECREDUCE_SMIN:
7129 case ISD::VECREDUCE_UMAX:
7130 case ISD::VECREDUCE_UMIN:
7131 case ISD::VECREDUCE_FMAX:
7132 case ISD::VECREDUCE_FMIN:
7133 case ISD::VECREDUCE_FMAXIMUM:
7134 case ISD::VECREDUCE_FMINIMUM:
7135 Res = WidenVecOp_VECREDUCE(
N);
7137 case ISD::VECREDUCE_SEQ_FADD:
7138 case ISD::VECREDUCE_SEQ_FMUL:
7139 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7141 case ISD::VP_REDUCE_FADD:
7142 case ISD::VP_REDUCE_SEQ_FADD:
7143 case ISD::VP_REDUCE_FMUL:
7144 case ISD::VP_REDUCE_SEQ_FMUL:
7145 case ISD::VP_REDUCE_ADD:
7146 case ISD::VP_REDUCE_MUL:
7147 case ISD::VP_REDUCE_AND:
7148 case ISD::VP_REDUCE_OR:
7149 case ISD::VP_REDUCE_XOR:
7150 case ISD::VP_REDUCE_SMAX:
7151 case ISD::VP_REDUCE_SMIN:
7152 case ISD::VP_REDUCE_UMAX:
7153 case ISD::VP_REDUCE_UMIN:
7154 case ISD::VP_REDUCE_FMAX:
7155 case ISD::VP_REDUCE_FMIN:
7156 case ISD::VP_REDUCE_FMAXIMUM:
7157 case ISD::VP_REDUCE_FMINIMUM:
7158 Res = WidenVecOp_VP_REDUCE(
N);
7160 case ISD::VP_CTTZ_ELTS:
7161 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7162 Res = WidenVecOp_VP_CttzElements(
N);
7167 if (!Res.
getNode())
return false;
7175 if (
N->isStrictFPOpcode())
7177 "Invalid operand expansion");
7180 "Invalid operand expansion");
7182 ReplaceValueWith(
SDValue(
N, 0), Res);
7188 EVT VT =
N->getValueType(0);
7193 "Unexpected type action");
7194 InOp = GetWidenedVector(InOp);
7197 "Input wasn't widened!");
7205 EVT FixedEltVT = FixedVT.getVectorElementType();
7206 if (TLI.isTypeLegal(FixedVT) &&
7208 FixedEltVT == InEltVT) {
7210 "Not enough elements in the fixed type for the operand!");
7212 "We can't have the same type as we started with!");
7214 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7216 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7225 return WidenVecOp_Convert(
N);
7230 switch (
N->getOpcode()) {
7245 EVT OpVT =
N->getOperand(0).getValueType();
7246 EVT ResVT =
N->getValueType(0);
7253 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7254 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7260 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7261 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7263 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7270 return DAG.UnrollVectorOp(
N);
7275 EVT ResultVT =
N->getValueType(0);
7277 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7280 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7286 {WideArg,
Test},
N->getFlags());
7292 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7294 EVT OpVT =
N->getOperand(0).getValueType();
7297 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7302 EVT VT =
N->getValueType(0);
7308 "Unexpected type action");
7309 InOp = GetWidenedVector(InOp);
7311 unsigned Opcode =
N->getOpcode();
7317 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7319 if (
N->isStrictFPOpcode()) {
7321 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7324 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7325 {
N->getOperand(0), InOp });
7331 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7333 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7335 return DAG.getExtractSubvector(dl, VT, Res, 0);
7343 if (
N->isStrictFPOpcode()) {
7346 for (
unsigned i=0; i < NumElts; ++i) {
7347 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7348 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7352 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7354 for (
unsigned i = 0; i < NumElts; ++i)
7355 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7356 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7359 return DAG.getBuildVector(VT, dl,
Ops);
7363 EVT DstVT =
N->getValueType(0);
7364 SDValue Src = GetWidenedVector(
N->getOperand(0));
7365 EVT SrcVT = Src.getValueType();
7372 if (TLI.isTypeLegal(WideDstVT)) {
7374 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7377 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7381 return DAG.UnrollVectorOp(
N);
7385 EVT VT =
N->getValueType(0);
7386 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7394 if (!VT.
isVector() && VT != MVT::x86mmx &&
7398 if (TLI.isTypeLegal(NewVT)) {
7399 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
7400 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7412 ElementCount NewNumElts =
7414 .divideCoefficientBy(EltSize);
7416 if (TLI.isTypeLegal(NewVT)) {
7418 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7423 return CreateStackStoreLoad(InOp, VT);
7431 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7432 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7437 EVT VT =
N->getValueType(0);
7439 EVT InVT =
N->getOperand(0).getValueType();
7444 unsigned NumOperands =
N->getNumOperands();
7445 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7447 for (i = 1; i < NumOperands; ++i)
7448 if (!
N->getOperand(i).isUndef())
7451 if (i == NumOperands)
7452 return GetWidenedVector(
N->getOperand(0));
7462 for (
unsigned i=0; i < NumOperands; ++i) {
7466 "Unexpected type action");
7467 InOp = GetWidenedVector(InOp);
7468 for (
unsigned j = 0;
j < NumInElts; ++
j)
7469 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7471 return DAG.getBuildVector(VT, dl,
Ops);
7474SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7475 EVT VT =
N->getValueType(0);
7480 SubVec = GetWidenedVector(SubVec);
7485 bool IndicesValid =
false;
7488 IndicesValid =
true;
7492 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7493 Attribute::VScaleRange);
7498 IndicesValid =
true;
7504 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7510 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7517 Align Alignment = DAG.getReducedAlign(VT,
false);
7519 MachineFunction &MF = DAG.getMachineFunction();
7532 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7540 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7541 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7546 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7551 unsigned Idx =
N->getConstantOperandVal(2);
7557 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7563SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7564 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7566 N->getValueType(0), InOp,
N->getOperand(1));
7569SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7570 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7572 N->getValueType(0), InOp,
N->getOperand(1));
7575SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7576 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7577 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7585 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7586 return TLI.scalarizeVectorStore(ST, DAG);
7588 if (
ST->isTruncatingStore())
7589 return TLI.scalarizeVectorStore(ST, DAG);
7599 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7600 EVT WideMaskVT = getSetCCResultType(WideVT);
7602 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7603 TLI.isTypeLegal(WideMaskVT)) {
7606 StVal = GetWidenedVector(StVal);
7608 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7610 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7611 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7612 ST->getAddressingMode());
7616 if (GenWidenVectorStores(StChain, ST)) {
7617 if (StChain.
size() == 1)
7626 SDValue WideStVal = GetWidenedVector(StVal);
7630 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7631 ST->getOffset(), Mask,
ST->getMemoryVT(),
7632 ST->getMemOperand(),
ST->getAddressingMode(),
7633 ST->isTruncatingStore());
7639SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7640 assert((OpNo == 1 || OpNo == 3) &&
7641 "Can widen only data or mask operand of vp_store");
7649 StVal = GetWidenedVector(StVal);
7655 "Unable to widen VP store");
7656 Mask = GetWidenedVector(Mask);
7658 Mask = GetWidenedVector(Mask);
7664 "Unable to widen VP store");
7665 StVal = GetWidenedVector(StVal);
7668 assert(
Mask.getValueType().getVectorElementCount() ==
7670 "Mask and data vectors should have the same number of elements");
7671 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7672 ST->getOffset(), Mask,
ST->getVectorLength(),
7673 ST->getMemoryVT(),
ST->getMemOperand(),
7674 ST->getAddressingMode(),
ST->isTruncatingStore(),
7675 ST->isCompressingStore());
7680 assert((OpNo == 1 || OpNo == 4) &&
7681 "Can widen only data or mask operand of vp_strided_store");
7690 "Unable to widen VP strided store");
7694 "Unable to widen VP strided store");
7696 StVal = GetWidenedVector(StVal);
7697 Mask = GetWidenedVector(Mask);
7700 Mask.getValueType().getVectorElementCount() &&
7701 "Data and mask vectors should have the same number of elements");
7703 return DAG.getStridedStoreVP(
7710SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7711 assert((OpNo == 1 || OpNo == 4) &&
7712 "Can widen only data or mask operand of mstore");
7715 EVT MaskVT =
Mask.getValueType();
7720 EVT WideVT, WideMaskVT;
7723 StVal = GetWidenedVector(StVal);
7730 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7737 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7738 TLI.isTypeLegal(WideMaskVT)) {
7739 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7740 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7749 Mask = ModifyToType(Mask, WideMaskVT,
true);
7752 Mask = ModifyToType(Mask, WideMaskVT,
true);
7754 StVal = ModifyToType(StVal, WideVT);
7757 assert(
Mask.getValueType().getVectorElementCount() ==
7759 "Mask and data vectors should have the same number of elements");
7766SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7767 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7769 SDValue DataOp = MG->getPassThru();
7771 SDValue Scale = MG->getScale();
7779 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7780 MG->getMemOperand(), MG->getIndexType(),
7781 MG->getExtensionType());
7787SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7796 DataOp = GetWidenedVector(DataOp);
7800 EVT IndexVT =
Index.getValueType();
7803 Index = ModifyToType(Index, WideIndexVT);
7806 EVT MaskVT =
Mask.getValueType();
7809 Mask = ModifyToType(Mask, WideMaskVT,
true);
7814 }
else if (OpNo == 4) {
7816 Index = GetWidenedVector(Index);
7822 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7827SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7836 DataOp = GetWidenedVector(DataOp);
7837 Index = GetWidenedVector(Index);
7839 Mask = GetWidenedMask(Mask, WideEC);
7842 }
else if (OpNo == 3) {
7844 Index = GetWidenedVector(Index);
7851 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7856 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7857 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7859 EVT VT =
N->getValueType(0);
7874 SVT, InOp0, InOp1,
N->getOperand(2));
7880 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7882 EVT OpVT =
N->getOperand(0).getValueType();
7885 return DAG.getNode(ExtendCode, dl, VT, CC);
7895 EVT VT =
N->getValueType(0);
7897 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7904 for (
unsigned i = 0; i != NumElts; ++i) {
7905 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7906 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7908 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7909 {Chain, LHSElem, RHSElem, CC});
7910 Chains[i] = Scalars[i].getValue(1);
7911 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7912 DAG.getBoolConstant(
true, dl, EltVT, VT),
7913 DAG.getBoolConstant(
false, dl, EltVT, VT));
7917 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7919 return DAG.getBuildVector(VT, dl, Scalars);
7926 case ISD::VECREDUCE_ADD:
7927 case ISD::VECREDUCE_MUL:
7928 case ISD::VECREDUCE_AND:
7929 case ISD::VECREDUCE_OR:
7930 case ISD::VECREDUCE_XOR:
7932 case ISD::VECREDUCE_SMAX:
7933 case ISD::VECREDUCE_SMIN:
7935 case ISD::VECREDUCE_UMAX:
7936 case ISD::VECREDUCE_UMIN:
7943 SDValue Op = GetWidenedVector(
N->getOperand(0));
7944 EVT VT =
N->getValueType(0);
7945 EVT OrigVT =
N->getOperand(0).getValueType();
7946 EVT WideVT =
Op.getValueType();
7948 SDNodeFlags
Flags =
N->getFlags();
7950 unsigned Opc =
N->getOpcode();
7952 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7953 assert(NeutralElem &&
"Neutral element must exist");
7963 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7970 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7971 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7977 unsigned GCD = std::gcd(OrigElts, WideElts);
7980 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
7981 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
7982 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
7983 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7986 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
7987 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
7989 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7998 EVT VT =
N->getValueType(0);
8000 EVT WideVT =
Op.getValueType();
8002 SDNodeFlags
Flags =
N->getFlags();
8004 unsigned Opc =
N->getOpcode();
8006 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8016 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8019 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8020 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8026 unsigned GCD = std::gcd(OrigElts, WideElts);
8029 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8030 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8031 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8032 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8035 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8036 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8038 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8042 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8045 SDValue Op = GetWidenedVector(
N->getOperand(1));
8047 Op.getValueType().getVectorElementCount());
8049 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8050 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8058 EVT VT =
N->getValueType(0);
8062 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8063 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8068 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8074 EVT SrcVT =
Source.getValueType();
8078 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8079 {Source, Mask, N->getOperand(2)},
N->getFlags());
8096 unsigned WidenEx = 0) {
8101 unsigned AlignInBits =
Align*8;
8103 EVT RetVT = WidenEltVT;
8108 if (Width == WidenEltWidth)
8119 (WidenWidth % MemVTWidth) == 0 &&
8121 (MemVTWidth <= Width ||
8122 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8123 if (MemVTWidth == WidenWidth)
8142 (WidenWidth % MemVTWidth) == 0 &&
8144 (MemVTWidth <= Width ||
8145 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8154 return std::nullopt;
8165 unsigned Start,
unsigned End) {
8166 SDLoc dl(LdOps[Start]);
8167 EVT LdTy = LdOps[Start].getValueType();
8175 for (
unsigned i = Start + 1; i != End; ++i) {
8176 EVT NewLdTy = LdOps[i].getValueType();
8177 if (NewLdTy != LdTy) {
8180 VecOp = DAG.
getNode(ISD::BITCAST, dl, NewVecVT, VecOp);
8187 return DAG.
getNode(ISD::BITCAST, dl, VecTy, VecOp);
8196 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8197 EVT LdVT =
LD->getMemoryVT();
8207 AAMDNodes AAInfo =
LD->getAAInfo();
8211 TypeSize WidthDiff = WidenWidth - LdWidth;
8218 std::optional<EVT> FirstVT =
8219 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8226 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8231 std::optional<EVT> NewVT = FirstVT;
8232 TypeSize RemainingWidth = LdWidth;
8233 TypeSize NewVTWidth = FirstVTWidth;
8235 RemainingWidth -= NewVTWidth;
8242 NewVTWidth = NewVT->getSizeInBits();
8248 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8249 LD->getBaseAlign(), MMOFlags, AAInfo);
8253 if (MemVTs.
empty()) {
8255 if (!FirstVT->isVector()) {
8260 return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
8262 if (FirstVT == WidenVT)
8267 unsigned NumConcat =
8270 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8271 ConcatOps[0] = LdOp;
8272 for (
unsigned i = 1; i != NumConcat; ++i)
8273 ConcatOps[i] = UndefVal;
8281 uint64_t ScaledOffset = 0;
8282 MachinePointerInfo MPI =
LD->getPointerInfo();
8288 for (EVT MemVT : MemVTs) {
8289 Align NewAlign = ScaledOffset == 0
8290 ?
LD->getBaseAlign()
8293 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8301 unsigned End = LdOps.
size();
8312 EVT LdTy = LdOps[i].getValueType();
8315 for (--i; i >= 0; --i) {
8316 LdTy = LdOps[i].getValueType();
8323 ConcatOps[--Idx] = LdOps[i];
8324 for (--i; i >= 0; --i) {
8325 EVT NewLdTy = LdOps[i].getValueType();
8326 if (NewLdTy != LdTy) {
8336 for (;
j != End-Idx; ++
j)
8337 WidenOps[j] = ConcatOps[Idx+j];
8339 WidenOps[j] = DAG.getUNDEF(LdTy);
8346 ConcatOps[--Idx] = LdOps[i];
8351 ArrayRef(&ConcatOps[Idx], End - Idx));
8357 SDValue UndefVal = DAG.getUNDEF(LdTy);
8360 for (; i != End-Idx; ++i)
8361 WidenOps[i] = ConcatOps[Idx+i];
8363 WidenOps[i] = UndefVal;
8374 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8375 EVT LdVT =
LD->getMemoryVT();
8384 AAMDNodes AAInfo =
LD->getAAInfo();
8398 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8399 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8405 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8406 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8407 LD->getBaseAlign(), MMOFlags, AAInfo);
8412 SDValue UndefVal = DAG.getUNDEF(EltVT);
8413 for (; i != WidenNumElts; ++i)
8416 return DAG.getBuildVector(WidenVT, dl,
Ops);
8427 AAMDNodes AAInfo =
ST->getAAInfo();
8428 SDValue ValOp = GetWidenedVector(
ST->getValue());
8431 EVT StVT =
ST->getMemoryVT();
8439 "Mismatch between store and value types");
8443 MachinePointerInfo MPI =
ST->getPointerInfo();
8444 uint64_t ScaledOffset = 0;
8453 std::optional<EVT> NewVT =
8458 TypeSize NewVTWidth = NewVT->getSizeInBits();
8461 StWidth -= NewVTWidth;
8462 MemVTs.
back().second++;
8466 for (
const auto &Pair : MemVTs) {
8467 EVT NewVT = Pair.first;
8468 unsigned Count = Pair.second;
8474 Align NewAlign = ScaledOffset == 0
8475 ?
ST->getBaseAlign()
8477 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8478 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8494 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8495 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8496 ST->getBaseAlign(), MMOFlags, AAInfo);
8513 bool FillWithZeroes) {
8518 "input and widen element type must match");
8520 "cannot modify scalable vectors in this way");
8532 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8535 for (
unsigned i = 1; i != NumConcat; ++i)
8542 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8545 "Scalable vectors should have been handled already.");
8553 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8555 for (Idx = 0; Idx < MinNumElts; ++Idx)
8556 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8558 SDValue UndefVal = DAG.getUNDEF(EltVT);
8559 for (; Idx < WidenNumElts; ++Idx)
8560 Ops[Idx] = UndefVal;
8562 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8563 if (!FillWithZeroes)
8567 "We expect to never want to FillWithZeroes for non-integral types.");
8570 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8571 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8573 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8574 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.
@ LOOP_DEPENDENCE_RAW_MASK
@ 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.
@ 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.
@ 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 ...
@ FADD
Simple binary floating point operators.
@ 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.
@ 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...
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ 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).
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ 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.
@ 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) ...
@ 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...
@ 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.
@ 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.
@ 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...
@ 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 ...
@ 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.
@ 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 ...
@ 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
Set rounding mode.
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.