35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
46 switch (
N->getOpcode()) {
49 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
58 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
61 case ISD::BITCAST: R = ScalarizeVecRes_BITCAST(
N);
break;
69 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
72 case ISD::ATOMIC_LOAD:
81 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
83 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
89 R = ScalarizeVecRes_VecInregOp(
N);
114 case ISD::FNEARBYINT:
117 case ISD::ARITH_FENCE:
125 case ISD::FROUNDEVEN:
140 R = ScalarizeVecRes_UnaryOp(
N);
142 case ISD::ADDRSPACECAST:
143 R = ScalarizeVecRes_ADDRSPACECAST(
N);
149 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
163 case ISD::FMINNUM_IEEE:
164 case ISD::FMAXNUM_IEEE:
167 case ISD::FMINIMUMNUM:
168 case ISD::FMAXIMUMNUM:
203 R = ScalarizeVecRes_BinOp(
N);
208 R = ScalarizeVecRes_CMP(
N);
214 R = ScalarizeVecRes_TernaryOp(
N);
217#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
218 case ISD::STRICT_##DAGN:
219#include "llvm/IR/ConstrainedOps.def"
220 R = ScalarizeVecRes_StrictFPOp(
N);
225 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
234 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
244 R = ScalarizeVecRes_FIX(
N);
250 SetScalarizedVector(
SDValue(
N, ResNo), R);
254 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
255 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
256 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
265 if (getTypeAction(
LHS.getValueType()) ==
267 LHS = GetScalarizedVector(
LHS);
268 RHS = GetScalarizedVector(
RHS);
270 EVT VT =
LHS.getValueType().getVectorElementType();
271 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
272 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
275 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
276 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
280 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
281 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
282 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
283 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
288 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
289 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
296DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
298 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
299 "Unexpected vector type!");
300 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
302 EVT VT0 =
N->getValueType(0);
303 EVT VT1 =
N->getValueType(1);
307 DAG.getNode(
N->getOpcode(), dl,
308 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
312 unsigned OtherNo = 1 - ResNo;
313 EVT OtherVT =
N->getValueType(OtherNo);
315 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
319 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
322 return SDValue(ScalarNode, ResNo);
327 unsigned NumOpers =
N->getNumOperands();
329 EVT ValueVTs[] = {VT, MVT::Other};
338 for (
unsigned i = 1; i < NumOpers; ++i) {
344 Oper = GetScalarizedVector(Oper);
353 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
354 Opers,
N->getFlags());
365 EVT ResVT =
N->getValueType(0);
366 EVT OvVT =
N->getValueType(1);
370 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
371 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
374 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
375 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
376 ScalarLHS = ElemsLHS[0];
377 ScalarRHS = ElemsRHS[0];
380 SDVTList ScalarVTs = DAG.getVTList(
382 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
383 {ScalarLHS, ScalarRHS},
N->getFlags())
387 unsigned OtherNo = 1 - ResNo;
388 EVT OtherVT =
N->getValueType(OtherNo);
390 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
394 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
397 return SDValue(ScalarNode, ResNo);
402 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
403 return GetScalarizedVector(
Op);
406SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
414 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
425 Op = GetScalarizedVector(
Op);
426 EVT NewVT =
N->getValueType(0).getVectorElementType();
427 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
431SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
441SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
443 N->getValueType(0).getVectorElementType(),
444 N->getOperand(0),
N->getOperand(1));
450 EVT OpVT =
Op.getValueType();
454 Op = GetScalarizedVector(
Op);
457 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
460 N->getValueType(0).getVectorElementType(),
Op,
464SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
465 SDValue Op = GetScalarizedVector(
N->getOperand(0));
466 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
470SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
475 if (
Op.getValueType() != EltVT)
483 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
484 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
494 assert(
N->isUnindexed() &&
"Indexed vector load?");
498 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
499 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
500 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
501 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
513 EVT OpVT =
Op.getValueType();
523 Op = GetScalarizedVector(
Op);
526 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
528 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
534 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
535 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
536 LHS, DAG.getValueType(ExtVT));
543 EVT OpVT =
Op.getValueType();
548 Op = GetScalarizedVector(
Op);
550 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
553 switch (
N->getOpcode()) {
565SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
568 EVT OpVT =
Op.getValueType();
578 Op = GetScalarizedVector(
Op);
581 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
584 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
585 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
586 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
589SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
601 EVT OpVT =
Cond.getValueType();
610 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
613 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
615 TLI.getBooleanContents(
false,
false);
622 if (TLI.getBooleanContents(
false,
false) !=
623 TLI.getBooleanContents(
false,
true)) {
627 EVT OpVT =
Cond->getOperand(0).getValueType();
629 VecBool = TLI.getBooleanContents(OpVT);
634 EVT CondVT =
Cond.getValueType();
635 if (ScalarBool != VecBool) {
636 switch (ScalarBool) {
644 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
651 Cond, DAG.getValueType(MVT::i1));
657 auto BoolVT = getSetCCResultType(CondVT);
658 if (BoolVT.bitsLT(CondVT))
661 return DAG.getSelect(SDLoc(
N),
663 GetScalarizedVector(
N->getOperand(2)));
667 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
668 return DAG.getSelect(SDLoc(
N),
669 LHS.getValueType(),
N->getOperand(0),
LHS,
670 GetScalarizedVector(
N->getOperand(2)));
674 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
676 N->getOperand(0),
N->getOperand(1),
677 LHS, GetScalarizedVector(
N->getOperand(3)),
682 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
685SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
689 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
691 return GetScalarizedVector(
N->getOperand(
Op));
694SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
696 EVT SrcVT = Src.getValueType();
701 Src = GetScalarizedVector(Src);
705 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
707 EVT DstVT =
N->getValueType(0).getVectorElementType();
708 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
712 assert(
N->getValueType(0).isVector() &&
713 N->getOperand(0).getValueType().isVector() &&
714 "Operand types must be vectors");
717 EVT OpVT =
LHS.getValueType();
718 EVT NVT =
N->getValueType(0).getVectorElementType();
723 LHS = GetScalarizedVector(
LHS);
724 RHS = GetScalarizedVector(
RHS);
727 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
728 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
738 return DAG.getNode(ExtendCode,
DL, NVT, Res);
749 Arg = GetScalarizedVector(Arg);
752 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
761 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
768bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
773 switch (
N->getOpcode()) {
776 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
783 Res = ScalarizeVecOp_BITCAST(
N);
786 Res = ScalarizeVecOp_FAKE_USE(
N);
800 Res = ScalarizeVecOp_UnaryOp(
N);
804 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
810 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
813 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
816 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
819 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
822 Res = ScalarizeVecOp_VSELECT(
N);
825 Res = ScalarizeVecOp_VSETCC(
N);
829 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
835 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
838 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
841 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
844 Res = ScalarizeVecOp_FP_EXTEND(
N);
846 case ISD::VECREDUCE_FADD:
847 case ISD::VECREDUCE_FMUL:
848 case ISD::VECREDUCE_ADD:
849 case ISD::VECREDUCE_MUL:
850 case ISD::VECREDUCE_AND:
851 case ISD::VECREDUCE_OR:
852 case ISD::VECREDUCE_XOR:
853 case ISD::VECREDUCE_SMAX:
854 case ISD::VECREDUCE_SMIN:
855 case ISD::VECREDUCE_UMAX:
856 case ISD::VECREDUCE_UMIN:
857 case ISD::VECREDUCE_FMAX:
858 case ISD::VECREDUCE_FMIN:
859 case ISD::VECREDUCE_FMAXIMUM:
860 case ISD::VECREDUCE_FMINIMUM:
861 Res = ScalarizeVecOp_VECREDUCE(
N);
863 case ISD::VECREDUCE_SEQ_FADD:
864 case ISD::VECREDUCE_SEQ_FMUL:
865 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
869 Res = ScalarizeVecOp_CMP(
N);
874 if (!Res.
getNode())
return false;
882 "Invalid operand expansion");
884 ReplaceValueWith(
SDValue(
N, 0), Res);
891 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
892 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
893 N->getValueType(0), Elt);
898 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
899 "Fake Use: Unexpected vector type!");
900 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
901 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
907 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
908 "Unexpected vector type!");
909 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
911 N->getValueType(0).getScalarType(), Elt);
919SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
920 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
921 "Unexpected vector type!");
922 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
924 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
925 Elt,
N->getOperand(1));
933SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
934 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
935 "Unexpected vector type!");
936 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
938 {
N->getValueType(0).getScalarType(), MVT::Other },
939 {
N->getOperand(0), Elt });
949 ReplaceValueWith(
SDValue(
N, 0), Res);
954SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
956 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
957 Ops[i] = GetScalarizedVector(
N->getOperand(i));
958 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
963SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
967 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
968 SDValue ContainingVec =
N->getOperand(0);
976SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
977 EVT VT =
N->getValueType(0);
978 SDValue Res = GetScalarizedVector(
N->getOperand(0));
981 ? DAG.getNode(ISD::FP_EXTEND, SDLoc(
N), VT, Res)
990 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
991 EVT VT =
N->getValueType(0);
993 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1001 assert(
N->getValueType(0).isVector() &&
1002 N->getOperand(0).getValueType().isVector() &&
1003 "Operand types must be vectors");
1004 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1006 EVT VT =
N->getValueType(0);
1007 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1008 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1010 EVT OpVT =
N->getOperand(0).getValueType();
1022 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1028SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1030 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1031 assert(
N->getValueType(0).isVector() &&
1032 N->getOperand(1).getValueType().isVector() &&
1033 "Operand types must be vectors");
1034 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1036 EVT VT =
N->getValueType(0);
1038 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1039 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1042 EVT OpVT =
N->getOperand(1).getValueType();
1046 {Ch, LHS, RHS, CC});
1055 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1060 ReplaceValueWith(
SDValue(
N, 0), Res);
1067 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1068 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1071 if (
N->isTruncatingStore())
1072 return DAG.getTruncStore(
1073 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1074 N->getBasePtr(),
N->getPointerInfo(),
1075 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1076 N->getMemOperand()->getFlags(),
N->getAAInfo());
1078 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1079 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1080 N->getMemOperand()->getFlags(),
N->getAAInfo());
1085SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1086 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1087 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1089 N->getValueType(0).getVectorElementType(), Elt,
1094SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1096 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1097 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1099 {
N->getValueType(0).getVectorElementType(),
1110 ReplaceValueWith(
SDValue(
N, 0), Res);
1117 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1119 N->getValueType(0).getVectorElementType(), Elt);
1125SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1126 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1129 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1130 {
N->getOperand(0), Elt});
1139 ReplaceValueWith(
SDValue(
N, 0), Res);
1144 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1151SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1157 SDValue Op = GetScalarizedVector(VecOp);
1158 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1159 AccOp,
Op,
N->getFlags());
1163 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1164 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1179void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1184 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1187 switch (
N->getOpcode()) {
1190 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1199 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1206 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1210 case ISD::BITCAST: SplitVecRes_BITCAST(
N,
Lo,
Hi);
break;
1220 case ISD::EXPERIMENTAL_VP_SPLAT: SplitVecRes_VP_SPLAT(
N,
Lo,
Hi);
break;
1223 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1226 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1235 case ISD::VP_LOAD_FF:
1238 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1245 case ISD::VP_GATHER:
1249 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1253 SplitVecRes_SETCC(
N,
Lo,
Hi);
1256 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1262 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1265 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1268 SplitVecRes_VECTOR_INTERLEAVE(
N);
1271 SplitVecRes_VAARG(
N,
Lo,
Hi);
1277 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1283 case ISD::VP_BITREVERSE:
1291 case ISD::VP_CTLZ_ZERO_UNDEF:
1293 case ISD::VP_CTTZ_ZERO_UNDEF:
1296 case ISD::FABS:
case ISD::VP_FABS:
1308 case ISD::VP_FFLOOR:
1312 case ISD::FNEARBYINT:
1313 case ISD::VP_FNEARBYINT:
1314 case ISD::FNEG:
case ISD::VP_FNEG:
1316 case ISD::ARITH_FENCE:
1317 case ISD::FP_EXTEND:
1318 case ISD::VP_FP_EXTEND:
1320 case ISD::VP_FP_ROUND:
1322 case ISD::VP_FP_TO_SINT:
1324 case ISD::VP_FP_TO_UINT:
1330 case ISD::VP_LLRINT:
1332 case ISD::VP_FROUND:
1333 case ISD::FROUNDEVEN:
1334 case ISD::VP_FROUNDEVEN:
1339 case ISD::FSQRT:
case ISD::VP_SQRT:
1343 case ISD::VP_FROUNDTOZERO:
1345 case ISD::VP_SINT_TO_FP:
1347 case ISD::VP_TRUNCATE:
1349 case ISD::VP_UINT_TO_FP:
1352 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1354 case ISD::ADDRSPACECAST:
1355 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1360 case ISD::FSINCOSPI:
1361 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1367 case ISD::VP_SIGN_EXTEND:
1368 case ISD::VP_ZERO_EXTEND:
1369 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1387 case ISD::FMINNUM_IEEE:
1388 case ISD::VP_FMINNUM:
1390 case ISD::FMAXNUM_IEEE:
1391 case ISD::VP_FMAXNUM:
1393 case ISD::VP_FMINIMUM:
1395 case ISD::VP_FMAXIMUM:
1396 case ISD::FMINIMUMNUM:
1397 case ISD::FMAXIMUMNUM:
1404 case ISD::OR:
case ISD::VP_OR:
1424 case ISD::VP_FCOPYSIGN:
1425 SplitVecRes_BinOp(
N,
Lo,
Hi);
1432 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1436 SplitVecRes_CMP(
N,
Lo,
Hi);
1439#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1440 case ISD::STRICT_##DAGN:
1441#include "llvm/IR/ConstrainedOps.def"
1442 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1447 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1456 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1466 SplitVecRes_FIX(
N,
Lo,
Hi);
1468 case ISD::EXPERIMENTAL_VP_SPLICE:
1469 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1471 case ISD::EXPERIMENTAL_VP_REVERSE:
1472 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1474 case ISD::PARTIAL_REDUCE_UMLA:
1475 case ISD::PARTIAL_REDUCE_SMLA:
1476 case ISD::PARTIAL_REDUCE_SUMLA:
1477 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1479 case ISD::GET_ACTIVE_LANE_MASK:
1480 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1489void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1491 uint64_t *ScaledOffset) {
1496 SDValue BytesIncrement = DAG.getVScale(
1497 DL,
Ptr.getValueType(),
1498 APInt(
Ptr.getValueSizeInBits().getFixedValue(), IncrementSize));
1499 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1501 *ScaledOffset += IncrementSize;
1511std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1512 return SplitMask(Mask, SDLoc(Mask));
1515std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1518 EVT MaskVT =
Mask.getValueType();
1520 GetSplitVector(Mask, MaskLo, MaskHi);
1522 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1523 return std::make_pair(MaskLo, MaskHi);
1528 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1530 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1533 const SDNodeFlags
Flags =
N->getFlags();
1534 unsigned Opcode =
N->getOpcode();
1535 if (
N->getNumOperands() == 2) {
1536 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1537 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1541 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1542 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1545 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1548 std::tie(EVLLo, EVLHi) =
1549 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1552 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1554 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1560 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1562 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1564 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1567 const SDNodeFlags
Flags =
N->getFlags();
1568 unsigned Opcode =
N->getOpcode();
1569 if (
N->getNumOperands() == 3) {
1570 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1571 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1575 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1576 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1579 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1582 std::tie(EVLLo, EVLHi) =
1583 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1586 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1588 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1592 LLVMContext &Ctxt = *DAG.getContext();
1598 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1600 GetSplitVector(
LHS, LHSLo, LHSHi);
1601 GetSplitVector(
RHS, RHSLo, RHSHi);
1603 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1604 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1608 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1609 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1614 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1616 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1620 unsigned Opcode =
N->getOpcode();
1621 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1623 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1632 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1639 switch (getTypeAction(InVT)) {
1654 GetExpandedOp(InOp,
Lo,
Hi);
1655 if (DAG.getDataLayout().isBigEndian())
1657 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1658 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1665 GetSplitVector(InOp,
Lo,
Hi);
1666 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1667 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1674 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1675 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, InLo);
1676 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, InHi);
1683 if (DAG.getDataLayout().isBigEndian())
1686 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1688 if (DAG.getDataLayout().isBigEndian())
1690 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1691 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1694void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1698 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1701 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
N->getOperand(2));
1706 ? DAG.getVScale(
DL, MVT::i64, APInt(64,
Offset))
1707 : DAG.getConstant(
Offset,
DL, MVT::i64);
1710 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
N->getOperand(2));
1717 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1720 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1723 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1728 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1730 unsigned NumSubvectors =
N->getNumOperands() / 2;
1731 if (NumSubvectors == 1) {
1732 Lo =
N->getOperand(0);
1733 Hi =
N->getOperand(1);
1738 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1747void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1754 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1769 GetSplitVector(Vec,
Lo,
Hi);
1772 EVT LoVT =
Lo.getValueType();
1782 if (IdxVal + SubElems <= LoElems) {
1790 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1792 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1798 SDValue WideSubVec = GetWidenedVector(SubVec);
1800 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1808 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1810 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1811 auto &MF = DAG.getMachineFunction();
1815 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1820 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1821 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1825 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1830 MachinePointerInfo MPI =
Load->getPointerInfo();
1831 IncrementPointer(Load, LoVT, MPI, StackPtr);
1834 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1843 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1848 EVT RHSVT =
RHS.getValueType();
1851 GetSplitVector(
RHS, RHSLo, RHSHi);
1853 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1868 SDValue FpValue =
N->getOperand(0);
1870 GetSplitVector(FpValue, ArgLo, ArgHi);
1872 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1874 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1883 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1887 std::tie(LoVT, HiVT) =
1891 DAG.getValueType(LoVT));
1893 DAG.getValueType(HiVT));
1898 unsigned Opcode =
N->getOpcode();
1905 GetSplitVector(N0, InLo, InHi);
1907 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1912 EVT OutLoVT, OutHiVT;
1913 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1915 assert((2 * OutNumElements) <= InNumElements &&
1916 "Illegal extend vector in reg split");
1925 SmallVector<int, 8> SplitHi(InNumElements, -1);
1926 for (
unsigned i = 0; i != OutNumElements; ++i)
1927 SplitHi[i] = i + OutNumElements;
1928 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1930 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1931 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1936 unsigned NumOps =
N->getNumOperands();
1940 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1950 for (
unsigned i = 1; i <
NumOps; ++i) {
1955 EVT InVT =
Op.getValueType();
1960 GetSplitVector(
Op, OpLo, OpHi);
1962 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
1969 EVT LoValueVTs[] = {LoVT, MVT::Other};
1970 EVT HiValueVTs[] = {HiVT, MVT::Other};
1971 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1973 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
1979 Lo.getValue(1),
Hi.getValue(1));
1983 ReplaceValueWith(
SDValue(
N, 1), Chain);
1986SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
1988 EVT VT =
N->getValueType(0);
1999 else if (NE > ResNE)
2003 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2007 for (i = 0; i !=
NE; ++i) {
2008 Operands[0] = Chain;
2009 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2010 SDValue Operand =
N->getOperand(j);
2014 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2016 Operands[
j] = Operand;
2020 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2028 for (; i < ResNE; ++i)
2033 ReplaceValueWith(
SDValue(
N, 1), Chain);
2037 return DAG.getBuildVector(VecVT, dl, Scalars);
2040void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2043 EVT ResVT =
N->getValueType(0);
2044 EVT OvVT =
N->getValueType(1);
2045 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2046 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2047 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2049 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2051 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2052 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2054 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2055 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2058 unsigned Opcode =
N->getOpcode();
2059 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2060 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2062 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2064 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2070 unsigned OtherNo = 1 - ResNo;
2071 EVT OtherVT =
N->getValueType(OtherNo);
2073 SetSplitVector(
SDValue(
N, OtherNo),
2079 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2083void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2089 GetSplitVector(Vec,
Lo,
Hi);
2092 unsigned IdxVal = CIdx->getZExtValue();
2093 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2094 if (IdxVal < LoNumElts) {
2096 Lo.getValueType(),
Lo, Elt, Idx);
2099 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2119 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2121 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2122 auto &MF = DAG.getMachineFunction();
2126 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2131 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2132 Store = DAG.getTruncStore(
2138 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2141 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2145 MachinePointerInfo MPI =
Load->getPointerInfo();
2146 IncrementPointer(Load, LoVT, MPI, StackPtr);
2148 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2151 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2152 if (LoVT !=
Lo.getValueType())
2154 if (HiVT !=
Hi.getValueType())
2162 assert(
N->getValueType(0).isScalableVector() &&
2163 "Only scalable vectors are supported for STEP_VECTOR");
2164 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2185 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2186 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2188 Hi = DAG.getUNDEF(HiVT);
2198 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2199 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
2200 auto [EVLLo, EVLHi] = DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2201 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0), MaskLo, EVLLo);
2202 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
N->getOperand(0), MaskHi, EVLHi);
2210 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2216 EVT MemoryVT =
LD->getMemoryVT();
2218 AAMDNodes AAInfo =
LD->getAAInfo();
2220 EVT LoMemVT, HiMemVT;
2221 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2225 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2226 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2227 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2232 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2235 MachinePointerInfo MPI;
2236 IncrementPointer(LD, LoMemVT, MPI,
Ptr);
2239 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2248 ReplaceValueWith(
SDValue(LD, 1), Ch);
2253 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2256 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2262 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2263 Align Alignment =
LD->getBaseAlign();
2266 EVT MemoryVT =
LD->getMemoryVT();
2268 EVT LoMemVT, HiMemVT;
2269 bool HiIsEmpty =
false;
2270 std::tie(LoMemVT, HiMemVT) =
2271 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2276 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2279 GetSplitVector(Mask, MaskLo, MaskHi);
2281 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2286 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2288 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2294 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch,
Ptr,
Offset,
2295 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2303 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo, dl, LoMemVT, DAG,
2304 LD->isExpandingLoad());
2306 MachinePointerInfo MPI;
2308 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2310 MPI =
LD->getPointerInfo().getWithOffset(
2313 MMO = DAG.getMachineFunction().getMachineMemOperand(
2315 Alignment,
LD->getAAInfo(),
LD->getRanges());
2317 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch,
Ptr,
2318 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2319 LD->isExpandingLoad());
2329 ReplaceValueWith(
SDValue(LD, 1), Ch);
2335 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2339 Align Alignment =
LD->getBaseAlign();
2346 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2349 GetSplitVector(Mask, MaskLo, MaskHi);
2351 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2355 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2357 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2362 Lo = DAG.getLoadFFVP(LoVT, dl, Ch,
Ptr, MaskLo, EVLLo, MMO);
2365 Hi = DAG.getUNDEF(HiVT);
2367 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2368 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2374 "Indexed VP strided load during type legalization!");
2376 "Unexpected indexed variable-length load offset");
2381 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2383 EVT LoMemVT, HiMemVT;
2384 bool HiIsEmpty =
false;
2385 std::tie(LoMemVT, HiMemVT) =
2386 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2391 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2394 GetSplitVector(Mask, LoMask, HiMask);
2396 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2400 std::tie(LoEVL, HiEVL) =
2404 Lo = DAG.getStridedLoadVP(
2431 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2438 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2449 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2457 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2462 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(
2496 Lo = DAG.getMaskedLoad(LoVT, dl, Ch,
Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2506 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo, dl, LoMemVT, DAG,
2509 MachinePointerInfo MPI;
2516 MMO = DAG.getMachineFunction().getMachineMemOperand(
2520 Hi = DAG.getMaskedLoad(HiVT, dl, Ch,
Ptr,
Offset, MaskHi, PassThruHi,
2532 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2540 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2548 }
Ops = [&]() -> Operands {
2550 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2553 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2556 EVT MemoryVT =
N->getMemoryVT();
2557 Align Alignment =
N->getBaseAlign();
2562 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2564 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2567 EVT LoMemVT, HiMemVT;
2569 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2572 if (getTypeAction(
Ops.Index.getValueType()) ==
2574 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2576 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2579 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2581 Alignment,
N->getAAInfo(),
N->getRanges());
2584 SDValue PassThru = MGT->getPassThru();
2585 SDValue PassThruLo, PassThruHi;
2588 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2590 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2595 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo,
Ptr, IndexLo,
Ops.Scale};
2596 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2597 OpsLo, MMO, IndexTy, ExtType);
2599 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi,
Ptr, IndexHi,
Ops.Scale};
2600 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2601 OpsHi, MMO, IndexTy, ExtType);
2605 std::tie(EVLLo, EVLHi) =
2606 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2608 SDValue OpsLo[] = {Ch,
Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2609 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2610 MMO, VPGT->getIndexType());
2612 SDValue OpsHi[] = {Ch,
Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2613 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2614 MMO, VPGT->getIndexType());
2624 ReplaceValueWith(
SDValue(
N, 1), Ch);
2638 EVT VecVT =
N->getValueType(0);
2640 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2641 bool HasCustomLowering =
false;
2648 HasCustomLowering =
true;
2654 SDValue Passthru =
N->getOperand(2);
2655 if (!HasCustomLowering) {
2656 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2657 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2664 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2665 std::tie(LoMask, HiMask) = SplitMask(Mask);
2667 SDValue UndefPassthru = DAG.getUNDEF(LoVT);
2672 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2673 MachineFunction &MF = DAG.getMachineFunction();
2680 SDValue Offset = DAG.getNode(ISD::VECREDUCE_ADD,
DL, MVT::i32, WideMask);
2681 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2683 SDValue Chain = DAG.getEntryNode();
2684 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2688 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2693 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2697 assert(
N->getValueType(0).isVector() &&
2698 N->getOperand(0).getValueType().isVector() &&
2699 "Operand types must be vectors");
2703 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2707 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2709 GetSplitVector(
N->getOperand(0), LL, LH);
2711 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2713 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2715 GetSplitVector(
N->getOperand(1), RL, RH);
2717 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2720 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2721 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2723 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2724 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2725 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2726 std::tie(EVLLo, EVLHi) =
2727 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2728 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2730 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2740 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2744 EVT InVT =
N->getOperand(0).getValueType();
2746 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2748 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2750 const SDNodeFlags
Flags =
N->getFlags();
2751 unsigned Opcode =
N->getOpcode();
2752 if (
N->getNumOperands() <= 2) {
2754 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2755 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2757 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2758 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2763 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2764 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2767 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2770 std::tie(EVLLo, EVLHi) =
2771 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2774 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2780 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2784 EVT InVT =
N->getOperand(0).getValueType();
2786 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2788 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2791 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2792 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2793 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2794 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2797void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2802 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2803 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2807 EVT InVT =
N->getOperand(0).getValueType();
2809 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2811 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2813 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2814 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2816 SDNode *HiNode =
Hi.getNode();
2817 SDNode *LoNode =
Lo.getNode();
2820 unsigned OtherNo = 1 - ResNo;
2821 EVT OtherVT =
N->getValueType(OtherNo);
2829 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2836 EVT SrcVT =
N->getOperand(0).getValueType();
2837 EVT DestVT =
N->getValueType(0);
2839 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2856 LLVMContext &Ctx = *DAG.getContext();
2860 EVT SplitLoVT, SplitHiVT;
2861 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2862 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2863 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2864 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2865 N->dump(&DAG);
dbgs() <<
"\n");
2866 if (!
N->isVPOpcode()) {
2869 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2871 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2873 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2874 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2880 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2881 N->getOperand(1),
N->getOperand(2));
2883 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2886 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2889 std::tie(EVLLo, EVLHi) =
2890 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2892 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2893 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2898 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2906 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2907 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2913 return N.getResNo() == 0 &&
2917 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2919 ArrayRef<int>
Mask) {
2922 "Expected build vector node.");
2925 for (
unsigned I = 0;
I < NewElts; ++
I) {
2928 unsigned Idx =
Mask[
I];
2930 Ops[
I] = Input2.getOperand(Idx - NewElts);
2932 Ops[
I] = Input1.getOperand(Idx);
2937 return DAG.getBuildVector(NewVT,
DL,
Ops);
2943 SmallVector<int> OrigMask(
N->getMask());
2945 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2946 &
DL](SmallVectorImpl<int> &
Mask) {
2948 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2949 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2960 for (
auto &
P : ShufflesIdxs) {
2961 if (
P.second.size() < 2)
2965 for (
int &Idx : Mask) {
2968 unsigned SrcRegIdx = Idx / NewElts;
2969 if (Inputs[SrcRegIdx].
isUndef()) {
2977 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2982 Idx = MaskElt % NewElts +
2983 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
2989 Inputs[
P.second[0]] =
P.first.first;
2990 Inputs[
P.second[1]] =
P.first.second;
2993 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
2996 SmallBitVector UsedSubVector(2 * std::size(Inputs));
2997 for (
int &Idx : Mask) {
3000 unsigned SrcRegIdx = Idx / NewElts;
3001 if (Inputs[SrcRegIdx].
isUndef()) {
3008 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3009 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3012 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3014 if (UsedSubVector.count() > 1) {
3016 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3017 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3019 if (Pairs.
empty() || Pairs.
back().size() == 2)
3021 if (UsedSubVector.test(2 *
I)) {
3022 Pairs.
back().emplace_back(
I, 0);
3024 assert(UsedSubVector.test(2 *
I + 1) &&
3025 "Expected to be used one of the subvectors.");
3026 Pairs.
back().emplace_back(
I, 1);
3029 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3031 for (
int &Idx : Mask) {
3034 unsigned SrcRegIdx = Idx / NewElts;
3036 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3037 return Idxs.front().first == SrcRegIdx ||
3038 Idxs.back().first == SrcRegIdx;
3040 if (It == Pairs.
end())
3042 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3043 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3046 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3047 Inputs[Idxs.front().first] = DAG.
getNode(
3049 Inputs[Idxs.front().first].getValueType(),
3050 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3051 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3060 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3064 if (Shuffle->getOperand(0).getValueType() != NewVT)
3067 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3068 !Shuffle->isSplat()) {
3070 }
else if (!Inputs[
I].hasOneUse() &&
3071 !Shuffle->getOperand(1).isUndef()) {
3073 for (
int &Idx : Mask) {
3076 unsigned SrcRegIdx = Idx / NewElts;
3079 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3084 int OpIdx = MaskElt / NewElts;
3098 if (Shuffle->getOperand(
OpIdx).isUndef())
3100 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3101 if (It == std::end(Inputs))
3103 int FoundOp = std::distance(std::begin(Inputs), It);
3106 for (
int &Idx : Mask) {
3109 unsigned SrcRegIdx = Idx / NewElts;
3112 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3117 int MaskIdx = MaskElt / NewElts;
3118 if (
OpIdx == MaskIdx)
3119 Idx = MaskElt % NewElts + FoundOp * NewElts;
3130 for (
int &Idx : Mask) {
3133 unsigned SrcRegIdx = Idx / NewElts;
3136 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3137 int OpIdx = MaskElt / NewElts;
3140 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3146 TryPeekThroughShufflesInputs(OrigMask);
3148 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3149 NewElts](SmallVectorImpl<int> &
Mask) {
3150 SetVector<SDValue> UniqueInputs;
3151 SetVector<SDValue> UniqueConstantInputs;
3152 for (
const auto &
I : Inputs) {
3154 UniqueConstantInputs.
insert(
I);
3155 else if (!
I.isUndef())
3160 if (UniqueInputs.
size() != std::size(Inputs)) {
3161 auto &&UniqueVec = UniqueInputs.
takeVector();
3162 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3163 unsigned ConstNum = UniqueConstantVec.size();
3164 for (
int &Idx : Mask) {
3167 unsigned SrcRegIdx = Idx / NewElts;
3168 if (Inputs[SrcRegIdx].
isUndef()) {
3172 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3173 if (It != UniqueConstantVec.end()) {
3174 Idx = (Idx % NewElts) +
3175 NewElts * std::distance(UniqueConstantVec.begin(), It);
3176 assert(Idx >= 0 &&
"Expected defined mask idx.");
3179 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3180 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3181 Idx = (Idx % NewElts) +
3182 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3183 assert(Idx >= 0 &&
"Expected defined mask idx.");
3185 copy(UniqueConstantVec, std::begin(Inputs));
3186 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3189 MakeUniqueInputs(OrigMask);
3191 copy(Inputs, std::begin(OrigInputs));
3197 unsigned FirstMaskIdx =
High * NewElts;
3200 assert(!Output &&
"Expected default initialized initial value.");
3201 TryPeekThroughShufflesInputs(Mask);
3202 MakeUniqueInputs(Mask);
3204 copy(Inputs, std::begin(TmpInputs));
3207 bool SecondIteration =
false;
3208 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3213 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3214 SecondIteration =
true;
3215 return SecondIteration;
3218 Mask, std::size(Inputs), std::size(Inputs),
3220 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3221 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3222 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3224 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3226 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3227 DAG.getUNDEF(NewVT), Mask);
3228 Inputs[Idx] = Output;
3230 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3231 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3232 unsigned Idx2,
bool ) {
3233 if (AccumulateResults(Idx1)) {
3236 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3238 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3239 Inputs[Idx2], Mask);
3243 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3245 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3246 TmpInputs[Idx2], Mask);
3248 Inputs[Idx1] = Output;
3250 copy(OrigInputs, std::begin(Inputs));
3255 EVT OVT =
N->getValueType(0);
3262 const Align Alignment =
3263 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3265 Lo = DAG.getVAArg(NVT, dl, Chain,
Ptr, SV, Alignment.
value());
3266 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1),
Ptr, SV, Alignment.
value());
3271 ReplaceValueWith(
SDValue(
N, 1), Chain);
3276 EVT DstVTLo, DstVTHi;
3277 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3281 EVT SrcVT =
N->getOperand(0).getValueType();
3283 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3285 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3287 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3288 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3294 GetSplitVector(
N->getOperand(0), InLo, InHi);
3305 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3306 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3311 EVT VT =
N->getValueType(0);
3318 Align Alignment = DAG.getReducedAlign(VT,
false);
3323 EVT PtrVT =
StackPtr.getValueType();
3324 auto &MF = DAG.getMachineFunction();
3328 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3331 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3337 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3338 DAG.getConstant(1,
DL, PtrVT));
3340 DAG.getConstant(EltWidth,
DL, PtrVT));
3342 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3344 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3345 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3346 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3349 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3351 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3356 EVT VT =
N->getValueType(0);
3368 EVL1 = ZExtPromotedInteger(EVL1);
3370 Align Alignment = DAG.getReducedAlign(VT,
false);
3375 EVT PtrVT =
StackPtr.getValueType();
3376 auto &MF = DAG.getMachineFunction();
3380 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3383 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3387 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3389 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3390 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3391 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3395 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3400 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3401 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3403 uint64_t TrailingElts = -
Imm;
3405 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3414 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3418 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3420 DAG.getVectorIdxConstant(0,
DL));
3426void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3434 GetSplitVector(Acc, AccLo, AccHi);
3435 unsigned Opcode =
N->getOpcode();
3447 GetSplitVector(Input1, Input1Lo, Input1Hi);
3448 GetSplitVector(Input2, Input2Lo, Input2Hi);
3451 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3452 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3455void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3463 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3465 Lo = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, LoVT, Op0, Op1);
3468 Hi = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, HiVT, HiStartVal, Op1);
3471void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3472 unsigned Factor =
N->getNumOperands();
3475 for (
unsigned i = 0; i != Factor; ++i) {
3477 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3479 Ops[i * 2 + 1] = OpHi;
3490 for (
unsigned i = 0; i != Factor; ++i)
3494void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3495 unsigned Factor =
N->getNumOperands();
3498 for (
unsigned i = 0; i != Factor; ++i) {
3500 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3502 Ops[i + Factor] = OpHi;
3513 for (
unsigned i = 0; i != Factor; ++i) {
3514 unsigned IdxLo = 2 * i;
3515 unsigned IdxHi = 2 * i + 1;
3516 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3517 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3529bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3534 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3537 switch (
N->getOpcode()) {
3540 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3550 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3551 case ISD::BITCAST: Res = SplitVecOp_BITCAST(
N);
break;
3556 case ISD::VP_TRUNCATE:
3558 Res = SplitVecOp_TruncateHelper(
N);
3561 case ISD::VP_FP_ROUND:
3570 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3577 case ISD::VP_SCATTER:
3581 case ISD::VP_GATHER:
3585 Res = SplitVecOp_VSELECT(
N, OpNo);
3588 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3594 case ISD::VP_SINT_TO_FP:
3595 case ISD::VP_UINT_TO_FP:
3596 if (
N->getValueType(0).bitsLT(
3597 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3598 Res = SplitVecOp_TruncateHelper(
N);
3600 Res = SplitVecOp_UnaryOp(
N);
3604 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3608 case ISD::VP_FP_TO_SINT:
3609 case ISD::VP_FP_TO_UINT:
3613 case ISD::FP_EXTEND:
3622 Res = SplitVecOp_UnaryOp(
N);
3625 Res = SplitVecOp_FPOpDifferentTypes(
N);
3630 Res = SplitVecOp_CMP(
N);
3634 Res = SplitVecOp_FAKE_USE(
N);
3639 Res = SplitVecOp_ExtVecInRegOp(
N);
3642 case ISD::VECREDUCE_FADD:
3643 case ISD::VECREDUCE_FMUL:
3644 case ISD::VECREDUCE_ADD:
3645 case ISD::VECREDUCE_MUL:
3646 case ISD::VECREDUCE_AND:
3647 case ISD::VECREDUCE_OR:
3648 case ISD::VECREDUCE_XOR:
3649 case ISD::VECREDUCE_SMAX:
3650 case ISD::VECREDUCE_SMIN:
3651 case ISD::VECREDUCE_UMAX:
3652 case ISD::VECREDUCE_UMIN:
3653 case ISD::VECREDUCE_FMAX:
3654 case ISD::VECREDUCE_FMIN:
3655 case ISD::VECREDUCE_FMAXIMUM:
3656 case ISD::VECREDUCE_FMINIMUM:
3657 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3659 case ISD::VECREDUCE_SEQ_FADD:
3660 case ISD::VECREDUCE_SEQ_FMUL:
3661 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3663 case ISD::VP_REDUCE_FADD:
3664 case ISD::VP_REDUCE_SEQ_FADD:
3665 case ISD::VP_REDUCE_FMUL:
3666 case ISD::VP_REDUCE_SEQ_FMUL:
3667 case ISD::VP_REDUCE_ADD:
3668 case ISD::VP_REDUCE_MUL:
3669 case ISD::VP_REDUCE_AND:
3670 case ISD::VP_REDUCE_OR:
3671 case ISD::VP_REDUCE_XOR:
3672 case ISD::VP_REDUCE_SMAX:
3673 case ISD::VP_REDUCE_SMIN:
3674 case ISD::VP_REDUCE_UMAX:
3675 case ISD::VP_REDUCE_UMIN:
3676 case ISD::VP_REDUCE_FMAX:
3677 case ISD::VP_REDUCE_FMIN:
3678 case ISD::VP_REDUCE_FMAXIMUM:
3679 case ISD::VP_REDUCE_FMINIMUM:
3680 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3682 case ISD::VP_CTTZ_ELTS:
3683 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3684 Res = SplitVecOp_VP_CttzElements(
N);
3686 case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
3687 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3689 case ISD::PARTIAL_REDUCE_UMLA:
3690 case ISD::PARTIAL_REDUCE_SMLA:
3691 case ISD::PARTIAL_REDUCE_SUMLA:
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 uint64_t LoEltsMin =
Lo.getValueType().getVectorMinNumElements();
3946 if (IdxVal < LoEltsMin) {
3948 if (IdxVal + NumResultElts <= LoEltsMin)
3957 DAG.ExtractVectorElements(
Lo, Elts, IdxVal,
3958 LoEltsMin - IdxVal);
3959 DAG.ExtractVectorElements(
Hi, Elts, 0,
3962 return DAG.getBuildVector(SubVT, dl, Elts);
3965 EVT SrcVT =
N->getOperand(0).getValueType();
3967 uint64_t ExtractIdx = IdxVal - LoEltsMin;
3968 if (ExtractIdx % NumResultElts == 0)
3969 return DAG.getExtractSubvector(dl, SubVT,
Hi, ExtractIdx);
3974 EVT HiVT =
Hi.getValueType();
3976 for (
int I = 0;
I !=
static_cast<int>(NumResultElts); ++
I)
3977 Mask[
I] = ExtractIdx +
I;
3980 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
3981 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
3987 "Extracting scalable subvector from fixed-width unsupported");
3995 "subvector from a scalable predicate vector");
4001 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4003 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4004 auto &MF = DAG.getMachineFunction();
4008 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4012 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4015 SubVT, dl, Store, StackPtr,
4019SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4025 uint64_t IdxVal =
Index->getZExtValue();
4028 GetSplitVector(Vec,
Lo,
Hi);
4030 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4032 if (IdxVal < LoElts)
4033 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4036 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4041 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4053 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4059 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4061 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4062 auto &MF = DAG.getMachineFunction();
4065 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4069 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4073 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4075 return DAG.getExtLoad(
4086 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4094 SplitVecRes_Gather(
N,
Lo,
Hi);
4097 ReplaceValueWith(
SDValue(
N, 0), Res);
4102 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4106 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4108 SDValue EVL =
N->getVectorLength();
4110 Align Alignment =
N->getBaseAlign();
4116 GetSplitVector(
Data, DataLo, DataHi);
4118 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4123 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4126 GetSplitVector(Mask, MaskLo, MaskHi);
4128 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4131 EVT MemoryVT =
N->getMemoryVT();
4132 EVT LoMemVT, HiMemVT;
4133 bool HiIsEmpty =
false;
4134 std::tie(LoMemVT, HiMemVT) =
4135 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4139 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4142 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4147 Lo = DAG.getStoreVP(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4148 N->getAddressingMode(),
N->isTruncatingStore(),
4149 N->isCompressingStore());
4155 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo,
DL, LoMemVT, DAG,
4156 N->isCompressingStore());
4158 MachinePointerInfo MPI;
4162 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4167 MMO = DAG.getMachineFunction().getMachineMemOperand(
4169 Alignment,
N->getAAInfo(),
N->getRanges());
4171 Hi = DAG.getStoreVP(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4172 N->getAddressingMode(),
N->isTruncatingStore(),
4173 N->isCompressingStore());
4182 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4183 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4190 GetSplitVector(
Data, LoData, HiData);
4192 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4194 EVT LoMemVT, HiMemVT;
4195 bool HiIsEmpty =
false;
4196 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4202 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4203 else if (getTypeAction(
Mask.getValueType()) ==
4205 GetSplitVector(Mask, LoMask, HiMask);
4207 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4210 std::tie(LoEVL, HiEVL) =
4211 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4215 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4216 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4217 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4228 EVT PtrVT =
N->getBasePtr().getValueType();
4231 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4234 Align Alignment =
N->getBaseAlign();
4239 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4240 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4242 Alignment,
N->getAAInfo(),
N->getRanges());
4245 N->getChain(),
DL, HiData,
Ptr,
N->getOffset(),
N->getStride(), HiMask,
4246 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4247 N->isCompressingStore());
4256 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4260 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4263 Align Alignment =
N->getBaseAlign();
4269 GetSplitVector(
Data, DataLo, DataHi);
4271 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4276 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4279 GetSplitVector(Mask, MaskLo, MaskHi);
4281 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4284 EVT MemoryVT =
N->getMemoryVT();
4285 EVT LoMemVT, HiMemVT;
4286 bool HiIsEmpty =
false;
4287 std::tie(LoMemVT, HiMemVT) =
4288 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4291 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4296 Lo = DAG.getMaskedStore(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, LoMemVT, MMO,
4297 N->getAddressingMode(),
N->isTruncatingStore(),
4298 N->isCompressingStore());
4306 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo,
DL, LoMemVT, DAG,
4307 N->isCompressingStore());
4309 MachinePointerInfo MPI;
4313 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4318 MMO = DAG.getMachineFunction().getMachineMemOperand(
4320 Alignment,
N->getAAInfo(),
N->getRanges());
4322 Hi = DAG.getMaskedStore(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, HiMemVT, MMO,
4323 N->getAddressingMode(),
N->isTruncatingStore(),
4324 N->isCompressingStore());
4337 EVT MemoryVT =
N->getMemoryVT();
4338 Align Alignment =
N->getBaseAlign();
4345 }
Ops = [&]() -> Operands {
4347 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4351 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4356 EVT LoMemVT, HiMemVT;
4357 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4362 GetSplitVector(
Ops.Data, DataLo, DataHi);
4364 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4369 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4371 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4375 if (getTypeAction(
Ops.Index.getValueType()) ==
4377 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4379 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4383 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4385 Alignment,
N->getAAInfo(),
N->getRanges());
4388 SDValue OpsLo[] = {Ch, DataLo, MaskLo,
Ptr, IndexLo,
Ops.Scale};
4390 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4391 MSC->getIndexType(), MSC->isTruncatingStore());
4397 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4398 MMO, MSC->getIndexType(),
4399 MSC->isTruncatingStore());
4403 std::tie(EVLLo, EVLHi) =
4404 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4406 SDValue OpsLo[] = {Ch, DataLo,
Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4407 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4408 VPSC->getIndexType());
4413 SDValue OpsHi[] = {
Lo, DataHi,
Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4414 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4415 VPSC->getIndexType());
4419 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4420 assert(OpNo == 1 &&
"Can only split the stored value");
4423 bool isTruncating =
N->isTruncatingStore();
4426 EVT MemoryVT =
N->getMemoryVT();
4427 Align Alignment =
N->getBaseAlign();
4429 AAMDNodes AAInfo =
N->getAAInfo();
4431 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4433 EVT LoMemVT, HiMemVT;
4434 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4438 return TLI.scalarizeVectorStore(
N, DAG);
4441 Lo = DAG.getTruncStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), LoMemVT,
4442 Alignment, MMOFlags, AAInfo);
4444 Lo = DAG.getStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4447 MachinePointerInfo MPI;
4448 IncrementPointer(
N, LoMemVT, MPI,
Ptr);
4451 Hi = DAG.getTruncStore(Ch,
DL,
Hi,
Ptr, MPI,
4452 HiMemVT, Alignment, MMOFlags, AAInfo);
4454 Hi = DAG.getStore(Ch,
DL,
Hi,
Ptr, MPI, Alignment, MMOFlags, AAInfo);
4470 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4476 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4497 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4498 SDValue InVec =
N->getOperand(OpNo);
4500 EVT OutVT =
N->getValueType(0);
4508 EVT LoOutVT, HiOutVT;
4509 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4510 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4515 if (isTypeLegal(LoOutVT) ||
4516 InElementSize <= OutElementSize * 2)
4517 return SplitVecOp_UnaryOp(
N);
4526 return SplitVecOp_UnaryOp(
N);
4530 GetSplitVector(InVec, InLoVec, InHiVec);
4536 EVT HalfElementVT = IsFloat ?
4538 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4545 if (
N->isStrictFPOpcode()) {
4546 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4547 {N->getOperand(0), InLoVec});
4548 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4549 {N->getOperand(0), InHiVec});
4555 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4556 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4560 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4568 if (
N->isStrictFPOpcode()) {
4572 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4580 DAG.getTargetConstant(
4581 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4588 assert(
N->getValueType(0).isVector() &&
4589 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4590 "Operand types must be vectors");
4592 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4594 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4595 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4597 EVT VT =
N->getValueType(0);
4603 }
else if (isStrict) {
4604 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4605 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4606 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4607 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4610 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4612 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4613 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4614 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4615 std::tie(EVLLo, EVLHi) =
4616 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4617 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4618 N->getOperand(2), MaskLo, EVLLo);
4619 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4620 N->getOperand(2), MaskHi, EVLHi);
4629 EVT ResVT =
N->getValueType(0);
4632 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4633 EVT InVT =
Lo.getValueType();
4638 if (
N->isStrictFPOpcode()) {
4639 Lo = DAG.getNode(
N->getOpcode(),
DL, { OutVT, MVT::Other },
4640 { N->getOperand(0), Lo, N->getOperand(2) });
4641 Hi = DAG.getNode(
N->getOpcode(),
DL, { OutVT, MVT::Other },
4642 { N->getOperand(0), Hi, N->getOperand(2) });
4646 Lo.getValue(1),
Hi.getValue(1));
4647 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4648 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4649 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4650 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4651 std::tie(EVLLo, EVLHi) =
4652 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4653 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4654 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4668SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4671 EVT LHSLoVT, LHSHiVT;
4672 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4674 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4675 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4678 std::tie(LHSLo, LHSHi) =
4679 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4682 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4685 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4691 LLVMContext &Ctxt = *DAG.getContext();
4694 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4695 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4696 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4698 EVT ResVT =
N->getValueType(0);
4703 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4704 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4710 EVT ResVT =
N->getValueType(0);
4713 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4714 EVT InVT =
Lo.getValueType();
4720 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4721 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4728 EVT ResVT =
N->getValueType(0);
4732 GetSplitVector(VecOp,
Lo,
Hi);
4734 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4735 auto [EVLLo, EVLHi] =
4737 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4743 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4745 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4746 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4749SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4760 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4761 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4762 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4764 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4765 OpsLo, MMO, IndexType);
4766 SDValue OpsHi[] = {
Lo, Inc, MaskHi,
Ptr, IndexHi, Scale, IntID};
4767 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4771SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4774 "Accumulator should already be a legal type, and shouldn't need "
4775 "further splitting");
4778 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4779 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4780 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4781 unsigned Opcode =
N->getOpcode();
4784 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4785 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4792void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4793 unsigned WidenResNo) {
4794 unsigned NumResults =
N->getNumValues();
4795 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4796 if (ResNo == WidenResNo)
4798 EVT ResVT =
N->getValueType(ResNo);
4804 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4805 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4810void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4811 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4814 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4819 auto unrollExpandedOp = [&]() {
4824 EVT VT =
N->getValueType(0);
4825 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4826 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4829 if (
N->getNumValues() > 1)
4830 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4836 switch (
N->getOpcode()) {
4839 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4847 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4850 case ISD::ADDRSPACECAST:
4851 Res = WidenVecRes_ADDRSPACECAST(
N);
4854 case ISD::BITCAST: Res = WidenVecRes_BITCAST(
N);
break;
4858 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4862 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4866 case ISD::EXPERIMENTAL_VP_SPLAT:
4867 Res = WidenVecRes_ScalarOp(
N);
4872 case ISD::VP_SELECT:
4874 Res = WidenVecRes_Select(
N);
4878 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4880 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4887 case ISD::VP_LOAD_FF:
4890 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4894 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4902 case ISD::VP_GATHER:
4906 Res = WidenVecRes_VECTOR_REVERSE(
N);
4908 case ISD::GET_ACTIVE_LANE_MASK:
4909 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4919 case ISD::OR:
case ISD::VP_OR:
4926 case ISD::FMINNUM_IEEE:
4927 case ISD::VP_FMINNUM:
4929 case ISD::FMAXNUM_IEEE:
4930 case ISD::VP_FMAXNUM:
4932 case ISD::VP_FMINIMUM:
4934 case ISD::VP_FMAXIMUM:
4935 case ISD::FMINIMUMNUM:
4936 case ISD::FMAXIMUMNUM:
4967 case ISD::VP_FCOPYSIGN:
4968 Res = WidenVecRes_Binary(
N);
4973 Res = WidenVecRes_CMP(
N);
4979 if (unrollExpandedOp())
4994 Res = WidenVecRes_BinaryCanTrap(
N);
5003 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5006#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5007 case ISD::STRICT_##DAGN:
5008#include "llvm/IR/ConstrainedOps.def"
5009 Res = WidenVecRes_StrictFP(
N);
5018 Res = WidenVecRes_OverflowOp(
N, ResNo);
5022 Res = WidenVecRes_FCOPYSIGN(
N);
5027 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5032 if (!unrollExpandedOp())
5033 Res = WidenVecRes_ExpOp(
N);
5039 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5043 case ISD::FP_EXTEND:
5044 case ISD::VP_FP_EXTEND:
5046 case ISD::VP_FP_ROUND:
5048 case ISD::VP_FP_TO_SINT:
5050 case ISD::VP_FP_TO_UINT:
5052 case ISD::VP_SIGN_EXTEND:
5054 case ISD::VP_SINT_TO_FP:
5055 case ISD::VP_TRUNCATE:
5058 case ISD::VP_UINT_TO_FP:
5060 case ISD::VP_ZERO_EXTEND:
5061 Res = WidenVecRes_Convert(
N);
5066 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5072 case ISD::VP_LLRINT:
5075 Res = WidenVecRes_XROUND(
N);
5091 case ISD::FNEARBYINT:
5094 case ISD::FROUNDEVEN:
5101 if (unrollExpandedOp())
5111 case ISD::VP_BITREVERSE:
5117 case ISD::VP_CTLZ_ZERO_UNDEF:
5123 case ISD::VP_CTTZ_ZERO_UNDEF:
5124 case ISD::FNEG:
case ISD::VP_FNEG:
5125 case ISD::FABS:
case ISD::VP_FABS:
5128 case ISD::VP_FFLOOR:
5130 case ISD::VP_FNEARBYINT:
5131 case ISD::VP_FROUND:
5132 case ISD::VP_FROUNDEVEN:
5133 case ISD::VP_FROUNDTOZERO:
5135 case ISD::ARITH_FENCE:
5138 Res = WidenVecRes_Unary(
N);
5145 Res = WidenVecRes_Ternary(
N);
5150 case ISD::FSINCOSPI: {
5151 if (!unrollExpandedOp())
5152 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5159 SetWidenedVector(
SDValue(
N, ResNo), Res);
5165 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5166 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5167 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5168 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5169 if (
N->getNumOperands() == 3)
5170 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5172 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5173 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5177 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5178 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5184 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5185 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5186 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5187 if (
N->getNumOperands() == 2)
5188 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5191 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5192 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5196 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5197 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5201 LLVMContext &Ctxt = *DAG.getContext();
5206 EVT OpVT =
LHS.getValueType();
5208 LHS = GetWidenedVector(
LHS);
5209 RHS = GetWidenedVector(
RHS);
5210 OpVT =
LHS.getValueType();
5213 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5216 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5222SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5225 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5226 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5227 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5229 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5238 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5241 if (ConcatEnd == 1) {
5242 VT = ConcatOps[0].getValueType();
5244 return ConcatOps[0];
5247 SDLoc dl(ConcatOps[0]);
5254 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5255 int Idx = ConcatEnd - 1;
5256 VT = ConcatOps[Idx--].getValueType();
5257 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5270 unsigned NumToInsert = ConcatEnd - Idx - 1;
5271 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5273 ConcatOps[Idx+1] = VecOp;
5274 ConcatEnd = Idx + 2;
5280 unsigned RealVals = ConcatEnd - Idx - 1;
5281 unsigned SubConcatEnd = 0;
5282 unsigned SubConcatIdx = Idx + 1;
5283 while (SubConcatEnd < RealVals)
5284 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5285 while (SubConcatEnd < OpsToConcat)
5286 SubConcatOps[SubConcatEnd++] = undefVec;
5288 NextVT, SubConcatOps);
5289 ConcatEnd = SubConcatIdx + 1;
5294 if (ConcatEnd == 1) {
5295 VT = ConcatOps[0].getValueType();
5297 return ConcatOps[0];
5302 if (
NumOps != ConcatEnd ) {
5304 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5305 ConcatOps[j] = UndefVal;
5313 unsigned Opcode =
N->getOpcode();
5315 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5319 const SDNodeFlags
Flags =
N->getFlags();
5320 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5321 NumElts = NumElts / 2;
5325 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5327 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5328 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5329 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5337 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5340 TLI.isTypeLegal(WideMaskVT)) {
5341 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5342 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5343 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5345 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5346 N->getValueType(0).getVectorElementCount());
5347 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5361 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5362 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5363 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5366 unsigned ConcatEnd = 0;
5374 while (CurNumElts != 0) {
5375 while (CurNumElts >= NumElts) {
5376 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5377 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5378 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5380 CurNumElts -= NumElts;
5383 NumElts = NumElts / 2;
5385 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5388 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5389 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5390 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5391 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5402 switch (
N->getOpcode()) {
5405 return WidenVecRes_STRICT_FSETCC(
N);
5412 return WidenVecRes_Convert_StrictFP(
N);
5419 unsigned Opcode =
N->getOpcode();
5421 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5425 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5426 NumElts = NumElts / 2;
5437 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5441 unsigned ConcatEnd = 0;
5448 for (
unsigned i = 1; i < NumOpers; ++i) {
5454 Oper = GetWidenedVector(Oper);
5460 DAG.getUNDEF(WideOpVT), Oper,
5461 DAG.getVectorIdxConstant(0, dl));
5473 while (CurNumElts != 0) {
5474 while (CurNumElts >= NumElts) {
5477 for (
unsigned i = 0; i < NumOpers; ++i) {
5480 EVT OpVT =
Op.getValueType();
5485 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5491 EVT OperVT[] = {VT, MVT::Other};
5493 ConcatOps[ConcatEnd++] = Oper;
5496 CurNumElts -= NumElts;
5499 NumElts = NumElts / 2;
5501 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5504 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5507 for (
unsigned i = 0; i < NumOpers; ++i) {
5510 EVT OpVT =
Op.getValueType();
5518 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5520 ConcatOps[ConcatEnd++] = Oper;
5529 if (Chains.
size() == 1)
5530 NewChain = Chains[0];
5533 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5538SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5540 EVT ResVT =
N->getValueType(0);
5541 EVT OvVT =
N->getValueType(1);
5542 EVT WideResVT, WideOvVT;
5547 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5552 WideLHS = GetWidenedVector(
N->getOperand(0));
5553 WideRHS = GetWidenedVector(
N->getOperand(1));
5555 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5563 N->getOperand(0), Zero);
5566 N->getOperand(1), Zero);
5569 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5570 SDNode *WideNode = DAG.getNode(
5571 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5574 unsigned OtherNo = 1 - ResNo;
5575 EVT OtherVT =
N->getValueType(OtherNo);
5582 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5585 return SDValue(WideNode, ResNo);
5589 LLVMContext &Ctx = *DAG.getContext();
5593 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5598 unsigned Opcode =
N->getOpcode();
5599 const SDNodeFlags
Flags =
N->getFlags();
5605 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5607 InOp = ZExtPromotedInteger(InOp);
5618 InOp = GetWidenedVector(
N->getOperand(0));
5621 if (InVTEC == WidenEC) {
5622 if (
N->getNumOperands() == 1)
5623 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5624 if (
N->getNumOperands() == 3) {
5625 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5628 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5630 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5645 if (TLI.isTypeLegal(InWidenVT)) {
5653 unsigned NumConcat =
5658 if (
N->getNumOperands() == 1)
5659 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5660 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5664 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5666 if (
N->getNumOperands() == 1)
5667 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5668 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5677 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5678 for (
unsigned i=0; i < MinElts; ++i) {
5679 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5680 if (
N->getNumOperands() == 1)
5683 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5686 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5691 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5695 EVT SrcVT = Src.getValueType();
5699 Src = GetWidenedVector(Src);
5700 SrcVT = Src.getValueType();
5707 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5712 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5716 EVT SrcVT = Src.getValueType();
5720 Src = GetWidenedVector(Src);
5721 SrcVT = Src.getValueType();
5728 if (
N->getNumOperands() == 1)
5729 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5731 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5732 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5736 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5739SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5744 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5750 unsigned Opcode =
N->getOpcode();
5756 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5761 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5762 for (
unsigned i=0; i < MinElts; ++i) {
5763 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5764 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5768 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5770 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5773SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5774 unsigned Opcode =
N->getOpcode();
5778 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5787 InOp = GetWidenedVector(InOp);
5794 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5801 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5802 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5819 while (
Ops.size() != WidenNumElts)
5820 Ops.push_back(DAG.getUNDEF(WidenSVT));
5822 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5828 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5829 return WidenVecRes_BinaryCanTrap(
N);
5832 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5839SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5841 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5844 SDValue Arg = GetWidenedVector(FpValue);
5845 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5850 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5851 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5853 EVT ExpVT =
RHS.getValueType();
5858 ExpOp = ModifyToType(
RHS, WideExpVT);
5861 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5866 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5867 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5868 if (
N->getNumOperands() == 1)
5869 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5871 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5872 N->getOperand(1),
N->getFlags());
5874 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5875 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5879 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5880 {InOp,
Mask,
N->getOperand(2)});
5884 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5887 .getVectorElementType(),
5889 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5890 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5891 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5894SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5896 EVT VT0 =
N->getValueType(0);
5897 EVT VT1 =
N->getValueType(1);
5901 "expected both results to be vectors of matching element count");
5903 LLVMContext &Ctx = *DAG.getContext();
5904 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5906 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5913 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5916 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5917 return SDValue(WidenNode, ResNo);
5920SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5921 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5922 return GetWidenedVector(WidenVec);
5926 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5927 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5930 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5931 AddrSpaceCastN->getSrcAddressSpace(),
5932 AddrSpaceCastN->getDestAddressSpace());
5938 EVT VT =
N->getValueType(0);
5939 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5942 switch (getTypeAction(InVT)) {
5956 SDValue NInOp = GetPromotedInteger(InOp);
5958 if (WidenVT.
bitsEq(NInVT)) {
5961 if (DAG.getDataLayout().isBigEndian()) {
5964 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
5966 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NInOp);
5983 InOp = GetWidenedVector(InOp);
5985 if (WidenVT.
bitsEq(InVT))
5987 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp);
5995 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6000 unsigned NewNumParts = WidenSize / InSize;
6013 EVT OrigInVT =
N->getOperand(0).getValueType();
6018 if (TLI.isTypeLegal(NewInVT)) {
6026 if (WidenSize % InSize == 0) {
6033 DAG.ExtractVectorElements(InOp,
Ops);
6034 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6042 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec);
6046 return CreateStackStoreLoad(InOp, WidenVT);
6049SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6051 N->getOpcode(), SDLoc(
N),
6052 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6053 N->getOperand(0),
N->getOperand(1),
N->getOperand(2));
6059 EVT VT =
N->getValueType(0);
6063 EVT EltVT =
N->getOperand(0).getValueType();
6066 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6070 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6071 NewOps.append(WidenNumElts - NumElts, DAG.getUNDEF(EltVT));
6073 return DAG.getBuildVector(WidenVT, dl, NewOps);
6077 EVT InVT =
N->getOperand(0).getValueType();
6078 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6080 unsigned NumOperands =
N->getNumOperands();
6082 bool InputWidened =
false;
6086 if (WidenNumElts % NumInElts == 0) {
6088 unsigned NumConcat = WidenNumElts / NumInElts;
6089 SDValue UndefVal = DAG.getUNDEF(InVT);
6091 for (
unsigned i=0; i < NumOperands; ++i)
6092 Ops[i] =
N->getOperand(i);
6093 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6098 InputWidened =
true;
6099 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6102 for (i=1; i < NumOperands; ++i)
6103 if (!
N->getOperand(i).isUndef())
6106 if (i == NumOperands)
6109 return GetWidenedVector(
N->getOperand(0));
6111 if (NumOperands == 2) {
6113 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6118 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6119 for (
unsigned i = 0; i < NumInElts; ++i) {
6121 MaskOps[i + NumInElts] = i + WidenNumElts;
6123 return DAG.getVectorShuffle(WidenVT, dl,
6124 GetWidenedVector(
N->getOperand(0)),
6125 GetWidenedVector(
N->getOperand(1)),
6132 "Cannot use build vectors to widen CONCAT_VECTOR result");
6140 for (
unsigned i=0; i < NumOperands; ++i) {
6143 InOp = GetWidenedVector(InOp);
6144 for (
unsigned j = 0;
j < NumInElts; ++
j)
6145 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6147 SDValue UndefVal = DAG.getUNDEF(EltVT);
6148 for (; Idx < WidenNumElts; ++Idx)
6149 Ops[Idx] = UndefVal;
6150 return DAG.getBuildVector(WidenVT, dl,
Ops);
6153SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6154 EVT VT =
N->getValueType(0);
6155 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6156 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6163SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6164 EVT VT =
N->getValueType(0);
6166 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6171 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6173 InOp = GetWidenedVector(InOp);
6179 if (IdxVal == 0 && InVT == WidenVT)
6186 assert(IdxVal % VTNumElts == 0 &&
6187 "Expected Idx to be a multiple of subvector minimum vector length");
6188 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6201 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6202 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6203 "down type's element count");
6210 for (;
I < VTNumElts / GCD; ++
I)
6212 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6213 for (;
I < WidenNumElts / GCD; ++
I)
6220 "EXTRACT_SUBVECTOR for scalable vectors");
6227 for (i = 0; i < VTNumElts; ++i)
6228 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6230 SDValue UndefVal = DAG.getUNDEF(EltVT);
6231 for (; i < WidenNumElts; ++i)
6233 return DAG.getBuildVector(WidenVT, dl,
Ops);
6239 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6244SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6245 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6248 N->getOperand(1),
N->getOperand(2));
6261 if (!
LD->getMemoryVT().isByteSized()) {
6263 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6265 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6274 EVT VT =
LD->getValueType(0);
6275 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6276 EVT WideMaskVT = getSetCCResultType(WideVT);
6279 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6280 TLI.isTypeLegal(WideMaskVT)) {
6283 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6287 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6288 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6300 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6302 Result = GenWidenVectorLoads(LdChain, LD);
6309 if (LdChain.
size() == 1)
6310 NewChain = LdChain[0];
6316 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6324 EVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout());
6327 SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, WideMaskVT,
6328 DAG.getConstant(0,
DL, IdxVT), Len);
6330 SDValue NewLoad = DAG.getMaskedLoad(
6331 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6332 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6333 LD->getAddressingMode(),
LD->getExtensionType());
6343 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6345 SDValue EVL =
N->getVectorLength();
6352 "Unable to widen binary VP op");
6353 Mask = GetWidenedVector(Mask);
6354 assert(
Mask.getValueType().getVectorElementCount() ==
6355 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6356 .getVectorElementCount() &&
6357 "Unable to widen vector load");
6360 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6361 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6362 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6370 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6372 SDValue EVL =
N->getVectorLength();
6378 "Unable to widen binary VP op");
6379 Mask = GetWidenedVector(Mask);
6380 assert(
Mask.getValueType().getVectorElementCount() ==
6381 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6382 .getVectorElementCount() &&
6383 "Unable to widen vector load");
6385 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6386 Mask, EVL,
N->getMemOperand());
6399 "Unable to widen VP strided load");
6400 Mask = GetWidenedVector(Mask);
6402 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6403 assert(
Mask.getValueType().getVectorElementCount() ==
6405 "Data and mask vectors should have the same number of elements");
6407 SDValue Res = DAG.getStridedLoadVP(
6408 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6409 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6410 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6411 N->isExpandingLoad());
6419SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6424 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6426 Mask.getValueType().getVectorElementType(),
6429 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6430 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6431 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6433 WideMask, WidePassthru);
6437 EVT VT =
N->getValueType(0);
6438 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6440 EVT MaskVT =
Mask.getValueType();
6441 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6450 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6451 TLI.isTypeLegal(WideMaskVT) &&
6457 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6458 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6462 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6463 N->getMemoryVT(),
N->getMemOperand());
6467 if (!
N->getPassThru()->isUndef()) {
6470 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6481 Mask = ModifyToType(Mask, WideMaskVT,
true);
6483 SDValue Res = DAG.getMaskedLoad(
6484 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6485 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6486 ExtType,
N->isExpandingLoad());
6495 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6497 EVT MaskVT =
Mask.getValueType();
6498 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6507 Mask = ModifyToType(Mask, WideMaskVT,
true);
6512 Index.getValueType().getScalarType(),
6514 Index = ModifyToType(Index, WideIndexVT);
6520 N->getMemoryVT().getScalarType(), NumElts);
6521 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6522 WideMemVT, dl,
Ops,
N->getMemOperand(),
6523 N->getIndexType(),
N->getExtensionType());
6532 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6540 N->getMemoryVT().getScalarType(), WideEC);
6541 Mask = GetWidenedMask(Mask, WideEC);
6544 Mask,
N->getVectorLength()};
6545 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6546 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6555 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6556 if (
N->isVPOpcode())
6557 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0),
6558 N->getOperand(1),
N->getOperand(2));
6559 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6587 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6588 return N->getOperand(OpNo).getValueType();
6596 N =
N.getOperand(0);
6598 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6599 if (!
N->getOperand(i)->isUndef())
6601 N =
N.getOperand(0);
6605 N =
N.getOperand(0);
6607 N =
N.getOperand(0);
6634 { MaskVT, MVT::Other },
Ops);
6635 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6642 LLVMContext &Ctx = *DAG.getContext();
6645 if (MaskScalarBits < ToMaskScalBits) {
6649 }
else if (MaskScalarBits > ToMaskScalBits) {
6655 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6657 "Mask should have the right element size by now.");
6660 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6662 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6665 EVT SubVT =
Mask->getValueType(0);
6671 assert((
Mask->getValueType(0) == ToMaskVT) &&
6672 "A mask of ToMaskVT should have been produced by now.");
6682 LLVMContext &Ctx = *DAG.getContext();
6693 EVT CondVT =
Cond->getValueType(0);
6697 EVT VSelVT =
N->getValueType(0);
6709 EVT FinalVT = VSelVT;
6720 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6721 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6728 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6736 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6739 EVT ToMaskVT = VSelVT;
6746 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6762 if (ScalarBits0 != ScalarBits1) {
6763 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6764 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6776 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6777 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6778 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6781 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6789 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6794 unsigned Opcode =
N->getOpcode();
6796 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6797 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6798 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6800 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6806 Cond1 = GetWidenedVector(Cond1);
6814 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6815 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6820 Cond1 = ModifyToType(Cond1, CondWidenVT);
6823 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6824 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6826 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6827 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6829 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6833 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6834 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6837 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6841 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6842 return DAG.getUNDEF(WidenVT);
6846 EVT VT =
N->getValueType(0);
6849 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6853 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6854 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6857 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6858 for (
unsigned i = 0; i != NumElts; ++i) {
6859 int Idx =
N->getMaskElt(i);
6860 if (Idx < (
int)NumElts)
6863 NewMask[i] = Idx - NumElts + WidenNumElts;
6865 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6869 EVT VT =
N->getValueType(0);
6873 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6874 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6880 unsigned IdxVal = WidenNumElts - VTNumElts;
6893 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6896 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6897 "down type's element count");
6900 for (; i < VTNumElts / GCD; ++i)
6902 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6903 for (; i < WidenNumElts / GCD; ++i)
6911 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6912 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6914 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6918SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6919 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6920 return DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, SDLoc(
N), NVT,
N->ops());
6924 assert(
N->getValueType(0).isVector() &&
6925 N->getOperand(0).getValueType().isVector() &&
6926 "Operands must be vectors");
6927 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6940 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
6941 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
6948 InOp1 = GetWidenedVector(InOp1);
6949 InOp2 = GetWidenedVector(InOp2);
6952 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
6963 "Input not widened to expected type!");
6965 if (
N->getOpcode() == ISD::VP_SETCC) {
6968 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6969 N->getOperand(2), Mask,
N->getOperand(4));
6971 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6976 assert(
N->getValueType(0).isVector() &&
6977 N->getOperand(1).getValueType().isVector() &&
6978 "Operands must be vectors");
6979 EVT VT =
N->getValueType(0);
6980 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6990 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
6995 for (
unsigned i = 0; i != NumElts; ++i) {
6996 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
6997 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
6999 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7000 {Chain, LHSElem, RHSElem, CC});
7001 Chains[i] = Scalars[i].getValue(1);
7002 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7003 DAG.getBoolConstant(
true, dl, EltVT, VT),
7004 DAG.getBoolConstant(
false, dl, EltVT, VT));
7008 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7010 return DAG.getBuildVector(WidenVT, dl, Scalars);
7016bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7017 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7021 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7024 switch (
N->getOpcode()) {
7027 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7033 case ISD::BITCAST: Res = WidenVecOp_BITCAST(
N);
break;
7035 Res = WidenVecOp_FAKE_USE(
N);
7041 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7042 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7043 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7044 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7049 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7051 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7052 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7053 case ISD::MSCATTER: Res = WidenVecOp_MSCATTER(
N, OpNo);
break;
7054 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7055 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7065 Res = WidenVecOp_UnrollVectorOp(
N);
7072 Res = WidenVecOp_EXTEND(
N);
7077 Res = WidenVecOp_CMP(
N);
7080 case ISD::FP_EXTEND:
7093 Res = WidenVecOp_Convert(
N);
7098 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7101 case ISD::EXPERIMENTAL_VP_SPLAT:
7102 Res = WidenVecOp_VP_SPLAT(
N, OpNo);
7105 case ISD::VECREDUCE_FADD:
7106 case ISD::VECREDUCE_FMUL:
7107 case ISD::VECREDUCE_ADD:
7108 case ISD::VECREDUCE_MUL:
7109 case ISD::VECREDUCE_AND:
7110 case ISD::VECREDUCE_OR:
7111 case ISD::VECREDUCE_XOR:
7112 case ISD::VECREDUCE_SMAX:
7113 case ISD::VECREDUCE_SMIN:
7114 case ISD::VECREDUCE_UMAX:
7115 case ISD::VECREDUCE_UMIN:
7116 case ISD::VECREDUCE_FMAX:
7117 case ISD::VECREDUCE_FMIN:
7118 case ISD::VECREDUCE_FMAXIMUM:
7119 case ISD::VECREDUCE_FMINIMUM:
7120 Res = WidenVecOp_VECREDUCE(
N);
7122 case ISD::VECREDUCE_SEQ_FADD:
7123 case ISD::VECREDUCE_SEQ_FMUL:
7124 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7126 case ISD::VP_REDUCE_FADD:
7127 case ISD::VP_REDUCE_SEQ_FADD:
7128 case ISD::VP_REDUCE_FMUL:
7129 case ISD::VP_REDUCE_SEQ_FMUL:
7130 case ISD::VP_REDUCE_ADD:
7131 case ISD::VP_REDUCE_MUL:
7132 case ISD::VP_REDUCE_AND:
7133 case ISD::VP_REDUCE_OR:
7134 case ISD::VP_REDUCE_XOR:
7135 case ISD::VP_REDUCE_SMAX:
7136 case ISD::VP_REDUCE_SMIN:
7137 case ISD::VP_REDUCE_UMAX:
7138 case ISD::VP_REDUCE_UMIN:
7139 case ISD::VP_REDUCE_FMAX:
7140 case ISD::VP_REDUCE_FMIN:
7141 case ISD::VP_REDUCE_FMAXIMUM:
7142 case ISD::VP_REDUCE_FMINIMUM:
7143 Res = WidenVecOp_VP_REDUCE(
N);
7145 case ISD::VP_CTTZ_ELTS:
7146 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7147 Res = WidenVecOp_VP_CttzElements(
N);
7152 if (!Res.
getNode())
return false;
7160 if (
N->isStrictFPOpcode())
7162 "Invalid operand expansion");
7165 "Invalid operand expansion");
7167 ReplaceValueWith(
SDValue(
N, 0), Res);
7173 EVT VT =
N->getValueType(0);
7178 "Unexpected type action");
7179 InOp = GetWidenedVector(InOp);
7182 "Input wasn't widened!");
7190 EVT FixedEltVT = FixedVT.getVectorElementType();
7191 if (TLI.isTypeLegal(FixedVT) &&
7193 FixedEltVT == InEltVT) {
7195 "Not enough elements in the fixed type for the operand!");
7197 "We can't have the same type as we started with!");
7199 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7201 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7210 return WidenVecOp_Convert(
N);
7215 switch (
N->getOpcode()) {
7230 EVT OpVT =
N->getOperand(0).getValueType();
7231 EVT ResVT =
N->getValueType(0);
7238 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7239 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7245 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7246 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7248 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7255 return DAG.UnrollVectorOp(
N);
7260 EVT ResultVT =
N->getValueType(0);
7262 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7265 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7271 {WideArg,
Test},
N->getFlags());
7277 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7279 EVT OpVT =
N->getOperand(0).getValueType();
7282 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7287 EVT VT =
N->getValueType(0);
7293 "Unexpected type action");
7294 InOp = GetWidenedVector(InOp);
7296 unsigned Opcode =
N->getOpcode();
7302 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7304 if (
N->isStrictFPOpcode()) {
7306 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7309 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7310 {
N->getOperand(0), InOp });
7316 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7318 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7320 return DAG.getExtractSubvector(dl, VT, Res, 0);
7328 if (
N->isStrictFPOpcode()) {
7331 for (
unsigned i=0; i < NumElts; ++i) {
7332 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7333 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7337 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7339 for (
unsigned i = 0; i < NumElts; ++i)
7340 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7341 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7344 return DAG.getBuildVector(VT, dl,
Ops);
7348 EVT DstVT =
N->getValueType(0);
7349 SDValue Src = GetWidenedVector(
N->getOperand(0));
7350 EVT SrcVT = Src.getValueType();
7357 if (TLI.isTypeLegal(WideDstVT)) {
7359 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7362 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7366 return DAG.UnrollVectorOp(
N);
7370 EVT VT =
N->getValueType(0);
7371 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7379 if (!VT.
isVector() && VT != MVT::x86mmx &&
7383 if (TLI.isTypeLegal(NewVT)) {
7384 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
7385 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7397 ElementCount NewNumElts =
7399 .divideCoefficientBy(EltSize);
7401 if (TLI.isTypeLegal(NewVT)) {
7403 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7408 return CreateStackStoreLoad(InOp, VT);
7416 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7417 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7422 EVT VT =
N->getValueType(0);
7424 EVT InVT =
N->getOperand(0).getValueType();
7429 unsigned NumOperands =
N->getNumOperands();
7430 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7432 for (i = 1; i < NumOperands; ++i)
7433 if (!
N->getOperand(i).isUndef())
7436 if (i == NumOperands)
7437 return GetWidenedVector(
N->getOperand(0));
7447 for (
unsigned i=0; i < NumOperands; ++i) {
7451 "Unexpected type action");
7452 InOp = GetWidenedVector(InOp);
7453 for (
unsigned j = 0;
j < NumInElts; ++
j)
7454 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7456 return DAG.getBuildVector(VT, dl,
Ops);
7459SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7460 EVT VT =
N->getValueType(0);
7466 SubVec = GetWidenedVector(SubVec);
7472 bool IndicesValid =
false;
7475 IndicesValid =
true;
7479 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7480 Attribute::VScaleRange);
7485 IndicesValid =
true;
7493 if (IndicesValid && InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7499 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7503 unsigned Idx =
N->getConstantOperandVal(2);
7509 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7515SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7516 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7518 N->getValueType(0), InOp,
N->getOperand(1));
7521SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7522 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7524 N->getValueType(0), InOp,
N->getOperand(1));
7527SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7528 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7529 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7537 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7538 return TLI.scalarizeVectorStore(ST, DAG);
7540 if (
ST->isTruncatingStore())
7541 return TLI.scalarizeVectorStore(ST, DAG);
7551 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7552 EVT WideMaskVT = getSetCCResultType(WideVT);
7554 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7555 TLI.isTypeLegal(WideMaskVT)) {
7558 StVal = GetWidenedVector(StVal);
7560 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7562 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7563 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7564 ST->getAddressingMode());
7568 if (GenWidenVectorStores(StChain, ST)) {
7569 if (StChain.
size() == 1)
7578 EVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout());
7580 SDValue WideStVal = GetWidenedVector(StVal);
7582 SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, WideMaskVT,
7583 DAG.getConstant(0,
DL, IdxVT), Len);
7585 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7586 ST->getOffset(), Mask,
ST->getMemoryVT(),
7587 ST->getMemOperand(),
ST->getAddressingMode(),
7588 ST->isTruncatingStore());
7594SDValue DAGTypeLegalizer::WidenVecOp_VP_SPLAT(
SDNode *
N,
unsigned OpNo) {
7595 assert(OpNo == 1 &&
"Can widen only mask operand of vp_splat");
7596 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
7597 N->getOperand(0), GetWidenedVector(
N->getOperand(1)),
7601SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7602 assert((OpNo == 1 || OpNo == 3) &&
7603 "Can widen only data or mask operand of vp_store");
7611 StVal = GetWidenedVector(StVal);
7617 "Unable to widen VP store");
7618 Mask = GetWidenedVector(Mask);
7620 Mask = GetWidenedVector(Mask);
7626 "Unable to widen VP store");
7627 StVal = GetWidenedVector(StVal);
7630 assert(
Mask.getValueType().getVectorElementCount() ==
7632 "Mask and data vectors should have the same number of elements");
7633 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7634 ST->getOffset(), Mask,
ST->getVectorLength(),
7635 ST->getMemoryVT(),
ST->getMemOperand(),
7636 ST->getAddressingMode(),
ST->isTruncatingStore(),
7637 ST->isCompressingStore());
7642 assert((OpNo == 1 || OpNo == 4) &&
7643 "Can widen only data or mask operand of vp_strided_store");
7652 "Unable to widen VP strided store");
7656 "Unable to widen VP strided store");
7658 StVal = GetWidenedVector(StVal);
7659 Mask = GetWidenedVector(Mask);
7662 Mask.getValueType().getVectorElementCount() &&
7663 "Data and mask vectors should have the same number of elements");
7665 return DAG.getStridedStoreVP(
7672SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7673 assert((OpNo == 1 || OpNo == 4) &&
7674 "Can widen only data or mask operand of mstore");
7677 EVT MaskVT =
Mask.getValueType();
7682 EVT WideVT, WideMaskVT;
7685 StVal = GetWidenedVector(StVal);
7692 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7699 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7700 TLI.isTypeLegal(WideMaskVT)) {
7701 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7702 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7711 Mask = ModifyToType(Mask, WideMaskVT,
true);
7714 Mask = ModifyToType(Mask, WideMaskVT,
true);
7716 StVal = ModifyToType(StVal, WideVT);
7719 assert(
Mask.getValueType().getVectorElementCount() ==
7721 "Mask and data vectors should have the same number of elements");
7728SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7729 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7731 SDValue DataOp = MG->getPassThru();
7733 SDValue Scale = MG->getScale();
7741 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7742 MG->getMemOperand(), MG->getIndexType(),
7743 MG->getExtensionType());
7749SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7758 DataOp = GetWidenedVector(DataOp);
7762 EVT IndexVT =
Index.getValueType();
7765 Index = ModifyToType(Index, WideIndexVT);
7768 EVT MaskVT =
Mask.getValueType();
7771 Mask = ModifyToType(Mask, WideMaskVT,
true);
7776 }
else if (OpNo == 4) {
7778 Index = GetWidenedVector(Index);
7784 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7789SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7798 DataOp = GetWidenedVector(DataOp);
7799 Index = GetWidenedVector(Index);
7801 Mask = GetWidenedMask(Mask, WideEC);
7804 }
else if (OpNo == 3) {
7806 Index = GetWidenedVector(Index);
7813 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7818 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7819 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7821 EVT VT =
N->getValueType(0);
7836 SVT, InOp0, InOp1,
N->getOperand(2));
7842 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7844 EVT OpVT =
N->getOperand(0).getValueType();
7847 return DAG.getNode(ExtendCode, dl, VT, CC);
7857 EVT VT =
N->getValueType(0);
7859 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7866 for (
unsigned i = 0; i != NumElts; ++i) {
7867 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7868 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7870 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7871 {Chain, LHSElem, RHSElem, CC});
7872 Chains[i] = Scalars[i].getValue(1);
7873 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7874 DAG.getBoolConstant(
true, dl, EltVT, VT),
7875 DAG.getBoolConstant(
false, dl, EltVT, VT));
7879 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7881 return DAG.getBuildVector(VT, dl, Scalars);
7888 case ISD::VECREDUCE_ADD:
7889 case ISD::VECREDUCE_MUL:
7890 case ISD::VECREDUCE_AND:
7891 case ISD::VECREDUCE_OR:
7892 case ISD::VECREDUCE_XOR:
7894 case ISD::VECREDUCE_SMAX:
7895 case ISD::VECREDUCE_SMIN:
7897 case ISD::VECREDUCE_UMAX:
7898 case ISD::VECREDUCE_UMIN:
7905 SDValue Op = GetWidenedVector(
N->getOperand(0));
7906 EVT VT =
N->getValueType(0);
7907 EVT OrigVT =
N->getOperand(0).getValueType();
7908 EVT WideVT =
Op.getValueType();
7910 SDNodeFlags
Flags =
N->getFlags();
7912 unsigned Opc =
N->getOpcode();
7914 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7915 assert(NeutralElem &&
"Neutral element must exist");
7925 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7932 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7933 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7939 unsigned GCD = std::gcd(OrigElts, WideElts);
7942 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
7943 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
7944 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
7945 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7948 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
7949 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
7951 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7960 EVT VT =
N->getValueType(0);
7962 EVT WideVT =
Op.getValueType();
7964 SDNodeFlags
Flags =
N->getFlags();
7966 unsigned Opc =
N->getOpcode();
7968 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7978 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7981 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7982 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7988 unsigned GCD = std::gcd(OrigElts, WideElts);
7991 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
7992 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
7993 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
7994 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
7997 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
7998 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8000 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8004 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8007 SDValue Op = GetWidenedVector(
N->getOperand(1));
8009 Op.getValueType().getVectorElementCount());
8011 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8012 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8020 EVT VT =
N->getValueType(0);
8024 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8025 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8030 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8036 EVT SrcVT =
Source.getValueType();
8040 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8041 {Source, Mask, N->getOperand(2)},
N->getFlags());
8058 unsigned WidenEx = 0) {
8063 unsigned AlignInBits =
Align*8;
8065 EVT RetVT = WidenEltVT;
8070 if (Width == WidenEltWidth)
8081 (WidenWidth % MemVTWidth) == 0 &&
8083 (MemVTWidth <= Width ||
8084 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8085 if (MemVTWidth == WidenWidth)
8104 (WidenWidth % MemVTWidth) == 0 &&
8106 (MemVTWidth <= Width ||
8107 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8116 return std::nullopt;
8127 unsigned Start,
unsigned End) {
8128 SDLoc dl(LdOps[Start]);
8129 EVT LdTy = LdOps[Start].getValueType();
8137 for (
unsigned i = Start + 1; i != End; ++i) {
8138 EVT NewLdTy = LdOps[i].getValueType();
8139 if (NewLdTy != LdTy) {
8142 VecOp = DAG.
getNode(ISD::BITCAST, dl, NewVecVT, VecOp);
8149 return DAG.
getNode(ISD::BITCAST, dl, VecTy, VecOp);
8158 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8159 EVT LdVT =
LD->getMemoryVT();
8169 AAMDNodes AAInfo =
LD->getAAInfo();
8173 TypeSize WidthDiff = WidenWidth - LdWidth;
8180 std::optional<EVT> FirstVT =
8181 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8188 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8193 std::optional<EVT> NewVT = FirstVT;
8194 TypeSize RemainingWidth = LdWidth;
8195 TypeSize NewVTWidth = FirstVTWidth;
8197 RemainingWidth -= NewVTWidth;
8204 NewVTWidth = NewVT->getSizeInBits();
8210 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8211 LD->getBaseAlign(), MMOFlags, AAInfo);
8215 if (MemVTs.
empty()) {
8217 if (!FirstVT->isVector()) {
8222 return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
8224 if (FirstVT == WidenVT)
8229 unsigned NumConcat =
8232 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8233 ConcatOps[0] = LdOp;
8234 for (
unsigned i = 1; i != NumConcat; ++i)
8235 ConcatOps[i] = UndefVal;
8243 uint64_t ScaledOffset = 0;
8244 MachinePointerInfo MPI =
LD->getPointerInfo();
8250 for (EVT MemVT : MemVTs) {
8251 Align NewAlign = ScaledOffset == 0
8252 ?
LD->getBaseAlign()
8255 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8263 unsigned End = LdOps.
size();
8274 EVT LdTy = LdOps[i].getValueType();
8277 for (--i; i >= 0; --i) {
8278 LdTy = LdOps[i].getValueType();
8285 ConcatOps[--Idx] = LdOps[i];
8286 for (--i; i >= 0; --i) {
8287 EVT NewLdTy = LdOps[i].getValueType();
8288 if (NewLdTy != LdTy) {
8298 for (;
j != End-Idx; ++
j)
8299 WidenOps[j] = ConcatOps[Idx+j];
8301 WidenOps[j] = DAG.getUNDEF(LdTy);
8308 ConcatOps[--Idx] = LdOps[i];
8313 ArrayRef(&ConcatOps[Idx], End - Idx));
8319 SDValue UndefVal = DAG.getUNDEF(LdTy);
8322 for (; i != End-Idx; ++i)
8323 WidenOps[i] = ConcatOps[Idx+i];
8325 WidenOps[i] = UndefVal;
8336 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8337 EVT LdVT =
LD->getMemoryVT();
8346 AAMDNodes AAInfo =
LD->getAAInfo();
8360 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8361 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8367 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8368 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8369 LD->getBaseAlign(), MMOFlags, AAInfo);
8374 SDValue UndefVal = DAG.getUNDEF(EltVT);
8375 for (; i != WidenNumElts; ++i)
8378 return DAG.getBuildVector(WidenVT, dl,
Ops);
8389 AAMDNodes AAInfo =
ST->getAAInfo();
8390 SDValue ValOp = GetWidenedVector(
ST->getValue());
8393 EVT StVT =
ST->getMemoryVT();
8401 "Mismatch between store and value types");
8405 MachinePointerInfo MPI =
ST->getPointerInfo();
8406 uint64_t ScaledOffset = 0;
8415 std::optional<EVT> NewVT =
8420 TypeSize NewVTWidth = NewVT->getSizeInBits();
8423 StWidth -= NewVTWidth;
8424 MemVTs.
back().second++;
8428 for (
const auto &Pair : MemVTs) {
8429 EVT NewVT = Pair.first;
8430 unsigned Count = Pair.second;
8436 Align NewAlign = ScaledOffset == 0
8437 ?
ST->getBaseAlign()
8439 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8440 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8456 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8457 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8458 ST->getBaseAlign(), MMOFlags, AAInfo);
8475 bool FillWithZeroes) {
8480 "input and widen element type must match");
8482 "cannot modify scalable vectors in this way");
8494 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8497 for (
unsigned i = 1; i != NumConcat; ++i)
8504 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8507 "Scalable vectors should have been handled already.");
8515 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8517 for (Idx = 0; Idx < MinNumElts; ++Idx)
8518 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8520 SDValue UndefVal = DAG.getUNDEF(EltVT);
8521 for (; Idx < WidenNumElts; ++Idx)
8522 Ops[Idx] = UndefVal;
8524 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8525 if (!FillWithZeroes)
8529 "We expect to never want to FillWithZeroes for non-integral types.");
8532 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8533 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8535 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8536 DAG.getBuildVector(NVT, dl, MaskOps));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align=0, unsigned WidenEx=0)
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
This file implements the SmallBitVector class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ LOOP_DEPENDENCE_RAW_MASK
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ADD
Simple integer binary arithmetic operators.
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ VECTOR_SPLICE
VECTOR_SPLICE(VEC1, VEC2, IMM) - Returns a subvector of the same type as VEC1/VEC2 from CONCAT_VECTOR...
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
Set rounding mode.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
EVT changeElementType(EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isScalableVT() const
Return true if the type is a scalable type.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeVectorElementType(EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.