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));
1099 {
N->getValueType(0).getVectorElementType(),
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;
1220 case ISD::EXPERIMENTAL_VP_SPLAT: SplitVecRes_VP_SPLAT(
N,
Lo,
Hi);
break;
1223 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1226 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1235 case ISD::VP_LOAD_FF:
1238 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1245 case ISD::VP_GATHER:
1249 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1253 SplitVecRes_SETCC(
N,
Lo,
Hi);
1256 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1262 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1265 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1268 SplitVecRes_VECTOR_INTERLEAVE(
N);
1271 SplitVecRes_VAARG(
N,
Lo,
Hi);
1277 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1283 case ISD::VP_BITREVERSE:
1291 case ISD::VP_CTLZ_ZERO_UNDEF:
1293 case ISD::VP_CTTZ_ZERO_UNDEF:
1296 case ISD::FABS:
case ISD::VP_FABS:
1308 case ISD::VP_FFLOOR:
1312 case ISD::FNEARBYINT:
1313 case ISD::VP_FNEARBYINT:
1314 case ISD::FNEG:
case ISD::VP_FNEG:
1316 case ISD::ARITH_FENCE:
1317 case ISD::FP_EXTEND:
1318 case ISD::VP_FP_EXTEND:
1320 case ISD::VP_FP_ROUND:
1322 case ISD::VP_FP_TO_SINT:
1324 case ISD::VP_FP_TO_UINT:
1330 case ISD::VP_LLRINT:
1332 case ISD::VP_FROUND:
1333 case ISD::FROUNDEVEN:
1334 case ISD::VP_FROUNDEVEN:
1339 case ISD::FSQRT:
case ISD::VP_SQRT:
1343 case ISD::VP_FROUNDTOZERO:
1345 case ISD::VP_SINT_TO_FP:
1347 case ISD::VP_TRUNCATE:
1349 case ISD::VP_UINT_TO_FP:
1352 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1354 case ISD::ADDRSPACECAST:
1355 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1360 case ISD::FSINCOSPI:
1361 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1367 case ISD::VP_SIGN_EXTEND:
1368 case ISD::VP_ZERO_EXTEND:
1369 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1387 case ISD::FMINNUM_IEEE:
1388 case ISD::VP_FMINNUM:
1390 case ISD::FMAXNUM_IEEE:
1391 case ISD::VP_FMAXNUM:
1393 case ISD::VP_FMINIMUM:
1395 case ISD::VP_FMAXIMUM:
1396 case ISD::FMINIMUMNUM:
1397 case ISD::FMAXIMUMNUM:
1404 case ISD::OR:
case ISD::VP_OR:
1424 case ISD::VP_FCOPYSIGN:
1425 SplitVecRes_BinOp(
N,
Lo,
Hi);
1432 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1436 SplitVecRes_CMP(
N,
Lo,
Hi);
1439#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1440 case ISD::STRICT_##DAGN:
1441#include "llvm/IR/ConstrainedOps.def"
1442 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1447 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1456 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1466 SplitVecRes_FIX(
N,
Lo,
Hi);
1468 case ISD::EXPERIMENTAL_VP_SPLICE:
1469 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1471 case ISD::EXPERIMENTAL_VP_REVERSE:
1472 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1474 case ISD::PARTIAL_REDUCE_UMLA:
1475 case ISD::PARTIAL_REDUCE_SMLA:
1476 case ISD::PARTIAL_REDUCE_SUMLA:
1477 case ISD::PARTIAL_REDUCE_FMLA:
1478 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1480 case ISD::GET_ACTIVE_LANE_MASK:
1481 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1490void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1492 uint64_t *ScaledOffset) {
1497 SDValue BytesIncrement = DAG.getVScale(
1498 DL,
Ptr.getValueType(),
1499 APInt(
Ptr.getValueSizeInBits().getFixedValue(), IncrementSize));
1500 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1502 *ScaledOffset += IncrementSize;
1512std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1513 return SplitMask(Mask, SDLoc(Mask));
1516std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1519 EVT MaskVT =
Mask.getValueType();
1521 GetSplitVector(Mask, MaskLo, MaskHi);
1523 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1524 return std::make_pair(MaskLo, MaskHi);
1529 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1531 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1534 const SDNodeFlags
Flags =
N->getFlags();
1535 unsigned Opcode =
N->getOpcode();
1536 if (
N->getNumOperands() == 2) {
1537 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1538 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1542 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1543 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1546 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1549 std::tie(EVLLo, EVLHi) =
1550 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1553 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1555 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1561 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1563 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1565 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1568 const SDNodeFlags
Flags =
N->getFlags();
1569 unsigned Opcode =
N->getOpcode();
1570 if (
N->getNumOperands() == 3) {
1571 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1572 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1576 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1577 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1580 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1583 std::tie(EVLLo, EVLHi) =
1584 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1587 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1589 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1593 LLVMContext &Ctxt = *DAG.getContext();
1599 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1601 GetSplitVector(
LHS, LHSLo, LHSHi);
1602 GetSplitVector(
RHS, RHSLo, RHSHi);
1604 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1605 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1609 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1610 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1615 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1617 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1621 unsigned Opcode =
N->getOpcode();
1622 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1624 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1633 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1640 switch (getTypeAction(InVT)) {
1655 GetExpandedOp(InOp,
Lo,
Hi);
1656 if (DAG.getDataLayout().isBigEndian())
1658 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1659 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1666 GetSplitVector(InOp,
Lo,
Hi);
1667 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1668 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1675 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1676 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, InLo);
1677 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, InHi);
1684 if (DAG.getDataLayout().isBigEndian())
1687 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1689 if (DAG.getDataLayout().isBigEndian())
1691 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1692 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1695void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1699 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1702 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
N->getOperand(2));
1707 ? DAG.getVScale(
DL, MVT::i64, APInt(64,
Offset))
1708 : DAG.getConstant(
Offset,
DL, MVT::i64);
1711 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
N->getOperand(2));
1718 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1721 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1724 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1729 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1731 unsigned NumSubvectors =
N->getNumOperands() / 2;
1732 if (NumSubvectors == 1) {
1733 Lo =
N->getOperand(0);
1734 Hi =
N->getOperand(1);
1739 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1748void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1755 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1770 GetSplitVector(Vec,
Lo,
Hi);
1773 EVT LoVT =
Lo.getValueType();
1783 if (IdxVal + SubElems <= LoElems) {
1791 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1793 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1799 SDValue WideSubVec = GetWidenedVector(SubVec);
1801 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1809 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1811 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1812 auto &MF = DAG.getMachineFunction();
1816 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1821 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1822 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1826 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1831 MachinePointerInfo MPI =
Load->getPointerInfo();
1832 IncrementPointer(Load, LoVT, MPI, StackPtr);
1835 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1844 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1849 EVT RHSVT =
RHS.getValueType();
1852 GetSplitVector(
RHS, RHSLo, RHSHi);
1854 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1869 SDValue FpValue =
N->getOperand(0);
1871 GetSplitVector(FpValue, ArgLo, ArgHi);
1873 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1875 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1884 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1888 std::tie(LoVT, HiVT) =
1892 DAG.getValueType(LoVT));
1894 DAG.getValueType(HiVT));
1899 unsigned Opcode =
N->getOpcode();
1906 GetSplitVector(N0, InLo, InHi);
1908 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1913 EVT OutLoVT, OutHiVT;
1914 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1916 assert((2 * OutNumElements) <= InNumElements &&
1917 "Illegal extend vector in reg split");
1926 SmallVector<int, 8> SplitHi(InNumElements, -1);
1927 for (
unsigned i = 0; i != OutNumElements; ++i)
1928 SplitHi[i] = i + OutNumElements;
1929 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1931 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1932 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1937 unsigned NumOps =
N->getNumOperands();
1941 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1951 for (
unsigned i = 1; i <
NumOps; ++i) {
1956 EVT InVT =
Op.getValueType();
1961 GetSplitVector(
Op, OpLo, OpHi);
1963 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
1970 EVT LoValueVTs[] = {LoVT, MVT::Other};
1971 EVT HiValueVTs[] = {HiVT, MVT::Other};
1972 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1974 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
1980 Lo.getValue(1),
Hi.getValue(1));
1984 ReplaceValueWith(
SDValue(
N, 1), Chain);
1987SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
1989 EVT VT =
N->getValueType(0);
2000 else if (NE > ResNE)
2004 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2008 for (i = 0; i !=
NE; ++i) {
2009 Operands[0] = Chain;
2010 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2011 SDValue Operand =
N->getOperand(j);
2015 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2017 Operands[
j] = Operand;
2021 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2029 for (; i < ResNE; ++i)
2034 ReplaceValueWith(
SDValue(
N, 1), Chain);
2038 return DAG.getBuildVector(VecVT, dl, Scalars);
2041void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2044 EVT ResVT =
N->getValueType(0);
2045 EVT OvVT =
N->getValueType(1);
2046 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2047 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2048 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2050 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2052 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2053 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2055 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2056 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2059 unsigned Opcode =
N->getOpcode();
2060 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2061 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2063 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2065 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2071 unsigned OtherNo = 1 - ResNo;
2072 EVT OtherVT =
N->getValueType(OtherNo);
2074 SetSplitVector(
SDValue(
N, OtherNo),
2080 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2084void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2090 GetSplitVector(Vec,
Lo,
Hi);
2093 unsigned IdxVal = CIdx->getZExtValue();
2094 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2095 if (IdxVal < LoNumElts) {
2097 Lo.getValueType(),
Lo, Elt, Idx);
2100 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2120 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2122 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2123 auto &MF = DAG.getMachineFunction();
2127 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2132 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2133 Store = DAG.getTruncStore(
2139 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2142 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2146 MachinePointerInfo MPI =
Load->getPointerInfo();
2147 IncrementPointer(Load, LoVT, MPI, StackPtr);
2149 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2152 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2153 if (LoVT !=
Lo.getValueType())
2155 if (HiVT !=
Hi.getValueType())
2163 assert(
N->getValueType(0).isScalableVector() &&
2164 "Only scalable vectors are supported for STEP_VECTOR");
2165 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2186 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2187 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2189 Hi = DAG.getUNDEF(HiVT);
2199 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2200 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
2201 auto [EVLLo, EVLHi] = DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2202 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0), MaskLo, EVLLo);
2203 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
N->getOperand(0), MaskHi, EVLHi);
2211 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2217 EVT MemoryVT =
LD->getMemoryVT();
2219 AAMDNodes AAInfo =
LD->getAAInfo();
2221 EVT LoMemVT, HiMemVT;
2222 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2226 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2227 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2228 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2233 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2236 MachinePointerInfo MPI;
2237 IncrementPointer(LD, LoMemVT, MPI,
Ptr);
2240 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2249 ReplaceValueWith(
SDValue(LD, 1), Ch);
2254 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2257 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2263 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2264 Align Alignment =
LD->getBaseAlign();
2267 EVT MemoryVT =
LD->getMemoryVT();
2269 EVT LoMemVT, HiMemVT;
2270 bool HiIsEmpty =
false;
2271 std::tie(LoMemVT, HiMemVT) =
2272 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2277 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2280 GetSplitVector(Mask, MaskLo, MaskHi);
2282 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2287 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2289 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2295 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch,
Ptr,
Offset,
2296 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2304 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo, dl, LoMemVT, DAG,
2305 LD->isExpandingLoad());
2307 MachinePointerInfo MPI;
2309 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2311 MPI =
LD->getPointerInfo().getWithOffset(
2314 MMO = DAG.getMachineFunction().getMachineMemOperand(
2316 Alignment,
LD->getAAInfo(),
LD->getRanges());
2318 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch,
Ptr,
2319 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2320 LD->isExpandingLoad());
2330 ReplaceValueWith(
SDValue(LD, 1), Ch);
2336 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2340 Align Alignment =
LD->getBaseAlign();
2347 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2350 GetSplitVector(Mask, MaskLo, MaskHi);
2352 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2356 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2358 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2363 Lo = DAG.getLoadFFVP(LoVT, dl, Ch,
Ptr, MaskLo, EVLLo, MMO);
2366 Hi = DAG.getUNDEF(HiVT);
2368 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2369 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2375 "Indexed VP strided load during type legalization!");
2377 "Unexpected indexed variable-length load offset");
2382 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2384 EVT LoMemVT, HiMemVT;
2385 bool HiIsEmpty =
false;
2386 std::tie(LoMemVT, HiMemVT) =
2387 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2392 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2395 GetSplitVector(Mask, LoMask, HiMask);
2397 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2401 std::tie(LoEVL, HiEVL) =
2405 Lo = DAG.getStridedLoadVP(
2432 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2439 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2450 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2458 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2463 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2472 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2475 GetSplitVector(Mask, MaskLo, MaskHi);
2477 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2481 EVT LoMemVT, HiMemVT;
2482 bool HiIsEmpty =
false;
2483 std::tie(LoMemVT, HiMemVT) =
2484 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2486 SDValue PassThruLo, PassThruHi;
2488 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2490 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2492 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2497 Lo = DAG.getMaskedLoad(LoVT, dl, Ch,
Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2507 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo, dl, LoMemVT, DAG,
2510 MachinePointerInfo MPI;
2517 MMO = DAG.getMachineFunction().getMachineMemOperand(
2521 Hi = DAG.getMaskedLoad(HiVT, dl, Ch,
Ptr,
Offset, MaskHi, PassThruHi,
2533 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2541 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2549 }
Ops = [&]() -> Operands {
2551 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2554 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2557 EVT MemoryVT =
N->getMemoryVT();
2558 Align Alignment =
N->getBaseAlign();
2563 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2565 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2568 EVT LoMemVT, HiMemVT;
2570 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2573 if (getTypeAction(
Ops.Index.getValueType()) ==
2575 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2577 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2580 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2582 Alignment,
N->getAAInfo(),
N->getRanges());
2585 SDValue PassThru = MGT->getPassThru();
2586 SDValue PassThruLo, PassThruHi;
2589 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2591 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2596 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo,
Ptr, IndexLo,
Ops.Scale};
2597 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2598 OpsLo, MMO, IndexTy, ExtType);
2600 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi,
Ptr, IndexHi,
Ops.Scale};
2601 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2602 OpsHi, MMO, IndexTy, ExtType);
2606 std::tie(EVLLo, EVLHi) =
2607 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2609 SDValue OpsLo[] = {Ch,
Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2610 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2611 MMO, VPGT->getIndexType());
2613 SDValue OpsHi[] = {Ch,
Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2614 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2615 MMO, VPGT->getIndexType());
2625 ReplaceValueWith(
SDValue(
N, 1), Ch);
2639 EVT VecVT =
N->getValueType(0);
2641 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2642 bool HasCustomLowering =
false;
2649 HasCustomLowering =
true;
2655 SDValue Passthru =
N->getOperand(2);
2656 if (!HasCustomLowering) {
2657 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2658 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2665 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2666 std::tie(LoMask, HiMask) = SplitMask(Mask);
2668 SDValue UndefPassthru = DAG.getUNDEF(LoVT);
2673 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2674 MachineFunction &MF = DAG.getMachineFunction();
2681 SDValue Offset = DAG.getNode(ISD::VECREDUCE_ADD,
DL, MVT::i32, WideMask);
2682 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2684 SDValue Chain = DAG.getEntryNode();
2685 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2689 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2694 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2698 assert(
N->getValueType(0).isVector() &&
2699 N->getOperand(0).getValueType().isVector() &&
2700 "Operand types must be vectors");
2704 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2708 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2710 GetSplitVector(
N->getOperand(0), LL, LH);
2712 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2714 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2716 GetSplitVector(
N->getOperand(1), RL, RH);
2718 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2721 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2722 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2724 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2725 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2726 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2727 std::tie(EVLLo, EVLHi) =
2728 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2729 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2731 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2741 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2745 EVT InVT =
N->getOperand(0).getValueType();
2747 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2749 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2751 const SDNodeFlags
Flags =
N->getFlags();
2752 unsigned Opcode =
N->getOpcode();
2753 if (
N->getNumOperands() <= 2) {
2755 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2756 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2758 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2759 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2764 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2765 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2768 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2771 std::tie(EVLLo, EVLHi) =
2772 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2775 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2781 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2785 EVT InVT =
N->getOperand(0).getValueType();
2787 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2789 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2792 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2793 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2794 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2795 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2798void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2803 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2804 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2808 EVT InVT =
N->getOperand(0).getValueType();
2810 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2812 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2814 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2815 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2817 SDNode *HiNode =
Hi.getNode();
2818 SDNode *LoNode =
Lo.getNode();
2821 unsigned OtherNo = 1 - ResNo;
2822 EVT OtherVT =
N->getValueType(OtherNo);
2830 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2837 EVT SrcVT =
N->getOperand(0).getValueType();
2838 EVT DestVT =
N->getValueType(0);
2840 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2857 LLVMContext &Ctx = *DAG.getContext();
2861 EVT SplitLoVT, SplitHiVT;
2862 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2863 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2864 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2865 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2866 N->dump(&DAG);
dbgs() <<
"\n");
2867 if (!
N->isVPOpcode()) {
2870 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2872 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2874 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2875 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2881 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2882 N->getOperand(1),
N->getOperand(2));
2884 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2887 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2890 std::tie(EVLLo, EVLHi) =
2891 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2893 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2894 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2899 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2907 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2908 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2914 return N.getResNo() == 0 &&
2918 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2920 ArrayRef<int>
Mask) {
2923 "Expected build vector node.");
2926 for (
unsigned I = 0;
I < NewElts; ++
I) {
2929 unsigned Idx =
Mask[
I];
2931 Ops[
I] = Input2.getOperand(Idx - NewElts);
2933 Ops[
I] = Input1.getOperand(Idx);
2938 return DAG.getBuildVector(NewVT,
DL,
Ops);
2944 SmallVector<int> OrigMask(
N->getMask());
2946 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2947 &
DL](SmallVectorImpl<int> &
Mask) {
2949 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2950 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2961 for (
auto &
P : ShufflesIdxs) {
2962 if (
P.second.size() < 2)
2966 for (
int &Idx : Mask) {
2969 unsigned SrcRegIdx = Idx / NewElts;
2970 if (Inputs[SrcRegIdx].
isUndef()) {
2978 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2983 Idx = MaskElt % NewElts +
2984 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
2990 Inputs[
P.second[0]] =
P.first.first;
2991 Inputs[
P.second[1]] =
P.first.second;
2994 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
2997 SmallBitVector UsedSubVector(2 * std::size(Inputs));
2998 for (
int &Idx : Mask) {
3001 unsigned SrcRegIdx = Idx / NewElts;
3002 if (Inputs[SrcRegIdx].
isUndef()) {
3009 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3010 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3013 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3015 if (UsedSubVector.count() > 1) {
3017 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3018 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3020 if (Pairs.
empty() || Pairs.
back().size() == 2)
3022 if (UsedSubVector.test(2 *
I)) {
3023 Pairs.
back().emplace_back(
I, 0);
3025 assert(UsedSubVector.test(2 *
I + 1) &&
3026 "Expected to be used one of the subvectors.");
3027 Pairs.
back().emplace_back(
I, 1);
3030 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3032 for (
int &Idx : Mask) {
3035 unsigned SrcRegIdx = Idx / NewElts;
3037 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3038 return Idxs.front().first == SrcRegIdx ||
3039 Idxs.back().first == SrcRegIdx;
3041 if (It == Pairs.
end())
3043 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3044 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3047 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3048 Inputs[Idxs.front().first] = DAG.
getNode(
3050 Inputs[Idxs.front().first].getValueType(),
3051 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3052 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3061 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3065 if (Shuffle->getOperand(0).getValueType() != NewVT)
3068 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3069 !Shuffle->isSplat()) {
3071 }
else if (!Inputs[
I].hasOneUse() &&
3072 !Shuffle->getOperand(1).isUndef()) {
3074 for (
int &Idx : Mask) {
3077 unsigned SrcRegIdx = Idx / NewElts;
3080 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3085 int OpIdx = MaskElt / NewElts;
3099 if (Shuffle->getOperand(
OpIdx).isUndef())
3101 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3102 if (It == std::end(Inputs))
3104 int FoundOp = std::distance(std::begin(Inputs), It);
3107 for (
int &Idx : Mask) {
3110 unsigned SrcRegIdx = Idx / NewElts;
3113 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3118 int MaskIdx = MaskElt / NewElts;
3119 if (
OpIdx == MaskIdx)
3120 Idx = MaskElt % NewElts + FoundOp * NewElts;
3131 for (
int &Idx : Mask) {
3134 unsigned SrcRegIdx = Idx / NewElts;
3137 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3138 int OpIdx = MaskElt / NewElts;
3141 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3147 TryPeekThroughShufflesInputs(OrigMask);
3149 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3150 NewElts](SmallVectorImpl<int> &
Mask) {
3151 SetVector<SDValue> UniqueInputs;
3152 SetVector<SDValue> UniqueConstantInputs;
3153 for (
const auto &
I : Inputs) {
3155 UniqueConstantInputs.
insert(
I);
3156 else if (!
I.isUndef())
3161 if (UniqueInputs.
size() != std::size(Inputs)) {
3162 auto &&UniqueVec = UniqueInputs.
takeVector();
3163 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3164 unsigned ConstNum = UniqueConstantVec.size();
3165 for (
int &Idx : Mask) {
3168 unsigned SrcRegIdx = Idx / NewElts;
3169 if (Inputs[SrcRegIdx].
isUndef()) {
3173 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3174 if (It != UniqueConstantVec.end()) {
3175 Idx = (Idx % NewElts) +
3176 NewElts * std::distance(UniqueConstantVec.begin(), It);
3177 assert(Idx >= 0 &&
"Expected defined mask idx.");
3180 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3181 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3182 Idx = (Idx % NewElts) +
3183 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3184 assert(Idx >= 0 &&
"Expected defined mask idx.");
3186 copy(UniqueConstantVec, std::begin(Inputs));
3187 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3190 MakeUniqueInputs(OrigMask);
3192 copy(Inputs, std::begin(OrigInputs));
3198 unsigned FirstMaskIdx =
High * NewElts;
3201 assert(!Output &&
"Expected default initialized initial value.");
3202 TryPeekThroughShufflesInputs(Mask);
3203 MakeUniqueInputs(Mask);
3205 copy(Inputs, std::begin(TmpInputs));
3208 bool SecondIteration =
false;
3209 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3214 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3215 SecondIteration =
true;
3216 return SecondIteration;
3219 Mask, std::size(Inputs), std::size(Inputs),
3221 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3222 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3223 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3225 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3227 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3228 DAG.getUNDEF(NewVT), Mask);
3229 Inputs[Idx] = Output;
3231 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3232 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3233 unsigned Idx2,
bool ) {
3234 if (AccumulateResults(Idx1)) {
3237 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3239 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3240 Inputs[Idx2], Mask);
3244 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3246 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3247 TmpInputs[Idx2], Mask);
3249 Inputs[Idx1] = Output;
3251 copy(OrigInputs, std::begin(Inputs));
3256 EVT OVT =
N->getValueType(0);
3263 const Align Alignment =
3264 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3266 Lo = DAG.getVAArg(NVT, dl, Chain,
Ptr, SV, Alignment.
value());
3267 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1),
Ptr, SV, Alignment.
value());
3272 ReplaceValueWith(
SDValue(
N, 1), Chain);
3277 EVT DstVTLo, DstVTHi;
3278 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3282 EVT SrcVT =
N->getOperand(0).getValueType();
3284 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3286 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3288 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3289 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3295 GetSplitVector(
N->getOperand(0), InLo, InHi);
3306 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3307 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3312 EVT VT =
N->getValueType(0);
3319 Align Alignment = DAG.getReducedAlign(VT,
false);
3324 EVT PtrVT =
StackPtr.getValueType();
3325 auto &MF = DAG.getMachineFunction();
3329 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3332 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3338 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3339 DAG.getConstant(1,
DL, PtrVT));
3341 DAG.getConstant(EltWidth,
DL, PtrVT));
3343 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3345 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3346 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3347 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3350 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3352 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3357 EVT VT =
N->getValueType(0);
3369 EVL1 = ZExtPromotedInteger(EVL1);
3371 Align Alignment = DAG.getReducedAlign(VT,
false);
3376 EVT PtrVT =
StackPtr.getValueType();
3377 auto &MF = DAG.getMachineFunction();
3381 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3384 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3388 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3390 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3391 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3392 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3396 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3401 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3402 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3404 uint64_t TrailingElts = -
Imm;
3406 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3415 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3419 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3421 DAG.getVectorIdxConstant(0,
DL));
3427void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3435 GetSplitVector(Acc, AccLo, AccHi);
3436 unsigned Opcode =
N->getOpcode();
3448 GetSplitVector(Input1, Input1Lo, Input1Hi);
3449 GetSplitVector(Input2, Input2Lo, Input2Hi);
3452 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3453 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3456void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3464 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3466 Lo = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, LoVT, Op0, Op1);
3469 Hi = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, HiVT, HiStartVal, Op1);
3472void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3473 unsigned Factor =
N->getNumOperands();
3476 for (
unsigned i = 0; i != Factor; ++i) {
3478 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3480 Ops[i * 2 + 1] = OpHi;
3491 for (
unsigned i = 0; i != Factor; ++i)
3495void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3496 unsigned Factor =
N->getNumOperands();
3499 for (
unsigned i = 0; i != Factor; ++i) {
3501 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3503 Ops[i + Factor] = OpHi;
3514 for (
unsigned i = 0; i != Factor; ++i) {
3515 unsigned IdxLo = 2 * i;
3516 unsigned IdxHi = 2 * i + 1;
3517 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3518 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3530bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3535 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3538 switch (
N->getOpcode()) {
3541 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3551 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3552 case ISD::BITCAST: Res = SplitVecOp_BITCAST(
N);
break;
3557 case ISD::VP_TRUNCATE:
3559 Res = SplitVecOp_TruncateHelper(
N);
3562 case ISD::VP_FP_ROUND:
3571 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3578 case ISD::VP_SCATTER:
3582 case ISD::VP_GATHER:
3586 Res = SplitVecOp_VSELECT(
N, OpNo);
3589 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3595 case ISD::VP_SINT_TO_FP:
3596 case ISD::VP_UINT_TO_FP:
3597 if (
N->getValueType(0).bitsLT(
3598 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3599 Res = SplitVecOp_TruncateHelper(
N);
3601 Res = SplitVecOp_UnaryOp(
N);
3605 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3609 case ISD::VP_FP_TO_SINT:
3610 case ISD::VP_FP_TO_UINT:
3614 case ISD::FP_EXTEND:
3623 Res = SplitVecOp_UnaryOp(
N);
3626 Res = SplitVecOp_FPOpDifferentTypes(
N);
3631 Res = SplitVecOp_CMP(
N);
3635 Res = SplitVecOp_FAKE_USE(
N);
3640 Res = SplitVecOp_ExtVecInRegOp(
N);
3643 case ISD::VECREDUCE_FADD:
3644 case ISD::VECREDUCE_FMUL:
3645 case ISD::VECREDUCE_ADD:
3646 case ISD::VECREDUCE_MUL:
3647 case ISD::VECREDUCE_AND:
3648 case ISD::VECREDUCE_OR:
3649 case ISD::VECREDUCE_XOR:
3650 case ISD::VECREDUCE_SMAX:
3651 case ISD::VECREDUCE_SMIN:
3652 case ISD::VECREDUCE_UMAX:
3653 case ISD::VECREDUCE_UMIN:
3654 case ISD::VECREDUCE_FMAX:
3655 case ISD::VECREDUCE_FMIN:
3656 case ISD::VECREDUCE_FMAXIMUM:
3657 case ISD::VECREDUCE_FMINIMUM:
3658 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3660 case ISD::VECREDUCE_SEQ_FADD:
3661 case ISD::VECREDUCE_SEQ_FMUL:
3662 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3664 case ISD::VP_REDUCE_FADD:
3665 case ISD::VP_REDUCE_SEQ_FADD:
3666 case ISD::VP_REDUCE_FMUL:
3667 case ISD::VP_REDUCE_SEQ_FMUL:
3668 case ISD::VP_REDUCE_ADD:
3669 case ISD::VP_REDUCE_MUL:
3670 case ISD::VP_REDUCE_AND:
3671 case ISD::VP_REDUCE_OR:
3672 case ISD::VP_REDUCE_XOR:
3673 case ISD::VP_REDUCE_SMAX:
3674 case ISD::VP_REDUCE_SMIN:
3675 case ISD::VP_REDUCE_UMAX:
3676 case ISD::VP_REDUCE_UMIN:
3677 case ISD::VP_REDUCE_FMAX:
3678 case ISD::VP_REDUCE_FMIN:
3679 case ISD::VP_REDUCE_FMAXIMUM:
3680 case ISD::VP_REDUCE_FMINIMUM:
3681 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3683 case ISD::VP_CTTZ_ELTS:
3684 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3685 Res = SplitVecOp_VP_CttzElements(
N);
3687 case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
3688 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3690 case ISD::PARTIAL_REDUCE_UMLA:
3691 case ISD::PARTIAL_REDUCE_SMLA:
3692 case ISD::PARTIAL_REDUCE_SUMLA:
3693 case ISD::PARTIAL_REDUCE_FMLA:
3694 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3699 if (!Res.
getNode())
return false;
3706 if (
N->isStrictFPOpcode())
3708 "Invalid operand expansion");
3711 "Invalid operand expansion");
3713 ReplaceValueWith(
SDValue(
N, 0), Res);
3717SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3720 assert(OpNo == 0 &&
"Illegal operand must be mask");
3727 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3730 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3731 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3732 "Lo and Hi have differing types");
3735 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3736 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3738 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3739 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3740 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3741 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3751SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3754 assert(OpNo == 1 &&
"Illegal operand must be mask");
3759 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3761 EVT VecVT =
N->getValueType(0);
3765SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3766 EVT ResVT =
N->getValueType(0);
3772 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3773 GetSplitVector(VecOp,
Lo,
Hi);
3775 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3780 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3781 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3785 EVT ResVT =
N->getValueType(0);
3791 SDNodeFlags
Flags =
N->getFlags();
3794 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3795 GetSplitVector(VecOp,
Lo,
Hi);
3797 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3803 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3806SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3807 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3808 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3810 unsigned Opc =
N->getOpcode();
3811 EVT ResVT =
N->getValueType(0);
3817 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3818 GetSplitVector(VecOp,
Lo,
Hi);
3821 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3824 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3826 const SDNodeFlags
Flags =
N->getFlags();
3830 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3835 EVT ResVT =
N->getValueType(0);
3838 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3839 EVT InVT =
Lo.getValueType();
3844 if (
N->isStrictFPOpcode()) {
3845 Lo = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3846 { N->getOperand(0), Lo });
3847 Hi = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3848 { N->getOperand(0), Hi });
3857 ReplaceValueWith(
SDValue(
N, 1), Ch);
3858 }
else if (
N->getNumOperands() == 3) {
3859 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3860 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3861 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3862 std::tie(EVLLo, EVLHi) =
3863 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3864 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3865 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3867 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3868 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3877 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3879 DAG.
getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
Lo);
3880 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other, Chain,
Hi);
3887 EVT ResVT =
N->getValueType(0);
3889 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3893 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3894 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
3895 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
3899 Lo = BitConvertToInteger(
Lo);
3900 Hi = BitConvertToInteger(
Hi);
3902 if (DAG.getDataLayout().isBigEndian())
3905 return DAG.getNode(ISD::BITCAST, dl, ResVT, JoinIntegers(
Lo,
Hi));
3910 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3912 EVT ResVT =
N->getValueType(0);
3920 GetSplitVector(SubVec,
Lo,
Hi);
3929 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3931 return SecondInsertion;
3934SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3941 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3943 uint64_t LoEltsMin =
Lo.getValueType().getVectorMinNumElements();
3948 if (IdxVal < LoEltsMin) {
3950 if (IdxVal + NumResultElts <= LoEltsMin)
3959 DAG.ExtractVectorElements(
Lo, Elts, IdxVal,
3960 LoEltsMin - IdxVal);
3961 DAG.ExtractVectorElements(
Hi, Elts, 0,
3964 return DAG.getBuildVector(SubVT, dl, Elts);
3967 EVT SrcVT =
N->getOperand(0).getValueType();
3969 uint64_t ExtractIdx = IdxVal - LoEltsMin;
3970 if (ExtractIdx % NumResultElts == 0)
3971 return DAG.getExtractSubvector(dl, SubVT,
Hi, ExtractIdx);
3976 EVT HiVT =
Hi.getValueType();
3978 for (
int I = 0;
I !=
static_cast<int>(NumResultElts); ++
I)
3979 Mask[
I] = ExtractIdx +
I;
3982 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
3983 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
3989 "Extracting scalable subvector from fixed-width unsupported");
3997 "subvector from a scalable predicate vector");
4003 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4005 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4006 auto &MF = DAG.getMachineFunction();
4010 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4014 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4017 SubVT, dl, Store, StackPtr,
4021SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4027 uint64_t IdxVal =
Index->getZExtValue();
4030 GetSplitVector(Vec,
Lo,
Hi);
4032 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4034 if (IdxVal < LoElts)
4035 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4038 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4043 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4055 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4061 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4063 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4064 auto &MF = DAG.getMachineFunction();
4067 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4071 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4075 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4077 return DAG.getExtLoad(
4088 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4096 SplitVecRes_Gather(
N,
Lo,
Hi);
4099 ReplaceValueWith(
SDValue(
N, 0), Res);
4104 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4108 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4110 SDValue EVL =
N->getVectorLength();
4112 Align Alignment =
N->getBaseAlign();
4118 GetSplitVector(
Data, DataLo, DataHi);
4120 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4125 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4128 GetSplitVector(Mask, MaskLo, MaskHi);
4130 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4133 EVT MemoryVT =
N->getMemoryVT();
4134 EVT LoMemVT, HiMemVT;
4135 bool HiIsEmpty =
false;
4136 std::tie(LoMemVT, HiMemVT) =
4137 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4141 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4144 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4149 Lo = DAG.getStoreVP(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4150 N->getAddressingMode(),
N->isTruncatingStore(),
4151 N->isCompressingStore());
4157 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo,
DL, LoMemVT, DAG,
4158 N->isCompressingStore());
4160 MachinePointerInfo MPI;
4164 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4169 MMO = DAG.getMachineFunction().getMachineMemOperand(
4171 Alignment,
N->getAAInfo(),
N->getRanges());
4173 Hi = DAG.getStoreVP(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4174 N->getAddressingMode(),
N->isTruncatingStore(),
4175 N->isCompressingStore());
4184 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4185 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4192 GetSplitVector(
Data, LoData, HiData);
4194 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4196 EVT LoMemVT, HiMemVT;
4197 bool HiIsEmpty =
false;
4198 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4204 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4205 else if (getTypeAction(
Mask.getValueType()) ==
4207 GetSplitVector(Mask, LoMask, HiMask);
4209 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4212 std::tie(LoEVL, HiEVL) =
4213 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4217 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4218 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4219 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4230 EVT PtrVT =
N->getBasePtr().getValueType();
4233 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4236 Align Alignment =
N->getBaseAlign();
4241 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4242 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4244 Alignment,
N->getAAInfo(),
N->getRanges());
4247 N->getChain(),
DL, HiData,
Ptr,
N->getOffset(),
N->getStride(), HiMask,
4248 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4249 N->isCompressingStore());
4258 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4262 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4265 Align Alignment =
N->getBaseAlign();
4271 GetSplitVector(
Data, DataLo, DataHi);
4273 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4278 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4281 GetSplitVector(Mask, MaskLo, MaskHi);
4283 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4286 EVT MemoryVT =
N->getMemoryVT();
4287 EVT LoMemVT, HiMemVT;
4288 bool HiIsEmpty =
false;
4289 std::tie(LoMemVT, HiMemVT) =
4290 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4293 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4298 Lo = DAG.getMaskedStore(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, LoMemVT, MMO,
4299 N->getAddressingMode(),
N->isTruncatingStore(),
4300 N->isCompressingStore());
4308 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo,
DL, LoMemVT, DAG,
4309 N->isCompressingStore());
4311 MachinePointerInfo MPI;
4315 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4320 MMO = DAG.getMachineFunction().getMachineMemOperand(
4322 Alignment,
N->getAAInfo(),
N->getRanges());
4324 Hi = DAG.getMaskedStore(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, HiMemVT, MMO,
4325 N->getAddressingMode(),
N->isTruncatingStore(),
4326 N->isCompressingStore());
4339 EVT MemoryVT =
N->getMemoryVT();
4340 Align Alignment =
N->getBaseAlign();
4347 }
Ops = [&]() -> Operands {
4349 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4353 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4358 EVT LoMemVT, HiMemVT;
4359 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4364 GetSplitVector(
Ops.Data, DataLo, DataHi);
4366 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4371 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4373 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4377 if (getTypeAction(
Ops.Index.getValueType()) ==
4379 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4381 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4385 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4387 Alignment,
N->getAAInfo(),
N->getRanges());
4390 SDValue OpsLo[] = {Ch, DataLo, MaskLo,
Ptr, IndexLo,
Ops.Scale};
4392 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4393 MSC->getIndexType(), MSC->isTruncatingStore());
4399 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4400 MMO, MSC->getIndexType(),
4401 MSC->isTruncatingStore());
4405 std::tie(EVLLo, EVLHi) =
4406 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4408 SDValue OpsLo[] = {Ch, DataLo,
Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4409 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4410 VPSC->getIndexType());
4415 SDValue OpsHi[] = {
Lo, DataHi,
Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4416 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4417 VPSC->getIndexType());
4421 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4422 assert(OpNo == 1 &&
"Can only split the stored value");
4425 bool isTruncating =
N->isTruncatingStore();
4428 EVT MemoryVT =
N->getMemoryVT();
4429 Align Alignment =
N->getBaseAlign();
4431 AAMDNodes AAInfo =
N->getAAInfo();
4433 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4435 EVT LoMemVT, HiMemVT;
4436 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4440 return TLI.scalarizeVectorStore(
N, DAG);
4443 Lo = DAG.getTruncStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), LoMemVT,
4444 Alignment, MMOFlags, AAInfo);
4446 Lo = DAG.getStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4449 MachinePointerInfo MPI;
4450 IncrementPointer(
N, LoMemVT, MPI,
Ptr);
4453 Hi = DAG.getTruncStore(Ch,
DL,
Hi,
Ptr, MPI,
4454 HiMemVT, Alignment, MMOFlags, AAInfo);
4456 Hi = DAG.getStore(Ch,
DL,
Hi,
Ptr, MPI, Alignment, MMOFlags, AAInfo);
4472 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4478 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4499 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4500 SDValue InVec =
N->getOperand(OpNo);
4502 EVT OutVT =
N->getValueType(0);
4510 EVT LoOutVT, HiOutVT;
4511 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4512 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4517 if (isTypeLegal(LoOutVT) ||
4518 InElementSize <= OutElementSize * 2)
4519 return SplitVecOp_UnaryOp(
N);
4528 return SplitVecOp_UnaryOp(
N);
4532 GetSplitVector(InVec, InLoVec, InHiVec);
4538 EVT HalfElementVT = IsFloat ?
4540 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4547 if (
N->isStrictFPOpcode()) {
4548 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4549 {N->getOperand(0), InLoVec});
4550 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4551 {N->getOperand(0), InHiVec});
4557 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4558 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4562 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4570 if (
N->isStrictFPOpcode()) {
4574 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4582 DAG.getTargetConstant(
4583 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4590 assert(
N->getValueType(0).isVector() &&
4591 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4592 "Operand types must be vectors");
4594 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4596 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4597 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4599 EVT VT =
N->getValueType(0);
4605 }
else if (isStrict) {
4606 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4607 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4608 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4609 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4612 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4614 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4615 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4616 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4617 std::tie(EVLLo, EVLHi) =
4618 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4619 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4620 N->getOperand(2), MaskLo, EVLLo);
4621 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4622 N->getOperand(2), MaskHi, EVLHi);
4631 EVT ResVT =
N->getValueType(0);
4634 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4635 EVT InVT =
Lo.getValueType();
4640 if (
N->isStrictFPOpcode()) {
4641 Lo = DAG.getNode(
N->getOpcode(),
DL, { OutVT, MVT::Other },
4642 { N->getOperand(0), Lo, N->getOperand(2) });
4643 Hi = DAG.getNode(
N->getOpcode(),
DL, { OutVT, MVT::Other },
4644 { N->getOperand(0), Hi, N->getOperand(2) });
4648 Lo.getValue(1),
Hi.getValue(1));
4649 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4650 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4651 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4652 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4653 std::tie(EVLLo, EVLHi) =
4654 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4655 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4656 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4670SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4673 EVT LHSLoVT, LHSHiVT;
4674 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4676 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4677 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4680 std::tie(LHSLo, LHSHi) =
4681 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4684 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4687 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4693 LLVMContext &Ctxt = *DAG.getContext();
4696 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4697 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4698 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4700 EVT ResVT =
N->getValueType(0);
4705 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4706 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4712 EVT ResVT =
N->getValueType(0);
4715 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4716 EVT InVT =
Lo.getValueType();
4722 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4723 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4730 EVT ResVT =
N->getValueType(0);
4734 GetSplitVector(VecOp,
Lo,
Hi);
4736 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4737 auto [EVLLo, EVLHi] =
4739 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4745 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4747 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4748 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4751SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4762 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4763 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4764 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4766 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4767 OpsLo, MMO, IndexType);
4768 SDValue OpsHi[] = {
Lo, Inc, MaskHi,
Ptr, IndexHi, Scale, IntID};
4769 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4773SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4776 "Accumulator should already be a legal type, and shouldn't need "
4777 "further splitting");
4780 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4781 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4782 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4783 unsigned Opcode =
N->getOpcode();
4786 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4787 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4794void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4795 unsigned WidenResNo) {
4796 unsigned NumResults =
N->getNumValues();
4797 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4798 if (ResNo == WidenResNo)
4800 EVT ResVT =
N->getValueType(ResNo);
4806 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4807 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4812void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4813 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4816 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4821 auto unrollExpandedOp = [&]() {
4826 EVT VT =
N->getValueType(0);
4827 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4828 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4831 if (
N->getNumValues() > 1)
4832 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4838 switch (
N->getOpcode()) {
4841 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4849 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4852 case ISD::ADDRSPACECAST:
4853 Res = WidenVecRes_ADDRSPACECAST(
N);
4856 case ISD::BITCAST: Res = WidenVecRes_BITCAST(
N);
break;
4860 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4864 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4868 case ISD::EXPERIMENTAL_VP_SPLAT:
4869 Res = WidenVecRes_ScalarOp(
N);
4874 case ISD::VP_SELECT:
4876 Res = WidenVecRes_Select(
N);
4880 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4882 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4889 case ISD::VP_LOAD_FF:
4892 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4896 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4904 case ISD::VP_GATHER:
4908 Res = WidenVecRes_VECTOR_REVERSE(
N);
4910 case ISD::GET_ACTIVE_LANE_MASK:
4911 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4921 case ISD::OR:
case ISD::VP_OR:
4928 case ISD::FMINNUM_IEEE:
4929 case ISD::VP_FMINNUM:
4931 case ISD::FMAXNUM_IEEE:
4932 case ISD::VP_FMAXNUM:
4934 case ISD::VP_FMINIMUM:
4936 case ISD::VP_FMAXIMUM:
4937 case ISD::FMINIMUMNUM:
4938 case ISD::FMAXIMUMNUM:
4969 case ISD::VP_FCOPYSIGN:
4970 Res = WidenVecRes_Binary(
N);
4975 Res = WidenVecRes_CMP(
N);
4981 if (unrollExpandedOp())
4996 Res = WidenVecRes_BinaryCanTrap(
N);
5005 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5008#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5009 case ISD::STRICT_##DAGN:
5010#include "llvm/IR/ConstrainedOps.def"
5011 Res = WidenVecRes_StrictFP(
N);
5020 Res = WidenVecRes_OverflowOp(
N, ResNo);
5024 Res = WidenVecRes_FCOPYSIGN(
N);
5029 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5034 if (!unrollExpandedOp())
5035 Res = WidenVecRes_ExpOp(
N);
5041 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5045 case ISD::FP_EXTEND:
5046 case ISD::VP_FP_EXTEND:
5048 case ISD::VP_FP_ROUND:
5050 case ISD::VP_FP_TO_SINT:
5052 case ISD::VP_FP_TO_UINT:
5054 case ISD::VP_SIGN_EXTEND:
5056 case ISD::VP_SINT_TO_FP:
5057 case ISD::VP_TRUNCATE:
5060 case ISD::VP_UINT_TO_FP:
5062 case ISD::VP_ZERO_EXTEND:
5063 Res = WidenVecRes_Convert(
N);
5068 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5074 case ISD::VP_LLRINT:
5077 Res = WidenVecRes_XROUND(
N);
5093 case ISD::FNEARBYINT:
5096 case ISD::FROUNDEVEN:
5103 if (unrollExpandedOp())
5113 case ISD::VP_BITREVERSE:
5119 case ISD::VP_CTLZ_ZERO_UNDEF:
5125 case ISD::VP_CTTZ_ZERO_UNDEF:
5126 case ISD::FNEG:
case ISD::VP_FNEG:
5127 case ISD::FABS:
case ISD::VP_FABS:
5130 case ISD::VP_FFLOOR:
5132 case ISD::VP_FNEARBYINT:
5133 case ISD::VP_FROUND:
5134 case ISD::VP_FROUNDEVEN:
5135 case ISD::VP_FROUNDTOZERO:
5137 case ISD::ARITH_FENCE:
5140 Res = WidenVecRes_Unary(
N);
5147 Res = WidenVecRes_Ternary(
N);
5152 case ISD::FSINCOSPI: {
5153 if (!unrollExpandedOp())
5154 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5161 SetWidenedVector(
SDValue(
N, ResNo), Res);
5167 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5168 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5169 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5170 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5171 if (
N->getNumOperands() == 3)
5172 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5174 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5175 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5179 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5180 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5186 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5187 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5188 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5189 if (
N->getNumOperands() == 2)
5190 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5193 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5194 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5198 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5199 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5203 LLVMContext &Ctxt = *DAG.getContext();
5208 EVT OpVT =
LHS.getValueType();
5210 LHS = GetWidenedVector(
LHS);
5211 RHS = GetWidenedVector(
RHS);
5212 OpVT =
LHS.getValueType();
5215 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5218 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5224SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5227 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5228 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5229 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5231 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5240 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5243 if (ConcatEnd == 1) {
5244 VT = ConcatOps[0].getValueType();
5246 return ConcatOps[0];
5249 SDLoc dl(ConcatOps[0]);
5256 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5257 int Idx = ConcatEnd - 1;
5258 VT = ConcatOps[Idx--].getValueType();
5259 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5272 unsigned NumToInsert = ConcatEnd - Idx - 1;
5273 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5275 ConcatOps[Idx+1] = VecOp;
5276 ConcatEnd = Idx + 2;
5282 unsigned RealVals = ConcatEnd - Idx - 1;
5283 unsigned SubConcatEnd = 0;
5284 unsigned SubConcatIdx = Idx + 1;
5285 while (SubConcatEnd < RealVals)
5286 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5287 while (SubConcatEnd < OpsToConcat)
5288 SubConcatOps[SubConcatEnd++] = undefVec;
5290 NextVT, SubConcatOps);
5291 ConcatEnd = SubConcatIdx + 1;
5296 if (ConcatEnd == 1) {
5297 VT = ConcatOps[0].getValueType();
5299 return ConcatOps[0];
5304 if (
NumOps != ConcatEnd ) {
5306 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5307 ConcatOps[j] = UndefVal;
5315 unsigned Opcode =
N->getOpcode();
5317 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5321 const SDNodeFlags
Flags =
N->getFlags();
5322 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5323 NumElts = NumElts / 2;
5327 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5329 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5330 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5331 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5339 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5342 TLI.isTypeLegal(WideMaskVT)) {
5343 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5344 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5345 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5347 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5348 N->getValueType(0).getVectorElementCount());
5349 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5363 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5364 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5365 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5368 unsigned ConcatEnd = 0;
5376 while (CurNumElts != 0) {
5377 while (CurNumElts >= NumElts) {
5378 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5379 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5380 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5382 CurNumElts -= NumElts;
5385 NumElts = NumElts / 2;
5387 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5390 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5391 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5392 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5393 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5404 switch (
N->getOpcode()) {
5407 return WidenVecRes_STRICT_FSETCC(
N);
5414 return WidenVecRes_Convert_StrictFP(
N);
5421 unsigned Opcode =
N->getOpcode();
5423 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5427 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5428 NumElts = NumElts / 2;
5439 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5443 unsigned ConcatEnd = 0;
5450 for (
unsigned i = 1; i < NumOpers; ++i) {
5456 Oper = GetWidenedVector(Oper);
5462 DAG.getUNDEF(WideOpVT), Oper,
5463 DAG.getVectorIdxConstant(0, dl));
5475 while (CurNumElts != 0) {
5476 while (CurNumElts >= NumElts) {
5479 for (
unsigned i = 0; i < NumOpers; ++i) {
5482 EVT OpVT =
Op.getValueType();
5487 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5493 EVT OperVT[] = {VT, MVT::Other};
5495 ConcatOps[ConcatEnd++] = Oper;
5498 CurNumElts -= NumElts;
5501 NumElts = NumElts / 2;
5503 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5506 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5509 for (
unsigned i = 0; i < NumOpers; ++i) {
5512 EVT OpVT =
Op.getValueType();
5520 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5522 ConcatOps[ConcatEnd++] = Oper;
5531 if (Chains.
size() == 1)
5532 NewChain = Chains[0];
5535 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5540SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5542 EVT ResVT =
N->getValueType(0);
5543 EVT OvVT =
N->getValueType(1);
5544 EVT WideResVT, WideOvVT;
5549 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5554 WideLHS = GetWidenedVector(
N->getOperand(0));
5555 WideRHS = GetWidenedVector(
N->getOperand(1));
5557 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5565 N->getOperand(0), Zero);
5568 N->getOperand(1), Zero);
5571 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5572 SDNode *WideNode = DAG.getNode(
5573 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5576 unsigned OtherNo = 1 - ResNo;
5577 EVT OtherVT =
N->getValueType(OtherNo);
5584 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5587 return SDValue(WideNode, ResNo);
5591 LLVMContext &Ctx = *DAG.getContext();
5595 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5600 unsigned Opcode =
N->getOpcode();
5601 const SDNodeFlags
Flags =
N->getFlags();
5607 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5609 InOp = ZExtPromotedInteger(InOp);
5620 InOp = GetWidenedVector(
N->getOperand(0));
5623 if (InVTEC == WidenEC) {
5624 if (
N->getNumOperands() == 1)
5625 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5626 if (
N->getNumOperands() == 3) {
5627 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5630 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5632 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5647 if (TLI.isTypeLegal(InWidenVT)) {
5655 unsigned NumConcat =
5660 if (
N->getNumOperands() == 1)
5661 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5662 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5666 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5668 if (
N->getNumOperands() == 1)
5669 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5670 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5679 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5680 for (
unsigned i=0; i < MinElts; ++i) {
5681 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5682 if (
N->getNumOperands() == 1)
5685 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5688 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5693 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5697 EVT SrcVT = Src.getValueType();
5701 Src = GetWidenedVector(Src);
5702 SrcVT = Src.getValueType();
5709 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5714 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5718 EVT SrcVT = Src.getValueType();
5722 Src = GetWidenedVector(Src);
5723 SrcVT = Src.getValueType();
5730 if (
N->getNumOperands() == 1)
5731 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5733 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5734 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5738 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5741SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5746 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5752 unsigned Opcode =
N->getOpcode();
5758 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5763 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5764 for (
unsigned i=0; i < MinElts; ++i) {
5765 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5766 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5770 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5772 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5775SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5776 unsigned Opcode =
N->getOpcode();
5780 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5789 InOp = GetWidenedVector(InOp);
5796 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5803 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5804 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5821 while (
Ops.size() != WidenNumElts)
5822 Ops.push_back(DAG.getUNDEF(WidenSVT));
5824 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5830 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5831 return WidenVecRes_BinaryCanTrap(
N);
5834 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5841SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5843 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5846 SDValue Arg = GetWidenedVector(FpValue);
5847 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5852 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5853 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5855 EVT ExpVT =
RHS.getValueType();
5860 ExpOp = ModifyToType(
RHS, WideExpVT);
5863 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5868 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5869 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5870 if (
N->getNumOperands() == 1)
5871 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5873 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5874 N->getOperand(1),
N->getFlags());
5876 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5877 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5881 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5882 {InOp,
Mask,
N->getOperand(2)});
5886 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5889 .getVectorElementType(),
5891 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5892 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5893 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5896SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5898 EVT VT0 =
N->getValueType(0);
5899 EVT VT1 =
N->getValueType(1);
5903 "expected both results to be vectors of matching element count");
5905 LLVMContext &Ctx = *DAG.getContext();
5906 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5908 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5915 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5918 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5919 return SDValue(WidenNode, ResNo);
5922SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5923 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5924 return GetWidenedVector(WidenVec);
5928 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5929 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5932 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5933 AddrSpaceCastN->getSrcAddressSpace(),
5934 AddrSpaceCastN->getDestAddressSpace());
5940 EVT VT =
N->getValueType(0);
5941 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5944 switch (getTypeAction(InVT)) {
5958 SDValue NInOp = GetPromotedInteger(InOp);
5960 if (WidenVT.
bitsEq(NInVT)) {
5963 if (DAG.getDataLayout().isBigEndian()) {
5966 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
5968 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NInOp);
5985 InOp = GetWidenedVector(InOp);
5987 if (WidenVT.
bitsEq(InVT))
5989 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp);
5997 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6002 unsigned NewNumParts = WidenSize / InSize;
6015 EVT OrigInVT =
N->getOperand(0).getValueType();
6020 if (TLI.isTypeLegal(NewInVT)) {
6028 if (WidenSize % InSize == 0) {
6035 DAG.ExtractVectorElements(InOp,
Ops);
6036 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6044 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec);
6048 return CreateStackStoreLoad(InOp, WidenVT);
6051SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6053 N->getOpcode(), SDLoc(
N),
6054 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6055 N->getOperand(0),
N->getOperand(1),
N->getOperand(2));
6061 EVT VT =
N->getValueType(0);
6065 EVT EltVT =
N->getOperand(0).getValueType();
6068 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6072 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6073 NewOps.append(WidenNumElts - NumElts, DAG.getUNDEF(EltVT));
6075 return DAG.getBuildVector(WidenVT, dl, NewOps);
6079 EVT InVT =
N->getOperand(0).getValueType();
6080 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6082 unsigned NumOperands =
N->getNumOperands();
6084 bool InputWidened =
false;
6088 if (WidenNumElts % NumInElts == 0) {
6090 unsigned NumConcat = WidenNumElts / NumInElts;
6091 SDValue UndefVal = DAG.getUNDEF(InVT);
6093 for (
unsigned i=0; i < NumOperands; ++i)
6094 Ops[i] =
N->getOperand(i);
6095 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6100 InputWidened =
true;
6101 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6104 for (i=1; i < NumOperands; ++i)
6105 if (!
N->getOperand(i).isUndef())
6108 if (i == NumOperands)
6111 return GetWidenedVector(
N->getOperand(0));
6113 if (NumOperands == 2) {
6115 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6120 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6121 for (
unsigned i = 0; i < NumInElts; ++i) {
6123 MaskOps[i + NumInElts] = i + WidenNumElts;
6125 return DAG.getVectorShuffle(WidenVT, dl,
6126 GetWidenedVector(
N->getOperand(0)),
6127 GetWidenedVector(
N->getOperand(1)),
6134 "Cannot use build vectors to widen CONCAT_VECTOR result");
6142 for (
unsigned i=0; i < NumOperands; ++i) {
6145 InOp = GetWidenedVector(InOp);
6146 for (
unsigned j = 0;
j < NumInElts; ++
j)
6147 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6149 SDValue UndefVal = DAG.getUNDEF(EltVT);
6150 for (; Idx < WidenNumElts; ++Idx)
6151 Ops[Idx] = UndefVal;
6152 return DAG.getBuildVector(WidenVT, dl,
Ops);
6155SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6156 EVT VT =
N->getValueType(0);
6157 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6158 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6165SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6166 EVT VT =
N->getValueType(0);
6168 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6173 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6175 InOp = GetWidenedVector(InOp);
6181 if (IdxVal == 0 && InVT == WidenVT)
6188 assert(IdxVal % VTNumElts == 0 &&
6189 "Expected Idx to be a multiple of subvector minimum vector length");
6190 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6203 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6204 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6205 "down type's element count");
6212 for (;
I < VTNumElts / GCD; ++
I)
6214 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6215 for (;
I < WidenNumElts / GCD; ++
I)
6222 "EXTRACT_SUBVECTOR for scalable vectors");
6229 for (i = 0; i < VTNumElts; ++i)
6230 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6232 SDValue UndefVal = DAG.getUNDEF(EltVT);
6233 for (; i < WidenNumElts; ++i)
6235 return DAG.getBuildVector(WidenVT, dl,
Ops);
6241 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6246SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6247 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6250 N->getOperand(1),
N->getOperand(2));
6263 if (!
LD->getMemoryVT().isByteSized()) {
6265 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6267 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6276 EVT VT =
LD->getValueType(0);
6277 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6278 EVT WideMaskVT = getSetCCResultType(WideVT);
6281 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6282 TLI.isTypeLegal(WideMaskVT)) {
6285 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6289 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6290 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6302 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6304 Result = GenWidenVectorLoads(LdChain, LD);
6311 if (LdChain.
size() == 1)
6312 NewChain = LdChain[0];
6318 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6326 EVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout());
6329 SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, WideMaskVT,
6330 DAG.getConstant(0,
DL, IdxVT), Len);
6332 SDValue NewLoad = DAG.getMaskedLoad(
6333 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6334 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6335 LD->getAddressingMode(),
LD->getExtensionType());
6345 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6347 SDValue EVL =
N->getVectorLength();
6354 "Unable to widen binary VP op");
6355 Mask = GetWidenedVector(Mask);
6356 assert(
Mask.getValueType().getVectorElementCount() ==
6357 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6358 .getVectorElementCount() &&
6359 "Unable to widen vector load");
6362 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6363 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6364 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6372 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6374 SDValue EVL =
N->getVectorLength();
6380 "Unable to widen binary VP op");
6381 Mask = GetWidenedVector(Mask);
6382 assert(
Mask.getValueType().getVectorElementCount() ==
6383 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6384 .getVectorElementCount() &&
6385 "Unable to widen vector load");
6387 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6388 Mask, EVL,
N->getMemOperand());
6401 "Unable to widen VP strided load");
6402 Mask = GetWidenedVector(Mask);
6404 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6405 assert(
Mask.getValueType().getVectorElementCount() ==
6407 "Data and mask vectors should have the same number of elements");
6409 SDValue Res = DAG.getStridedLoadVP(
6410 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6411 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6412 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6413 N->isExpandingLoad());
6421SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6426 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6428 Mask.getValueType().getVectorElementType(),
6431 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6432 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6433 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6435 WideMask, WidePassthru);
6439 EVT VT =
N->getValueType(0);
6440 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6442 EVT MaskVT =
Mask.getValueType();
6443 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6452 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6453 TLI.isTypeLegal(WideMaskVT) &&
6459 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6460 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6464 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6465 N->getMemoryVT(),
N->getMemOperand());
6469 if (!
N->getPassThru()->isUndef()) {
6472 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6483 Mask = ModifyToType(Mask, WideMaskVT,
true);
6485 SDValue Res = DAG.getMaskedLoad(
6486 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6487 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6488 ExtType,
N->isExpandingLoad());
6497 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6499 EVT MaskVT =
Mask.getValueType();
6500 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6509 Mask = ModifyToType(Mask, WideMaskVT,
true);
6514 Index.getValueType().getScalarType(),
6516 Index = ModifyToType(Index, WideIndexVT);
6522 N->getMemoryVT().getScalarType(), NumElts);
6523 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6524 WideMemVT, dl,
Ops,
N->getMemOperand(),
6525 N->getIndexType(),
N->getExtensionType());
6534 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6542 N->getMemoryVT().getScalarType(), WideEC);
6543 Mask = GetWidenedMask(Mask, WideEC);
6546 Mask,
N->getVectorLength()};
6547 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6548 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6557 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6558 if (
N->isVPOpcode())
6559 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0),
6560 N->getOperand(1),
N->getOperand(2));
6561 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6589 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6590 return N->getOperand(OpNo).getValueType();
6598 N =
N.getOperand(0);
6600 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6601 if (!
N->getOperand(i)->isUndef())
6603 N =
N.getOperand(0);
6607 N =
N.getOperand(0);
6609 N =
N.getOperand(0);
6636 { MaskVT, MVT::Other },
Ops);
6637 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6644 LLVMContext &Ctx = *DAG.getContext();
6647 if (MaskScalarBits < ToMaskScalBits) {
6651 }
else if (MaskScalarBits > ToMaskScalBits) {
6657 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6659 "Mask should have the right element size by now.");
6662 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6664 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6667 EVT SubVT =
Mask->getValueType(0);
6673 assert((
Mask->getValueType(0) == ToMaskVT) &&
6674 "A mask of ToMaskVT should have been produced by now.");
6684 LLVMContext &Ctx = *DAG.getContext();
6695 EVT CondVT =
Cond->getValueType(0);
6699 EVT VSelVT =
N->getValueType(0);
6711 EVT FinalVT = VSelVT;
6722 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6723 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6730 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6738 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6741 EVT ToMaskVT = VSelVT;
6748 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6764 if (ScalarBits0 != ScalarBits1) {
6765 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6766 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6778 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6779 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6780 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6783 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6791 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6796 unsigned Opcode =
N->getOpcode();
6798 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6799 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6800 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6802 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6808 Cond1 = GetWidenedVector(Cond1);
6816 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6817 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6822 Cond1 = ModifyToType(Cond1, CondWidenVT);
6825 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6826 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6828 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6829 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6831 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6835 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6836 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6839 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6843 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6844 return DAG.getUNDEF(WidenVT);
6848 EVT VT =
N->getValueType(0);
6851 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6855 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6856 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6859 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6860 for (
unsigned i = 0; i != NumElts; ++i) {
6861 int Idx =
N->getMaskElt(i);
6862 if (Idx < (
int)NumElts)
6865 NewMask[i] = Idx - NumElts + WidenNumElts;
6867 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6871 EVT VT =
N->getValueType(0);
6875 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6876 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6882 unsigned IdxVal = WidenNumElts - VTNumElts;
6895 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6898 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6899 "down type's element count");
6902 for (; i < VTNumElts / GCD; ++i)
6904 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6905 for (; i < WidenNumElts / GCD; ++i)
6913 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6914 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6916 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6920SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6921 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6922 return DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, SDLoc(
N), NVT,
N->ops());
6926 assert(
N->getValueType(0).isVector() &&
6927 N->getOperand(0).getValueType().isVector() &&
6928 "Operands must be vectors");
6929 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6942 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
6943 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
6950 InOp1 = GetWidenedVector(InOp1);
6951 InOp2 = GetWidenedVector(InOp2);
6954 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
6965 "Input not widened to expected type!");
6967 if (
N->getOpcode() == ISD::VP_SETCC) {
6970 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6971 N->getOperand(2), Mask,
N->getOperand(4));
6973 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6978 assert(
N->getValueType(0).isVector() &&
6979 N->getOperand(1).getValueType().isVector() &&
6980 "Operands must be vectors");
6981 EVT VT =
N->getValueType(0);
6982 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6992 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
6997 for (
unsigned i = 0; i != NumElts; ++i) {
6998 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
6999 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7001 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7002 {Chain, LHSElem, RHSElem, CC});
7003 Chains[i] = Scalars[i].getValue(1);
7004 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7005 DAG.getBoolConstant(
true, dl, EltVT, VT),
7006 DAG.getBoolConstant(
false, dl, EltVT, VT));
7010 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7012 return DAG.getBuildVector(WidenVT, dl, Scalars);
7018bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7019 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7023 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7026 switch (
N->getOpcode()) {
7029 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7035 case ISD::BITCAST: Res = WidenVecOp_BITCAST(
N);
break;
7037 Res = WidenVecOp_FAKE_USE(
N);
7043 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7044 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7045 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7046 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7051 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7053 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7054 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7055 case ISD::MSCATTER: Res = WidenVecOp_MSCATTER(
N, OpNo);
break;
7056 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7057 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7067 Res = WidenVecOp_UnrollVectorOp(
N);
7074 Res = WidenVecOp_EXTEND(
N);
7079 Res = WidenVecOp_CMP(
N);
7082 case ISD::FP_EXTEND:
7095 Res = WidenVecOp_Convert(
N);
7100 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7103 case ISD::EXPERIMENTAL_VP_SPLAT:
7104 Res = WidenVecOp_VP_SPLAT(
N, OpNo);
7107 case ISD::VECREDUCE_FADD:
7108 case ISD::VECREDUCE_FMUL:
7109 case ISD::VECREDUCE_ADD:
7110 case ISD::VECREDUCE_MUL:
7111 case ISD::VECREDUCE_AND:
7112 case ISD::VECREDUCE_OR:
7113 case ISD::VECREDUCE_XOR:
7114 case ISD::VECREDUCE_SMAX:
7115 case ISD::VECREDUCE_SMIN:
7116 case ISD::VECREDUCE_UMAX:
7117 case ISD::VECREDUCE_UMIN:
7118 case ISD::VECREDUCE_FMAX:
7119 case ISD::VECREDUCE_FMIN:
7120 case ISD::VECREDUCE_FMAXIMUM:
7121 case ISD::VECREDUCE_FMINIMUM:
7122 Res = WidenVecOp_VECREDUCE(
N);
7124 case ISD::VECREDUCE_SEQ_FADD:
7125 case ISD::VECREDUCE_SEQ_FMUL:
7126 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7128 case ISD::VP_REDUCE_FADD:
7129 case ISD::VP_REDUCE_SEQ_FADD:
7130 case ISD::VP_REDUCE_FMUL:
7131 case ISD::VP_REDUCE_SEQ_FMUL:
7132 case ISD::VP_REDUCE_ADD:
7133 case ISD::VP_REDUCE_MUL:
7134 case ISD::VP_REDUCE_AND:
7135 case ISD::VP_REDUCE_OR:
7136 case ISD::VP_REDUCE_XOR:
7137 case ISD::VP_REDUCE_SMAX:
7138 case ISD::VP_REDUCE_SMIN:
7139 case ISD::VP_REDUCE_UMAX:
7140 case ISD::VP_REDUCE_UMIN:
7141 case ISD::VP_REDUCE_FMAX:
7142 case ISD::VP_REDUCE_FMIN:
7143 case ISD::VP_REDUCE_FMAXIMUM:
7144 case ISD::VP_REDUCE_FMINIMUM:
7145 Res = WidenVecOp_VP_REDUCE(
N);
7147 case ISD::VP_CTTZ_ELTS:
7148 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7149 Res = WidenVecOp_VP_CttzElements(
N);
7154 if (!Res.
getNode())
return false;
7162 if (
N->isStrictFPOpcode())
7164 "Invalid operand expansion");
7167 "Invalid operand expansion");
7169 ReplaceValueWith(
SDValue(
N, 0), Res);
7175 EVT VT =
N->getValueType(0);
7180 "Unexpected type action");
7181 InOp = GetWidenedVector(InOp);
7184 "Input wasn't widened!");
7192 EVT FixedEltVT = FixedVT.getVectorElementType();
7193 if (TLI.isTypeLegal(FixedVT) &&
7195 FixedEltVT == InEltVT) {
7197 "Not enough elements in the fixed type for the operand!");
7199 "We can't have the same type as we started with!");
7201 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7203 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7212 return WidenVecOp_Convert(
N);
7217 switch (
N->getOpcode()) {
7232 EVT OpVT =
N->getOperand(0).getValueType();
7233 EVT ResVT =
N->getValueType(0);
7240 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7241 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7247 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7248 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7250 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7257 return DAG.UnrollVectorOp(
N);
7262 EVT ResultVT =
N->getValueType(0);
7264 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7267 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7273 {WideArg,
Test},
N->getFlags());
7279 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7281 EVT OpVT =
N->getOperand(0).getValueType();
7284 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7289 EVT VT =
N->getValueType(0);
7295 "Unexpected type action");
7296 InOp = GetWidenedVector(InOp);
7298 unsigned Opcode =
N->getOpcode();
7304 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7306 if (
N->isStrictFPOpcode()) {
7308 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7311 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7312 {
N->getOperand(0), InOp });
7318 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7320 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7322 return DAG.getExtractSubvector(dl, VT, Res, 0);
7330 if (
N->isStrictFPOpcode()) {
7333 for (
unsigned i=0; i < NumElts; ++i) {
7334 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7335 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7339 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7341 for (
unsigned i = 0; i < NumElts; ++i)
7342 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7343 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7346 return DAG.getBuildVector(VT, dl,
Ops);
7350 EVT DstVT =
N->getValueType(0);
7351 SDValue Src = GetWidenedVector(
N->getOperand(0));
7352 EVT SrcVT = Src.getValueType();
7359 if (TLI.isTypeLegal(WideDstVT)) {
7361 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7364 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7368 return DAG.UnrollVectorOp(
N);
7372 EVT VT =
N->getValueType(0);
7373 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7381 if (!VT.
isVector() && VT != MVT::x86mmx &&
7385 if (TLI.isTypeLegal(NewVT)) {
7386 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
7387 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7399 ElementCount NewNumElts =
7401 .divideCoefficientBy(EltSize);
7403 if (TLI.isTypeLegal(NewVT)) {
7405 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7410 return CreateStackStoreLoad(InOp, VT);
7418 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7419 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7424 EVT VT =
N->getValueType(0);
7426 EVT InVT =
N->getOperand(0).getValueType();
7431 unsigned NumOperands =
N->getNumOperands();
7432 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7434 for (i = 1; i < NumOperands; ++i)
7435 if (!
N->getOperand(i).isUndef())
7438 if (i == NumOperands)
7439 return GetWidenedVector(
N->getOperand(0));
7449 for (
unsigned i=0; i < NumOperands; ++i) {
7453 "Unexpected type action");
7454 InOp = GetWidenedVector(InOp);
7455 for (
unsigned j = 0;
j < NumInElts; ++
j)
7456 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7458 return DAG.getBuildVector(VT, dl,
Ops);
7461SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7462 EVT VT =
N->getValueType(0);
7468 SubVec = GetWidenedVector(SubVec);
7474 bool IndicesValid =
false;
7477 IndicesValid =
true;
7481 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7482 Attribute::VScaleRange);
7487 IndicesValid =
true;
7495 if (IndicesValid && InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7501 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7505 unsigned Idx =
N->getConstantOperandVal(2);
7511 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7517SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7518 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7520 N->getValueType(0), InOp,
N->getOperand(1));
7523SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7524 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7526 N->getValueType(0), InOp,
N->getOperand(1));
7529SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7530 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7531 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7539 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7540 return TLI.scalarizeVectorStore(ST, DAG);
7542 if (
ST->isTruncatingStore())
7543 return TLI.scalarizeVectorStore(ST, DAG);
7553 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7554 EVT WideMaskVT = getSetCCResultType(WideVT);
7556 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7557 TLI.isTypeLegal(WideMaskVT)) {
7560 StVal = GetWidenedVector(StVal);
7562 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7564 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7565 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7566 ST->getAddressingMode());
7570 if (GenWidenVectorStores(StChain, ST)) {
7571 if (StChain.
size() == 1)
7580 EVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout());
7582 SDValue WideStVal = GetWidenedVector(StVal);
7584 SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, WideMaskVT,
7585 DAG.getConstant(0,
DL, IdxVT), Len);
7587 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7588 ST->getOffset(), Mask,
ST->getMemoryVT(),
7589 ST->getMemOperand(),
ST->getAddressingMode(),
7590 ST->isTruncatingStore());
7596SDValue DAGTypeLegalizer::WidenVecOp_VP_SPLAT(
SDNode *
N,
unsigned OpNo) {
7597 assert(OpNo == 1 &&
"Can widen only mask operand of vp_splat");
7598 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
7599 N->getOperand(0), GetWidenedVector(
N->getOperand(1)),
7603SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7604 assert((OpNo == 1 || OpNo == 3) &&
7605 "Can widen only data or mask operand of vp_store");
7613 StVal = GetWidenedVector(StVal);
7619 "Unable to widen VP store");
7620 Mask = GetWidenedVector(Mask);
7622 Mask = GetWidenedVector(Mask);
7628 "Unable to widen VP store");
7629 StVal = GetWidenedVector(StVal);
7632 assert(
Mask.getValueType().getVectorElementCount() ==
7634 "Mask and data vectors should have the same number of elements");
7635 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7636 ST->getOffset(), Mask,
ST->getVectorLength(),
7637 ST->getMemoryVT(),
ST->getMemOperand(),
7638 ST->getAddressingMode(),
ST->isTruncatingStore(),
7639 ST->isCompressingStore());
7644 assert((OpNo == 1 || OpNo == 4) &&
7645 "Can widen only data or mask operand of vp_strided_store");
7654 "Unable to widen VP strided store");
7658 "Unable to widen VP strided store");
7660 StVal = GetWidenedVector(StVal);
7661 Mask = GetWidenedVector(Mask);
7664 Mask.getValueType().getVectorElementCount() &&
7665 "Data and mask vectors should have the same number of elements");
7667 return DAG.getStridedStoreVP(
7674SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7675 assert((OpNo == 1 || OpNo == 4) &&
7676 "Can widen only data or mask operand of mstore");
7679 EVT MaskVT =
Mask.getValueType();
7684 EVT WideVT, WideMaskVT;
7687 StVal = GetWidenedVector(StVal);
7694 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7701 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7702 TLI.isTypeLegal(WideMaskVT)) {
7703 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7704 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7713 Mask = ModifyToType(Mask, WideMaskVT,
true);
7716 Mask = ModifyToType(Mask, WideMaskVT,
true);
7718 StVal = ModifyToType(StVal, WideVT);
7721 assert(
Mask.getValueType().getVectorElementCount() ==
7723 "Mask and data vectors should have the same number of elements");
7730SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7731 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7733 SDValue DataOp = MG->getPassThru();
7735 SDValue Scale = MG->getScale();
7743 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7744 MG->getMemOperand(), MG->getIndexType(),
7745 MG->getExtensionType());
7751SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7760 DataOp = GetWidenedVector(DataOp);
7764 EVT IndexVT =
Index.getValueType();
7767 Index = ModifyToType(Index, WideIndexVT);
7770 EVT MaskVT =
Mask.getValueType();
7773 Mask = ModifyToType(Mask, WideMaskVT,
true);
7778 }
else if (OpNo == 4) {
7780 Index = GetWidenedVector(Index);
7786 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7791SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7800 DataOp = GetWidenedVector(DataOp);
7801 Index = GetWidenedVector(Index);
7803 Mask = GetWidenedMask(Mask, WideEC);
7806 }
else if (OpNo == 3) {
7808 Index = GetWidenedVector(Index);
7815 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7820 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7821 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7823 EVT VT =
N->getValueType(0);
7838 SVT, InOp0, InOp1,
N->getOperand(2));
7844 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7846 EVT OpVT =
N->getOperand(0).getValueType();
7849 return DAG.getNode(ExtendCode, dl, VT, CC);
7859 EVT VT =
N->getValueType(0);
7861 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7868 for (
unsigned i = 0; i != NumElts; ++i) {
7869 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7870 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7872 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7873 {Chain, LHSElem, RHSElem, CC});
7874 Chains[i] = Scalars[i].getValue(1);
7875 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7876 DAG.getBoolConstant(
true, dl, EltVT, VT),
7877 DAG.getBoolConstant(
false, dl, EltVT, VT));
7881 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7883 return DAG.getBuildVector(VT, dl, Scalars);
7890 case ISD::VECREDUCE_ADD:
7891 case ISD::VECREDUCE_MUL:
7892 case ISD::VECREDUCE_AND:
7893 case ISD::VECREDUCE_OR:
7894 case ISD::VECREDUCE_XOR:
7896 case ISD::VECREDUCE_SMAX:
7897 case ISD::VECREDUCE_SMIN:
7899 case ISD::VECREDUCE_UMAX:
7900 case ISD::VECREDUCE_UMIN:
7907 SDValue Op = GetWidenedVector(
N->getOperand(0));
7908 EVT VT =
N->getValueType(0);
7909 EVT OrigVT =
N->getOperand(0).getValueType();
7910 EVT WideVT =
Op.getValueType();
7912 SDNodeFlags
Flags =
N->getFlags();
7914 unsigned Opc =
N->getOpcode();
7916 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7917 assert(NeutralElem &&
"Neutral element must exist");
7927 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7934 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7935 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7941 unsigned GCD = std::gcd(OrigElts, WideElts);
7944 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
7945 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
7946 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
7947 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7950 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
7951 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
7953 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7962 EVT VT =
N->getValueType(0);
7964 EVT WideVT =
Op.getValueType();
7966 SDNodeFlags
Flags =
N->getFlags();
7968 unsigned Opc =
N->getOpcode();
7970 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7980 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7983 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7984 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7990 unsigned GCD = std::gcd(OrigElts, WideElts);
7993 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
7994 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
7995 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
7996 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
7999 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8000 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8002 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8006 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8009 SDValue Op = GetWidenedVector(
N->getOperand(1));
8011 Op.getValueType().getVectorElementCount());
8013 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8014 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8022 EVT VT =
N->getValueType(0);
8026 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8027 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8032 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8038 EVT SrcVT =
Source.getValueType();
8042 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8043 {Source, Mask, N->getOperand(2)},
N->getFlags());
8060 unsigned WidenEx = 0) {
8065 unsigned AlignInBits =
Align*8;
8067 EVT RetVT = WidenEltVT;
8072 if (Width == WidenEltWidth)
8083 (WidenWidth % MemVTWidth) == 0 &&
8085 (MemVTWidth <= Width ||
8086 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8087 if (MemVTWidth == WidenWidth)
8106 (WidenWidth % MemVTWidth) == 0 &&
8108 (MemVTWidth <= Width ||
8109 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8118 return std::nullopt;
8129 unsigned Start,
unsigned End) {
8130 SDLoc dl(LdOps[Start]);
8131 EVT LdTy = LdOps[Start].getValueType();
8139 for (
unsigned i = Start + 1; i != End; ++i) {
8140 EVT NewLdTy = LdOps[i].getValueType();
8141 if (NewLdTy != LdTy) {
8144 VecOp = DAG.
getNode(ISD::BITCAST, dl, NewVecVT, VecOp);
8151 return DAG.
getNode(ISD::BITCAST, dl, VecTy, VecOp);
8160 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8161 EVT LdVT =
LD->getMemoryVT();
8171 AAMDNodes AAInfo =
LD->getAAInfo();
8175 TypeSize WidthDiff = WidenWidth - LdWidth;
8182 std::optional<EVT> FirstVT =
8183 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8190 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8195 std::optional<EVT> NewVT = FirstVT;
8196 TypeSize RemainingWidth = LdWidth;
8197 TypeSize NewVTWidth = FirstVTWidth;
8199 RemainingWidth -= NewVTWidth;
8206 NewVTWidth = NewVT->getSizeInBits();
8212 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8213 LD->getBaseAlign(), MMOFlags, AAInfo);
8217 if (MemVTs.
empty()) {
8219 if (!FirstVT->isVector()) {
8224 return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
8226 if (FirstVT == WidenVT)
8231 unsigned NumConcat =
8234 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8235 ConcatOps[0] = LdOp;
8236 for (
unsigned i = 1; i != NumConcat; ++i)
8237 ConcatOps[i] = UndefVal;
8245 uint64_t ScaledOffset = 0;
8246 MachinePointerInfo MPI =
LD->getPointerInfo();
8252 for (EVT MemVT : MemVTs) {
8253 Align NewAlign = ScaledOffset == 0
8254 ?
LD->getBaseAlign()
8257 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8265 unsigned End = LdOps.
size();
8276 EVT LdTy = LdOps[i].getValueType();
8279 for (--i; i >= 0; --i) {
8280 LdTy = LdOps[i].getValueType();
8287 ConcatOps[--Idx] = LdOps[i];
8288 for (--i; i >= 0; --i) {
8289 EVT NewLdTy = LdOps[i].getValueType();
8290 if (NewLdTy != LdTy) {
8300 for (;
j != End-Idx; ++
j)
8301 WidenOps[j] = ConcatOps[Idx+j];
8303 WidenOps[j] = DAG.getUNDEF(LdTy);
8310 ConcatOps[--Idx] = LdOps[i];
8315 ArrayRef(&ConcatOps[Idx], End - Idx));
8321 SDValue UndefVal = DAG.getUNDEF(LdTy);
8324 for (; i != End-Idx; ++i)
8325 WidenOps[i] = ConcatOps[Idx+i];
8327 WidenOps[i] = UndefVal;
8338 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8339 EVT LdVT =
LD->getMemoryVT();
8348 AAMDNodes AAInfo =
LD->getAAInfo();
8362 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8363 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8369 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8370 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8371 LD->getBaseAlign(), MMOFlags, AAInfo);
8376 SDValue UndefVal = DAG.getUNDEF(EltVT);
8377 for (; i != WidenNumElts; ++i)
8380 return DAG.getBuildVector(WidenVT, dl,
Ops);
8391 AAMDNodes AAInfo =
ST->getAAInfo();
8392 SDValue ValOp = GetWidenedVector(
ST->getValue());
8395 EVT StVT =
ST->getMemoryVT();
8403 "Mismatch between store and value types");
8407 MachinePointerInfo MPI =
ST->getPointerInfo();
8408 uint64_t ScaledOffset = 0;
8417 std::optional<EVT> NewVT =
8422 TypeSize NewVTWidth = NewVT->getSizeInBits();
8425 StWidth -= NewVTWidth;
8426 MemVTs.
back().second++;
8430 for (
const auto &Pair : MemVTs) {
8431 EVT NewVT = Pair.first;
8432 unsigned Count = Pair.second;
8438 Align NewAlign = ScaledOffset == 0
8439 ?
ST->getBaseAlign()
8441 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8442 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8458 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8459 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8460 ST->getBaseAlign(), MMOFlags, AAInfo);
8477 bool FillWithZeroes) {
8482 "input and widen element type must match");
8484 "cannot modify scalable vectors in this way");
8496 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8499 for (
unsigned i = 1; i != NumConcat; ++i)
8506 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8509 "Scalable vectors should have been handled already.");
8517 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8519 for (Idx = 0; Idx < MinNumElts; ++Idx)
8520 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8522 SDValue UndefVal = DAG.getUNDEF(EltVT);
8523 for (; Idx < WidenNumElts; ++Idx)
8524 Ops[Idx] = UndefVal;
8526 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8527 if (!FillWithZeroes)
8531 "We expect to never want to FillWithZeroes for non-integral types.");
8534 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8535 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8537 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8538 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)
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()
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
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.
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 isScalableVT() const
Return true if the type is a scalable type.
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.