35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
47 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
50 switch (
N->getOpcode()) {
53 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
62 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
70 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
73 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
79 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
91 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
93 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
99 R = ScalarizeVecRes_VecInregOp(
N);
151 R = ScalarizeVecRes_UnaryOp(
N);
154 R = ScalarizeVecRes_ADDRSPACECAST(
N);
160 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
219 R = ScalarizeVecRes_BinOp(
N);
226 R = ScalarizeVecRes_MaskedBinOp(
N);
231 R = ScalarizeVecRes_CMP(
N);
237 R = ScalarizeVecRes_TernaryOp(
N);
240#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
241 case ISD::STRICT_##DAGN:
242#include "llvm/IR/ConstrainedOps.def"
243 R = ScalarizeVecRes_StrictFPOp(
N);
248 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
257 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
267 R = ScalarizeVecRes_FIX(
N);
273 SetScalarizedVector(
SDValue(
N, ResNo), R);
277 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
278 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
279 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
285 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
286 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
288 EVT MaskVT =
Mask.getValueType();
293 Mask = GetScalarizedVector(Mask);
302 DAG.getConstant(1,
DL,
LHS.getValueType()));
304 LHS.getValueType(),
LHS, Divisor);
312 if (getTypeAction(
LHS.getValueType()) ==
314 LHS = GetScalarizedVector(
LHS);
315 RHS = GetScalarizedVector(
RHS);
317 EVT VT =
LHS.getValueType().getVectorElementType();
318 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
319 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
322 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
323 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
327 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
328 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
329 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
330 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
335 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
336 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
343DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
345 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
346 "Unexpected vector type!");
347 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
349 EVT VT0 =
N->getValueType(0);
350 EVT VT1 =
N->getValueType(1);
354 DAG.getNode(
N->getOpcode(), dl,
355 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
359 unsigned OtherNo = 1 - ResNo;
360 EVT OtherVT =
N->getValueType(OtherNo);
362 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
366 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
369 return SDValue(ScalarNode, ResNo);
374 unsigned NumOpers =
N->getNumOperands();
376 EVT ValueVTs[] = {VT, MVT::Other};
385 for (
unsigned i = 1; i < NumOpers; ++i) {
391 Oper = GetScalarizedVector(Oper);
400 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
401 Opers,
N->getFlags());
412 EVT ResVT =
N->getValueType(0);
413 EVT OvVT =
N->getValueType(1);
417 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
418 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
421 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
422 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
423 ScalarLHS = ElemsLHS[0];
424 ScalarRHS = ElemsRHS[0];
427 SDVTList ScalarVTs = DAG.getVTList(
429 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
430 {ScalarLHS, ScalarRHS},
N->getFlags())
434 unsigned OtherNo = 1 - ResNo;
435 EVT OtherVT =
N->getValueType(OtherNo);
437 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
441 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
444 return SDValue(ScalarNode, ResNo);
449 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
450 return GetScalarizedVector(
Op);
453SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
458 N->getValueType(0).getScalarType(), Mask,
459 DAG.getVectorIdxConstant(0,
DL));
465 Op = GetScalarizedVector(
Op);
466 EVT NewVT =
N->getValueType(0).getVectorElementType();
471SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
481SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
483 N->getValueType(0).getVectorElementType(),
484 N->getOperand(0),
N->getOperand(1));
490 EVT OpVT =
Op.getValueType();
494 Op = GetScalarizedVector(
Op);
497 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
500 N->getValueType(0).getVectorElementType(),
Op,
504SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
507 EVT OpVT =
Op.getValueType();
511 Op = GetScalarizedVector(
Op);
514 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
517 N->getValueType(0).getVectorElementType(),
Op,
521SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
524 EVT OpVT =
Op.getValueType();
527 Op = GetScalarizedVector(
Op);
530 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
533 N->getValueType(0).getVectorElementType(),
Op,
534 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
537SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
538 SDValue Op = GetScalarizedVector(
N->getOperand(0));
539 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
543SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
548 if (
Op.getValueType() != EltVT)
556 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
557 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
567 assert(
N->isUnindexed() &&
"Indexed vector load?");
571 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
572 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
573 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
574 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
586 EVT OpVT =
Op.getValueType();
596 Op = GetScalarizedVector(
Op);
599 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
601 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
607 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
608 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
609 LHS, DAG.getValueType(ExtVT));
616 EVT OpVT =
Op.getValueType();
621 Op = GetScalarizedVector(
Op);
623 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
626 switch (
N->getOpcode()) {
638SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
641 EVT OpVT =
Op.getValueType();
651 Op = GetScalarizedVector(
Op);
654 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
657 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
658 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
659 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
662SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
674 EVT OpVT =
Cond.getValueType();
683 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
686 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
688 TLI.getBooleanContents(
false,
false);
695 if (TLI.getBooleanContents(
false,
false) !=
696 TLI.getBooleanContents(
false,
true)) {
700 EVT OpVT =
Cond->getOperand(0).getValueType();
702 VecBool = TLI.getBooleanContents(OpVT);
707 EVT CondVT =
Cond.getValueType();
708 if (ScalarBool != VecBool) {
709 switch (ScalarBool) {
717 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
724 Cond, DAG.getValueType(MVT::i1));
730 auto BoolVT = getSetCCResultType(CondVT);
731 if (BoolVT.bitsLT(CondVT))
734 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
735 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
739 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
740 return DAG.getSelect(SDLoc(
N),
741 LHS.getValueType(),
N->getOperand(0),
LHS,
742 GetScalarizedVector(
N->getOperand(2)));
746 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
748 N->getOperand(0),
N->getOperand(1),
749 LHS, GetScalarizedVector(
N->getOperand(3)),
754 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
757SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
761 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
763 return GetScalarizedVector(
N->getOperand(
Op));
766SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
768 EVT SrcVT = Src.getValueType();
773 Src = GetScalarizedVector(Src);
777 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
779 EVT DstVT =
N->getValueType(0).getVectorElementType();
780 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
784 assert(
N->getValueType(0).isVector() &&
785 N->getOperand(0).getValueType().isVector() &&
786 "Operand types must be vectors");
789 EVT OpVT =
LHS.getValueType();
790 EVT NVT =
N->getValueType(0).getVectorElementType();
795 LHS = GetScalarizedVector(
LHS);
796 RHS = GetScalarizedVector(
RHS);
799 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
800 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
810 return DAG.getNode(ExtendCode,
DL, NVT, Res);
821 Arg = GetScalarizedVector(Arg);
824 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
833 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
840bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
846 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
849 switch (
N->getOpcode()) {
852 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
859 Res = ScalarizeVecOp_BITCAST(
N);
862 Res = ScalarizeVecOp_FAKE_USE(
N);
876 Res = ScalarizeVecOp_UnaryOp(
N);
881 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
884 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
885 "Unexpected vector type!");
886 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
888 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
889 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
897 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
900 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
903 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
906 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
909 Res = ScalarizeVecOp_VSELECT(
N);
912 Res = ScalarizeVecOp_VSETCC(
N);
916 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
925 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
928 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
931 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
934 Res = ScalarizeVecOp_FP_EXTEND(
N);
951 Res = ScalarizeVecOp_VECREDUCE(
N);
955 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
959 Res = ScalarizeVecOp_CMP(
N);
962 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
966 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
972 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
977 if (!Res.
getNode())
return false;
985 "Invalid operand expansion");
987 ReplaceValueWith(
SDValue(
N, 0), Res);
994 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
996 N->getValueType(0), Elt);
1001 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1002 "Fake Use: Unexpected vector type!");
1003 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1004 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1010 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1011 "Unexpected vector type!");
1012 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1013 SDValue Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1014 N->getValueType(0).getScalarType(), Elt);
1022SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1023 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1024 "Unexpected vector type!");
1025 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1027 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1028 Elt,
N->getOperand(1));
1036SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1037 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1038 "Unexpected vector type!");
1039 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1041 {
N->getValueType(0).getScalarType(), MVT::Other },
1042 {
N->getOperand(0), Elt });
1052 ReplaceValueWith(
SDValue(
N, 0), Res);
1057SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1059 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1060 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1061 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1066SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1070 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1071 SDValue ContainingVec =
N->getOperand(0);
1079SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1080 EVT VT =
N->getValueType(0);
1081 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1093 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1094 EVT VT =
N->getValueType(0);
1096 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1104 assert(
N->getValueType(0).isVector() &&
1105 N->getOperand(0).getValueType().isVector() &&
1106 "Operand types must be vectors");
1107 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1109 EVT VT =
N->getValueType(0);
1110 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1111 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1113 EVT OpVT =
N->getOperand(0).getValueType();
1125 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1131SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1133 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1134 assert(
N->getValueType(0).isVector() &&
1135 N->getOperand(1).getValueType().isVector() &&
1136 "Operand types must be vectors");
1137 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1139 EVT VT =
N->getValueType(0);
1141 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1142 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1145 EVT OpVT =
N->getOperand(1).getValueType();
1149 {Ch, LHS, RHS, CC});
1158 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1163 ReplaceValueWith(
SDValue(
N, 0), Res);
1170 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1171 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1174 if (
N->isTruncatingStore())
1175 return DAG.getTruncStore(
1176 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1177 N->getBasePtr(),
N->getPointerInfo(),
1178 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1179 N->getMemOperand()->getFlags(),
N->getAAInfo());
1181 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1182 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1183 N->getMemOperand()->getFlags(),
N->getAAInfo());
1189 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1191 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1192 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1197SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1198 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1199 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1201 N->getValueType(0).getVectorElementType(), Elt,
1206SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1208 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1209 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1212 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1222 ReplaceValueWith(
SDValue(
N, 0), Res);
1229 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1231 N->getValueType(0).getVectorElementType(), Elt);
1237SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1238 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1241 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1242 {
N->getOperand(0), Elt});
1251 ReplaceValueWith(
SDValue(
N, 0), Res);
1256 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1263SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1269 SDValue Op = GetScalarizedVector(VecOp);
1270 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1271 AccOp,
Op,
N->getFlags());
1275 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1276 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1283SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1291 EVT VT =
N->getValueType(0);
1292 return DAG.getConstant(0, SDLoc(
N), VT);
1299 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1300 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1302 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1303 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1304 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1307SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1308 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1311 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1312 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1321 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1333void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1338 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1341 switch (
N->getOpcode()) {
1344 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1353 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1361 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1377 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1380 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1392 case ISD::VP_LOAD_FF:
1395 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1402 case ISD::VP_GATHER:
1406 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1410 SplitVecRes_SETCC(
N,
Lo,
Hi);
1413 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1420 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1423 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1426 SplitVecRes_VECTOR_INTERLEAVE(
N);
1429 SplitVecRes_VAARG(
N,
Lo,
Hi);
1435 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1442 case ISD::VP_BITREVERSE:
1450 case ISD::VP_CTLZ_ZERO_POISON:
1452 case ISD::VP_CTTZ_ZERO_POISON:
1467 case ISD::VP_FFLOOR:
1472 case ISD::VP_FNEARBYINT:
1477 case ISD::VP_FP_EXTEND:
1479 case ISD::VP_FP_ROUND:
1481 case ISD::VP_FP_TO_SINT:
1483 case ISD::VP_FP_TO_UINT:
1489 case ISD::VP_LLRINT:
1491 case ISD::VP_FROUND:
1493 case ISD::VP_FROUNDEVEN:
1502 case ISD::VP_FROUNDTOZERO:
1504 case ISD::VP_SINT_TO_FP:
1506 case ISD::VP_TRUNCATE:
1508 case ISD::VP_UINT_TO_FP:
1513 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1516 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1522 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1528 case ISD::VP_SIGN_EXTEND:
1529 case ISD::VP_ZERO_EXTEND:
1530 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1554 case ISD::VP_FMINNUM:
1557 case ISD::VP_FMAXNUM:
1559 case ISD::VP_FMINIMUM:
1561 case ISD::VP_FMAXIMUM:
1570 case ISD::OR:
case ISD::VP_OR:
1590 case ISD::VP_FCOPYSIGN:
1591 SplitVecRes_BinOp(
N,
Lo,
Hi);
1597 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1604 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1608 SplitVecRes_CMP(
N,
Lo,
Hi);
1611#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1612 case ISD::STRICT_##DAGN:
1613#include "llvm/IR/ConstrainedOps.def"
1614 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1619 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1628 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1638 SplitVecRes_FIX(
N,
Lo,
Hi);
1640 case ISD::EXPERIMENTAL_VP_SPLICE:
1641 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1643 case ISD::EXPERIMENTAL_VP_REVERSE:
1644 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1650 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1653 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1662void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1664 uint64_t *ScaledOffset) {
1669 SDValue BytesIncrement = DAG.getVScale(
1672 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1674 *ScaledOffset += IncrementSize;
1684std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1685 return SplitMask(Mask, SDLoc(Mask));
1688std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1691 EVT MaskVT =
Mask.getValueType();
1693 GetSplitVector(Mask, MaskLo, MaskHi);
1695 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1696 return std::make_pair(MaskLo, MaskHi);
1701 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1703 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1706 const SDNodeFlags
Flags =
N->getFlags();
1707 unsigned Opcode =
N->getOpcode();
1708 if (
N->getNumOperands() == 2) {
1709 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1710 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1714 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1715 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1718 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1721 std::tie(EVLLo, EVLHi) =
1722 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1725 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1727 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1733 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1735 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1736 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(2));
1739 const SDNodeFlags
Flags =
N->getFlags();
1740 unsigned Opcode =
N->getOpcode();
1741 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1743 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1750 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1752 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1754 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1757 const SDNodeFlags
Flags =
N->getFlags();
1758 unsigned Opcode =
N->getOpcode();
1759 if (
N->getNumOperands() == 3) {
1760 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1761 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1765 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1766 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1769 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1772 std::tie(EVLLo, EVLHi) =
1773 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1776 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1778 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1782 LLVMContext &Ctxt = *DAG.getContext();
1788 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1790 GetSplitVector(
LHS, LHSLo, LHSHi);
1791 GetSplitVector(
RHS, RHSLo, RHSHi);
1793 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1794 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1798 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1799 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1804 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1806 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1810 unsigned Opcode =
N->getOpcode();
1811 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1813 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1822 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1829 switch (getTypeAction(InVT)) {
1843 GetExpandedOp(InOp,
Lo,
Hi);
1844 if (DAG.getDataLayout().isBigEndian())
1854 GetSplitVector(InOp,
Lo,
Hi);
1863 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1872 if (DAG.getDataLayout().isBigEndian())
1875 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1877 if (DAG.getDataLayout().isBigEndian())
1883void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1889 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1892 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1897 unsigned LaneOffset =
1900 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1902 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1909 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1912 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1915 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1920 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1922 unsigned NumSubvectors =
N->getNumOperands() / 2;
1923 if (NumSubvectors == 1) {
1924 Lo =
N->getOperand(0);
1925 Hi =
N->getOperand(1);
1930 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1939void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1946 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1961 GetSplitVector(Vec,
Lo,
Hi);
1964 EVT LoVT =
Lo.getValueType();
1974 if (IdxVal + SubElems <= LoElems) {
1982 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1984 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1990 SDValue WideSubVec = GetWidenedVector(SubVec);
1992 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2000 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2002 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2003 auto &MF = DAG.getMachineFunction();
2007 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2012 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2013 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2017 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2022 MachinePointerInfo MPI =
Load->getPointerInfo();
2023 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2026 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2035 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2040 EVT RHSVT =
RHS.getValueType();
2043 GetSplitVector(
RHS, RHSLo, RHSHi);
2045 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2060 SDValue FpValue =
N->getOperand(0);
2062 GetSplitVector(FpValue, ArgLo, ArgHi);
2064 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2066 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2075 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2079 std::tie(LoVT, HiVT) =
2083 DAG.getValueType(LoVT));
2085 DAG.getValueType(HiVT));
2090 unsigned Opcode =
N->getOpcode();
2097 GetSplitVector(N0, InLo, InHi);
2099 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2104 EVT OutLoVT, OutHiVT;
2105 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2107 assert((2 * OutNumElements) <= InNumElements &&
2108 "Illegal extend vector in reg split");
2117 SmallVector<int, 8> SplitHi(InNumElements, -1);
2118 for (
unsigned i = 0; i != OutNumElements; ++i)
2119 SplitHi[i] = i + OutNumElements;
2120 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2122 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2123 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2128 unsigned NumOps =
N->getNumOperands();
2132 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2142 for (
unsigned i = 1; i <
NumOps; ++i) {
2147 EVT InVT =
Op.getValueType();
2152 GetSplitVector(
Op, OpLo, OpHi);
2154 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2161 EVT LoValueVTs[] = {LoVT, MVT::Other};
2162 EVT HiValueVTs[] = {HiVT, MVT::Other};
2163 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2165 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2171 Lo.getValue(1),
Hi.getValue(1));
2175 ReplaceValueWith(
SDValue(
N, 1), Chain);
2178SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2180 EVT VT =
N->getValueType(0);
2191 else if (NE > ResNE)
2195 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2199 for (i = 0; i !=
NE; ++i) {
2200 Operands[0] = Chain;
2201 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2202 SDValue Operand =
N->getOperand(j);
2206 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2208 Operands[
j] = Operand;
2212 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2220 for (; i < ResNE; ++i)
2221 Scalars.
push_back(DAG.getPOISON(EltVT));
2225 ReplaceValueWith(
SDValue(
N, 1), Chain);
2229 return DAG.getBuildVector(VecVT, dl, Scalars);
2232void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2235 EVT ResVT =
N->getValueType(0);
2236 EVT OvVT =
N->getValueType(1);
2237 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2238 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2239 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2241 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2243 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2244 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2246 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2247 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2250 unsigned Opcode =
N->getOpcode();
2251 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2252 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2254 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2256 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2262 unsigned OtherNo = 1 - ResNo;
2263 EVT OtherVT =
N->getValueType(OtherNo);
2265 SetSplitVector(
SDValue(
N, OtherNo),
2271 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2275void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2281 GetSplitVector(Vec,
Lo,
Hi);
2284 unsigned IdxVal = CIdx->getZExtValue();
2285 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2286 if (IdxVal < LoNumElts) {
2288 Lo.getValueType(),
Lo, Elt, Idx);
2291 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2311 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2313 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2314 auto &MF = DAG.getMachineFunction();
2318 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2323 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2324 Store = DAG.getTruncStore(
2330 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2333 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2337 MachinePointerInfo MPI =
Load->getPointerInfo();
2338 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2340 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2343 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2344 if (LoVT !=
Lo.getValueType())
2346 if (HiVT !=
Hi.getValueType())
2354 assert(
N->getValueType(0).isScalableVector() &&
2355 "Only scalable vectors are supported for STEP_VECTOR");
2356 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2377 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2378 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2380 Hi = DAG.getPOISON(HiVT);
2390 "Extended load during type legalization!");
2392 EVT VT =
LD->getValueType(0);
2394 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2402 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2403 Ch, Ptr,
LD->getMemOperand());
2408 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2410 Lo = DAG.getBitcast(LoVT, ExtractLo);
2411 Hi = DAG.getBitcast(HiVT, ExtractHi);
2423 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2429 EVT MemoryVT =
LD->getMemoryVT();
2431 AAMDNodes AAInfo =
LD->getAAInfo();
2433 EVT LoMemVT, HiMemVT;
2434 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2438 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2439 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2440 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2445 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2448 MachinePointerInfo MPI;
2449 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2452 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2461 ReplaceValueWith(
SDValue(LD, 1), Ch);
2466 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2469 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2475 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2476 Align Alignment =
LD->getBaseAlign();
2479 EVT MemoryVT =
LD->getMemoryVT();
2481 EVT LoMemVT, HiMemVT;
2482 bool HiIsEmpty =
false;
2483 std::tie(LoMemVT, HiMemVT) =
2484 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2489 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2492 GetSplitVector(Mask, MaskLo, MaskHi);
2494 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2499 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2501 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2507 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2508 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2516 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2517 LD->isExpandingLoad());
2519 MachinePointerInfo MPI;
2521 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2523 MPI =
LD->getPointerInfo().getWithOffset(
2526 MMO = DAG.getMachineFunction().getMachineMemOperand(
2528 Alignment,
LD->getAAInfo(),
LD->getRanges());
2530 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2531 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2532 LD->isExpandingLoad());
2542 ReplaceValueWith(
SDValue(LD, 1), Ch);
2548 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2552 Align Alignment =
LD->getBaseAlign();
2559 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2562 GetSplitVector(Mask, MaskLo, MaskHi);
2564 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2568 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2570 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2575 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2578 Hi = DAG.getPOISON(HiVT);
2580 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2581 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2587 "Indexed VP strided load during type legalization!");
2589 "Unexpected indexed variable-length load offset");
2594 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2596 EVT LoMemVT, HiMemVT;
2597 bool HiIsEmpty =
false;
2598 std::tie(LoMemVT, HiMemVT) =
2599 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2604 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2607 GetSplitVector(Mask, LoMask, HiMask);
2609 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2613 std::tie(LoEVL, HiEVL) =
2617 Lo = DAG.getStridedLoadVP(
2644 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2651 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2662 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2670 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2675 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2685 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2688 GetSplitVector(Mask, MaskLo, MaskHi);
2690 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2694 EVT LoMemVT, HiMemVT;
2695 bool HiIsEmpty =
false;
2696 std::tie(LoMemVT, HiMemVT) =
2697 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2699 SDValue PassThruLo, PassThruHi;
2701 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2703 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2705 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2709 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2719 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2722 MachinePointerInfo MPI;
2729 MMO = DAG.getMachineFunction().getMachineMemOperand(
2733 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2745 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2753 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2761 }
Ops = [&]() -> Operands {
2763 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2766 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2769 EVT MemoryVT =
N->getMemoryVT();
2770 Align Alignment =
N->getBaseAlign();
2775 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2777 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2780 EVT LoMemVT, HiMemVT;
2782 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2785 if (getTypeAction(
Ops.Index.getValueType()) ==
2787 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2789 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2792 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2794 Alignment,
N->getAAInfo(),
N->getRanges());
2797 SDValue PassThru = MGT->getPassThru();
2798 SDValue PassThruLo, PassThruHi;
2801 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2803 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2808 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2809 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2810 OpsLo, MMO, IndexTy, ExtType);
2812 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2813 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2814 OpsHi, MMO, IndexTy, ExtType);
2818 std::tie(EVLLo, EVLHi) =
2819 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2821 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2822 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2823 MMO, VPGT->getIndexType());
2825 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2826 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2827 MMO, VPGT->getIndexType());
2837 ReplaceValueWith(
SDValue(
N, 1), Ch);
2851 EVT VecVT =
N->getValueType(0);
2853 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2854 bool HasCustomLowering =
false;
2861 HasCustomLowering =
true;
2867 SDValue Passthru =
N->getOperand(2);
2868 if (!HasCustomLowering) {
2869 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2870 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2877 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2878 std::tie(LoMask, HiMask) = SplitMask(Mask);
2880 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2885 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2886 MachineFunction &MF = DAG.getMachineFunction();
2898 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2900 SDValue Chain = DAG.getEntryNode();
2901 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2905 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2910 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2914 assert(
N->getValueType(0).isVector() &&
2915 N->getOperand(0).getValueType().isVector() &&
2916 "Operand types must be vectors");
2920 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2924 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2926 GetSplitVector(
N->getOperand(0), LL, LH);
2928 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2930 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2932 GetSplitVector(
N->getOperand(1), RL, RH);
2934 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2937 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2938 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2940 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2941 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2942 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2943 std::tie(EVLLo, EVLHi) =
2944 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2945 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2947 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2957 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2961 EVT InVT =
N->getOperand(0).getValueType();
2963 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2965 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2967 const SDNodeFlags
Flags =
N->getFlags();
2968 unsigned Opcode =
N->getOpcode();
2970 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
2971 N->getOperand(3), Flags);
2972 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
2973 N->getOperand(3), Flags);
2976 if (
N->getNumOperands() <= 2) {
2979 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2980 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2982 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2983 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2988 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2989 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2992 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2995 std::tie(EVLLo, EVLHi) =
2996 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2999 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
3005 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3009 EVT InVT =
N->getOperand(0).getValueType();
3011 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3013 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3016 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3017 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3018 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
3019 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
3022void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3027 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3028 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3032 EVT InVT =
N->getOperand(0).getValueType();
3034 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3036 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3038 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3039 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3041 SDNode *HiNode =
Hi.getNode();
3042 SDNode *LoNode =
Lo.getNode();
3045 unsigned OtherNo = 1 - ResNo;
3046 EVT OtherVT =
N->getValueType(OtherNo);
3054 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3061 EVT SrcVT =
N->getOperand(0).getValueType();
3062 EVT DestVT =
N->getValueType(0);
3064 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3081 LLVMContext &Ctx = *DAG.getContext();
3085 EVT SplitLoVT, SplitHiVT;
3086 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3087 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3088 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3089 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3090 N->dump(&DAG);
dbgs() <<
"\n");
3091 if (!
N->isVPOpcode()) {
3094 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3096 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3098 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3099 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3105 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
3106 N->getOperand(1),
N->getOperand(2));
3108 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3111 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3114 std::tie(EVLLo, EVLHi) =
3115 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3117 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
3118 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
3123 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3131 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3132 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3138 return N.getResNo() == 0 &&
3142 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3144 ArrayRef<int>
Mask) {
3147 "Expected build vector node.");
3150 for (
unsigned I = 0;
I < NewElts; ++
I) {
3153 unsigned Idx =
Mask[
I];
3155 Ops[
I] = Input2.getOperand(Idx - NewElts);
3157 Ops[
I] = Input1.getOperand(Idx);
3162 return DAG.getBuildVector(NewVT,
DL,
Ops);
3168 SmallVector<int> OrigMask(
N->getMask());
3170 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3171 &
DL](SmallVectorImpl<int> &
Mask) {
3173 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3174 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3185 for (
auto &
P : ShufflesIdxs) {
3186 if (
P.second.size() < 2)
3190 for (
int &Idx : Mask) {
3193 unsigned SrcRegIdx = Idx / NewElts;
3194 if (Inputs[SrcRegIdx].
isUndef()) {
3202 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3207 Idx = MaskElt % NewElts +
3208 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3214 Inputs[
P.second[0]] =
P.first.first;
3215 Inputs[
P.second[1]] =
P.first.second;
3218 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3221 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3222 for (
int &Idx : Mask) {
3225 unsigned SrcRegIdx = Idx / NewElts;
3226 if (Inputs[SrcRegIdx].
isUndef()) {
3233 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3234 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3237 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3239 if (UsedSubVector.count() > 1) {
3241 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3242 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3244 if (Pairs.
empty() || Pairs.
back().size() == 2)
3246 if (UsedSubVector.test(2 *
I)) {
3247 Pairs.
back().emplace_back(
I, 0);
3249 assert(UsedSubVector.test(2 *
I + 1) &&
3250 "Expected to be used one of the subvectors.");
3251 Pairs.
back().emplace_back(
I, 1);
3254 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3256 for (
int &Idx : Mask) {
3259 unsigned SrcRegIdx = Idx / NewElts;
3261 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3262 return Idxs.front().first == SrcRegIdx ||
3263 Idxs.back().first == SrcRegIdx;
3265 if (It == Pairs.
end())
3267 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3268 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3271 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3272 Inputs[Idxs.front().first] = DAG.
getNode(
3274 Inputs[Idxs.front().first].getValueType(),
3275 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3276 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3285 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3289 if (Shuffle->getOperand(0).getValueType() != NewVT)
3292 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3293 !Shuffle->isSplat()) {
3295 }
else if (!Inputs[
I].hasOneUse() &&
3296 !Shuffle->getOperand(1).isUndef()) {
3298 for (
int &Idx : Mask) {
3301 unsigned SrcRegIdx = Idx / NewElts;
3304 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3309 int OpIdx = MaskElt / NewElts;
3323 if (Shuffle->getOperand(
OpIdx).isUndef())
3325 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3326 if (It == std::end(Inputs))
3328 int FoundOp = std::distance(std::begin(Inputs), It);
3331 for (
int &Idx : Mask) {
3334 unsigned SrcRegIdx = Idx / NewElts;
3337 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3342 int MaskIdx = MaskElt / NewElts;
3343 if (
OpIdx == MaskIdx)
3344 Idx = MaskElt % NewElts + FoundOp * NewElts;
3355 for (
int &Idx : Mask) {
3358 unsigned SrcRegIdx = Idx / NewElts;
3361 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3362 int OpIdx = MaskElt / NewElts;
3365 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3371 TryPeekThroughShufflesInputs(OrigMask);
3373 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3374 NewElts](SmallVectorImpl<int> &
Mask) {
3375 SetVector<SDValue> UniqueInputs;
3376 SetVector<SDValue> UniqueConstantInputs;
3377 for (
const auto &
I : Inputs) {
3379 UniqueConstantInputs.
insert(
I);
3380 else if (!
I.isUndef())
3385 if (UniqueInputs.
size() != std::size(Inputs)) {
3386 auto &&UniqueVec = UniqueInputs.
takeVector();
3387 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3388 unsigned ConstNum = UniqueConstantVec.size();
3389 for (
int &Idx : Mask) {
3392 unsigned SrcRegIdx = Idx / NewElts;
3393 if (Inputs[SrcRegIdx].
isUndef()) {
3397 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3398 if (It != UniqueConstantVec.end()) {
3399 Idx = (Idx % NewElts) +
3400 NewElts * std::distance(UniqueConstantVec.begin(), It);
3401 assert(Idx >= 0 &&
"Expected defined mask idx.");
3404 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3405 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3406 Idx = (Idx % NewElts) +
3407 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3408 assert(Idx >= 0 &&
"Expected defined mask idx.");
3410 copy(UniqueConstantVec, std::begin(Inputs));
3411 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3414 MakeUniqueInputs(OrigMask);
3416 copy(Inputs, std::begin(OrigInputs));
3422 unsigned FirstMaskIdx =
High * NewElts;
3425 assert(!Output &&
"Expected default initialized initial value.");
3426 TryPeekThroughShufflesInputs(Mask);
3427 MakeUniqueInputs(Mask);
3429 copy(Inputs, std::begin(TmpInputs));
3432 bool SecondIteration =
false;
3433 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3438 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3439 SecondIteration =
true;
3440 return SecondIteration;
3443 Mask, std::size(Inputs), std::size(Inputs),
3445 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3446 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3447 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3449 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3451 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3452 DAG.getPOISON(NewVT), Mask);
3453 Inputs[Idx] = Output;
3455 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3456 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3457 unsigned Idx2,
bool ) {
3458 if (AccumulateResults(Idx1)) {
3461 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3463 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3464 Inputs[Idx2], Mask);
3468 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3470 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3471 TmpInputs[Idx2], Mask);
3473 Inputs[Idx1] = Output;
3475 copy(OrigInputs, std::begin(Inputs));
3480 EVT OVT =
N->getValueType(0);
3487 const Align Alignment =
3488 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3490 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3491 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3496 ReplaceValueWith(
SDValue(
N, 1), Chain);
3501 EVT DstVTLo, DstVTHi;
3502 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3506 EVT SrcVT =
N->getOperand(0).getValueType();
3508 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3510 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3512 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3513 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3519 GetSplitVector(
N->getOperand(0), InLo, InHi);
3530 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3531 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3536 EVT VT =
N->getValueType(0);
3554 Align Alignment = DAG.getReducedAlign(VT,
false);
3559 EVT PtrVT =
StackPtr.getValueType();
3560 auto &MF = DAG.getMachineFunction();
3564 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3567 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3573 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3574 DAG.getConstant(1,
DL, PtrVT));
3576 DAG.getConstant(EltWidth,
DL, PtrVT));
3578 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3580 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3581 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3582 DAG.getPOISON(PtrVT), Stride, TrueMask,
3591 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3596 EVT VT =
N->getValueType(0);
3608 EVL1 = ZExtPromotedInteger(EVL1);
3622 Align Alignment = DAG.getReducedAlign(VT,
false);
3627 EVT PtrVT =
StackPtr.getValueType();
3628 auto &MF = DAG.getMachineFunction();
3632 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3635 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3641 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3646 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3647 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3649 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3651 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3655 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3660 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3661 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3663 uint64_t TrailingElts = -
Imm;
3665 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3674 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3682 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3684 DAG.getVectorIdxConstant(0,
DL));
3690void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3698 GetSplitVector(Acc, AccLo, AccHi);
3699 unsigned Opcode =
N->getOpcode();
3711 GetSplitVector(Input1, Input1Lo, Input1Hi);
3712 GetSplitVector(Input2, Input2Lo, Input2Hi);
3715 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3716 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3719void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3727 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3735void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3736 unsigned Factor =
N->getNumOperands();
3739 for (
unsigned i = 0; i != Factor; ++i) {
3741 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3743 Ops[i * 2 + 1] = OpHi;
3754 for (
unsigned i = 0; i != Factor; ++i)
3758void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3759 unsigned Factor =
N->getNumOperands();
3762 for (
unsigned i = 0; i != Factor; ++i) {
3764 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3766 Ops[i + Factor] = OpHi;
3777 for (
unsigned i = 0; i != Factor; ++i) {
3778 unsigned IdxLo = 2 * i;
3779 unsigned IdxHi = 2 * i + 1;
3780 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3781 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3793bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3798 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3801 switch (
N->getOpcode()) {
3804 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3814 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3821 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3823 case ISD::VP_TRUNCATE:
3825 Res = SplitVecOp_TruncateHelper(
N);
3828 case ISD::VP_FP_ROUND:
3832 Res = SplitVecOp_FP_ROUND(
N);
3844 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3851 case ISD::VP_SCATTER:
3855 case ISD::VP_GATHER:
3859 Res = SplitVecOp_VSELECT(
N, OpNo);
3865 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3868 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3874 case ISD::VP_SINT_TO_FP:
3875 case ISD::VP_UINT_TO_FP:
3876 if (
N->getValueType(0).bitsLT(
3877 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3878 Res = SplitVecOp_TruncateHelper(
N);
3880 Res = SplitVecOp_UnaryOp(
N);
3884 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3888 case ISD::VP_FP_TO_SINT:
3889 case ISD::VP_FP_TO_UINT:
3902 Res = SplitVecOp_UnaryOp(
N);
3905 Res = SplitVecOp_FPOpDifferentTypes(
N);
3910 Res = SplitVecOp_CMP(
N);
3914 Res = SplitVecOp_FAKE_USE(
N);
3919 Res = SplitVecOp_ExtVecInRegOp(
N);
3937 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3941 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3943 case ISD::VP_REDUCE_FADD:
3944 case ISD::VP_REDUCE_SEQ_FADD:
3945 case ISD::VP_REDUCE_FMUL:
3946 case ISD::VP_REDUCE_SEQ_FMUL:
3947 case ISD::VP_REDUCE_ADD:
3948 case ISD::VP_REDUCE_MUL:
3949 case ISD::VP_REDUCE_AND:
3950 case ISD::VP_REDUCE_OR:
3951 case ISD::VP_REDUCE_XOR:
3952 case ISD::VP_REDUCE_SMAX:
3953 case ISD::VP_REDUCE_SMIN:
3954 case ISD::VP_REDUCE_UMAX:
3955 case ISD::VP_REDUCE_UMIN:
3956 case ISD::VP_REDUCE_FMAX:
3957 case ISD::VP_REDUCE_FMIN:
3958 case ISD::VP_REDUCE_FMAXIMUM:
3959 case ISD::VP_REDUCE_FMINIMUM:
3960 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3964 Res = SplitVecOp_CttzElts(
N);
3966 case ISD::VP_CTTZ_ELTS:
3967 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3968 Res = SplitVecOp_VP_CttzElements(
N);
3971 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3977 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3982 if (!Res.
getNode())
return false;
3989 if (
N->isStrictFPOpcode())
3991 "Invalid operand expansion");
3994 "Invalid operand expansion");
3996 ReplaceValueWith(
SDValue(
N, 0), Res);
4000SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4004 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4006 EVT VT =
N->getValueType(0);
4019 getSetCCResultType(MVT::i1), MVT::i1);
4024 DAG.getElementCount(
DL, VT, SplitEC)),
4028SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4031 assert(OpNo == 0 &&
"Illegal operand must be mask");
4038 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4041 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4042 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4043 "Lo and Hi have differing types");
4046 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4047 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4049 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4050 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4051 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4052 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4062SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4063 assert(OpNo == 2 &&
"Illegal operand must be mask");
4066 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4067 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4069 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4072 RHSLo, MaskLo,
N->getFlags());
4074 RHSHi, MaskHi,
N->getFlags());
4078SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4081 assert(OpNo == 1 &&
"Illegal operand must be mask");
4086 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4088 EVT VecVT =
N->getValueType(0);
4092SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4093 EVT ResVT =
N->getValueType(0);
4099 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4100 GetSplitVector(VecOp,
Lo,
Hi);
4102 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4107 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4108 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4112 EVT ResVT =
N->getValueType(0);
4118 SDNodeFlags
Flags =
N->getFlags();
4121 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4122 GetSplitVector(VecOp,
Lo,
Hi);
4124 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4130 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4133SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4134 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4135 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4137 unsigned Opc =
N->getOpcode();
4138 EVT ResVT =
N->getValueType(0);
4144 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4145 GetSplitVector(VecOp,
Lo,
Hi);
4148 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4151 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4153 const SDNodeFlags
Flags =
N->getFlags();
4157 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4162 EVT ResVT =
N->getValueType(0);
4165 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4166 EVT InVT =
Lo.getValueType();
4171 if (
N->isStrictFPOpcode()) {
4172 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4173 {N->getOperand(0), Lo});
4174 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4175 {N->getOperand(0), Hi});
4184 ReplaceValueWith(
SDValue(
N, 1), Ch);
4185 }
else if (
N->getNumOperands() == 3) {
4186 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4187 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4188 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4189 std::tie(EVLLo, EVLHi) =
4190 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4191 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4192 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4194 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4195 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4204 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4214 EVT ResVT =
N->getValueType(0);
4216 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4220 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4226 Lo = BitConvertToInteger(
Lo);
4227 Hi = BitConvertToInteger(
Hi);
4229 if (DAG.getDataLayout().isBigEndian())
4237 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4239 EVT ResVT =
N->getValueType(0);
4247 GetSplitVector(SubVec,
Lo,
Hi);
4256 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4258 return SecondInsertion;
4261SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4268 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4270 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4272 ElementCount IdxVal =
4276 EVT SrcVT =
N->getOperand(0).getValueType();
4295 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4296 LoEltsMin - IdxValMin);
4297 DAG.ExtractVectorElements(
Hi, Elts, 0,
4300 return DAG.getBuildVector(SubVT, dl, Elts);
4304 ElementCount ExtractIdx = IdxVal - LoElts;
4306 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4309 EVT HiVT =
Hi.getValueType();
4311 "Only fixed-vector extracts are supported in this case");
4321 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4322 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4328 "Extracting scalable subvector from fixed-width unsupported");
4336 "subvector from a scalable predicate vector");
4342 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4344 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4345 auto &MF = DAG.getMachineFunction();
4349 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4353 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4356 SubVT, dl,
Store, StackPtr,
4360SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4366 uint64_t IdxVal =
Index->getZExtValue();
4369 GetSplitVector(Vec,
Lo,
Hi);
4371 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4373 if (IdxVal < LoElts)
4374 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4377 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4382 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4394 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4400 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4402 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4403 auto &MF = DAG.getMachineFunction();
4406 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4410 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4414 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4416 return DAG.getExtLoad(
4427 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4435 SplitVecRes_Gather(
N,
Lo,
Hi);
4438 ReplaceValueWith(
SDValue(
N, 0), Res);
4443 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4447 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4449 SDValue EVL =
N->getVectorLength();
4451 Align Alignment =
N->getBaseAlign();
4457 GetSplitVector(
Data, DataLo, DataHi);
4459 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4464 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4467 GetSplitVector(Mask, MaskLo, MaskHi);
4469 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4472 EVT MemoryVT =
N->getMemoryVT();
4473 EVT LoMemVT, HiMemVT;
4474 bool HiIsEmpty =
false;
4475 std::tie(LoMemVT, HiMemVT) =
4476 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4480 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4483 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4488 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4489 N->getAddressingMode(),
N->isTruncatingStore(),
4490 N->isCompressingStore());
4496 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4497 N->isCompressingStore());
4499 MachinePointerInfo MPI;
4503 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4508 MMO = DAG.getMachineFunction().getMachineMemOperand(
4510 Alignment,
N->getAAInfo(),
N->getRanges());
4512 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4513 N->getAddressingMode(),
N->isTruncatingStore(),
4514 N->isCompressingStore());
4523 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4524 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4531 GetSplitVector(
Data, LoData, HiData);
4533 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4535 EVT LoMemVT, HiMemVT;
4536 bool HiIsEmpty =
false;
4537 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4543 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4544 else if (getTypeAction(
Mask.getValueType()) ==
4546 GetSplitVector(Mask, LoMask, HiMask);
4548 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4551 std::tie(LoEVL, HiEVL) =
4552 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4556 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4557 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4558 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4569 EVT PtrVT =
N->getBasePtr().getValueType();
4572 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4575 Align Alignment =
N->getBaseAlign();
4580 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4581 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4583 Alignment,
N->getAAInfo(),
N->getRanges());
4586 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4587 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4588 N->isCompressingStore());
4597 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4601 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4604 Align Alignment =
N->getBaseAlign();
4610 GetSplitVector(
Data, DataLo, DataHi);
4612 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4617 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4620 GetSplitVector(Mask, MaskLo, MaskHi);
4622 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4625 EVT MemoryVT =
N->getMemoryVT();
4626 EVT LoMemVT, HiMemVT;
4627 bool HiIsEmpty =
false;
4628 std::tie(LoMemVT, HiMemVT) =
4629 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4632 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4637 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4638 N->getAddressingMode(),
N->isTruncatingStore(),
4639 N->isCompressingStore());
4647 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4648 N->isCompressingStore());
4650 MachinePointerInfo MPI;
4654 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4659 MMO = DAG.getMachineFunction().getMachineMemOperand(
4661 Alignment,
N->getAAInfo(),
N->getRanges());
4663 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4664 N->getAddressingMode(),
N->isTruncatingStore(),
4665 N->isCompressingStore());
4678 EVT MemoryVT =
N->getMemoryVT();
4679 Align Alignment =
N->getBaseAlign();
4686 }
Ops = [&]() -> Operands {
4688 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4692 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4697 EVT LoMemVT, HiMemVT;
4698 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4703 GetSplitVector(
Ops.Data, DataLo, DataHi);
4705 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4710 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4712 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4716 if (getTypeAction(
Ops.Index.getValueType()) ==
4718 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4720 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4724 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4726 Alignment,
N->getAAInfo(),
N->getRanges());
4729 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4731 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4732 MSC->getIndexType(), MSC->isTruncatingStore());
4737 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4738 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4739 MMO, MSC->getIndexType(),
4740 MSC->isTruncatingStore());
4744 std::tie(EVLLo, EVLHi) =
4745 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4747 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4748 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4749 VPSC->getIndexType());
4754 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4755 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4756 VPSC->getIndexType());
4760 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4761 assert(OpNo == 1 &&
"Can only split the stored value");
4764 bool isTruncating =
N->isTruncatingStore();
4767 EVT MemoryVT =
N->getMemoryVT();
4768 Align Alignment =
N->getBaseAlign();
4770 AAMDNodes AAInfo =
N->getAAInfo();
4772 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4774 EVT LoMemVT, HiMemVT;
4775 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4779 return TLI.scalarizeVectorStore(
N, DAG);
4782 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4783 Alignment, MMOFlags, AAInfo);
4785 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4788 MachinePointerInfo MPI;
4789 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4792 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4793 HiMemVT, Alignment, MMOFlags, AAInfo);
4795 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4802 LLVMContext &Ctx = *DAG.getContext();
4820 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4821 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4825 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4828 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4829 DAG.getBitcast(MemVecVT, Wide), 0);
4831 N->getBasePtr(),
N->getMemOperand());
4839 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4841 N->getBasePtr(),
N->getMemOperand());
4855 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4861 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4882 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4883 SDValue InVec =
N->getOperand(OpNo);
4885 EVT OutVT =
N->getValueType(0);
4893 EVT LoOutVT, HiOutVT;
4894 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4895 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4900 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4902 return SplitVecOp_UnaryOp(
N);
4911 return SplitVecOp_UnaryOp(
N);
4915 GetSplitVector(InVec, InLoVec, InHiVec);
4921 EVT HalfElementVT = IsFloat ?
4923 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4930 if (
N->isStrictFPOpcode()) {
4931 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4932 {N->getOperand(0), InLoVec});
4933 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4934 {N->getOperand(0), InHiVec});
4940 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4941 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4945 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4953 if (
N->isStrictFPOpcode()) {
4957 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4965 DAG.getTargetConstant(
4966 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4973 assert(
N->getValueType(0).isVector() &&
4974 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4975 "Operand types must be vectors");
4977 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4979 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4980 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4982 EVT VT =
N->getValueType(0);
4983 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4988 }
else if (isStrict) {
4989 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4990 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4991 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4992 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4995 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4997 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4998 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4999 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
5000 std::tie(EVLLo, EVLHi) =
5001 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
5002 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
5003 N->getOperand(2), MaskLo, EVLLo);
5004 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
5005 N->getOperand(2), MaskHi, EVLHi);
5013 EVT OpVT =
N->getOperand(0).getValueType();
5016 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5022 EVT ResVT =
N->getValueType(0);
5025 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5026 EVT InVT =
Lo.getValueType();
5031 if (
N->isStrictFPOpcode()) {
5032 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5033 {N->getOperand(0), Lo, N->getOperand(2)});
5034 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5035 {N->getOperand(0), Hi, N->getOperand(2)});
5039 Lo.getValue(1),
Hi.getValue(1));
5040 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5041 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
5042 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
5043 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
5044 std::tie(EVLLo, EVLHi) =
5045 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
5046 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
5047 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
5049 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5050 N->getOperand(2),
N->getOperand(3));
5051 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5052 N->getOperand(2),
N->getOperand(3));
5054 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5055 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5066SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5069 EVT LHSLoVT, LHSHiVT;
5070 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5072 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5073 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5076 std::tie(LHSLo, LHSHi) =
5077 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5080 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5083 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5089 LLVMContext &Ctxt = *DAG.getContext();
5092 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5093 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5094 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5096 EVT ResVT =
N->getValueType(0);
5101 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5102 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5108 EVT ResVT =
N->getValueType(0);
5111 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5112 EVT InVT =
Lo.getValueType();
5118 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5119 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5126 EVT ResVT =
N->getValueType(0);
5130 GetSplitVector(VecOp,
Lo,
Hi);
5136 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5138 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5140 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5141 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5146 EVT ResVT =
N->getValueType(0);
5150 GetSplitVector(VecOp,
Lo,
Hi);
5152 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5153 auto [EVLLo, EVLHi] =
5155 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5161 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5163 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5164 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5167SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5178 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5179 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5180 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5181 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5182 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5183 OpsLo, MMO, IndexType);
5184 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5185 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5189SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5192 "Accumulator should already be a legal type, and shouldn't need "
5193 "further splitting");
5196 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5197 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5198 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5199 unsigned Opcode =
N->getOpcode();
5202 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5203 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5210void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5211 unsigned WidenResNo) {
5212 unsigned NumResults =
N->getNumValues();
5213 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5214 if (ResNo == WidenResNo)
5216 EVT ResVT =
N->getValueType(ResNo);
5222 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5223 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5228void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5229 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5232 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5237 auto unrollExpandedOp = [&]() {
5242 EVT VT =
N->getValueType(0);
5243 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5244 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5245 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5247 if (
N->getNumValues() > 1)
5248 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5254 switch (
N->getOpcode()) {
5257 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5265 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5269 Res = WidenVecRes_ADDRSPACECAST(
N);
5276 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5283 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5287 Res = WidenVecRes_ScalarOp(
N);
5292 case ISD::VP_SELECT:
5294 Res = WidenVecRes_Select(
N);
5298 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5300 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5307 case ISD::VP_LOAD_FF:
5310 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5314 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5322 case ISD::VP_GATHER:
5326 Res = WidenVecRes_VECTOR_REVERSE(
N);
5329 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5332 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5342 case ISD::OR:
case ISD::VP_OR:
5355 case ISD::VP_FMINNUM:
5358 case ISD::VP_FMAXNUM:
5360 case ISD::VP_FMINIMUM:
5362 case ISD::VP_FMAXIMUM:
5395 case ISD::VP_FCOPYSIGN:
5396 Res = WidenVecRes_Binary(
N);
5403 Res = WidenVecRes_MaskedBinary(
N);
5408 Res = WidenVecRes_CMP(
N);
5414 if (unrollExpandedOp())
5429 Res = WidenVecRes_BinaryCanTrap(
N);
5438 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5441#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5442 case ISD::STRICT_##DAGN:
5443#include "llvm/IR/ConstrainedOps.def"
5444 Res = WidenVecRes_StrictFP(
N);
5453 Res = WidenVecRes_OverflowOp(
N, ResNo);
5457 Res = WidenVecRes_FCOPYSIGN(
N);
5462 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5467 if (!unrollExpandedOp())
5468 Res = WidenVecRes_ExpOp(
N);
5474 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5479 case ISD::VP_FP_EXTEND:
5481 case ISD::VP_FP_ROUND:
5483 case ISD::VP_FP_TO_SINT:
5485 case ISD::VP_FP_TO_UINT:
5487 case ISD::VP_SIGN_EXTEND:
5489 case ISD::VP_SINT_TO_FP:
5490 case ISD::VP_TRUNCATE:
5493 case ISD::VP_UINT_TO_FP:
5495 case ISD::VP_ZERO_EXTEND:
5498 Res = WidenVecRes_Convert(
N);
5503 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5509 case ISD::VP_LLRINT:
5512 Res = WidenVecRes_XROUND(
N);
5538 if (unrollExpandedOp())
5549 case ISD::VP_BITREVERSE:
5555 case ISD::VP_CTLZ_ZERO_POISON:
5561 case ISD::VP_CTTZ_ZERO_POISON:
5566 case ISD::VP_FFLOOR:
5568 case ISD::VP_FNEARBYINT:
5569 case ISD::VP_FROUND:
5570 case ISD::VP_FROUNDEVEN:
5571 case ISD::VP_FROUNDTOZERO:
5576 Res = WidenVecRes_Unary(
N);
5583 Res = WidenVecRes_Ternary(
N);
5589 if (!unrollExpandedOp())
5590 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5597 SetWidenedVector(
SDValue(
N, ResNo), Res);
5603 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5604 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5605 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5606 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5607 if (
N->getNumOperands() == 3)
5608 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5610 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5611 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5615 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5616 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5622 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5623 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5624 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5625 if (
N->getNumOperands() == 2)
5626 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5629 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5630 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5634 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5635 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5640 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5641 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5642 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5645 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5646 Mask = ModifyToType(Mask, WideMaskVT,
true);
5647 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5652 LLVMContext &Ctxt = *DAG.getContext();
5657 EVT OpVT =
LHS.getValueType();
5659 LHS = GetWidenedVector(
LHS);
5660 RHS = GetWidenedVector(
RHS);
5661 OpVT =
LHS.getValueType();
5664 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5667 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5673SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5676 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5677 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5678 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5680 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5689 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5692 if (ConcatEnd == 1) {
5693 VT = ConcatOps[0].getValueType();
5695 return ConcatOps[0];
5698 SDLoc dl(ConcatOps[0]);
5705 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5706 int Idx = ConcatEnd - 1;
5707 VT = ConcatOps[Idx--].getValueType();
5708 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5721 unsigned NumToInsert = ConcatEnd - Idx - 1;
5722 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5724 ConcatOps[Idx+1] = VecOp;
5725 ConcatEnd = Idx + 2;
5731 unsigned RealVals = ConcatEnd - Idx - 1;
5732 unsigned SubConcatEnd = 0;
5733 unsigned SubConcatIdx = Idx + 1;
5734 while (SubConcatEnd < RealVals)
5735 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5736 while (SubConcatEnd < OpsToConcat)
5737 SubConcatOps[SubConcatEnd++] = undefVec;
5739 NextVT, SubConcatOps);
5740 ConcatEnd = SubConcatIdx + 1;
5745 if (ConcatEnd == 1) {
5746 VT = ConcatOps[0].getValueType();
5748 return ConcatOps[0];
5753 if (
NumOps != ConcatEnd ) {
5755 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5756 ConcatOps[j] = UndefVal;
5764 unsigned Opcode =
N->getOpcode();
5766 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5770 const SDNodeFlags
Flags =
N->getFlags();
5771 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5772 NumElts = NumElts / 2;
5776 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5778 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5779 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5780 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5788 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5791 TLI.isTypeLegal(WideMaskVT)) {
5792 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5793 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5794 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5796 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5797 N->getValueType(0).getVectorElementCount());
5798 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5812 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5813 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5814 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5817 unsigned ConcatEnd = 0;
5825 while (CurNumElts != 0) {
5826 while (CurNumElts >= NumElts) {
5827 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5828 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5829 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5831 CurNumElts -= NumElts;
5834 NumElts = NumElts / 2;
5836 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5839 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5840 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5841 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5842 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5853 switch (
N->getOpcode()) {
5856 return WidenVecRes_STRICT_FSETCC(
N);
5863 return WidenVecRes_Convert_StrictFP(
N);
5870 unsigned Opcode =
N->getOpcode();
5872 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5876 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5877 NumElts = NumElts / 2;
5888 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5892 unsigned ConcatEnd = 0;
5899 for (
unsigned i = 1; i < NumOpers; ++i) {
5905 Oper = GetWidenedVector(Oper);
5911 DAG.getPOISON(WideOpVT), Oper,
5912 DAG.getVectorIdxConstant(0, dl));
5924 while (CurNumElts != 0) {
5925 while (CurNumElts >= NumElts) {
5928 for (
unsigned i = 0; i < NumOpers; ++i) {
5931 EVT OpVT =
Op.getValueType();
5936 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5942 EVT OperVT[] = {VT, MVT::Other};
5944 ConcatOps[ConcatEnd++] = Oper;
5947 CurNumElts -= NumElts;
5950 NumElts = NumElts / 2;
5952 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5955 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5958 for (
unsigned i = 0; i < NumOpers; ++i) {
5961 EVT OpVT =
Op.getValueType();
5969 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5971 ConcatOps[ConcatEnd++] = Oper;
5980 if (Chains.
size() == 1)
5981 NewChain = Chains[0];
5984 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5989SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5991 EVT ResVT =
N->getValueType(0);
5992 EVT OvVT =
N->getValueType(1);
5993 EVT WideResVT, WideOvVT;
5998 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6003 WideLHS = GetWidenedVector(
N->getOperand(0));
6004 WideRHS = GetWidenedVector(
N->getOperand(1));
6006 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6015 N->getOperand(0), Zero);
6017 N->getOperand(1), Zero);
6020 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6021 SDNode *WideNode = DAG.getNode(
6022 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6025 unsigned OtherNo = 1 - ResNo;
6026 EVT OtherVT =
N->getValueType(OtherNo);
6033 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
6036 return SDValue(WideNode, ResNo);
6040 LLVMContext &Ctx = *DAG.getContext();
6044 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6049 unsigned Opcode =
N->getOpcode();
6050 const SDNodeFlags
Flags =
N->getFlags();
6056 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6058 InOp = ZExtPromotedInteger(InOp);
6070 if (
N->getNumOperands() == 1)
6071 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6073 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6074 N->getOperand(3), Flags);
6075 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6079 InOp = GetWidenedVector(
N->getOperand(0));
6082 if (InVTEC == WidenEC) {
6083 if (
N->getNumOperands() == 3 &&
N->isVPOpcode()) {
6086 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
6088 return MakeConvertNode(WidenVT, InOp);
6114 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6118 if (TLI.isTypeLegal(InWidenVT)) {
6126 unsigned NumConcat =
6131 return MakeConvertNode(WidenVT, InVec);
6135 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6137 return MakeConvertNode(WidenVT, InVal);
6146 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6147 for (
unsigned i=0; i < MinElts; ++i) {
6148 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6149 Ops[i] = MakeConvertNode(EltVT, Val);
6152 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6157 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6161 EVT SrcVT = Src.getValueType();
6165 Src = GetWidenedVector(Src);
6166 SrcVT = Src.getValueType();
6173 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6178 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6182 EVT SrcVT = Src.getValueType();
6186 Src = GetWidenedVector(Src);
6187 SrcVT = Src.getValueType();
6194 if (
N->getNumOperands() == 1)
6195 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6197 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6198 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6202 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6205SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6210 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6216 unsigned Opcode =
N->getOpcode();
6222 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6227 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6228 for (
unsigned i=0; i < MinElts; ++i) {
6229 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6230 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6234 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6236 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6239SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6240 unsigned Opcode =
N->getOpcode();
6244 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6253 InOp = GetWidenedVector(InOp);
6260 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6267 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6268 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6285 while (
Ops.size() != WidenNumElts)
6286 Ops.push_back(DAG.getPOISON(WidenSVT));
6288 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6294 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6295 return WidenVecRes_BinaryCanTrap(
N);
6298 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6305SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6307 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6310 SDValue Arg = GetWidenedVector(FpValue);
6311 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6316 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6317 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6319 EVT ExpVT =
RHS.getValueType();
6324 ExpOp = ModifyToType(
RHS, WideExpVT);
6327 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6332 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6333 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6334 if (
N->getNumOperands() == 1)
6335 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6337 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6338 N->getOperand(1),
N->getFlags());
6340 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6341 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6345 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6346 {InOp,
Mask,
N->getOperand(2)});
6350 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6355 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6356 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6357 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6360SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6362 EVT VT0 =
N->getValueType(0);
6363 EVT VT1 =
N->getValueType(1);
6367 "expected both results to be vectors of matching element count");
6369 LLVMContext &Ctx = *DAG.getContext();
6370 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6372 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6379 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6382 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6383 return SDValue(WidenNode, ResNo);
6386SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6387 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6388 return GetWidenedVector(WidenVec);
6392 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6393 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6396 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6397 AddrSpaceCastN->getSrcAddressSpace(),
6398 AddrSpaceCastN->getDestAddressSpace());
6404 EVT VT =
N->getValueType(0);
6405 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6408 switch (getTypeAction(InVT)) {
6422 SDValue NInOp = GetPromotedInteger(InOp);
6424 if (WidenVT.
bitsEq(NInVT)) {
6427 if (DAG.getDataLayout().isBigEndian()) {
6430 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6448 InOp = GetWidenedVector(InOp);
6450 if (WidenVT.
bitsEq(InVT))
6460 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6465 unsigned NewNumParts = WidenSize / InSize;
6478 EVT OrigInVT =
N->getOperand(0).getValueType();
6483 if (TLI.isTypeLegal(NewInVT)) {
6491 if (WidenSize % InSize == 0) {
6498 DAG.ExtractVectorElements(InOp,
Ops);
6499 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6511 return CreateStackStoreLoad(InOp, WidenVT);
6514SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6516 N->getOpcode(), SDLoc(
N),
6517 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6518 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6524 EVT VT =
N->getValueType(0);
6528 EVT EltVT =
N->getOperand(0).getValueType();
6531 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6535 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6536 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6538 return DAG.getBuildVector(WidenVT, dl, NewOps);
6542 EVT InVT =
N->getOperand(0).getValueType();
6543 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6545 unsigned NumOperands =
N->getNumOperands();
6547 bool InputWidened =
false;
6551 if (WidenNumElts % NumInElts == 0) {
6553 unsigned NumConcat = WidenNumElts / NumInElts;
6554 SDValue UndefVal = DAG.getPOISON(InVT);
6556 for (
unsigned i=0; i < NumOperands; ++i)
6557 Ops[i] =
N->getOperand(i);
6558 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6563 InputWidened =
true;
6564 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6567 for (i=1; i < NumOperands; ++i)
6568 if (!
N->getOperand(i).isUndef())
6571 if (i == NumOperands)
6574 return GetWidenedVector(
N->getOperand(0));
6576 if (NumOperands == 2) {
6578 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6583 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6584 for (
unsigned i = 0; i < NumInElts; ++i) {
6586 MaskOps[i + NumInElts] = i + WidenNumElts;
6588 return DAG.getVectorShuffle(WidenVT, dl,
6589 GetWidenedVector(
N->getOperand(0)),
6590 GetWidenedVector(
N->getOperand(1)),
6597 "Cannot use build vectors to widen CONCAT_VECTOR result");
6605 for (
unsigned i=0; i < NumOperands; ++i) {
6608 InOp = GetWidenedVector(InOp);
6609 for (
unsigned j = 0;
j < NumInElts; ++
j)
6610 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6612 SDValue UndefVal = DAG.getPOISON(EltVT);
6613 for (; Idx < WidenNumElts; ++Idx)
6614 Ops[Idx] = UndefVal;
6615 return DAG.getBuildVector(WidenVT, dl,
Ops);
6618SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6619 EVT VT =
N->getValueType(0);
6620 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6621 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6628SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6629 EVT VT =
N->getValueType(0);
6631 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6636 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6638 InOp = GetWidenedVector(InOp);
6644 if (IdxVal == 0 && InVT == WidenVT)
6651 assert(IdxVal % VTNumElts == 0 &&
6652 "Expected Idx to be a multiple of subvector minimum vector length");
6653 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6666 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6667 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6668 "down type's element count");
6675 for (;
I < VTNumElts / GCD; ++
I)
6677 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6678 for (;
I < WidenNumElts / GCD; ++
I)
6686 Align Alignment = DAG.getReducedAlign(InVT,
false);
6688 MachineFunction &MF = DAG.getMachineFunction();
6700 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6707 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6708 return DAG.getMaskedLoad(
6709 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6717 for (i = 0; i < VTNumElts; ++i)
6718 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6720 SDValue UndefVal = DAG.getPOISON(EltVT);
6721 for (; i < WidenNumElts; ++i)
6723 return DAG.getBuildVector(WidenVT, dl,
Ops);
6729 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6734SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6735 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6738 N->getOperand(1),
N->getOperand(2));
6747 "Load width must be less than or equal to first value type width");
6756 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6773 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6784 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6785 EVT LdVT =
LD->getMemoryVT();
6794 TypeSize WidthDiff = WidenWidth - LdWidth;
6797 std::optional<EVT> FirstVT =
6798 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6805 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6808 Chain, BasePtr,
LD->getMemOperand());
6812 FirstVTWidth, dl, DAG);
6830 if (!
LD->getMemoryVT().isByteSized()) {
6832 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6834 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6843 EVT VT =
LD->getValueType(0);
6844 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6845 EVT WideMaskVT = getSetCCResultType(WideVT);
6848 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6849 TLI.isTypeLegal(WideMaskVT)) {
6852 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6856 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6857 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6869 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6871 Result = GenWidenVectorLoads(LdChain, LD);
6878 if (LdChain.
size() == 1)
6879 NewChain = LdChain[0];
6885 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6896 SDValue NewLoad = DAG.getMaskedLoad(
6897 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6898 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6899 LD->getAddressingMode(),
LD->getExtensionType());
6909 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6911 SDValue EVL =
N->getVectorLength();
6918 "Unable to widen binary VP op");
6919 Mask = GetWidenedVector(Mask);
6920 assert(
Mask.getValueType().getVectorElementCount() ==
6921 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6922 .getVectorElementCount() &&
6923 "Unable to widen vector load");
6926 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6927 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6928 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6936 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6938 SDValue EVL =
N->getVectorLength();
6944 "Unable to widen binary VP op");
6945 Mask = GetWidenedVector(Mask);
6946 assert(
Mask.getValueType().getVectorElementCount() ==
6947 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6948 .getVectorElementCount() &&
6949 "Unable to widen vector load");
6951 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6952 Mask, EVL,
N->getMemOperand());
6965 "Unable to widen VP strided load");
6966 Mask = GetWidenedVector(Mask);
6968 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6969 assert(
Mask.getValueType().getVectorElementCount() ==
6971 "Data and mask vectors should have the same number of elements");
6973 SDValue Res = DAG.getStridedLoadVP(
6974 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6975 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6976 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6977 N->isExpandingLoad());
6985SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6990 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6992 Mask.getValueType().getVectorElementType(),
6995 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6996 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6997 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6999 WideMask, WidePassthru);
7003 EVT VT =
N->getValueType(0);
7004 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7006 EVT MaskVT =
Mask.getValueType();
7007 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7016 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7017 TLI.isTypeLegal(WideMaskVT) &&
7023 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7024 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7028 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7029 N->getMemoryVT(),
N->getMemOperand());
7033 if (!
N->getPassThru()->isUndef()) {
7037 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7038 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7039 DAG.getPOISON(WidenVT), EVL);
7050 Mask = ModifyToType(Mask, WideMaskVT,
true);
7052 SDValue Res = DAG.getMaskedLoad(
7053 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7054 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7055 ExtType,
N->isExpandingLoad());
7064 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7066 EVT MaskVT =
Mask.getValueType();
7067 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7075 Mask = ModifyToType(Mask, WideMaskVT,
true);
7080 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7081 Index = ModifyToType(Index, WideIndexVT);
7087 N->getMemoryVT().getScalarType(), WideEC);
7088 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7089 WideMemVT, dl,
Ops,
N->getMemOperand(),
7090 N->getIndexType(),
N->getExtensionType());
7099 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7107 N->getMemoryVT().getScalarType(), WideEC);
7108 Mask = GetWidenedMask(Mask, WideEC);
7111 Mask,
N->getVectorLength()};
7112 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7113 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7122 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7123 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7151 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7152 return N->getOperand(OpNo).getValueType();
7160 N =
N.getOperand(0);
7162 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7163 if (!
N->getOperand(i)->isUndef())
7165 N =
N.getOperand(0);
7169 N =
N.getOperand(0);
7171 N =
N.getOperand(0);
7198 { MaskVT, MVT::Other },
Ops);
7199 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7207 LLVMContext &Ctx = *DAG.getContext();
7210 if (MaskScalarBits < ToMaskScalBits) {
7214 }
else if (MaskScalarBits > ToMaskScalBits) {
7220 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7222 "Mask should have the right element size by now.");
7225 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7227 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7230 EVT SubVT =
Mask->getValueType(0);
7236 assert((
Mask->getValueType(0) == ToMaskVT) &&
7237 "A mask of ToMaskVT should have been produced by now.");
7247 LLVMContext &Ctx = *DAG.getContext();
7258 EVT CondVT =
Cond->getValueType(0);
7262 EVT VSelVT =
N->getValueType(0);
7274 EVT FinalVT = VSelVT;
7285 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7286 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7293 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7301 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7304 EVT ToMaskVT = VSelVT;
7311 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7327 if (ScalarBits0 != ScalarBits1) {
7328 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7329 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7341 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7342 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7343 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7346 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7354 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7359 unsigned Opcode =
N->getOpcode();
7361 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7362 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7363 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7365 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7371 Cond1 = GetWidenedVector(Cond1);
7379 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7380 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7385 Cond1 = ModifyToType(Cond1, CondWidenVT);
7388 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7389 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7391 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7392 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7394 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7398 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7399 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7402 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7406 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7407 return DAG.getUNDEF(WidenVT);
7411 EVT VT =
N->getValueType(0);
7414 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7418 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7419 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7422 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7423 for (
unsigned i = 0; i != NumElts; ++i) {
7424 int Idx =
N->getMaskElt(i);
7425 if (Idx < (
int)NumElts)
7428 NewMask[i] = Idx - NumElts + WidenNumElts;
7430 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7434 EVT VT =
N->getValueType(0);
7438 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7439 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7445 unsigned IdxVal = WidenNumElts - VTNumElts;
7458 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7461 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7462 "down type's element count");
7465 for (; i < VTNumElts / GCD; ++i)
7467 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7468 for (; i < WidenNumElts / GCD; ++i)
7476 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7477 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7479 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7483SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7484 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7488void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7489 EVT VT =
N->getValueType(0);
7492 unsigned Factor =
N->getNumOperands();
7495 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7508 SDValue PackedWidenVec = DAG.getInsertSubvector(
7509 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7513 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7514 NewOps[Idx] = DAG.getExtractSubvector(
7515 DL, WidenVT, PackedWidenVec,
7522 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7527 assert(
N->getValueType(0).isVector() &&
7528 N->getOperand(0).getValueType().isVector() &&
7529 "Operands must be vectors");
7530 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7543 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7544 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7551 InOp1 = GetWidenedVector(InOp1);
7552 InOp2 = GetWidenedVector(InOp2);
7555 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7566 "Input not widened to expected type!");
7568 if (
N->getOpcode() == ISD::VP_SETCC) {
7571 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7572 N->getOperand(2), Mask,
N->getOperand(4));
7574 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7579 assert(
N->getValueType(0).isVector() &&
7580 N->getOperand(1).getValueType().isVector() &&
7581 "Operands must be vectors");
7582 EVT VT =
N->getValueType(0);
7583 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7593 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7598 for (
unsigned i = 0; i != NumElts; ++i) {
7599 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7600 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7602 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7603 {Chain, LHSElem, RHSElem, CC});
7604 Chains[i] = Scalars[i].getValue(1);
7605 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7606 DAG.getBoolConstant(
true, dl, EltVT, VT),
7607 DAG.getBoolConstant(
false, dl, EltVT, VT));
7611 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7613 return DAG.getBuildVector(WidenVT, dl, Scalars);
7619bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7620 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7624 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7627 switch (
N->getOpcode()) {
7630 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7638 Res = WidenVecOp_FAKE_USE(
N);
7644 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7648 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7649 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7650 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7655 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7657 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7658 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7660 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7661 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7671 Res = WidenVecOp_UnrollVectorOp(
N);
7678 Res = WidenVecOp_EXTEND(
N);
7683 Res = WidenVecOp_CMP(
N);
7701 Res = WidenVecOp_Convert(
N);
7706 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7724 Res = WidenVecOp_VECREDUCE(
N);
7728 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7730 case ISD::VP_REDUCE_FADD:
7731 case ISD::VP_REDUCE_SEQ_FADD:
7732 case ISD::VP_REDUCE_FMUL:
7733 case ISD::VP_REDUCE_SEQ_FMUL:
7734 case ISD::VP_REDUCE_ADD:
7735 case ISD::VP_REDUCE_MUL:
7736 case ISD::VP_REDUCE_AND:
7737 case ISD::VP_REDUCE_OR:
7738 case ISD::VP_REDUCE_XOR:
7739 case ISD::VP_REDUCE_SMAX:
7740 case ISD::VP_REDUCE_SMIN:
7741 case ISD::VP_REDUCE_UMAX:
7742 case ISD::VP_REDUCE_UMIN:
7743 case ISD::VP_REDUCE_FMAX:
7744 case ISD::VP_REDUCE_FMIN:
7745 case ISD::VP_REDUCE_FMAXIMUM:
7746 case ISD::VP_REDUCE_FMINIMUM:
7747 Res = WidenVecOp_VP_REDUCE(
N);
7751 Res = WidenVecOp_CttzElements(
N);
7753 case ISD::VP_CTTZ_ELTS:
7754 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7755 Res = WidenVecOp_VP_CttzElements(
N);
7758 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7763 if (!Res.
getNode())
return false;
7771 if (
N->isStrictFPOpcode())
7773 "Invalid operand expansion");
7776 "Invalid operand expansion");
7778 ReplaceValueWith(
SDValue(
N, 0), Res);
7784 EVT VT =
N->getValueType(0);
7789 "Unexpected type action");
7790 InOp = GetWidenedVector(InOp);
7793 "Input wasn't widened!");
7801 EVT FixedEltVT = FixedVT.getVectorElementType();
7802 if (TLI.isTypeLegal(FixedVT) &&
7804 FixedEltVT == InEltVT) {
7806 "Not enough elements in the fixed type for the operand!");
7808 "We can't have the same type as we started with!");
7810 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7812 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7821 return WidenVecOp_Convert(
N);
7826 switch (
N->getOpcode()) {
7841 EVT OpVT =
N->getOperand(0).getValueType();
7842 EVT ResVT =
N->getValueType(0);
7849 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7850 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7856 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7857 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7859 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7866 return DAG.UnrollVectorOp(
N);
7871 EVT ResultVT =
N->getValueType(0);
7873 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7876 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7882 {WideArg,
Test},
N->getFlags());
7888 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7890 EVT OpVT =
N->getOperand(0).getValueType();
7893 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7898 EVT VT =
N->getValueType(0);
7904 "Unexpected type action");
7905 InOp = GetWidenedVector(InOp);
7907 unsigned Opcode =
N->getOpcode();
7912 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7915 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7916 return DAG.getNode(Opcode, dl, VT,
Op);
7923 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7925 if (
N->isStrictFPOpcode()) {
7927 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7930 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7931 {
N->getOperand(0), InOp });
7936 Res = MakeConvertNode(WideVT, InOp);
7938 return DAG.getExtractSubvector(dl, VT, Res, 0);
7946 if (
N->isStrictFPOpcode()) {
7949 for (
unsigned i=0; i < NumElts; ++i) {
7950 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7951 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7955 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7957 for (
unsigned i = 0; i < NumElts; ++i) {
7958 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7959 Ops[i] = MakeConvertNode(EltVT, Elt);
7963 return DAG.getBuildVector(VT, dl,
Ops);
7967 EVT DstVT =
N->getValueType(0);
7968 SDValue Src = GetWidenedVector(
N->getOperand(0));
7969 EVT SrcVT = Src.getValueType();
7976 if (TLI.isTypeLegal(WideDstVT)) {
7978 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7981 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7985 return DAG.UnrollVectorOp(
N);
7989 EVT VT =
N->getValueType(0);
7990 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7998 if (!VT.
isVector() && VT != MVT::x86mmx &&
8002 if (TLI.isTypeLegal(NewVT)) {
8004 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8016 ElementCount NewNumElts =
8018 .divideCoefficientBy(EltSize);
8020 if (TLI.isTypeLegal(NewVT)) {
8022 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8027 return CreateStackStoreLoad(InOp, VT);
8035 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8036 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8041 EVT VT =
N->getValueType(0);
8043 EVT InVT =
N->getOperand(0).getValueType();
8048 unsigned NumOperands =
N->getNumOperands();
8049 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8051 for (i = 1; i < NumOperands; ++i)
8052 if (!
N->getOperand(i).isUndef())
8055 if (i == NumOperands)
8056 return GetWidenedVector(
N->getOperand(0));
8066 for (
unsigned i=0; i < NumOperands; ++i) {
8070 "Unexpected type action");
8071 InOp = GetWidenedVector(InOp);
8072 for (
unsigned j = 0;
j < NumInElts; ++
j)
8073 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8075 return DAG.getBuildVector(VT, dl,
Ops);
8078SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8079 EVT VT =
N->getValueType(0);
8084 SubVec = GetWidenedVector(SubVec);
8089 bool IndicesValid =
false;
8092 IndicesValid =
true;
8096 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8097 Attribute::VScaleRange);
8102 IndicesValid =
true;
8108 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8114 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8121 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8128 Align Alignment = DAG.getReducedAlign(VT,
false);
8130 MachineFunction &MF = DAG.getMachineFunction();
8143 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8151 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8152 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8157 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8162 unsigned Idx =
N->getConstantOperandVal(2);
8168 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8174SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8175 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8177 N->getValueType(0), InOp,
N->getOperand(1));
8180SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8181 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8183 N->getValueType(0), InOp,
N->getOperand(1));
8186SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8188 EVT ResVT =
N->getValueType(0);
8191 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8197 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8205 "Widened input size must be a multiple of result element size");
8208 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8210 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8211 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8219 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8220 return TLI.scalarizeVectorStore(ST, DAG);
8222 if (
ST->isTruncatingStore())
8223 return TLI.scalarizeVectorStore(ST, DAG);
8233 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8234 EVT WideMaskVT = getSetCCResultType(WideVT);
8236 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8237 TLI.isTypeLegal(WideMaskVT)) {
8240 StVal = GetWidenedVector(StVal);
8242 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8244 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8245 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8246 ST->getAddressingMode());
8250 if (GenWidenVectorStores(StChain, ST)) {
8251 if (StChain.
size() == 1)
8260 SDValue WideStVal = GetWidenedVector(StVal);
8264 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8265 ST->getOffset(), Mask,
ST->getMemoryVT(),
8266 ST->getMemOperand(),
ST->getAddressingMode(),
8267 ST->isTruncatingStore());
8274 EVT StVT =
ST->getMemoryVT();
8277 SDValue StVal = GetWidenedVector(
ST->getVal());
8282 TypeSize WidthDiff = WidenWidth - StWidth;
8288 std::optional<EVT> FirstVT =
8289 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8294 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8300 ST->getBasePtr(),
ST->getMemOperand());
8303SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8304 assert((OpNo == 1 || OpNo == 3) &&
8305 "Can widen only data or mask operand of vp_store");
8313 StVal = GetWidenedVector(StVal);
8319 "Unable to widen VP store");
8320 Mask = GetWidenedVector(Mask);
8322 Mask = GetWidenedVector(Mask);
8328 "Unable to widen VP store");
8329 StVal = GetWidenedVector(StVal);
8332 assert(
Mask.getValueType().getVectorElementCount() ==
8334 "Mask and data vectors should have the same number of elements");
8335 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8336 ST->getOffset(), Mask,
ST->getVectorLength(),
8337 ST->getMemoryVT(),
ST->getMemOperand(),
8338 ST->getAddressingMode(),
ST->isTruncatingStore(),
8339 ST->isCompressingStore());
8344 assert((OpNo == 1 || OpNo == 4) &&
8345 "Can widen only data or mask operand of vp_strided_store");
8354 "Unable to widen VP strided store");
8358 "Unable to widen VP strided store");
8360 StVal = GetWidenedVector(StVal);
8361 Mask = GetWidenedVector(Mask);
8364 Mask.getValueType().getVectorElementCount() &&
8365 "Data and mask vectors should have the same number of elements");
8367 return DAG.getStridedStoreVP(
8374SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8375 assert((OpNo == 1 || OpNo == 4) &&
8376 "Can widen only data or mask operand of mstore");
8379 EVT MaskVT =
Mask.getValueType();
8384 EVT WideVT, WideMaskVT;
8387 StVal = GetWidenedVector(StVal);
8394 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8401 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8403 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8404 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8413 Mask = ModifyToType(Mask, WideMaskVT,
true);
8416 Mask = ModifyToType(Mask, WideMaskVT,
true);
8418 StVal = ModifyToType(StVal, WideVT);
8421 assert(
Mask.getValueType().getVectorElementCount() ==
8423 "Mask and data vectors should have the same number of elements");
8430SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8431 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8433 SDValue DataOp = MG->getPassThru();
8435 SDValue Scale = MG->getScale();
8443 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8444 MG->getMemOperand(), MG->getIndexType(),
8445 MG->getExtensionType());
8451SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8460 DataOp = GetWidenedVector(DataOp);
8464 EVT IndexVT =
Index.getValueType();
8467 Index = ModifyToType(Index, WideIndexVT);
8470 EVT MaskVT =
Mask.getValueType();
8473 Mask = ModifyToType(Mask, WideMaskVT,
true);
8478 }
else if (OpNo == 4) {
8480 Index = GetWidenedVector(Index);
8486 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8491SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8500 DataOp = GetWidenedVector(DataOp);
8501 Index = GetWidenedVector(Index);
8503 Mask = GetWidenedMask(Mask, WideEC);
8506 }
else if (OpNo == 3) {
8508 Index = GetWidenedVector(Index);
8515 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8520 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8521 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8523 EVT VT =
N->getValueType(0);
8538 SVT, InOp0, InOp1,
N->getOperand(2));
8544 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8546 EVT OpVT =
N->getOperand(0).getValueType();
8549 return DAG.getNode(ExtendCode, dl, VT, CC);
8559 EVT VT =
N->getValueType(0);
8561 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8568 for (
unsigned i = 0; i != NumElts; ++i) {
8569 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8570 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8572 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8573 {Chain, LHSElem, RHSElem, CC});
8574 Chains[i] = Scalars[i].getValue(1);
8575 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8576 DAG.getBoolConstant(
true, dl, EltVT, VT),
8577 DAG.getBoolConstant(
false, dl, EltVT, VT));
8581 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8583 return DAG.getBuildVector(VT, dl, Scalars);
8607 SDValue Op = GetWidenedVector(
N->getOperand(0));
8608 EVT VT =
N->getValueType(0);
8609 EVT OrigVT =
N->getOperand(0).getValueType();
8610 EVT WideVT =
Op.getValueType();
8612 SDNodeFlags
Flags =
N->getFlags();
8614 unsigned Opc =
N->getOpcode();
8616 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8617 assert(NeutralElem &&
"Neutral element must exist");
8627 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8634 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8635 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8641 unsigned GCD = std::gcd(OrigElts, WideElts);
8644 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8645 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8646 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8647 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8650 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8651 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8653 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8662 EVT VT =
N->getValueType(0);
8664 EVT WideVT =
Op.getValueType();
8666 SDNodeFlags
Flags =
N->getFlags();
8668 unsigned Opc =
N->getOpcode();
8670 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8680 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8683 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8684 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8690 unsigned GCD = std::gcd(OrigElts, WideElts);
8693 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8694 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8695 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8696 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8699 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8700 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8702 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8706 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8709 SDValue Op = GetWidenedVector(
N->getOperand(1));
8711 Op.getValueType().getVectorElementCount());
8713 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8714 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8722 EVT VT =
N->getValueType(0);
8726 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8727 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8732 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8739 TLI.getTypeToTransformTo(*DAG.getContext(),
Source.getValueType());
8743 WideSource = GetWidenedVector(Source);
8748 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8751 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8758 EVT SrcVT =
Source.getValueType();
8762 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8763 {Source, Mask, N->getOperand(2)},
N->getFlags());
8766SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8769 EVT OrigMaskVT =
Mask.getValueType();
8770 SDValue WideMask = GetWidenedVector(Mask);
8776 if (OrigElts != WideElts) {
8777 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8779 Mask, DAG.getVectorIdxConstant(0,
DL));
8800 unsigned WidenEx = 0) {
8805 unsigned AlignInBits =
Align*8;
8807 EVT RetVT = WidenEltVT;
8812 if (Width == WidenEltWidth)
8823 (WidenWidth % MemVTWidth) == 0 &&
8825 (MemVTWidth <= Width ||
8826 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8827 if (MemVTWidth == WidenWidth)
8846 (WidenWidth % MemVTWidth) == 0 &&
8848 (MemVTWidth <= Width ||
8849 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8858 return std::nullopt;
8869 unsigned Start,
unsigned End) {
8870 SDLoc dl(LdOps[Start]);
8871 EVT LdTy = LdOps[Start].getValueType();
8879 for (
unsigned i = Start + 1; i != End; ++i) {
8880 EVT NewLdTy = LdOps[i].getValueType();
8881 if (NewLdTy != LdTy) {
8900 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8901 EVT LdVT =
LD->getMemoryVT();
8911 AAMDNodes AAInfo =
LD->getAAInfo();
8915 TypeSize WidthDiff = WidenWidth - LdWidth;
8922 std::optional<EVT> FirstVT =
8923 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8930 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8935 std::optional<EVT> NewVT = FirstVT;
8936 TypeSize RemainingWidth = LdWidth;
8937 TypeSize NewVTWidth = FirstVTWidth;
8939 RemainingWidth -= NewVTWidth;
8946 NewVTWidth = NewVT->getSizeInBits();
8952 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8953 LD->getBaseAlign(), MMOFlags, AAInfo);
8965 uint64_t ScaledOffset = 0;
8966 MachinePointerInfo MPI =
LD->getPointerInfo();
8972 for (EVT MemVT : MemVTs) {
8973 Align NewAlign = ScaledOffset == 0
8974 ?
LD->getBaseAlign()
8977 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8985 unsigned End = LdOps.
size();
8996 EVT LdTy = LdOps[i].getValueType();
8999 for (--i; i >= 0; --i) {
9000 LdTy = LdOps[i].getValueType();
9007 ConcatOps[--Idx] = LdOps[i];
9008 for (--i; i >= 0; --i) {
9009 EVT NewLdTy = LdOps[i].getValueType();
9010 if (NewLdTy != LdTy) {
9020 for (;
j != End-Idx; ++
j)
9021 WidenOps[j] = ConcatOps[Idx+j];
9023 WidenOps[j] = DAG.getPOISON(LdTy);
9030 ConcatOps[--Idx] = LdOps[i];
9035 ArrayRef(&ConcatOps[Idx], End - Idx));
9041 SDValue UndefVal = DAG.getPOISON(LdTy);
9044 for (; i != End-Idx; ++i)
9045 WidenOps[i] = ConcatOps[Idx+i];
9047 WidenOps[i] = UndefVal;
9058 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9059 EVT LdVT =
LD->getMemoryVT();
9068 AAMDNodes AAInfo =
LD->getAAInfo();
9082 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9083 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9089 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9090 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9091 LD->getBaseAlign(), MMOFlags, AAInfo);
9096 SDValue UndefVal = DAG.getPOISON(EltVT);
9097 for (; i != WidenNumElts; ++i)
9100 return DAG.getBuildVector(WidenVT, dl,
Ops);
9111 AAMDNodes AAInfo =
ST->getAAInfo();
9112 SDValue ValOp = GetWidenedVector(
ST->getValue());
9115 EVT StVT =
ST->getMemoryVT();
9123 "Mismatch between store and value types");
9127 MachinePointerInfo MPI =
ST->getPointerInfo();
9128 uint64_t ScaledOffset = 0;
9137 std::optional<EVT> NewVT =
9142 TypeSize NewVTWidth = NewVT->getSizeInBits();
9145 StWidth -= NewVTWidth;
9146 MemVTs.
back().second++;
9150 for (
const auto &Pair : MemVTs) {
9151 EVT NewVT = Pair.first;
9152 unsigned Count = Pair.second;
9158 Align NewAlign = ScaledOffset == 0
9159 ?
ST->getBaseAlign()
9161 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9162 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9178 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9179 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9180 ST->getBaseAlign(), MMOFlags, AAInfo);
9197 bool FillWithZeroes) {
9202 "input and widen element type must match");
9204 "cannot modify scalable vectors in this way");
9217 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9219 for (
unsigned i = 1; i != NumConcat; ++i)
9226 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9229 "Scalable vectors should have been handled already.");
9237 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9239 for (Idx = 0; Idx < MinNumElts; ++Idx)
9240 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9242 SDValue UndefVal = DAG.getPOISON(EltVT);
9243 for (; Idx < WidenNumElts; ++Idx)
9244 Ops[Idx] = UndefVal;
9246 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9247 if (!FillWithZeroes)
9251 "We expect to never want to FillWithZeroes for non-integral types.");
9254 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9255 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9257 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9258 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")
static constexpr Value * getValue(Ty &ValueOrUse)
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 std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT, TypeSize FirstVTWidth, const SDLoc &dl, SelectionDAG &DAG)
Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the widened value so it can b...
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
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, bool LookThroughCmp=false)
Returns the "element type" of the given value/instruction V.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file implements the SmallBitVector class.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique 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.
SDNodeFlags getFlags() const
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
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtractVectorElt(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Extract element at Idx from Vec.
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.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
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 LeafTy multiplyCoefficientBy(ScalarTy RHS) const
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by OFFSET elements an...
@ 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.
@ MASKED_UDIV
Masked vector arithmetic that returns poison on disabled lanes.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
@ 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.
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
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.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
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.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) 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.
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.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
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.