35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
46 switch (
N->getOpcode()) {
49 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
58 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
61 case ISD::BITCAST: R = ScalarizeVecRes_BITCAST(
N);
break;
69 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
72 case ISD::ATOMIC_LOAD:
81 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
83 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
89 R = ScalarizeVecRes_VecInregOp(
N);
114 case ISD::FNEARBYINT:
117 case ISD::ARITH_FENCE:
125 case ISD::FROUNDEVEN:
140 R = ScalarizeVecRes_UnaryOp(
N);
142 case ISD::ADDRSPACECAST:
143 R = ScalarizeVecRes_ADDRSPACECAST(
N);
149 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
163 case ISD::FMINNUM_IEEE:
164 case ISD::FMAXNUM_IEEE:
167 case ISD::FMINIMUMNUM:
168 case ISD::FMAXIMUMNUM:
203 R = ScalarizeVecRes_BinOp(
N);
208 R = ScalarizeVecRes_CMP(
N);
214 R = ScalarizeVecRes_TernaryOp(
N);
217#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
218 case ISD::STRICT_##DAGN:
219#include "llvm/IR/ConstrainedOps.def"
220 R = ScalarizeVecRes_StrictFPOp(
N);
225 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
234 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
244 R = ScalarizeVecRes_FIX(
N);
250 SetScalarizedVector(
SDValue(
N, ResNo), R);
254 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
255 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
256 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
265 if (getTypeAction(
LHS.getValueType()) ==
267 LHS = GetScalarizedVector(
LHS);
268 RHS = GetScalarizedVector(
RHS);
270 EVT VT =
LHS.getValueType().getVectorElementType();
271 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
272 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
275 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
276 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
280 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
281 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
282 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
283 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
288 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
289 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
296DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
298 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
299 "Unexpected vector type!");
300 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
302 EVT VT0 =
N->getValueType(0);
303 EVT VT1 =
N->getValueType(1);
307 DAG.getNode(
N->getOpcode(), dl,
308 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
312 unsigned OtherNo = 1 - ResNo;
313 EVT OtherVT =
N->getValueType(OtherNo);
315 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
319 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
322 return SDValue(ScalarNode, ResNo);
327 unsigned NumOpers =
N->getNumOperands();
329 EVT ValueVTs[] = {VT, MVT::Other};
338 for (
unsigned i = 1; i < NumOpers; ++i) {
344 Oper = GetScalarizedVector(Oper);
353 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
354 Opers,
N->getFlags());
365 EVT ResVT =
N->getValueType(0);
366 EVT OvVT =
N->getValueType(1);
370 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
371 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
374 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
375 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
376 ScalarLHS = ElemsLHS[0];
377 ScalarRHS = ElemsRHS[0];
380 SDVTList ScalarVTs = DAG.getVTList(
382 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
383 {ScalarLHS, ScalarRHS},
N->getFlags())
387 unsigned OtherNo = 1 - ResNo;
388 EVT OtherVT =
N->getValueType(OtherNo);
390 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
394 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
397 return SDValue(ScalarNode, ResNo);
402 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
403 return GetScalarizedVector(
Op);
406SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
414 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
425 Op = GetScalarizedVector(
Op);
426 EVT NewVT =
N->getValueType(0).getVectorElementType();
427 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
431SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
441SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
443 N->getValueType(0).getVectorElementType(),
444 N->getOperand(0),
N->getOperand(1));
450 EVT OpVT =
Op.getValueType();
454 Op = GetScalarizedVector(
Op);
457 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
460 N->getValueType(0).getVectorElementType(),
Op,
464SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
465 SDValue Op = GetScalarizedVector(
N->getOperand(0));
466 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
470SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
475 if (
Op.getValueType() != EltVT)
483 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
484 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
494 assert(
N->isUnindexed() &&
"Indexed vector load?");
498 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
499 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
500 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
501 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
513 EVT OpVT =
Op.getValueType();
523 Op = GetScalarizedVector(
Op);
526 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
528 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
534 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
535 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
536 LHS, DAG.getValueType(ExtVT));
543 EVT OpVT =
Op.getValueType();
548 Op = GetScalarizedVector(
Op);
550 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
553 switch (
N->getOpcode()) {
565SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
568 EVT OpVT =
Op.getValueType();
578 Op = GetScalarizedVector(
Op);
581 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
584 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
585 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
586 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
589SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
601 EVT OpVT =
Cond.getValueType();
610 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
613 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
615 TLI.getBooleanContents(
false,
false);
622 if (TLI.getBooleanContents(
false,
false) !=
623 TLI.getBooleanContents(
false,
true)) {
627 EVT OpVT =
Cond->getOperand(0).getValueType();
629 VecBool = TLI.getBooleanContents(OpVT);
634 EVT CondVT =
Cond.getValueType();
635 if (ScalarBool != VecBool) {
636 switch (ScalarBool) {
644 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
651 Cond, DAG.getValueType(MVT::i1));
657 auto BoolVT = getSetCCResultType(CondVT);
658 if (BoolVT.bitsLT(CondVT))
661 return DAG.getSelect(SDLoc(
N),
663 GetScalarizedVector(
N->getOperand(2)));
667 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
668 return DAG.getSelect(SDLoc(
N),
669 LHS.getValueType(),
N->getOperand(0),
LHS,
670 GetScalarizedVector(
N->getOperand(2)));
674 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
676 N->getOperand(0),
N->getOperand(1),
677 LHS, GetScalarizedVector(
N->getOperand(3)),
682 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
685SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
689 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
691 return GetScalarizedVector(
N->getOperand(
Op));
694SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
696 EVT SrcVT = Src.getValueType();
701 Src = GetScalarizedVector(Src);
705 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
707 EVT DstVT =
N->getValueType(0).getVectorElementType();
708 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
712 assert(
N->getValueType(0).isVector() &&
713 N->getOperand(0).getValueType().isVector() &&
714 "Operand types must be vectors");
717 EVT OpVT =
LHS.getValueType();
718 EVT NVT =
N->getValueType(0).getVectorElementType();
723 LHS = GetScalarizedVector(
LHS);
724 RHS = GetScalarizedVector(
RHS);
727 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
728 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
738 return DAG.getNode(ExtendCode,
DL, NVT, Res);
749 Arg = GetScalarizedVector(Arg);
752 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
761 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
768bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
773 switch (
N->getOpcode()) {
776 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
783 Res = ScalarizeVecOp_BITCAST(
N);
786 Res = ScalarizeVecOp_FAKE_USE(
N);
800 Res = ScalarizeVecOp_UnaryOp(
N);
804 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
810 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
813 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
816 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
819 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
822 Res = ScalarizeVecOp_VSELECT(
N);
825 Res = ScalarizeVecOp_VSETCC(
N);
829 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
835 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
838 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
841 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
844 Res = ScalarizeVecOp_FP_EXTEND(
N);
846 case ISD::VECREDUCE_FADD:
847 case ISD::VECREDUCE_FMUL:
848 case ISD::VECREDUCE_ADD:
849 case ISD::VECREDUCE_MUL:
850 case ISD::VECREDUCE_AND:
851 case ISD::VECREDUCE_OR:
852 case ISD::VECREDUCE_XOR:
853 case ISD::VECREDUCE_SMAX:
854 case ISD::VECREDUCE_SMIN:
855 case ISD::VECREDUCE_UMAX:
856 case ISD::VECREDUCE_UMIN:
857 case ISD::VECREDUCE_FMAX:
858 case ISD::VECREDUCE_FMIN:
859 case ISD::VECREDUCE_FMAXIMUM:
860 case ISD::VECREDUCE_FMINIMUM:
861 Res = ScalarizeVecOp_VECREDUCE(
N);
863 case ISD::VECREDUCE_SEQ_FADD:
864 case ISD::VECREDUCE_SEQ_FMUL:
865 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
869 Res = ScalarizeVecOp_CMP(
N);
874 if (!Res.
getNode())
return false;
882 "Invalid operand expansion");
884 ReplaceValueWith(
SDValue(
N, 0), Res);
891 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
892 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
893 N->getValueType(0), Elt);
898 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
899 "Fake Use: Unexpected vector type!");
900 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
901 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
907 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
908 "Unexpected vector type!");
909 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
911 N->getValueType(0).getScalarType(), Elt);
919SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
920 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
921 "Unexpected vector type!");
922 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
924 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
925 Elt,
N->getOperand(1));
933SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
934 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
935 "Unexpected vector type!");
936 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
938 {
N->getValueType(0).getScalarType(), MVT::Other },
939 {
N->getOperand(0), Elt });
949 ReplaceValueWith(
SDValue(
N, 0), Res);
954SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
956 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
957 Ops[i] = GetScalarizedVector(
N->getOperand(i));
958 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
963SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
967 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
968 SDValue ContainingVec =
N->getOperand(0);
976SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
977 EVT VT =
N->getValueType(0);
978 SDValue Res = GetScalarizedVector(
N->getOperand(0));
981 ? DAG.getNode(ISD::FP_EXTEND, SDLoc(
N), VT, Res)
990 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
991 EVT VT =
N->getValueType(0);
993 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1001 assert(
N->getValueType(0).isVector() &&
1002 N->getOperand(0).getValueType().isVector() &&
1003 "Operand types must be vectors");
1004 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1006 EVT VT =
N->getValueType(0);
1007 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1008 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1010 EVT OpVT =
N->getOperand(0).getValueType();
1022 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1028SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1030 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1031 assert(
N->getValueType(0).isVector() &&
1032 N->getOperand(1).getValueType().isVector() &&
1033 "Operand types must be vectors");
1034 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1036 EVT VT =
N->getValueType(0);
1038 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1039 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1042 EVT OpVT =
N->getOperand(1).getValueType();
1046 {Ch, LHS, RHS, CC});
1055 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1060 ReplaceValueWith(
SDValue(
N, 0), Res);
1067 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1068 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1071 if (
N->isTruncatingStore())
1072 return DAG.getTruncStore(
1073 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1074 N->getBasePtr(),
N->getPointerInfo(),
1075 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1076 N->getMemOperand()->getFlags(),
N->getAAInfo());
1078 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1079 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1080 N->getMemOperand()->getFlags(),
N->getAAInfo());
1085SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1086 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1087 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1089 N->getValueType(0).getVectorElementType(), Elt,
1094SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1096 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1097 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1100 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1110 ReplaceValueWith(
SDValue(
N, 0), Res);
1117 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1119 N->getValueType(0).getVectorElementType(), Elt);
1125SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1126 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1129 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1130 {
N->getOperand(0), Elt});
1139 ReplaceValueWith(
SDValue(
N, 0), Res);
1144 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1151SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1157 SDValue Op = GetScalarizedVector(VecOp);
1158 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1159 AccOp,
Op,
N->getFlags());
1163 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1164 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1179void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1184 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1187 switch (
N->getOpcode()) {
1190 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1199 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1206 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1210 case ISD::BITCAST: SplitVecRes_BITCAST(
N,
Lo,
Hi);
break;
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(
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));
1709 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
N->getOperand(2));
1716 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1719 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1722 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1727 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1729 unsigned NumSubvectors =
N->getNumOperands() / 2;
1730 if (NumSubvectors == 1) {
1731 Lo =
N->getOperand(0);
1732 Hi =
N->getOperand(1);
1737 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1746void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1753 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1768 GetSplitVector(Vec,
Lo,
Hi);
1771 EVT LoVT =
Lo.getValueType();
1781 if (IdxVal + SubElems <= LoElems) {
1789 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1791 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1797 SDValue WideSubVec = GetWidenedVector(SubVec);
1799 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1807 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1809 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1810 auto &MF = DAG.getMachineFunction();
1814 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1819 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1820 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1824 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1829 MachinePointerInfo MPI =
Load->getPointerInfo();
1830 IncrementPointer(Load, LoVT, MPI, StackPtr);
1833 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1842 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1847 EVT RHSVT =
RHS.getValueType();
1850 GetSplitVector(
RHS, RHSLo, RHSHi);
1852 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1867 SDValue FpValue =
N->getOperand(0);
1869 GetSplitVector(FpValue, ArgLo, ArgHi);
1871 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1873 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1882 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1886 std::tie(LoVT, HiVT) =
1890 DAG.getValueType(LoVT));
1892 DAG.getValueType(HiVT));
1897 unsigned Opcode =
N->getOpcode();
1904 GetSplitVector(N0, InLo, InHi);
1906 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1911 EVT OutLoVT, OutHiVT;
1912 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1914 assert((2 * OutNumElements) <= InNumElements &&
1915 "Illegal extend vector in reg split");
1924 SmallVector<int, 8> SplitHi(InNumElements, -1);
1925 for (
unsigned i = 0; i != OutNumElements; ++i)
1926 SplitHi[i] = i + OutNumElements;
1927 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1929 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1930 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1935 unsigned NumOps =
N->getNumOperands();
1939 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1949 for (
unsigned i = 1; i <
NumOps; ++i) {
1954 EVT InVT =
Op.getValueType();
1959 GetSplitVector(
Op, OpLo, OpHi);
1961 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
1968 EVT LoValueVTs[] = {LoVT, MVT::Other};
1969 EVT HiValueVTs[] = {HiVT, MVT::Other};
1970 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1972 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
1978 Lo.getValue(1),
Hi.getValue(1));
1982 ReplaceValueWith(
SDValue(
N, 1), Chain);
1985SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
1987 EVT VT =
N->getValueType(0);
1998 else if (NE > ResNE)
2002 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2006 for (i = 0; i !=
NE; ++i) {
2007 Operands[0] = Chain;
2008 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2009 SDValue Operand =
N->getOperand(j);
2013 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2015 Operands[
j] = Operand;
2019 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2027 for (; i < ResNE; ++i)
2032 ReplaceValueWith(
SDValue(
N, 1), Chain);
2036 return DAG.getBuildVector(VecVT, dl, Scalars);
2039void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2042 EVT ResVT =
N->getValueType(0);
2043 EVT OvVT =
N->getValueType(1);
2044 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2045 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2046 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2048 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2050 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2051 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2053 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2054 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2057 unsigned Opcode =
N->getOpcode();
2058 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2059 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2061 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2063 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2069 unsigned OtherNo = 1 - ResNo;
2070 EVT OtherVT =
N->getValueType(OtherNo);
2072 SetSplitVector(
SDValue(
N, OtherNo),
2078 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2082void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2088 GetSplitVector(Vec,
Lo,
Hi);
2091 unsigned IdxVal = CIdx->getZExtValue();
2092 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2093 if (IdxVal < LoNumElts) {
2095 Lo.getValueType(),
Lo, Elt, Idx);
2098 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2118 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2120 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2121 auto &MF = DAG.getMachineFunction();
2125 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2130 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2131 Store = DAG.getTruncStore(
2137 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2140 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2144 MachinePointerInfo MPI =
Load->getPointerInfo();
2145 IncrementPointer(Load, LoVT, MPI, StackPtr);
2147 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2150 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2151 if (LoVT !=
Lo.getValueType())
2153 if (HiVT !=
Hi.getValueType())
2161 assert(
N->getValueType(0).isScalableVector() &&
2162 "Only scalable vectors are supported for STEP_VECTOR");
2163 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2184 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2185 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2187 Hi = DAG.getPOISON(HiVT);
2197 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2198 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
2199 auto [EVLLo, EVLHi] = DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2200 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0), MaskLo, EVLLo);
2201 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
N->getOperand(0), MaskHi, EVLHi);
2209 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2215 EVT MemoryVT =
LD->getMemoryVT();
2217 AAMDNodes AAInfo =
LD->getAAInfo();
2219 EVT LoMemVT, HiMemVT;
2220 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2224 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2225 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2226 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2231 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2234 MachinePointerInfo MPI;
2235 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2238 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2247 ReplaceValueWith(
SDValue(LD, 1), Ch);
2252 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2255 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2261 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2262 Align Alignment =
LD->getBaseAlign();
2265 EVT MemoryVT =
LD->getMemoryVT();
2267 EVT LoMemVT, HiMemVT;
2268 bool HiIsEmpty =
false;
2269 std::tie(LoMemVT, HiMemVT) =
2270 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2275 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2278 GetSplitVector(Mask, MaskLo, MaskHi);
2280 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2285 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2287 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2293 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2294 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2302 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2303 LD->isExpandingLoad());
2305 MachinePointerInfo MPI;
2307 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2309 MPI =
LD->getPointerInfo().getWithOffset(
2312 MMO = DAG.getMachineFunction().getMachineMemOperand(
2314 Alignment,
LD->getAAInfo(),
LD->getRanges());
2316 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2317 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2318 LD->isExpandingLoad());
2328 ReplaceValueWith(
SDValue(LD, 1), Ch);
2334 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2338 Align Alignment =
LD->getBaseAlign();
2345 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2348 GetSplitVector(Mask, MaskLo, MaskHi);
2350 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2354 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2356 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2361 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2364 Hi = DAG.getPOISON(HiVT);
2366 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2367 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2373 "Indexed VP strided load during type legalization!");
2375 "Unexpected indexed variable-length load offset");
2380 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2382 EVT LoMemVT, HiMemVT;
2383 bool HiIsEmpty =
false;
2384 std::tie(LoMemVT, HiMemVT) =
2385 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2390 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2393 GetSplitVector(Mask, LoMask, HiMask);
2395 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2399 std::tie(LoEVL, HiEVL) =
2403 Lo = DAG.getStridedLoadVP(
2430 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2437 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2448 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2456 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2461 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2471 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2474 GetSplitVector(Mask, MaskLo, MaskHi);
2476 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2480 EVT LoMemVT, HiMemVT;
2481 bool HiIsEmpty =
false;
2482 std::tie(LoMemVT, HiMemVT) =
2483 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2485 SDValue PassThruLo, PassThruHi;
2487 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2489 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2491 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2495 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2505 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2508 MachinePointerInfo MPI;
2515 MMO = DAG.getMachineFunction().getMachineMemOperand(
2519 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2531 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2539 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2547 }
Ops = [&]() -> Operands {
2549 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2552 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2555 EVT MemoryVT =
N->getMemoryVT();
2556 Align Alignment =
N->getBaseAlign();
2561 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2563 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2566 EVT LoMemVT, HiMemVT;
2568 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2571 if (getTypeAction(
Ops.Index.getValueType()) ==
2573 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2575 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2578 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2580 Alignment,
N->getAAInfo(),
N->getRanges());
2583 SDValue PassThru = MGT->getPassThru();
2584 SDValue PassThruLo, PassThruHi;
2587 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2589 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2594 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2595 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2596 OpsLo, MMO, IndexTy, ExtType);
2598 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2599 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2600 OpsHi, MMO, IndexTy, ExtType);
2604 std::tie(EVLLo, EVLHi) =
2605 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2607 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2608 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2609 MMO, VPGT->getIndexType());
2611 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2612 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2613 MMO, VPGT->getIndexType());
2623 ReplaceValueWith(
SDValue(
N, 1), Ch);
2637 EVT VecVT =
N->getValueType(0);
2639 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2640 bool HasCustomLowering =
false;
2647 HasCustomLowering =
true;
2653 SDValue Passthru =
N->getOperand(2);
2654 if (!HasCustomLowering) {
2655 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2656 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2663 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2664 std::tie(LoMask, HiMask) = SplitMask(Mask);
2666 SDValue UndefPassthru = DAG.getUNDEF(LoVT);
2671 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2672 MachineFunction &MF = DAG.getMachineFunction();
2679 SDValue Offset = DAG.getNode(ISD::VECREDUCE_ADD,
DL, MVT::i32, WideMask);
2680 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2682 SDValue Chain = DAG.getEntryNode();
2683 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2687 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2692 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2696 assert(
N->getValueType(0).isVector() &&
2697 N->getOperand(0).getValueType().isVector() &&
2698 "Operand types must be vectors");
2702 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2706 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2708 GetSplitVector(
N->getOperand(0), LL, LH);
2710 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2712 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2714 GetSplitVector(
N->getOperand(1), RL, RH);
2716 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2719 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2720 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2722 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2723 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2724 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2725 std::tie(EVLLo, EVLHi) =
2726 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2727 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2729 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2739 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2743 EVT InVT =
N->getOperand(0).getValueType();
2745 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2747 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2749 const SDNodeFlags
Flags =
N->getFlags();
2750 unsigned Opcode =
N->getOpcode();
2751 if (
N->getNumOperands() <= 2) {
2753 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2754 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2756 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2757 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2762 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2763 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2766 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2769 std::tie(EVLLo, EVLHi) =
2770 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2773 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2779 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2783 EVT InVT =
N->getOperand(0).getValueType();
2785 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2787 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2790 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2791 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2792 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2793 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2796void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2801 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2802 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2806 EVT InVT =
N->getOperand(0).getValueType();
2808 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2810 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2812 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2813 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2815 SDNode *HiNode =
Hi.getNode();
2816 SDNode *LoNode =
Lo.getNode();
2819 unsigned OtherNo = 1 - ResNo;
2820 EVT OtherVT =
N->getValueType(OtherNo);
2828 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2835 EVT SrcVT =
N->getOperand(0).getValueType();
2836 EVT DestVT =
N->getValueType(0);
2838 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2855 LLVMContext &Ctx = *DAG.getContext();
2859 EVT SplitLoVT, SplitHiVT;
2860 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2861 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2862 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2863 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2864 N->dump(&DAG);
dbgs() <<
"\n");
2865 if (!
N->isVPOpcode()) {
2868 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2870 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2872 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2873 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2879 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2880 N->getOperand(1),
N->getOperand(2));
2882 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2885 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2888 std::tie(EVLLo, EVLHi) =
2889 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2891 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2892 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2897 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2905 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2906 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2912 return N.getResNo() == 0 &&
2916 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2918 ArrayRef<int>
Mask) {
2921 "Expected build vector node.");
2924 for (
unsigned I = 0;
I < NewElts; ++
I) {
2927 unsigned Idx =
Mask[
I];
2929 Ops[
I] = Input2.getOperand(Idx - NewElts);
2931 Ops[
I] = Input1.getOperand(Idx);
2936 return DAG.getBuildVector(NewVT,
DL,
Ops);
2942 SmallVector<int> OrigMask(
N->getMask());
2944 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2945 &
DL](SmallVectorImpl<int> &
Mask) {
2947 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2948 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2959 for (
auto &
P : ShufflesIdxs) {
2960 if (
P.second.size() < 2)
2964 for (
int &Idx : Mask) {
2967 unsigned SrcRegIdx = Idx / NewElts;
2968 if (Inputs[SrcRegIdx].
isUndef()) {
2976 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2981 Idx = MaskElt % NewElts +
2982 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
2988 Inputs[
P.second[0]] =
P.first.first;
2989 Inputs[
P.second[1]] =
P.first.second;
2992 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
2995 SmallBitVector UsedSubVector(2 * std::size(Inputs));
2996 for (
int &Idx : Mask) {
2999 unsigned SrcRegIdx = Idx / NewElts;
3000 if (Inputs[SrcRegIdx].
isUndef()) {
3007 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3008 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3011 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3013 if (UsedSubVector.count() > 1) {
3015 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3016 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3018 if (Pairs.
empty() || Pairs.
back().size() == 2)
3020 if (UsedSubVector.test(2 *
I)) {
3021 Pairs.
back().emplace_back(
I, 0);
3023 assert(UsedSubVector.test(2 *
I + 1) &&
3024 "Expected to be used one of the subvectors.");
3025 Pairs.
back().emplace_back(
I, 1);
3028 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3030 for (
int &Idx : Mask) {
3033 unsigned SrcRegIdx = Idx / NewElts;
3035 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3036 return Idxs.front().first == SrcRegIdx ||
3037 Idxs.back().first == SrcRegIdx;
3039 if (It == Pairs.
end())
3041 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3042 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3045 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3046 Inputs[Idxs.front().first] = DAG.
getNode(
3048 Inputs[Idxs.front().first].getValueType(),
3049 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3050 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3059 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3063 if (Shuffle->getOperand(0).getValueType() != NewVT)
3066 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3067 !Shuffle->isSplat()) {
3069 }
else if (!Inputs[
I].hasOneUse() &&
3070 !Shuffle->getOperand(1).isUndef()) {
3072 for (
int &Idx : Mask) {
3075 unsigned SrcRegIdx = Idx / NewElts;
3078 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3083 int OpIdx = MaskElt / NewElts;
3097 if (Shuffle->getOperand(
OpIdx).isUndef())
3099 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3100 if (It == std::end(Inputs))
3102 int FoundOp = std::distance(std::begin(Inputs), It);
3105 for (
int &Idx : Mask) {
3108 unsigned SrcRegIdx = Idx / NewElts;
3111 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3116 int MaskIdx = MaskElt / NewElts;
3117 if (
OpIdx == MaskIdx)
3118 Idx = MaskElt % NewElts + FoundOp * NewElts;
3129 for (
int &Idx : Mask) {
3132 unsigned SrcRegIdx = Idx / NewElts;
3135 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3136 int OpIdx = MaskElt / NewElts;
3139 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3145 TryPeekThroughShufflesInputs(OrigMask);
3147 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3148 NewElts](SmallVectorImpl<int> &
Mask) {
3149 SetVector<SDValue> UniqueInputs;
3150 SetVector<SDValue> UniqueConstantInputs;
3151 for (
const auto &
I : Inputs) {
3153 UniqueConstantInputs.
insert(
I);
3154 else if (!
I.isUndef())
3159 if (UniqueInputs.
size() != std::size(Inputs)) {
3160 auto &&UniqueVec = UniqueInputs.
takeVector();
3161 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3162 unsigned ConstNum = UniqueConstantVec.size();
3163 for (
int &Idx : Mask) {
3166 unsigned SrcRegIdx = Idx / NewElts;
3167 if (Inputs[SrcRegIdx].
isUndef()) {
3171 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3172 if (It != UniqueConstantVec.end()) {
3173 Idx = (Idx % NewElts) +
3174 NewElts * std::distance(UniqueConstantVec.begin(), It);
3175 assert(Idx >= 0 &&
"Expected defined mask idx.");
3178 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3179 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3180 Idx = (Idx % NewElts) +
3181 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3182 assert(Idx >= 0 &&
"Expected defined mask idx.");
3184 copy(UniqueConstantVec, std::begin(Inputs));
3185 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3188 MakeUniqueInputs(OrigMask);
3190 copy(Inputs, std::begin(OrigInputs));
3196 unsigned FirstMaskIdx =
High * NewElts;
3199 assert(!Output &&
"Expected default initialized initial value.");
3200 TryPeekThroughShufflesInputs(Mask);
3201 MakeUniqueInputs(Mask);
3203 copy(Inputs, std::begin(TmpInputs));
3206 bool SecondIteration =
false;
3207 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3212 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3213 SecondIteration =
true;
3214 return SecondIteration;
3217 Mask, std::size(Inputs), std::size(Inputs),
3219 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3220 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3221 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3223 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3225 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3226 DAG.getUNDEF(NewVT), Mask);
3227 Inputs[Idx] = Output;
3229 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3230 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3231 unsigned Idx2,
bool ) {
3232 if (AccumulateResults(Idx1)) {
3235 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3237 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3238 Inputs[Idx2], Mask);
3242 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3244 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3245 TmpInputs[Idx2], Mask);
3247 Inputs[Idx1] = Output;
3249 copy(OrigInputs, std::begin(Inputs));
3254 EVT OVT =
N->getValueType(0);
3261 const Align Alignment =
3262 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3264 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3265 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3270 ReplaceValueWith(
SDValue(
N, 1), Chain);
3275 EVT DstVTLo, DstVTHi;
3276 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3280 EVT SrcVT =
N->getOperand(0).getValueType();
3282 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3284 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3286 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3287 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3293 GetSplitVector(
N->getOperand(0), InLo, InHi);
3304 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3305 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3310 EVT VT =
N->getValueType(0);
3317 Align Alignment = DAG.getReducedAlign(VT,
false);
3322 EVT PtrVT =
StackPtr.getValueType();
3323 auto &MF = DAG.getMachineFunction();
3327 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3330 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3336 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3337 DAG.getConstant(1,
DL, PtrVT));
3339 DAG.getConstant(EltWidth,
DL, PtrVT));
3341 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3343 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3344 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3345 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3348 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3350 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3355 EVT VT =
N->getValueType(0);
3367 EVL1 = ZExtPromotedInteger(EVL1);
3369 Align Alignment = DAG.getReducedAlign(VT,
false);
3374 EVT PtrVT =
StackPtr.getValueType();
3375 auto &MF = DAG.getMachineFunction();
3379 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3382 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3386 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3388 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3389 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3390 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3394 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3399 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3400 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3402 uint64_t TrailingElts = -
Imm;
3404 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3413 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3417 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3419 DAG.getVectorIdxConstant(0,
DL));
3425void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3433 GetSplitVector(Acc, AccLo, AccHi);
3434 unsigned Opcode =
N->getOpcode();
3446 GetSplitVector(Input1, Input1Lo, Input1Hi);
3447 GetSplitVector(Input2, Input2Lo, Input2Hi);
3450 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3451 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3454void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3462 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3464 Lo = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, LoVT, Op0, Op1);
3467 Hi = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, HiVT, HiStartVal, Op1);
3470void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3471 unsigned Factor =
N->getNumOperands();
3474 for (
unsigned i = 0; i != Factor; ++i) {
3476 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3478 Ops[i * 2 + 1] = OpHi;
3489 for (
unsigned i = 0; i != Factor; ++i)
3493void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3494 unsigned Factor =
N->getNumOperands();
3497 for (
unsigned i = 0; i != Factor; ++i) {
3499 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3501 Ops[i + Factor] = OpHi;
3512 for (
unsigned i = 0; i != Factor; ++i) {
3513 unsigned IdxLo = 2 * i;
3514 unsigned IdxHi = 2 * i + 1;
3515 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3516 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3528bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3533 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3536 switch (
N->getOpcode()) {
3539 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3549 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3550 case ISD::BITCAST: Res = SplitVecOp_BITCAST(
N);
break;
3555 case ISD::VP_TRUNCATE:
3557 Res = SplitVecOp_TruncateHelper(
N);
3560 case ISD::VP_FP_ROUND:
3569 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3576 case ISD::VP_SCATTER:
3580 case ISD::VP_GATHER:
3584 Res = SplitVecOp_VSELECT(
N, OpNo);
3587 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3593 case ISD::VP_SINT_TO_FP:
3594 case ISD::VP_UINT_TO_FP:
3595 if (
N->getValueType(0).bitsLT(
3596 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3597 Res = SplitVecOp_TruncateHelper(
N);
3599 Res = SplitVecOp_UnaryOp(
N);
3603 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3607 case ISD::VP_FP_TO_SINT:
3608 case ISD::VP_FP_TO_UINT:
3612 case ISD::FP_EXTEND:
3621 Res = SplitVecOp_UnaryOp(
N);
3624 Res = SplitVecOp_FPOpDifferentTypes(
N);
3629 Res = SplitVecOp_CMP(
N);
3633 Res = SplitVecOp_FAKE_USE(
N);
3638 Res = SplitVecOp_ExtVecInRegOp(
N);
3641 case ISD::VECREDUCE_FADD:
3642 case ISD::VECREDUCE_FMUL:
3643 case ISD::VECREDUCE_ADD:
3644 case ISD::VECREDUCE_MUL:
3645 case ISD::VECREDUCE_AND:
3646 case ISD::VECREDUCE_OR:
3647 case ISD::VECREDUCE_XOR:
3648 case ISD::VECREDUCE_SMAX:
3649 case ISD::VECREDUCE_SMIN:
3650 case ISD::VECREDUCE_UMAX:
3651 case ISD::VECREDUCE_UMIN:
3652 case ISD::VECREDUCE_FMAX:
3653 case ISD::VECREDUCE_FMIN:
3654 case ISD::VECREDUCE_FMAXIMUM:
3655 case ISD::VECREDUCE_FMINIMUM:
3656 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3658 case ISD::VECREDUCE_SEQ_FADD:
3659 case ISD::VECREDUCE_SEQ_FMUL:
3660 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3662 case ISD::VP_REDUCE_FADD:
3663 case ISD::VP_REDUCE_SEQ_FADD:
3664 case ISD::VP_REDUCE_FMUL:
3665 case ISD::VP_REDUCE_SEQ_FMUL:
3666 case ISD::VP_REDUCE_ADD:
3667 case ISD::VP_REDUCE_MUL:
3668 case ISD::VP_REDUCE_AND:
3669 case ISD::VP_REDUCE_OR:
3670 case ISD::VP_REDUCE_XOR:
3671 case ISD::VP_REDUCE_SMAX:
3672 case ISD::VP_REDUCE_SMIN:
3673 case ISD::VP_REDUCE_UMAX:
3674 case ISD::VP_REDUCE_UMIN:
3675 case ISD::VP_REDUCE_FMAX:
3676 case ISD::VP_REDUCE_FMIN:
3677 case ISD::VP_REDUCE_FMAXIMUM:
3678 case ISD::VP_REDUCE_FMINIMUM:
3679 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3681 case ISD::VP_CTTZ_ELTS:
3682 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3683 Res = SplitVecOp_VP_CttzElements(
N);
3685 case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
3686 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3688 case ISD::PARTIAL_REDUCE_UMLA:
3689 case ISD::PARTIAL_REDUCE_SMLA:
3690 case ISD::PARTIAL_REDUCE_SUMLA:
3691 case ISD::PARTIAL_REDUCE_FMLA:
3692 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3697 if (!Res.
getNode())
return false;
3704 if (
N->isStrictFPOpcode())
3706 "Invalid operand expansion");
3709 "Invalid operand expansion");
3711 ReplaceValueWith(
SDValue(
N, 0), Res);
3715SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3718 assert(OpNo == 0 &&
"Illegal operand must be mask");
3725 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3728 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3729 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3730 "Lo and Hi have differing types");
3733 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3734 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3736 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3737 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3738 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3739 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3749SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3752 assert(OpNo == 1 &&
"Illegal operand must be mask");
3757 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3759 EVT VecVT =
N->getValueType(0);
3763SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3764 EVT ResVT =
N->getValueType(0);
3770 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3771 GetSplitVector(VecOp,
Lo,
Hi);
3773 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3778 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3779 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3783 EVT ResVT =
N->getValueType(0);
3789 SDNodeFlags
Flags =
N->getFlags();
3792 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3793 GetSplitVector(VecOp,
Lo,
Hi);
3795 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3801 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3804SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3805 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3806 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3808 unsigned Opc =
N->getOpcode();
3809 EVT ResVT =
N->getValueType(0);
3815 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3816 GetSplitVector(VecOp,
Lo,
Hi);
3819 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3822 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3824 const SDNodeFlags
Flags =
N->getFlags();
3828 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3833 EVT ResVT =
N->getValueType(0);
3836 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3837 EVT InVT =
Lo.getValueType();
3842 if (
N->isStrictFPOpcode()) {
3843 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3844 {N->getOperand(0), Lo});
3845 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3846 {N->getOperand(0), Hi});
3855 ReplaceValueWith(
SDValue(
N, 1), Ch);
3856 }
else if (
N->getNumOperands() == 3) {
3857 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3858 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3859 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3860 std::tie(EVLLo, EVLHi) =
3861 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3862 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3863 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3865 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3866 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3875 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3877 DAG.
getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
Lo);
3878 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other, Chain,
Hi);
3885 EVT ResVT =
N->getValueType(0);
3887 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3891 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3892 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
3893 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
3897 Lo = BitConvertToInteger(
Lo);
3898 Hi = BitConvertToInteger(
Hi);
3900 if (DAG.getDataLayout().isBigEndian())
3903 return DAG.getNode(ISD::BITCAST, dl, ResVT, JoinIntegers(
Lo,
Hi));
3908 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3910 EVT ResVT =
N->getValueType(0);
3918 GetSplitVector(SubVec,
Lo,
Hi);
3927 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3929 return SecondInsertion;
3932SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3939 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3941 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
3943 ElementCount IdxVal =
3947 EVT SrcVT =
N->getOperand(0).getValueType();
3966 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
3967 LoEltsMin - IdxValMin);
3968 DAG.ExtractVectorElements(
Hi, Elts, 0,
3971 return DAG.getBuildVector(SubVT, dl, Elts);
3975 ElementCount ExtractIdx = IdxVal - LoElts;
3977 return DAG.getExtractSubvector(dl, SubVT,
Hi,
3980 EVT HiVT =
Hi.getValueType();
3982 "Only fixed-vector extracts are supported in this case");
3992 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
3993 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
3999 "Extracting scalable subvector from fixed-width unsupported");
4007 "subvector from a scalable predicate vector");
4013 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4015 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4016 auto &MF = DAG.getMachineFunction();
4020 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4024 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4027 SubVT, dl, Store, StackPtr,
4031SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4037 uint64_t IdxVal =
Index->getZExtValue();
4040 GetSplitVector(Vec,
Lo,
Hi);
4042 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4044 if (IdxVal < LoElts)
4045 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4048 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4053 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4065 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4071 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4073 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4074 auto &MF = DAG.getMachineFunction();
4077 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4081 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4085 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4087 return DAG.getExtLoad(
4098 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4106 SplitVecRes_Gather(
N,
Lo,
Hi);
4109 ReplaceValueWith(
SDValue(
N, 0), Res);
4114 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4118 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4120 SDValue EVL =
N->getVectorLength();
4122 Align Alignment =
N->getBaseAlign();
4128 GetSplitVector(
Data, DataLo, DataHi);
4130 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4135 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4138 GetSplitVector(Mask, MaskLo, MaskHi);
4140 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4143 EVT MemoryVT =
N->getMemoryVT();
4144 EVT LoMemVT, HiMemVT;
4145 bool HiIsEmpty =
false;
4146 std::tie(LoMemVT, HiMemVT) =
4147 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4151 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4154 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4159 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4160 N->getAddressingMode(),
N->isTruncatingStore(),
4161 N->isCompressingStore());
4167 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4168 N->isCompressingStore());
4170 MachinePointerInfo MPI;
4174 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4179 MMO = DAG.getMachineFunction().getMachineMemOperand(
4181 Alignment,
N->getAAInfo(),
N->getRanges());
4183 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4184 N->getAddressingMode(),
N->isTruncatingStore(),
4185 N->isCompressingStore());
4194 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4195 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4202 GetSplitVector(
Data, LoData, HiData);
4204 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4206 EVT LoMemVT, HiMemVT;
4207 bool HiIsEmpty =
false;
4208 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4214 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4215 else if (getTypeAction(
Mask.getValueType()) ==
4217 GetSplitVector(Mask, LoMask, HiMask);
4219 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4222 std::tie(LoEVL, HiEVL) =
4223 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4227 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4228 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4229 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4240 EVT PtrVT =
N->getBasePtr().getValueType();
4243 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4246 Align Alignment =
N->getBaseAlign();
4251 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4252 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4254 Alignment,
N->getAAInfo(),
N->getRanges());
4257 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4258 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4259 N->isCompressingStore());
4268 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4272 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4275 Align Alignment =
N->getBaseAlign();
4281 GetSplitVector(
Data, DataLo, DataHi);
4283 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4288 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4291 GetSplitVector(Mask, MaskLo, MaskHi);
4293 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4296 EVT MemoryVT =
N->getMemoryVT();
4297 EVT LoMemVT, HiMemVT;
4298 bool HiIsEmpty =
false;
4299 std::tie(LoMemVT, HiMemVT) =
4300 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4303 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4308 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4309 N->getAddressingMode(),
N->isTruncatingStore(),
4310 N->isCompressingStore());
4318 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4319 N->isCompressingStore());
4321 MachinePointerInfo MPI;
4325 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4330 MMO = DAG.getMachineFunction().getMachineMemOperand(
4332 Alignment,
N->getAAInfo(),
N->getRanges());
4334 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4335 N->getAddressingMode(),
N->isTruncatingStore(),
4336 N->isCompressingStore());
4349 EVT MemoryVT =
N->getMemoryVT();
4350 Align Alignment =
N->getBaseAlign();
4357 }
Ops = [&]() -> Operands {
4359 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4363 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4368 EVT LoMemVT, HiMemVT;
4369 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4374 GetSplitVector(
Ops.Data, DataLo, DataHi);
4376 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4381 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4383 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4387 if (getTypeAction(
Ops.Index.getValueType()) ==
4389 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4391 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4395 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4397 Alignment,
N->getAAInfo(),
N->getRanges());
4400 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4402 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4403 MSC->getIndexType(), MSC->isTruncatingStore());
4408 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4409 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4410 MMO, MSC->getIndexType(),
4411 MSC->isTruncatingStore());
4415 std::tie(EVLLo, EVLHi) =
4416 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4418 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4419 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4420 VPSC->getIndexType());
4425 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4426 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4427 VPSC->getIndexType());
4431 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4432 assert(OpNo == 1 &&
"Can only split the stored value");
4435 bool isTruncating =
N->isTruncatingStore();
4438 EVT MemoryVT =
N->getMemoryVT();
4439 Align Alignment =
N->getBaseAlign();
4441 AAMDNodes AAInfo =
N->getAAInfo();
4443 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4445 EVT LoMemVT, HiMemVT;
4446 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4450 return TLI.scalarizeVectorStore(
N, DAG);
4453 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4454 Alignment, MMOFlags, AAInfo);
4456 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4459 MachinePointerInfo MPI;
4460 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4463 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4464 HiMemVT, Alignment, MMOFlags, AAInfo);
4466 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4482 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4488 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4509 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4510 SDValue InVec =
N->getOperand(OpNo);
4512 EVT OutVT =
N->getValueType(0);
4520 EVT LoOutVT, HiOutVT;
4521 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4522 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4527 if (isTypeLegal(LoOutVT) ||
4528 InElementSize <= OutElementSize * 2)
4529 return SplitVecOp_UnaryOp(
N);
4538 return SplitVecOp_UnaryOp(
N);
4542 GetSplitVector(InVec, InLoVec, InHiVec);
4548 EVT HalfElementVT = IsFloat ?
4550 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4557 if (
N->isStrictFPOpcode()) {
4558 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4559 {N->getOperand(0), InLoVec});
4560 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4561 {N->getOperand(0), InHiVec});
4567 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4568 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4572 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4580 if (
N->isStrictFPOpcode()) {
4584 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4592 DAG.getTargetConstant(
4593 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4600 assert(
N->getValueType(0).isVector() &&
4601 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4602 "Operand types must be vectors");
4604 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4606 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4607 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4609 EVT VT =
N->getValueType(0);
4615 }
else if (isStrict) {
4616 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4617 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4618 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4619 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4622 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4624 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4625 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4626 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4627 std::tie(EVLLo, EVLHi) =
4628 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4629 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4630 N->getOperand(2), MaskLo, EVLLo);
4631 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4632 N->getOperand(2), MaskHi, EVLHi);
4641 EVT ResVT =
N->getValueType(0);
4644 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4645 EVT InVT =
Lo.getValueType();
4650 if (
N->isStrictFPOpcode()) {
4651 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4652 {N->getOperand(0), Lo, N->getOperand(2)});
4653 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4654 {N->getOperand(0), Hi, N->getOperand(2)});
4658 Lo.getValue(1),
Hi.getValue(1));
4659 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4660 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4661 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4662 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4663 std::tie(EVLLo, EVLHi) =
4664 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4665 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4666 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4680SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4683 EVT LHSLoVT, LHSHiVT;
4684 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4686 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4687 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4690 std::tie(LHSLo, LHSHi) =
4691 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4694 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4697 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4703 LLVMContext &Ctxt = *DAG.getContext();
4706 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4707 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4708 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4710 EVT ResVT =
N->getValueType(0);
4715 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4716 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4722 EVT ResVT =
N->getValueType(0);
4725 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4726 EVT InVT =
Lo.getValueType();
4732 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4733 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4740 EVT ResVT =
N->getValueType(0);
4744 GetSplitVector(VecOp,
Lo,
Hi);
4746 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4747 auto [EVLLo, EVLHi] =
4749 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4755 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4757 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4758 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4761SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4772 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4773 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4774 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4775 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4776 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4777 OpsLo, MMO, IndexType);
4778 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4779 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4783SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4786 "Accumulator should already be a legal type, and shouldn't need "
4787 "further splitting");
4790 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4791 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4792 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4793 unsigned Opcode =
N->getOpcode();
4796 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4797 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4804void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4805 unsigned WidenResNo) {
4806 unsigned NumResults =
N->getNumValues();
4807 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4808 if (ResNo == WidenResNo)
4810 EVT ResVT =
N->getValueType(ResNo);
4816 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4817 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4822void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4823 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4826 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4831 auto unrollExpandedOp = [&]() {
4836 EVT VT =
N->getValueType(0);
4837 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4838 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4841 if (
N->getNumValues() > 1)
4842 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4848 switch (
N->getOpcode()) {
4851 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4859 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4862 case ISD::ADDRSPACECAST:
4863 Res = WidenVecRes_ADDRSPACECAST(
N);
4866 case ISD::BITCAST: Res = WidenVecRes_BITCAST(
N);
break;
4870 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4874 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4878 case ISD::EXPERIMENTAL_VP_SPLAT:
4879 Res = WidenVecRes_ScalarOp(
N);
4884 case ISD::VP_SELECT:
4886 Res = WidenVecRes_Select(
N);
4890 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4892 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4899 case ISD::VP_LOAD_FF:
4902 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4906 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4914 case ISD::VP_GATHER:
4918 Res = WidenVecRes_VECTOR_REVERSE(
N);
4920 case ISD::GET_ACTIVE_LANE_MASK:
4921 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4931 case ISD::OR:
case ISD::VP_OR:
4938 case ISD::FMINNUM_IEEE:
4939 case ISD::VP_FMINNUM:
4941 case ISD::FMAXNUM_IEEE:
4942 case ISD::VP_FMAXNUM:
4944 case ISD::VP_FMINIMUM:
4946 case ISD::VP_FMAXIMUM:
4947 case ISD::FMINIMUMNUM:
4948 case ISD::FMAXIMUMNUM:
4979 case ISD::VP_FCOPYSIGN:
4980 Res = WidenVecRes_Binary(
N);
4985 Res = WidenVecRes_CMP(
N);
4991 if (unrollExpandedOp())
5006 Res = WidenVecRes_BinaryCanTrap(
N);
5015 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5018#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5019 case ISD::STRICT_##DAGN:
5020#include "llvm/IR/ConstrainedOps.def"
5021 Res = WidenVecRes_StrictFP(
N);
5030 Res = WidenVecRes_OverflowOp(
N, ResNo);
5034 Res = WidenVecRes_FCOPYSIGN(
N);
5039 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5044 if (!unrollExpandedOp())
5045 Res = WidenVecRes_ExpOp(
N);
5051 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5055 case ISD::FP_EXTEND:
5056 case ISD::VP_FP_EXTEND:
5058 case ISD::VP_FP_ROUND:
5060 case ISD::VP_FP_TO_SINT:
5062 case ISD::VP_FP_TO_UINT:
5064 case ISD::VP_SIGN_EXTEND:
5066 case ISD::VP_SINT_TO_FP:
5067 case ISD::VP_TRUNCATE:
5070 case ISD::VP_UINT_TO_FP:
5072 case ISD::VP_ZERO_EXTEND:
5073 Res = WidenVecRes_Convert(
N);
5078 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5084 case ISD::VP_LLRINT:
5087 Res = WidenVecRes_XROUND(
N);
5103 case ISD::FNEARBYINT:
5106 case ISD::FROUNDEVEN:
5113 if (unrollExpandedOp())
5123 case ISD::VP_BITREVERSE:
5129 case ISD::VP_CTLZ_ZERO_UNDEF:
5135 case ISD::VP_CTTZ_ZERO_UNDEF:
5136 case ISD::FNEG:
case ISD::VP_FNEG:
5137 case ISD::FABS:
case ISD::VP_FABS:
5140 case ISD::VP_FFLOOR:
5142 case ISD::VP_FNEARBYINT:
5143 case ISD::VP_FROUND:
5144 case ISD::VP_FROUNDEVEN:
5145 case ISD::VP_FROUNDTOZERO:
5147 case ISD::ARITH_FENCE:
5150 Res = WidenVecRes_Unary(
N);
5157 Res = WidenVecRes_Ternary(
N);
5162 case ISD::FSINCOSPI: {
5163 if (!unrollExpandedOp())
5164 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5171 SetWidenedVector(
SDValue(
N, ResNo), Res);
5177 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5178 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5179 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5180 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5181 if (
N->getNumOperands() == 3)
5182 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5184 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5185 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5189 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5190 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5196 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5197 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5198 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5199 if (
N->getNumOperands() == 2)
5200 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5203 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5204 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5208 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5209 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5213 LLVMContext &Ctxt = *DAG.getContext();
5218 EVT OpVT =
LHS.getValueType();
5220 LHS = GetWidenedVector(
LHS);
5221 RHS = GetWidenedVector(
RHS);
5222 OpVT =
LHS.getValueType();
5225 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5228 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5234SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5237 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5238 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5239 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5241 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5250 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5253 if (ConcatEnd == 1) {
5254 VT = ConcatOps[0].getValueType();
5256 return ConcatOps[0];
5259 SDLoc dl(ConcatOps[0]);
5266 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5267 int Idx = ConcatEnd - 1;
5268 VT = ConcatOps[Idx--].getValueType();
5269 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5282 unsigned NumToInsert = ConcatEnd - Idx - 1;
5283 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5285 ConcatOps[Idx+1] = VecOp;
5286 ConcatEnd = Idx + 2;
5292 unsigned RealVals = ConcatEnd - Idx - 1;
5293 unsigned SubConcatEnd = 0;
5294 unsigned SubConcatIdx = Idx + 1;
5295 while (SubConcatEnd < RealVals)
5296 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5297 while (SubConcatEnd < OpsToConcat)
5298 SubConcatOps[SubConcatEnd++] = undefVec;
5300 NextVT, SubConcatOps);
5301 ConcatEnd = SubConcatIdx + 1;
5306 if (ConcatEnd == 1) {
5307 VT = ConcatOps[0].getValueType();
5309 return ConcatOps[0];
5314 if (
NumOps != ConcatEnd ) {
5316 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5317 ConcatOps[j] = UndefVal;
5325 unsigned Opcode =
N->getOpcode();
5327 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5331 const SDNodeFlags
Flags =
N->getFlags();
5332 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5333 NumElts = NumElts / 2;
5337 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5339 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5340 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5341 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5349 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5352 TLI.isTypeLegal(WideMaskVT)) {
5353 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5354 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5355 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5357 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5358 N->getValueType(0).getVectorElementCount());
5359 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5373 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5374 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5375 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5378 unsigned ConcatEnd = 0;
5386 while (CurNumElts != 0) {
5387 while (CurNumElts >= NumElts) {
5388 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5389 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5390 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5392 CurNumElts -= NumElts;
5395 NumElts = NumElts / 2;
5397 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5400 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5401 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5402 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5403 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5414 switch (
N->getOpcode()) {
5417 return WidenVecRes_STRICT_FSETCC(
N);
5424 return WidenVecRes_Convert_StrictFP(
N);
5431 unsigned Opcode =
N->getOpcode();
5433 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5437 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5438 NumElts = NumElts / 2;
5449 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5453 unsigned ConcatEnd = 0;
5460 for (
unsigned i = 1; i < NumOpers; ++i) {
5466 Oper = GetWidenedVector(Oper);
5472 DAG.getUNDEF(WideOpVT), Oper,
5473 DAG.getVectorIdxConstant(0, dl));
5485 while (CurNumElts != 0) {
5486 while (CurNumElts >= NumElts) {
5489 for (
unsigned i = 0; i < NumOpers; ++i) {
5492 EVT OpVT =
Op.getValueType();
5497 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5503 EVT OperVT[] = {VT, MVT::Other};
5505 ConcatOps[ConcatEnd++] = Oper;
5508 CurNumElts -= NumElts;
5511 NumElts = NumElts / 2;
5513 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5516 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5519 for (
unsigned i = 0; i < NumOpers; ++i) {
5522 EVT OpVT =
Op.getValueType();
5530 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5532 ConcatOps[ConcatEnd++] = Oper;
5541 if (Chains.
size() == 1)
5542 NewChain = Chains[0];
5545 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5550SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5552 EVT ResVT =
N->getValueType(0);
5553 EVT OvVT =
N->getValueType(1);
5554 EVT WideResVT, WideOvVT;
5559 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5564 WideLHS = GetWidenedVector(
N->getOperand(0));
5565 WideRHS = GetWidenedVector(
N->getOperand(1));
5567 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5575 N->getOperand(0), Zero);
5578 N->getOperand(1), Zero);
5581 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5582 SDNode *WideNode = DAG.getNode(
5583 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5586 unsigned OtherNo = 1 - ResNo;
5587 EVT OtherVT =
N->getValueType(OtherNo);
5594 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5597 return SDValue(WideNode, ResNo);
5601 LLVMContext &Ctx = *DAG.getContext();
5605 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5610 unsigned Opcode =
N->getOpcode();
5611 const SDNodeFlags
Flags =
N->getFlags();
5617 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5619 InOp = ZExtPromotedInteger(InOp);
5630 InOp = GetWidenedVector(
N->getOperand(0));
5633 if (InVTEC == WidenEC) {
5634 if (
N->getNumOperands() == 1)
5635 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5636 if (
N->getNumOperands() == 3) {
5637 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5640 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5642 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5657 if (TLI.isTypeLegal(InWidenVT)) {
5665 unsigned NumConcat =
5670 if (
N->getNumOperands() == 1)
5671 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5672 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5676 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5678 if (
N->getNumOperands() == 1)
5679 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5680 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5689 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5690 for (
unsigned i=0; i < MinElts; ++i) {
5691 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5692 if (
N->getNumOperands() == 1)
5695 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5698 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5703 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5707 EVT SrcVT = Src.getValueType();
5711 Src = GetWidenedVector(Src);
5712 SrcVT = Src.getValueType();
5719 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5724 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5728 EVT SrcVT = Src.getValueType();
5732 Src = GetWidenedVector(Src);
5733 SrcVT = Src.getValueType();
5740 if (
N->getNumOperands() == 1)
5741 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5743 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5744 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5748 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5751SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5756 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5762 unsigned Opcode =
N->getOpcode();
5768 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5773 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5774 for (
unsigned i=0; i < MinElts; ++i) {
5775 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5776 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5780 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5782 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5785SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5786 unsigned Opcode =
N->getOpcode();
5790 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5799 InOp = GetWidenedVector(InOp);
5806 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5813 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5814 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5831 while (
Ops.size() != WidenNumElts)
5832 Ops.push_back(DAG.getPOISON(WidenSVT));
5834 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5840 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5841 return WidenVecRes_BinaryCanTrap(
N);
5844 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5851SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5853 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5856 SDValue Arg = GetWidenedVector(FpValue);
5857 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5862 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5863 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5865 EVT ExpVT =
RHS.getValueType();
5870 ExpOp = ModifyToType(
RHS, WideExpVT);
5873 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5878 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5879 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5880 if (
N->getNumOperands() == 1)
5881 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5883 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5884 N->getOperand(1),
N->getFlags());
5886 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5887 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5891 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5892 {InOp,
Mask,
N->getOperand(2)});
5896 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5899 .getVectorElementType(),
5901 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5902 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5903 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5906SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5908 EVT VT0 =
N->getValueType(0);
5909 EVT VT1 =
N->getValueType(1);
5913 "expected both results to be vectors of matching element count");
5915 LLVMContext &Ctx = *DAG.getContext();
5916 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5918 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5925 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5928 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5929 return SDValue(WidenNode, ResNo);
5932SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5933 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5934 return GetWidenedVector(WidenVec);
5938 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5939 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5942 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5943 AddrSpaceCastN->getSrcAddressSpace(),
5944 AddrSpaceCastN->getDestAddressSpace());
5950 EVT VT =
N->getValueType(0);
5951 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5954 switch (getTypeAction(InVT)) {
5968 SDValue NInOp = GetPromotedInteger(InOp);
5970 if (WidenVT.
bitsEq(NInVT)) {
5973 if (DAG.getDataLayout().isBigEndian()) {
5976 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
5978 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NInOp);
5995 InOp = GetWidenedVector(InOp);
5997 if (WidenVT.
bitsEq(InVT))
5999 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp);
6007 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6012 unsigned NewNumParts = WidenSize / InSize;
6025 EVT OrigInVT =
N->getOperand(0).getValueType();
6030 if (TLI.isTypeLegal(NewInVT)) {
6038 if (WidenSize % InSize == 0) {
6045 DAG.ExtractVectorElements(InOp,
Ops);
6046 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6054 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec);
6058 return CreateStackStoreLoad(InOp, WidenVT);
6061SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6063 N->getOpcode(), SDLoc(
N),
6064 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6065 N->getOperand(0),
N->getOperand(1),
N->getOperand(2));
6071 EVT VT =
N->getValueType(0);
6075 EVT EltVT =
N->getOperand(0).getValueType();
6078 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6082 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6083 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6085 return DAG.getBuildVector(WidenVT, dl, NewOps);
6089 EVT InVT =
N->getOperand(0).getValueType();
6090 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6092 unsigned NumOperands =
N->getNumOperands();
6094 bool InputWidened =
false;
6098 if (WidenNumElts % NumInElts == 0) {
6100 unsigned NumConcat = WidenNumElts / NumInElts;
6101 SDValue UndefVal = DAG.getPOISON(InVT);
6103 for (
unsigned i=0; i < NumOperands; ++i)
6104 Ops[i] =
N->getOperand(i);
6105 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6110 InputWidened =
true;
6111 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6114 for (i=1; i < NumOperands; ++i)
6115 if (!
N->getOperand(i).isUndef())
6118 if (i == NumOperands)
6121 return GetWidenedVector(
N->getOperand(0));
6123 if (NumOperands == 2) {
6125 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6130 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6131 for (
unsigned i = 0; i < NumInElts; ++i) {
6133 MaskOps[i + NumInElts] = i + WidenNumElts;
6135 return DAG.getVectorShuffle(WidenVT, dl,
6136 GetWidenedVector(
N->getOperand(0)),
6137 GetWidenedVector(
N->getOperand(1)),
6144 "Cannot use build vectors to widen CONCAT_VECTOR result");
6152 for (
unsigned i=0; i < NumOperands; ++i) {
6155 InOp = GetWidenedVector(InOp);
6156 for (
unsigned j = 0;
j < NumInElts; ++
j)
6157 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6159 SDValue UndefVal = DAG.getPOISON(EltVT);
6160 for (; Idx < WidenNumElts; ++Idx)
6161 Ops[Idx] = UndefVal;
6162 return DAG.getBuildVector(WidenVT, dl,
Ops);
6165SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6166 EVT VT =
N->getValueType(0);
6167 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6168 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6175SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6176 EVT VT =
N->getValueType(0);
6178 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6183 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6185 InOp = GetWidenedVector(InOp);
6191 if (IdxVal == 0 && InVT == WidenVT)
6198 assert(IdxVal % VTNumElts == 0 &&
6199 "Expected Idx to be a multiple of subvector minimum vector length");
6200 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6213 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6214 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6215 "down type's element count");
6222 for (;
I < VTNumElts / GCD; ++
I)
6224 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6225 for (;
I < WidenNumElts / GCD; ++
I)
6233 Align Alignment = DAG.getReducedAlign(InVT,
false);
6235 MachineFunction &MF = DAG.getMachineFunction();
6247 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6254 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6255 return DAG.getMaskedLoad(
6256 WidenVT, dl, Ch, StackPtr, DAG.getUNDEF(
StackPtr.getValueType()), Mask,
6264 for (i = 0; i < VTNumElts; ++i)
6265 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6267 SDValue UndefVal = DAG.getPOISON(EltVT);
6268 for (; i < WidenNumElts; ++i)
6270 return DAG.getBuildVector(WidenVT, dl,
Ops);
6276 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6281SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6282 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6285 N->getOperand(1),
N->getOperand(2));
6298 if (!
LD->getMemoryVT().isByteSized()) {
6300 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6302 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6311 EVT VT =
LD->getValueType(0);
6312 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6313 EVT WideMaskVT = getSetCCResultType(WideVT);
6316 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6317 TLI.isTypeLegal(WideMaskVT)) {
6320 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6324 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6325 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6337 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6339 Result = GenWidenVectorLoads(LdChain, LD);
6346 if (LdChain.
size() == 1)
6347 NewChain = LdChain[0];
6353 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6364 SDValue NewLoad = DAG.getMaskedLoad(
6365 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6366 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6367 LD->getAddressingMode(),
LD->getExtensionType());
6377 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6379 SDValue EVL =
N->getVectorLength();
6386 "Unable to widen binary VP op");
6387 Mask = GetWidenedVector(Mask);
6388 assert(
Mask.getValueType().getVectorElementCount() ==
6389 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6390 .getVectorElementCount() &&
6391 "Unable to widen vector load");
6394 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6395 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6396 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6404 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6406 SDValue EVL =
N->getVectorLength();
6412 "Unable to widen binary VP op");
6413 Mask = GetWidenedVector(Mask);
6414 assert(
Mask.getValueType().getVectorElementCount() ==
6415 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6416 .getVectorElementCount() &&
6417 "Unable to widen vector load");
6419 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6420 Mask, EVL,
N->getMemOperand());
6433 "Unable to widen VP strided load");
6434 Mask = GetWidenedVector(Mask);
6436 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6437 assert(
Mask.getValueType().getVectorElementCount() ==
6439 "Data and mask vectors should have the same number of elements");
6441 SDValue Res = DAG.getStridedLoadVP(
6442 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6443 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6444 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6445 N->isExpandingLoad());
6453SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6458 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6460 Mask.getValueType().getVectorElementType(),
6463 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6464 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6465 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6467 WideMask, WidePassthru);
6471 EVT VT =
N->getValueType(0);
6472 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6474 EVT MaskVT =
Mask.getValueType();
6475 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6484 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6485 TLI.isTypeLegal(WideMaskVT) &&
6491 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6492 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6496 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6497 N->getMemoryVT(),
N->getMemOperand());
6501 if (!
N->getPassThru()->isUndef()) {
6504 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6515 Mask = ModifyToType(Mask, WideMaskVT,
true);
6517 SDValue Res = DAG.getMaskedLoad(
6518 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6519 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6520 ExtType,
N->isExpandingLoad());
6529 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6531 EVT MaskVT =
Mask.getValueType();
6532 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6541 Mask = ModifyToType(Mask, WideMaskVT,
true);
6546 Index.getValueType().getScalarType(),
6548 Index = ModifyToType(Index, WideIndexVT);
6554 N->getMemoryVT().getScalarType(), NumElts);
6555 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6556 WideMemVT, dl,
Ops,
N->getMemOperand(),
6557 N->getIndexType(),
N->getExtensionType());
6566 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6574 N->getMemoryVT().getScalarType(), WideEC);
6575 Mask = GetWidenedMask(Mask, WideEC);
6578 Mask,
N->getVectorLength()};
6579 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6580 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6589 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6590 if (
N->isVPOpcode())
6591 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0),
6592 N->getOperand(1),
N->getOperand(2));
6593 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6621 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6622 return N->getOperand(OpNo).getValueType();
6630 N =
N.getOperand(0);
6632 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6633 if (!
N->getOperand(i)->isUndef())
6635 N =
N.getOperand(0);
6639 N =
N.getOperand(0);
6641 N =
N.getOperand(0);
6668 { MaskVT, MVT::Other },
Ops);
6669 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6676 LLVMContext &Ctx = *DAG.getContext();
6679 if (MaskScalarBits < ToMaskScalBits) {
6683 }
else if (MaskScalarBits > ToMaskScalBits) {
6689 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6691 "Mask should have the right element size by now.");
6694 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6696 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6699 EVT SubVT =
Mask->getValueType(0);
6705 assert((
Mask->getValueType(0) == ToMaskVT) &&
6706 "A mask of ToMaskVT should have been produced by now.");
6716 LLVMContext &Ctx = *DAG.getContext();
6727 EVT CondVT =
Cond->getValueType(0);
6731 EVT VSelVT =
N->getValueType(0);
6743 EVT FinalVT = VSelVT;
6754 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6755 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6762 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6770 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6773 EVT ToMaskVT = VSelVT;
6780 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6796 if (ScalarBits0 != ScalarBits1) {
6797 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6798 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6810 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6811 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6812 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6815 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6823 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6828 unsigned Opcode =
N->getOpcode();
6830 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6831 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6832 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6834 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6840 Cond1 = GetWidenedVector(Cond1);
6848 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6849 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6854 Cond1 = ModifyToType(Cond1, CondWidenVT);
6857 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6858 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6860 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6861 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6863 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6867 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6868 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6871 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6875 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6876 return DAG.getUNDEF(WidenVT);
6880 EVT VT =
N->getValueType(0);
6883 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6887 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6888 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6891 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6892 for (
unsigned i = 0; i != NumElts; ++i) {
6893 int Idx =
N->getMaskElt(i);
6894 if (Idx < (
int)NumElts)
6897 NewMask[i] = Idx - NumElts + WidenNumElts;
6899 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6903 EVT VT =
N->getValueType(0);
6907 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6908 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6914 unsigned IdxVal = WidenNumElts - VTNumElts;
6927 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6930 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6931 "down type's element count");
6934 for (; i < VTNumElts / GCD; ++i)
6936 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6937 for (; i < WidenNumElts / GCD; ++i)
6945 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6946 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6948 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6952SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6953 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6954 return DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, SDLoc(
N), NVT,
N->ops());
6958 assert(
N->getValueType(0).isVector() &&
6959 N->getOperand(0).getValueType().isVector() &&
6960 "Operands must be vectors");
6961 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6974 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
6975 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
6982 InOp1 = GetWidenedVector(InOp1);
6983 InOp2 = GetWidenedVector(InOp2);
6986 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
6997 "Input not widened to expected type!");
6999 if (
N->getOpcode() == ISD::VP_SETCC) {
7002 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7003 N->getOperand(2), Mask,
N->getOperand(4));
7005 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7010 assert(
N->getValueType(0).isVector() &&
7011 N->getOperand(1).getValueType().isVector() &&
7012 "Operands must be vectors");
7013 EVT VT =
N->getValueType(0);
7014 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7024 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7029 for (
unsigned i = 0; i != NumElts; ++i) {
7030 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7031 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7033 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7034 {Chain, LHSElem, RHSElem, CC});
7035 Chains[i] = Scalars[i].getValue(1);
7036 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7037 DAG.getBoolConstant(
true, dl, EltVT, VT),
7038 DAG.getBoolConstant(
false, dl, EltVT, VT));
7042 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7044 return DAG.getBuildVector(WidenVT, dl, Scalars);
7050bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7051 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7055 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7058 switch (
N->getOpcode()) {
7061 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7067 case ISD::BITCAST: Res = WidenVecOp_BITCAST(
N);
break;
7069 Res = WidenVecOp_FAKE_USE(
N);
7075 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7076 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7077 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7078 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7083 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7085 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7086 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7087 case ISD::MSCATTER: Res = WidenVecOp_MSCATTER(
N, OpNo);
break;
7088 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7089 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7099 Res = WidenVecOp_UnrollVectorOp(
N);
7106 Res = WidenVecOp_EXTEND(
N);
7111 Res = WidenVecOp_CMP(
N);
7114 case ISD::FP_EXTEND:
7127 Res = WidenVecOp_Convert(
N);
7132 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7135 case ISD::EXPERIMENTAL_VP_SPLAT:
7136 Res = WidenVecOp_VP_SPLAT(
N, OpNo);
7139 case ISD::VECREDUCE_FADD:
7140 case ISD::VECREDUCE_FMUL:
7141 case ISD::VECREDUCE_ADD:
7142 case ISD::VECREDUCE_MUL:
7143 case ISD::VECREDUCE_AND:
7144 case ISD::VECREDUCE_OR:
7145 case ISD::VECREDUCE_XOR:
7146 case ISD::VECREDUCE_SMAX:
7147 case ISD::VECREDUCE_SMIN:
7148 case ISD::VECREDUCE_UMAX:
7149 case ISD::VECREDUCE_UMIN:
7150 case ISD::VECREDUCE_FMAX:
7151 case ISD::VECREDUCE_FMIN:
7152 case ISD::VECREDUCE_FMAXIMUM:
7153 case ISD::VECREDUCE_FMINIMUM:
7154 Res = WidenVecOp_VECREDUCE(
N);
7156 case ISD::VECREDUCE_SEQ_FADD:
7157 case ISD::VECREDUCE_SEQ_FMUL:
7158 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7160 case ISD::VP_REDUCE_FADD:
7161 case ISD::VP_REDUCE_SEQ_FADD:
7162 case ISD::VP_REDUCE_FMUL:
7163 case ISD::VP_REDUCE_SEQ_FMUL:
7164 case ISD::VP_REDUCE_ADD:
7165 case ISD::VP_REDUCE_MUL:
7166 case ISD::VP_REDUCE_AND:
7167 case ISD::VP_REDUCE_OR:
7168 case ISD::VP_REDUCE_XOR:
7169 case ISD::VP_REDUCE_SMAX:
7170 case ISD::VP_REDUCE_SMIN:
7171 case ISD::VP_REDUCE_UMAX:
7172 case ISD::VP_REDUCE_UMIN:
7173 case ISD::VP_REDUCE_FMAX:
7174 case ISD::VP_REDUCE_FMIN:
7175 case ISD::VP_REDUCE_FMAXIMUM:
7176 case ISD::VP_REDUCE_FMINIMUM:
7177 Res = WidenVecOp_VP_REDUCE(
N);
7179 case ISD::VP_CTTZ_ELTS:
7180 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7181 Res = WidenVecOp_VP_CttzElements(
N);
7186 if (!Res.
getNode())
return false;
7194 if (
N->isStrictFPOpcode())
7196 "Invalid operand expansion");
7199 "Invalid operand expansion");
7201 ReplaceValueWith(
SDValue(
N, 0), Res);
7207 EVT VT =
N->getValueType(0);
7212 "Unexpected type action");
7213 InOp = GetWidenedVector(InOp);
7216 "Input wasn't widened!");
7224 EVT FixedEltVT = FixedVT.getVectorElementType();
7225 if (TLI.isTypeLegal(FixedVT) &&
7227 FixedEltVT == InEltVT) {
7229 "Not enough elements in the fixed type for the operand!");
7231 "We can't have the same type as we started with!");
7233 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7235 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7244 return WidenVecOp_Convert(
N);
7249 switch (
N->getOpcode()) {
7264 EVT OpVT =
N->getOperand(0).getValueType();
7265 EVT ResVT =
N->getValueType(0);
7272 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7273 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7279 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7280 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7282 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7289 return DAG.UnrollVectorOp(
N);
7294 EVT ResultVT =
N->getValueType(0);
7296 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7299 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7305 {WideArg,
Test},
N->getFlags());
7311 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7313 EVT OpVT =
N->getOperand(0).getValueType();
7316 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7321 EVT VT =
N->getValueType(0);
7327 "Unexpected type action");
7328 InOp = GetWidenedVector(InOp);
7330 unsigned Opcode =
N->getOpcode();
7336 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7338 if (
N->isStrictFPOpcode()) {
7340 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7343 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7344 {
N->getOperand(0), InOp });
7350 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7352 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7354 return DAG.getExtractSubvector(dl, VT, Res, 0);
7362 if (
N->isStrictFPOpcode()) {
7365 for (
unsigned i=0; i < NumElts; ++i) {
7366 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7367 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7371 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7373 for (
unsigned i = 0; i < NumElts; ++i)
7374 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7375 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7378 return DAG.getBuildVector(VT, dl,
Ops);
7382 EVT DstVT =
N->getValueType(0);
7383 SDValue Src = GetWidenedVector(
N->getOperand(0));
7384 EVT SrcVT = Src.getValueType();
7391 if (TLI.isTypeLegal(WideDstVT)) {
7393 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7396 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7400 return DAG.UnrollVectorOp(
N);
7404 EVT VT =
N->getValueType(0);
7405 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7413 if (!VT.
isVector() && VT != MVT::x86mmx &&
7417 if (TLI.isTypeLegal(NewVT)) {
7418 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
7419 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7431 ElementCount NewNumElts =
7433 .divideCoefficientBy(EltSize);
7435 if (TLI.isTypeLegal(NewVT)) {
7437 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7442 return CreateStackStoreLoad(InOp, VT);
7450 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7451 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7456 EVT VT =
N->getValueType(0);
7458 EVT InVT =
N->getOperand(0).getValueType();
7463 unsigned NumOperands =
N->getNumOperands();
7464 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7466 for (i = 1; i < NumOperands; ++i)
7467 if (!
N->getOperand(i).isUndef())
7470 if (i == NumOperands)
7471 return GetWidenedVector(
N->getOperand(0));
7481 for (
unsigned i=0; i < NumOperands; ++i) {
7485 "Unexpected type action");
7486 InOp = GetWidenedVector(InOp);
7487 for (
unsigned j = 0;
j < NumInElts; ++
j)
7488 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7490 return DAG.getBuildVector(VT, dl,
Ops);
7493SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7494 EVT VT =
N->getValueType(0);
7499 SubVec = GetWidenedVector(SubVec);
7504 bool IndicesValid =
false;
7507 IndicesValid =
true;
7511 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7512 Attribute::VScaleRange);
7517 IndicesValid =
true;
7523 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7529 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7536 Align Alignment = DAG.getReducedAlign(VT,
false);
7538 MachineFunction &MF = DAG.getMachineFunction();
7551 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7559 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7560 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7565 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7570 unsigned Idx =
N->getConstantOperandVal(2);
7576 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7582SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7583 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7585 N->getValueType(0), InOp,
N->getOperand(1));
7588SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7589 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7591 N->getValueType(0), InOp,
N->getOperand(1));
7594SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7595 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7596 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7604 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7605 return TLI.scalarizeVectorStore(ST, DAG);
7607 if (
ST->isTruncatingStore())
7608 return TLI.scalarizeVectorStore(ST, DAG);
7618 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7619 EVT WideMaskVT = getSetCCResultType(WideVT);
7621 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7622 TLI.isTypeLegal(WideMaskVT)) {
7625 StVal = GetWidenedVector(StVal);
7627 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7629 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7630 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7631 ST->getAddressingMode());
7635 if (GenWidenVectorStores(StChain, ST)) {
7636 if (StChain.
size() == 1)
7645 SDValue WideStVal = GetWidenedVector(StVal);
7649 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7650 ST->getOffset(), Mask,
ST->getMemoryVT(),
7651 ST->getMemOperand(),
ST->getAddressingMode(),
7652 ST->isTruncatingStore());
7658SDValue DAGTypeLegalizer::WidenVecOp_VP_SPLAT(
SDNode *
N,
unsigned OpNo) {
7659 assert(OpNo == 1 &&
"Can widen only mask operand of vp_splat");
7660 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
7661 N->getOperand(0), GetWidenedVector(
N->getOperand(1)),
7665SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7666 assert((OpNo == 1 || OpNo == 3) &&
7667 "Can widen only data or mask operand of vp_store");
7675 StVal = GetWidenedVector(StVal);
7681 "Unable to widen VP store");
7682 Mask = GetWidenedVector(Mask);
7684 Mask = GetWidenedVector(Mask);
7690 "Unable to widen VP store");
7691 StVal = GetWidenedVector(StVal);
7694 assert(
Mask.getValueType().getVectorElementCount() ==
7696 "Mask and data vectors should have the same number of elements");
7697 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7698 ST->getOffset(), Mask,
ST->getVectorLength(),
7699 ST->getMemoryVT(),
ST->getMemOperand(),
7700 ST->getAddressingMode(),
ST->isTruncatingStore(),
7701 ST->isCompressingStore());
7706 assert((OpNo == 1 || OpNo == 4) &&
7707 "Can widen only data or mask operand of vp_strided_store");
7716 "Unable to widen VP strided store");
7720 "Unable to widen VP strided store");
7722 StVal = GetWidenedVector(StVal);
7723 Mask = GetWidenedVector(Mask);
7726 Mask.getValueType().getVectorElementCount() &&
7727 "Data and mask vectors should have the same number of elements");
7729 return DAG.getStridedStoreVP(
7736SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7737 assert((OpNo == 1 || OpNo == 4) &&
7738 "Can widen only data or mask operand of mstore");
7741 EVT MaskVT =
Mask.getValueType();
7746 EVT WideVT, WideMaskVT;
7749 StVal = GetWidenedVector(StVal);
7756 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7763 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7764 TLI.isTypeLegal(WideMaskVT)) {
7765 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7766 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7775 Mask = ModifyToType(Mask, WideMaskVT,
true);
7778 Mask = ModifyToType(Mask, WideMaskVT,
true);
7780 StVal = ModifyToType(StVal, WideVT);
7783 assert(
Mask.getValueType().getVectorElementCount() ==
7785 "Mask and data vectors should have the same number of elements");
7792SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7793 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7795 SDValue DataOp = MG->getPassThru();
7797 SDValue Scale = MG->getScale();
7805 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7806 MG->getMemOperand(), MG->getIndexType(),
7807 MG->getExtensionType());
7813SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7822 DataOp = GetWidenedVector(DataOp);
7826 EVT IndexVT =
Index.getValueType();
7829 Index = ModifyToType(Index, WideIndexVT);
7832 EVT MaskVT =
Mask.getValueType();
7835 Mask = ModifyToType(Mask, WideMaskVT,
true);
7840 }
else if (OpNo == 4) {
7842 Index = GetWidenedVector(Index);
7848 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7853SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7862 DataOp = GetWidenedVector(DataOp);
7863 Index = GetWidenedVector(Index);
7865 Mask = GetWidenedMask(Mask, WideEC);
7868 }
else if (OpNo == 3) {
7870 Index = GetWidenedVector(Index);
7877 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7882 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7883 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7885 EVT VT =
N->getValueType(0);
7900 SVT, InOp0, InOp1,
N->getOperand(2));
7906 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7908 EVT OpVT =
N->getOperand(0).getValueType();
7911 return DAG.getNode(ExtendCode, dl, VT, CC);
7921 EVT VT =
N->getValueType(0);
7923 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7930 for (
unsigned i = 0; i != NumElts; ++i) {
7931 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7932 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7934 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7935 {Chain, LHSElem, RHSElem, CC});
7936 Chains[i] = Scalars[i].getValue(1);
7937 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7938 DAG.getBoolConstant(
true, dl, EltVT, VT),
7939 DAG.getBoolConstant(
false, dl, EltVT, VT));
7943 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7945 return DAG.getBuildVector(VT, dl, Scalars);
7952 case ISD::VECREDUCE_ADD:
7953 case ISD::VECREDUCE_MUL:
7954 case ISD::VECREDUCE_AND:
7955 case ISD::VECREDUCE_OR:
7956 case ISD::VECREDUCE_XOR:
7958 case ISD::VECREDUCE_SMAX:
7959 case ISD::VECREDUCE_SMIN:
7961 case ISD::VECREDUCE_UMAX:
7962 case ISD::VECREDUCE_UMIN:
7969 SDValue Op = GetWidenedVector(
N->getOperand(0));
7970 EVT VT =
N->getValueType(0);
7971 EVT OrigVT =
N->getOperand(0).getValueType();
7972 EVT WideVT =
Op.getValueType();
7974 SDNodeFlags
Flags =
N->getFlags();
7976 unsigned Opc =
N->getOpcode();
7978 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7979 assert(NeutralElem &&
"Neutral element must exist");
7989 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7996 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7997 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8003 unsigned GCD = std::gcd(OrigElts, WideElts);
8006 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8007 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8008 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8009 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8012 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8013 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8015 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8024 EVT VT =
N->getValueType(0);
8026 EVT WideVT =
Op.getValueType();
8028 SDNodeFlags
Flags =
N->getFlags();
8030 unsigned Opc =
N->getOpcode();
8032 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8042 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8045 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8046 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8052 unsigned GCD = std::gcd(OrigElts, WideElts);
8055 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8056 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8057 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8058 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8061 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8062 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8064 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8068 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8071 SDValue Op = GetWidenedVector(
N->getOperand(1));
8073 Op.getValueType().getVectorElementCount());
8075 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8076 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8084 EVT VT =
N->getValueType(0);
8088 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8089 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8094 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8100 EVT SrcVT =
Source.getValueType();
8104 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8105 {Source, Mask, N->getOperand(2)},
N->getFlags());
8122 unsigned WidenEx = 0) {
8127 unsigned AlignInBits =
Align*8;
8129 EVT RetVT = WidenEltVT;
8134 if (Width == WidenEltWidth)
8145 (WidenWidth % MemVTWidth) == 0 &&
8147 (MemVTWidth <= Width ||
8148 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8149 if (MemVTWidth == WidenWidth)
8168 (WidenWidth % MemVTWidth) == 0 &&
8170 (MemVTWidth <= Width ||
8171 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8180 return std::nullopt;
8191 unsigned Start,
unsigned End) {
8192 SDLoc dl(LdOps[Start]);
8193 EVT LdTy = LdOps[Start].getValueType();
8201 for (
unsigned i = Start + 1; i != End; ++i) {
8202 EVT NewLdTy = LdOps[i].getValueType();
8203 if (NewLdTy != LdTy) {
8206 VecOp = DAG.
getNode(ISD::BITCAST, dl, NewVecVT, VecOp);
8213 return DAG.
getNode(ISD::BITCAST, dl, VecTy, VecOp);
8222 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8223 EVT LdVT =
LD->getMemoryVT();
8233 AAMDNodes AAInfo =
LD->getAAInfo();
8237 TypeSize WidthDiff = WidenWidth - LdWidth;
8244 std::optional<EVT> FirstVT =
8245 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8252 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8257 std::optional<EVT> NewVT = FirstVT;
8258 TypeSize RemainingWidth = LdWidth;
8259 TypeSize NewVTWidth = FirstVTWidth;
8261 RemainingWidth -= NewVTWidth;
8268 NewVTWidth = NewVT->getSizeInBits();
8274 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8275 LD->getBaseAlign(), MMOFlags, AAInfo);
8279 if (MemVTs.
empty()) {
8281 if (!FirstVT->isVector()) {
8286 return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
8288 if (FirstVT == WidenVT)
8293 unsigned NumConcat =
8296 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8297 ConcatOps[0] = LdOp;
8298 for (
unsigned i = 1; i != NumConcat; ++i)
8299 ConcatOps[i] = UndefVal;
8307 uint64_t ScaledOffset = 0;
8308 MachinePointerInfo MPI =
LD->getPointerInfo();
8314 for (EVT MemVT : MemVTs) {
8315 Align NewAlign = ScaledOffset == 0
8316 ?
LD->getBaseAlign()
8319 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8327 unsigned End = LdOps.
size();
8338 EVT LdTy = LdOps[i].getValueType();
8341 for (--i; i >= 0; --i) {
8342 LdTy = LdOps[i].getValueType();
8349 ConcatOps[--Idx] = LdOps[i];
8350 for (--i; i >= 0; --i) {
8351 EVT NewLdTy = LdOps[i].getValueType();
8352 if (NewLdTy != LdTy) {
8362 for (;
j != End-Idx; ++
j)
8363 WidenOps[j] = ConcatOps[Idx+j];
8365 WidenOps[j] = DAG.getUNDEF(LdTy);
8372 ConcatOps[--Idx] = LdOps[i];
8377 ArrayRef(&ConcatOps[Idx], End - Idx));
8383 SDValue UndefVal = DAG.getUNDEF(LdTy);
8386 for (; i != End-Idx; ++i)
8387 WidenOps[i] = ConcatOps[Idx+i];
8389 WidenOps[i] = UndefVal;
8400 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8401 EVT LdVT =
LD->getMemoryVT();
8410 AAMDNodes AAInfo =
LD->getAAInfo();
8424 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8425 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8431 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8432 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8433 LD->getBaseAlign(), MMOFlags, AAInfo);
8438 SDValue UndefVal = DAG.getUNDEF(EltVT);
8439 for (; i != WidenNumElts; ++i)
8442 return DAG.getBuildVector(WidenVT, dl,
Ops);
8453 AAMDNodes AAInfo =
ST->getAAInfo();
8454 SDValue ValOp = GetWidenedVector(
ST->getValue());
8457 EVT StVT =
ST->getMemoryVT();
8465 "Mismatch between store and value types");
8469 MachinePointerInfo MPI =
ST->getPointerInfo();
8470 uint64_t ScaledOffset = 0;
8479 std::optional<EVT> NewVT =
8484 TypeSize NewVTWidth = NewVT->getSizeInBits();
8487 StWidth -= NewVTWidth;
8488 MemVTs.
back().second++;
8492 for (
const auto &Pair : MemVTs) {
8493 EVT NewVT = Pair.first;
8494 unsigned Count = Pair.second;
8500 Align NewAlign = ScaledOffset == 0
8501 ?
ST->getBaseAlign()
8503 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8504 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8520 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8521 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8522 ST->getBaseAlign(), MMOFlags, AAInfo);
8539 bool FillWithZeroes) {
8544 "input and widen element type must match");
8546 "cannot modify scalable vectors in this way");
8558 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8561 for (
unsigned i = 1; i != NumConcat; ++i)
8568 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8571 "Scalable vectors should have been handled already.");
8579 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8581 for (Idx = 0; Idx < MinNumElts; ++Idx)
8582 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8584 SDValue UndefVal = DAG.getUNDEF(EltVT);
8585 for (; Idx < WidenNumElts; ++Idx)
8586 Ops[Idx] = UndefVal;
8588 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8589 if (!FillWithZeroes)
8593 "We expect to never want to FillWithZeroes for non-integral types.");
8596 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8597 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8599 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8600 DAG.getBuildVector(NVT, dl, MaskOps));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align=0, unsigned WidenEx=0)
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
This file implements the SmallBitVector class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ LOOP_DEPENDENCE_RAW_MASK
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ADD
Simple integer binary arithmetic operators.
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ VECTOR_SPLICE
VECTOR_SPLICE(VEC1, VEC2, IMM) - Returns a subvector of the same type as VEC1/VEC2 from CONCAT_VECTOR...
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
Set rounding mode.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
EVT changeElementType(EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeVectorElementType(EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.