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);
3862 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3868 case ISD::VP_SINT_TO_FP:
3869 case ISD::VP_UINT_TO_FP:
3870 if (
N->getValueType(0).bitsLT(
3871 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3872 Res = SplitVecOp_TruncateHelper(
N);
3874 Res = SplitVecOp_UnaryOp(
N);
3878 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3882 case ISD::VP_FP_TO_SINT:
3883 case ISD::VP_FP_TO_UINT:
3896 Res = SplitVecOp_UnaryOp(
N);
3899 Res = SplitVecOp_FPOpDifferentTypes(
N);
3904 Res = SplitVecOp_CMP(
N);
3908 Res = SplitVecOp_FAKE_USE(
N);
3913 Res = SplitVecOp_ExtVecInRegOp(
N);
3931 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3935 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3937 case ISD::VP_REDUCE_FADD:
3938 case ISD::VP_REDUCE_SEQ_FADD:
3939 case ISD::VP_REDUCE_FMUL:
3940 case ISD::VP_REDUCE_SEQ_FMUL:
3941 case ISD::VP_REDUCE_ADD:
3942 case ISD::VP_REDUCE_MUL:
3943 case ISD::VP_REDUCE_AND:
3944 case ISD::VP_REDUCE_OR:
3945 case ISD::VP_REDUCE_XOR:
3946 case ISD::VP_REDUCE_SMAX:
3947 case ISD::VP_REDUCE_SMIN:
3948 case ISD::VP_REDUCE_UMAX:
3949 case ISD::VP_REDUCE_UMIN:
3950 case ISD::VP_REDUCE_FMAX:
3951 case ISD::VP_REDUCE_FMIN:
3952 case ISD::VP_REDUCE_FMAXIMUM:
3953 case ISD::VP_REDUCE_FMINIMUM:
3954 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3958 Res = SplitVecOp_CttzElts(
N);
3960 case ISD::VP_CTTZ_ELTS:
3961 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3962 Res = SplitVecOp_VP_CttzElements(
N);
3965 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3971 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3976 if (!Res.
getNode())
return false;
3983 if (
N->isStrictFPOpcode())
3985 "Invalid operand expansion");
3988 "Invalid operand expansion");
3990 ReplaceValueWith(
SDValue(
N, 0), Res);
3994SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3998 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4000 EVT VT =
N->getValueType(0);
4013 getSetCCResultType(MVT::i1), MVT::i1);
4018 DAG.getElementCount(
DL, VT, SplitEC)),
4022SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4025 assert(OpNo == 0 &&
"Illegal operand must be mask");
4032 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4035 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4036 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4037 "Lo and Hi have differing types");
4040 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4041 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4043 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4044 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4045 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4046 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4056SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4059 assert(OpNo == 1 &&
"Illegal operand must be mask");
4064 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4066 EVT VecVT =
N->getValueType(0);
4070SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4071 EVT ResVT =
N->getValueType(0);
4077 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4078 GetSplitVector(VecOp,
Lo,
Hi);
4080 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4085 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4086 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4090 EVT ResVT =
N->getValueType(0);
4096 SDNodeFlags
Flags =
N->getFlags();
4099 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4100 GetSplitVector(VecOp,
Lo,
Hi);
4102 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4108 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4111SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4112 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4113 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4115 unsigned Opc =
N->getOpcode();
4116 EVT ResVT =
N->getValueType(0);
4122 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4123 GetSplitVector(VecOp,
Lo,
Hi);
4126 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4129 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4131 const SDNodeFlags
Flags =
N->getFlags();
4135 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4140 EVT ResVT =
N->getValueType(0);
4143 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4144 EVT InVT =
Lo.getValueType();
4149 if (
N->isStrictFPOpcode()) {
4150 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4151 {N->getOperand(0), Lo});
4152 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4153 {N->getOperand(0), Hi});
4162 ReplaceValueWith(
SDValue(
N, 1), Ch);
4163 }
else if (
N->getNumOperands() == 3) {
4164 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4165 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4166 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4167 std::tie(EVLLo, EVLHi) =
4168 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4169 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4170 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4172 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4173 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4182 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4192 EVT ResVT =
N->getValueType(0);
4194 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4198 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4204 Lo = BitConvertToInteger(
Lo);
4205 Hi = BitConvertToInteger(
Hi);
4207 if (DAG.getDataLayout().isBigEndian())
4215 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4217 EVT ResVT =
N->getValueType(0);
4225 GetSplitVector(SubVec,
Lo,
Hi);
4234 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4236 return SecondInsertion;
4239SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4246 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4248 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4250 ElementCount IdxVal =
4254 EVT SrcVT =
N->getOperand(0).getValueType();
4273 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4274 LoEltsMin - IdxValMin);
4275 DAG.ExtractVectorElements(
Hi, Elts, 0,
4278 return DAG.getBuildVector(SubVT, dl, Elts);
4282 ElementCount ExtractIdx = IdxVal - LoElts;
4284 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4287 EVT HiVT =
Hi.getValueType();
4289 "Only fixed-vector extracts are supported in this case");
4299 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4300 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4306 "Extracting scalable subvector from fixed-width unsupported");
4314 "subvector from a scalable predicate vector");
4320 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4322 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4323 auto &MF = DAG.getMachineFunction();
4327 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4331 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4334 SubVT, dl,
Store, StackPtr,
4338SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4344 uint64_t IdxVal =
Index->getZExtValue();
4347 GetSplitVector(Vec,
Lo,
Hi);
4349 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4351 if (IdxVal < LoElts)
4352 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4355 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4360 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4372 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4378 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4380 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4381 auto &MF = DAG.getMachineFunction();
4384 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4388 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4392 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4394 return DAG.getExtLoad(
4405 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4413 SplitVecRes_Gather(
N,
Lo,
Hi);
4416 ReplaceValueWith(
SDValue(
N, 0), Res);
4421 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4425 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4427 SDValue EVL =
N->getVectorLength();
4429 Align Alignment =
N->getBaseAlign();
4435 GetSplitVector(
Data, DataLo, DataHi);
4437 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4442 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4445 GetSplitVector(Mask, MaskLo, MaskHi);
4447 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4450 EVT MemoryVT =
N->getMemoryVT();
4451 EVT LoMemVT, HiMemVT;
4452 bool HiIsEmpty =
false;
4453 std::tie(LoMemVT, HiMemVT) =
4454 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4458 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4461 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4466 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4467 N->getAddressingMode(),
N->isTruncatingStore(),
4468 N->isCompressingStore());
4474 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4475 N->isCompressingStore());
4477 MachinePointerInfo MPI;
4481 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4486 MMO = DAG.getMachineFunction().getMachineMemOperand(
4488 Alignment,
N->getAAInfo(),
N->getRanges());
4490 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4491 N->getAddressingMode(),
N->isTruncatingStore(),
4492 N->isCompressingStore());
4501 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4502 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4509 GetSplitVector(
Data, LoData, HiData);
4511 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4513 EVT LoMemVT, HiMemVT;
4514 bool HiIsEmpty =
false;
4515 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4521 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4522 else if (getTypeAction(
Mask.getValueType()) ==
4524 GetSplitVector(Mask, LoMask, HiMask);
4526 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4529 std::tie(LoEVL, HiEVL) =
4530 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4534 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4535 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4536 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4547 EVT PtrVT =
N->getBasePtr().getValueType();
4550 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4553 Align Alignment =
N->getBaseAlign();
4558 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4559 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4561 Alignment,
N->getAAInfo(),
N->getRanges());
4564 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4565 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4566 N->isCompressingStore());
4575 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4579 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4582 Align Alignment =
N->getBaseAlign();
4588 GetSplitVector(
Data, DataLo, DataHi);
4590 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4595 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4598 GetSplitVector(Mask, MaskLo, MaskHi);
4600 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4603 EVT MemoryVT =
N->getMemoryVT();
4604 EVT LoMemVT, HiMemVT;
4605 bool HiIsEmpty =
false;
4606 std::tie(LoMemVT, HiMemVT) =
4607 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4610 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4615 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4616 N->getAddressingMode(),
N->isTruncatingStore(),
4617 N->isCompressingStore());
4625 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4626 N->isCompressingStore());
4628 MachinePointerInfo MPI;
4632 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4637 MMO = DAG.getMachineFunction().getMachineMemOperand(
4639 Alignment,
N->getAAInfo(),
N->getRanges());
4641 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4642 N->getAddressingMode(),
N->isTruncatingStore(),
4643 N->isCompressingStore());
4656 EVT MemoryVT =
N->getMemoryVT();
4657 Align Alignment =
N->getBaseAlign();
4664 }
Ops = [&]() -> Operands {
4666 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4670 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4675 EVT LoMemVT, HiMemVT;
4676 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4681 GetSplitVector(
Ops.Data, DataLo, DataHi);
4683 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4688 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4690 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4694 if (getTypeAction(
Ops.Index.getValueType()) ==
4696 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4698 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4702 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4704 Alignment,
N->getAAInfo(),
N->getRanges());
4707 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4709 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4710 MSC->getIndexType(), MSC->isTruncatingStore());
4715 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4716 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4717 MMO, MSC->getIndexType(),
4718 MSC->isTruncatingStore());
4722 std::tie(EVLLo, EVLHi) =
4723 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4725 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4726 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4727 VPSC->getIndexType());
4732 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4733 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4734 VPSC->getIndexType());
4738 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4739 assert(OpNo == 1 &&
"Can only split the stored value");
4742 bool isTruncating =
N->isTruncatingStore();
4745 EVT MemoryVT =
N->getMemoryVT();
4746 Align Alignment =
N->getBaseAlign();
4748 AAMDNodes AAInfo =
N->getAAInfo();
4750 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4752 EVT LoMemVT, HiMemVT;
4753 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4757 return TLI.scalarizeVectorStore(
N, DAG);
4760 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4761 Alignment, MMOFlags, AAInfo);
4763 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4766 MachinePointerInfo MPI;
4767 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4770 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4771 HiMemVT, Alignment, MMOFlags, AAInfo);
4773 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4780 LLVMContext &Ctx = *DAG.getContext();
4798 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4799 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4803 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4806 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4807 DAG.getBitcast(MemVecVT, Wide), 0);
4809 N->getBasePtr(),
N->getMemOperand());
4817 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4819 N->getBasePtr(),
N->getMemOperand());
4833 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4839 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4860 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4861 SDValue InVec =
N->getOperand(OpNo);
4863 EVT OutVT =
N->getValueType(0);
4871 EVT LoOutVT, HiOutVT;
4872 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4873 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4878 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4880 return SplitVecOp_UnaryOp(
N);
4889 return SplitVecOp_UnaryOp(
N);
4893 GetSplitVector(InVec, InLoVec, InHiVec);
4899 EVT HalfElementVT = IsFloat ?
4901 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4908 if (
N->isStrictFPOpcode()) {
4909 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4910 {N->getOperand(0), InLoVec});
4911 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4912 {N->getOperand(0), InHiVec});
4918 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4919 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4923 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4931 if (
N->isStrictFPOpcode()) {
4935 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4943 DAG.getTargetConstant(
4944 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4951 assert(
N->getValueType(0).isVector() &&
4952 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4953 "Operand types must be vectors");
4955 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4957 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4958 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4960 EVT VT =
N->getValueType(0);
4961 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4966 }
else if (isStrict) {
4967 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4968 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4969 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4970 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4973 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4975 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4976 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4977 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4978 std::tie(EVLLo, EVLHi) =
4979 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4980 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4981 N->getOperand(2), MaskLo, EVLLo);
4982 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4983 N->getOperand(2), MaskHi, EVLHi);
4991 EVT OpVT =
N->getOperand(0).getValueType();
4994 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5000 EVT ResVT =
N->getValueType(0);
5003 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5004 EVT InVT =
Lo.getValueType();
5009 if (
N->isStrictFPOpcode()) {
5010 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5011 {N->getOperand(0), Lo, N->getOperand(2)});
5012 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5013 {N->getOperand(0), Hi, N->getOperand(2)});
5017 Lo.getValue(1),
Hi.getValue(1));
5018 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5019 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
5020 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
5021 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
5022 std::tie(EVLLo, EVLHi) =
5023 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
5024 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
5025 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
5027 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5028 N->getOperand(2),
N->getOperand(3));
5029 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5030 N->getOperand(2),
N->getOperand(3));
5032 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5033 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5044SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5047 EVT LHSLoVT, LHSHiVT;
5048 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5050 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5051 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5054 std::tie(LHSLo, LHSHi) =
5055 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5058 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5061 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5067 LLVMContext &Ctxt = *DAG.getContext();
5070 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5071 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5072 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5074 EVT ResVT =
N->getValueType(0);
5079 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5080 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5086 EVT ResVT =
N->getValueType(0);
5089 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5090 EVT InVT =
Lo.getValueType();
5096 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5097 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5104 EVT ResVT =
N->getValueType(0);
5108 GetSplitVector(VecOp,
Lo,
Hi);
5114 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5116 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5118 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5119 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5124 EVT ResVT =
N->getValueType(0);
5128 GetSplitVector(VecOp,
Lo,
Hi);
5130 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5131 auto [EVLLo, EVLHi] =
5133 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5139 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5141 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5142 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5145SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5156 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5157 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5158 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5159 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5160 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5161 OpsLo, MMO, IndexType);
5162 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5163 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5167SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5170 "Accumulator should already be a legal type, and shouldn't need "
5171 "further splitting");
5174 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5175 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5176 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5177 unsigned Opcode =
N->getOpcode();
5180 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5181 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5188void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5189 unsigned WidenResNo) {
5190 unsigned NumResults =
N->getNumValues();
5191 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5192 if (ResNo == WidenResNo)
5194 EVT ResVT =
N->getValueType(ResNo);
5200 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5201 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5206void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5207 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5210 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5215 auto unrollExpandedOp = [&]() {
5220 EVT VT =
N->getValueType(0);
5221 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5222 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5223 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5225 if (
N->getNumValues() > 1)
5226 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5232 switch (
N->getOpcode()) {
5235 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5243 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5247 Res = WidenVecRes_ADDRSPACECAST(
N);
5254 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5261 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5265 Res = WidenVecRes_ScalarOp(
N);
5270 case ISD::VP_SELECT:
5272 Res = WidenVecRes_Select(
N);
5276 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5278 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5285 case ISD::VP_LOAD_FF:
5288 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5292 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5300 case ISD::VP_GATHER:
5304 Res = WidenVecRes_VECTOR_REVERSE(
N);
5307 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5310 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5320 case ISD::OR:
case ISD::VP_OR:
5333 case ISD::VP_FMINNUM:
5336 case ISD::VP_FMAXNUM:
5338 case ISD::VP_FMINIMUM:
5340 case ISD::VP_FMAXIMUM:
5373 case ISD::VP_FCOPYSIGN:
5374 Res = WidenVecRes_Binary(
N);
5381 Res = WidenVecRes_MaskedBinary(
N);
5386 Res = WidenVecRes_CMP(
N);
5392 if (unrollExpandedOp())
5407 Res = WidenVecRes_BinaryCanTrap(
N);
5416 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5419#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5420 case ISD::STRICT_##DAGN:
5421#include "llvm/IR/ConstrainedOps.def"
5422 Res = WidenVecRes_StrictFP(
N);
5431 Res = WidenVecRes_OverflowOp(
N, ResNo);
5435 Res = WidenVecRes_FCOPYSIGN(
N);
5440 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5445 if (!unrollExpandedOp())
5446 Res = WidenVecRes_ExpOp(
N);
5452 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5457 case ISD::VP_FP_EXTEND:
5459 case ISD::VP_FP_ROUND:
5461 case ISD::VP_FP_TO_SINT:
5463 case ISD::VP_FP_TO_UINT:
5465 case ISD::VP_SIGN_EXTEND:
5467 case ISD::VP_SINT_TO_FP:
5468 case ISD::VP_TRUNCATE:
5471 case ISD::VP_UINT_TO_FP:
5473 case ISD::VP_ZERO_EXTEND:
5476 Res = WidenVecRes_Convert(
N);
5481 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5487 case ISD::VP_LLRINT:
5490 Res = WidenVecRes_XROUND(
N);
5516 if (unrollExpandedOp())
5527 case ISD::VP_BITREVERSE:
5533 case ISD::VP_CTLZ_ZERO_POISON:
5539 case ISD::VP_CTTZ_ZERO_POISON:
5544 case ISD::VP_FFLOOR:
5546 case ISD::VP_FNEARBYINT:
5547 case ISD::VP_FROUND:
5548 case ISD::VP_FROUNDEVEN:
5549 case ISD::VP_FROUNDTOZERO:
5554 Res = WidenVecRes_Unary(
N);
5561 Res = WidenVecRes_Ternary(
N);
5567 if (!unrollExpandedOp())
5568 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5575 SetWidenedVector(
SDValue(
N, ResNo), Res);
5581 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5582 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5583 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5584 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5585 if (
N->getNumOperands() == 3)
5586 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5588 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5589 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5593 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5594 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5600 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5601 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5602 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5603 if (
N->getNumOperands() == 2)
5604 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5607 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5608 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5612 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5613 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5618 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5619 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5620 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5623 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5624 Mask = ModifyToType(Mask, WideMaskVT,
true);
5625 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5630 LLVMContext &Ctxt = *DAG.getContext();
5635 EVT OpVT =
LHS.getValueType();
5637 LHS = GetWidenedVector(
LHS);
5638 RHS = GetWidenedVector(
RHS);
5639 OpVT =
LHS.getValueType();
5642 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5645 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5651SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5654 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5655 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5656 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5658 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5667 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5670 if (ConcatEnd == 1) {
5671 VT = ConcatOps[0].getValueType();
5673 return ConcatOps[0];
5676 SDLoc dl(ConcatOps[0]);
5683 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5684 int Idx = ConcatEnd - 1;
5685 VT = ConcatOps[Idx--].getValueType();
5686 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5699 unsigned NumToInsert = ConcatEnd - Idx - 1;
5700 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5702 ConcatOps[Idx+1] = VecOp;
5703 ConcatEnd = Idx + 2;
5709 unsigned RealVals = ConcatEnd - Idx - 1;
5710 unsigned SubConcatEnd = 0;
5711 unsigned SubConcatIdx = Idx + 1;
5712 while (SubConcatEnd < RealVals)
5713 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5714 while (SubConcatEnd < OpsToConcat)
5715 SubConcatOps[SubConcatEnd++] = undefVec;
5717 NextVT, SubConcatOps);
5718 ConcatEnd = SubConcatIdx + 1;
5723 if (ConcatEnd == 1) {
5724 VT = ConcatOps[0].getValueType();
5726 return ConcatOps[0];
5731 if (
NumOps != ConcatEnd ) {
5733 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5734 ConcatOps[j] = UndefVal;
5742 unsigned Opcode =
N->getOpcode();
5744 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5748 const SDNodeFlags
Flags =
N->getFlags();
5749 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5750 NumElts = NumElts / 2;
5754 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5756 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5757 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5758 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5766 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5769 TLI.isTypeLegal(WideMaskVT)) {
5770 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5771 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5772 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5774 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5775 N->getValueType(0).getVectorElementCount());
5776 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5790 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5791 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5792 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5795 unsigned ConcatEnd = 0;
5803 while (CurNumElts != 0) {
5804 while (CurNumElts >= NumElts) {
5805 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5806 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5807 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5809 CurNumElts -= NumElts;
5812 NumElts = NumElts / 2;
5814 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5817 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5818 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5819 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5820 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5831 switch (
N->getOpcode()) {
5834 return WidenVecRes_STRICT_FSETCC(
N);
5841 return WidenVecRes_Convert_StrictFP(
N);
5848 unsigned Opcode =
N->getOpcode();
5850 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5854 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5855 NumElts = NumElts / 2;
5866 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5870 unsigned ConcatEnd = 0;
5877 for (
unsigned i = 1; i < NumOpers; ++i) {
5883 Oper = GetWidenedVector(Oper);
5889 DAG.getPOISON(WideOpVT), Oper,
5890 DAG.getVectorIdxConstant(0, dl));
5902 while (CurNumElts != 0) {
5903 while (CurNumElts >= NumElts) {
5906 for (
unsigned i = 0; i < NumOpers; ++i) {
5909 EVT OpVT =
Op.getValueType();
5914 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5920 EVT OperVT[] = {VT, MVT::Other};
5922 ConcatOps[ConcatEnd++] = Oper;
5925 CurNumElts -= NumElts;
5928 NumElts = NumElts / 2;
5930 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5933 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5936 for (
unsigned i = 0; i < NumOpers; ++i) {
5939 EVT OpVT =
Op.getValueType();
5947 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5949 ConcatOps[ConcatEnd++] = Oper;
5958 if (Chains.
size() == 1)
5959 NewChain = Chains[0];
5962 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5967SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5969 EVT ResVT =
N->getValueType(0);
5970 EVT OvVT =
N->getValueType(1);
5971 EVT WideResVT, WideOvVT;
5976 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5981 WideLHS = GetWidenedVector(
N->getOperand(0));
5982 WideRHS = GetWidenedVector(
N->getOperand(1));
5984 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5993 N->getOperand(0), Zero);
5995 N->getOperand(1), Zero);
5998 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5999 SDNode *WideNode = DAG.getNode(
6000 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6003 unsigned OtherNo = 1 - ResNo;
6004 EVT OtherVT =
N->getValueType(OtherNo);
6011 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
6014 return SDValue(WideNode, ResNo);
6018 LLVMContext &Ctx = *DAG.getContext();
6022 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6027 unsigned Opcode =
N->getOpcode();
6028 const SDNodeFlags
Flags =
N->getFlags();
6034 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6036 InOp = ZExtPromotedInteger(InOp);
6048 if (
N->getNumOperands() == 1)
6049 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6051 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6052 N->getOperand(3), Flags);
6053 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6057 InOp = GetWidenedVector(
N->getOperand(0));
6060 if (InVTEC == WidenEC) {
6061 if (
N->getNumOperands() == 3 &&
N->isVPOpcode()) {
6064 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
6066 return MakeConvertNode(WidenVT, InOp);
6092 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6096 if (TLI.isTypeLegal(InWidenVT)) {
6104 unsigned NumConcat =
6109 return MakeConvertNode(WidenVT, InVec);
6113 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6115 return MakeConvertNode(WidenVT, InVal);
6124 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6125 for (
unsigned i=0; i < MinElts; ++i) {
6126 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6127 Ops[i] = MakeConvertNode(EltVT, Val);
6130 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6135 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6139 EVT SrcVT = Src.getValueType();
6143 Src = GetWidenedVector(Src);
6144 SrcVT = Src.getValueType();
6151 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6156 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6160 EVT SrcVT = Src.getValueType();
6164 Src = GetWidenedVector(Src);
6165 SrcVT = Src.getValueType();
6172 if (
N->getNumOperands() == 1)
6173 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6175 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6176 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6180 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6183SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6188 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6194 unsigned Opcode =
N->getOpcode();
6200 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6205 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6206 for (
unsigned i=0; i < MinElts; ++i) {
6207 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6208 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6212 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6214 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6217SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6218 unsigned Opcode =
N->getOpcode();
6222 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6231 InOp = GetWidenedVector(InOp);
6238 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6245 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6246 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6263 while (
Ops.size() != WidenNumElts)
6264 Ops.push_back(DAG.getPOISON(WidenSVT));
6266 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6272 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6273 return WidenVecRes_BinaryCanTrap(
N);
6276 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6283SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6285 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6288 SDValue Arg = GetWidenedVector(FpValue);
6289 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6294 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6295 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6297 EVT ExpVT =
RHS.getValueType();
6302 ExpOp = ModifyToType(
RHS, WideExpVT);
6305 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6310 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6311 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6312 if (
N->getNumOperands() == 1)
6313 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6315 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6316 N->getOperand(1),
N->getFlags());
6318 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6319 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6323 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6324 {InOp,
Mask,
N->getOperand(2)});
6328 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6333 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6334 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6335 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6338SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6340 EVT VT0 =
N->getValueType(0);
6341 EVT VT1 =
N->getValueType(1);
6345 "expected both results to be vectors of matching element count");
6347 LLVMContext &Ctx = *DAG.getContext();
6348 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6350 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6357 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6360 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6361 return SDValue(WidenNode, ResNo);
6364SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6365 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6366 return GetWidenedVector(WidenVec);
6370 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6371 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6374 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6375 AddrSpaceCastN->getSrcAddressSpace(),
6376 AddrSpaceCastN->getDestAddressSpace());
6382 EVT VT =
N->getValueType(0);
6383 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6386 switch (getTypeAction(InVT)) {
6400 SDValue NInOp = GetPromotedInteger(InOp);
6402 if (WidenVT.
bitsEq(NInVT)) {
6405 if (DAG.getDataLayout().isBigEndian()) {
6408 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6426 InOp = GetWidenedVector(InOp);
6428 if (WidenVT.
bitsEq(InVT))
6438 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6443 unsigned NewNumParts = WidenSize / InSize;
6456 EVT OrigInVT =
N->getOperand(0).getValueType();
6461 if (TLI.isTypeLegal(NewInVT)) {
6469 if (WidenSize % InSize == 0) {
6476 DAG.ExtractVectorElements(InOp,
Ops);
6477 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6489 return CreateStackStoreLoad(InOp, WidenVT);
6492SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6494 N->getOpcode(), SDLoc(
N),
6495 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6496 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6502 EVT VT =
N->getValueType(0);
6506 EVT EltVT =
N->getOperand(0).getValueType();
6509 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6513 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6514 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6516 return DAG.getBuildVector(WidenVT, dl, NewOps);
6520 EVT InVT =
N->getOperand(0).getValueType();
6521 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6523 unsigned NumOperands =
N->getNumOperands();
6525 bool InputWidened =
false;
6529 if (WidenNumElts % NumInElts == 0) {
6531 unsigned NumConcat = WidenNumElts / NumInElts;
6532 SDValue UndefVal = DAG.getPOISON(InVT);
6534 for (
unsigned i=0; i < NumOperands; ++i)
6535 Ops[i] =
N->getOperand(i);
6536 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6541 InputWidened =
true;
6542 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6545 for (i=1; i < NumOperands; ++i)
6546 if (!
N->getOperand(i).isUndef())
6549 if (i == NumOperands)
6552 return GetWidenedVector(
N->getOperand(0));
6554 if (NumOperands == 2) {
6556 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6561 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6562 for (
unsigned i = 0; i < NumInElts; ++i) {
6564 MaskOps[i + NumInElts] = i + WidenNumElts;
6566 return DAG.getVectorShuffle(WidenVT, dl,
6567 GetWidenedVector(
N->getOperand(0)),
6568 GetWidenedVector(
N->getOperand(1)),
6575 "Cannot use build vectors to widen CONCAT_VECTOR result");
6583 for (
unsigned i=0; i < NumOperands; ++i) {
6586 InOp = GetWidenedVector(InOp);
6587 for (
unsigned j = 0;
j < NumInElts; ++
j)
6588 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6590 SDValue UndefVal = DAG.getPOISON(EltVT);
6591 for (; Idx < WidenNumElts; ++Idx)
6592 Ops[Idx] = UndefVal;
6593 return DAG.getBuildVector(WidenVT, dl,
Ops);
6596SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6597 EVT VT =
N->getValueType(0);
6598 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6599 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6606SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6607 EVT VT =
N->getValueType(0);
6609 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6614 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6616 InOp = GetWidenedVector(InOp);
6622 if (IdxVal == 0 && InVT == WidenVT)
6629 assert(IdxVal % VTNumElts == 0 &&
6630 "Expected Idx to be a multiple of subvector minimum vector length");
6631 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6644 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6645 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6646 "down type's element count");
6653 for (;
I < VTNumElts / GCD; ++
I)
6655 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6656 for (;
I < WidenNumElts / GCD; ++
I)
6664 Align Alignment = DAG.getReducedAlign(InVT,
false);
6666 MachineFunction &MF = DAG.getMachineFunction();
6678 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6685 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6686 return DAG.getMaskedLoad(
6687 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6695 for (i = 0; i < VTNumElts; ++i)
6696 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6698 SDValue UndefVal = DAG.getPOISON(EltVT);
6699 for (; i < WidenNumElts; ++i)
6701 return DAG.getBuildVector(WidenVT, dl,
Ops);
6707 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6712SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6713 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6716 N->getOperand(1),
N->getOperand(2));
6725 "Load width must be less than or equal to first value type width");
6734 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6751 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6762 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6763 EVT LdVT =
LD->getMemoryVT();
6772 TypeSize WidthDiff = WidenWidth - LdWidth;
6775 std::optional<EVT> FirstVT =
6776 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6783 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6786 Chain, BasePtr,
LD->getMemOperand());
6790 FirstVTWidth, dl, DAG);
6808 if (!
LD->getMemoryVT().isByteSized()) {
6810 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6812 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6821 EVT VT =
LD->getValueType(0);
6822 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6823 EVT WideMaskVT = getSetCCResultType(WideVT);
6826 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6827 TLI.isTypeLegal(WideMaskVT)) {
6830 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6834 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6835 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6847 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6849 Result = GenWidenVectorLoads(LdChain, LD);
6856 if (LdChain.
size() == 1)
6857 NewChain = LdChain[0];
6863 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6874 SDValue NewLoad = DAG.getMaskedLoad(
6875 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6876 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6877 LD->getAddressingMode(),
LD->getExtensionType());
6887 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6889 SDValue EVL =
N->getVectorLength();
6896 "Unable to widen binary VP op");
6897 Mask = GetWidenedVector(Mask);
6898 assert(
Mask.getValueType().getVectorElementCount() ==
6899 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6900 .getVectorElementCount() &&
6901 "Unable to widen vector load");
6904 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6905 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6906 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6914 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6916 SDValue EVL =
N->getVectorLength();
6922 "Unable to widen binary VP op");
6923 Mask = GetWidenedVector(Mask);
6924 assert(
Mask.getValueType().getVectorElementCount() ==
6925 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6926 .getVectorElementCount() &&
6927 "Unable to widen vector load");
6929 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6930 Mask, EVL,
N->getMemOperand());
6943 "Unable to widen VP strided load");
6944 Mask = GetWidenedVector(Mask);
6946 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6947 assert(
Mask.getValueType().getVectorElementCount() ==
6949 "Data and mask vectors should have the same number of elements");
6951 SDValue Res = DAG.getStridedLoadVP(
6952 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6953 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6954 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6955 N->isExpandingLoad());
6963SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6968 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6970 Mask.getValueType().getVectorElementType(),
6973 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6974 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6975 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6977 WideMask, WidePassthru);
6981 EVT VT =
N->getValueType(0);
6982 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6984 EVT MaskVT =
Mask.getValueType();
6985 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6994 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6995 TLI.isTypeLegal(WideMaskVT) &&
7001 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7002 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7006 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7007 N->getMemoryVT(),
N->getMemOperand());
7011 if (!
N->getPassThru()->isUndef()) {
7015 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7016 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7017 DAG.getPOISON(WidenVT), EVL);
7028 Mask = ModifyToType(Mask, WideMaskVT,
true);
7030 SDValue Res = DAG.getMaskedLoad(
7031 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7032 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7033 ExtType,
N->isExpandingLoad());
7042 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7044 EVT MaskVT =
Mask.getValueType();
7045 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7053 Mask = ModifyToType(Mask, WideMaskVT,
true);
7058 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7059 Index = ModifyToType(Index, WideIndexVT);
7065 N->getMemoryVT().getScalarType(), WideEC);
7066 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7067 WideMemVT, dl,
Ops,
N->getMemOperand(),
7068 N->getIndexType(),
N->getExtensionType());
7077 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7085 N->getMemoryVT().getScalarType(), WideEC);
7086 Mask = GetWidenedMask(Mask, WideEC);
7089 Mask,
N->getVectorLength()};
7090 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7091 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7100 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7101 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7129 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7130 return N->getOperand(OpNo).getValueType();
7138 N =
N.getOperand(0);
7140 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7141 if (!
N->getOperand(i)->isUndef())
7143 N =
N.getOperand(0);
7147 N =
N.getOperand(0);
7149 N =
N.getOperand(0);
7176 { MaskVT, MVT::Other },
Ops);
7177 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7185 LLVMContext &Ctx = *DAG.getContext();
7188 if (MaskScalarBits < ToMaskScalBits) {
7192 }
else if (MaskScalarBits > ToMaskScalBits) {
7198 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7200 "Mask should have the right element size by now.");
7203 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7205 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7208 EVT SubVT =
Mask->getValueType(0);
7214 assert((
Mask->getValueType(0) == ToMaskVT) &&
7215 "A mask of ToMaskVT should have been produced by now.");
7225 LLVMContext &Ctx = *DAG.getContext();
7236 EVT CondVT =
Cond->getValueType(0);
7240 EVT VSelVT =
N->getValueType(0);
7252 EVT FinalVT = VSelVT;
7263 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7264 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7271 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7279 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7282 EVT ToMaskVT = VSelVT;
7289 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7305 if (ScalarBits0 != ScalarBits1) {
7306 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7307 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7319 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7320 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7321 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7324 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7332 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7337 unsigned Opcode =
N->getOpcode();
7339 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7340 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7341 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7343 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7349 Cond1 = GetWidenedVector(Cond1);
7357 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7358 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7363 Cond1 = ModifyToType(Cond1, CondWidenVT);
7366 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7367 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7369 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7370 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7372 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7376 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7377 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7380 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7384 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7385 return DAG.getUNDEF(WidenVT);
7389 EVT VT =
N->getValueType(0);
7392 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7396 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7397 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7400 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7401 for (
unsigned i = 0; i != NumElts; ++i) {
7402 int Idx =
N->getMaskElt(i);
7403 if (Idx < (
int)NumElts)
7406 NewMask[i] = Idx - NumElts + WidenNumElts;
7408 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7412 EVT VT =
N->getValueType(0);
7416 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7417 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7423 unsigned IdxVal = WidenNumElts - VTNumElts;
7436 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7439 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7440 "down type's element count");
7443 for (; i < VTNumElts / GCD; ++i)
7445 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7446 for (; i < WidenNumElts / GCD; ++i)
7454 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7455 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7457 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7461SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7462 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7466void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7467 EVT VT =
N->getValueType(0);
7470 unsigned Factor =
N->getNumOperands();
7473 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7486 SDValue PackedWidenVec = DAG.getInsertSubvector(
7487 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7491 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7492 NewOps[Idx] = DAG.getExtractSubvector(
7493 DL, WidenVT, PackedWidenVec,
7500 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7505 assert(
N->getValueType(0).isVector() &&
7506 N->getOperand(0).getValueType().isVector() &&
7507 "Operands must be vectors");
7508 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7521 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7522 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7529 InOp1 = GetWidenedVector(InOp1);
7530 InOp2 = GetWidenedVector(InOp2);
7533 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7544 "Input not widened to expected type!");
7546 if (
N->getOpcode() == ISD::VP_SETCC) {
7549 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7550 N->getOperand(2), Mask,
N->getOperand(4));
7552 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7557 assert(
N->getValueType(0).isVector() &&
7558 N->getOperand(1).getValueType().isVector() &&
7559 "Operands must be vectors");
7560 EVT VT =
N->getValueType(0);
7561 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7571 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7576 for (
unsigned i = 0; i != NumElts; ++i) {
7577 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7578 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7580 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7581 {Chain, LHSElem, RHSElem, CC});
7582 Chains[i] = Scalars[i].getValue(1);
7583 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7584 DAG.getBoolConstant(
true, dl, EltVT, VT),
7585 DAG.getBoolConstant(
false, dl, EltVT, VT));
7589 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7591 return DAG.getBuildVector(WidenVT, dl, Scalars);
7597bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7598 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7602 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7605 switch (
N->getOpcode()) {
7608 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7616 Res = WidenVecOp_FAKE_USE(
N);
7622 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7626 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7627 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7628 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7633 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7635 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7636 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7638 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7639 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7649 Res = WidenVecOp_UnrollVectorOp(
N);
7656 Res = WidenVecOp_EXTEND(
N);
7661 Res = WidenVecOp_CMP(
N);
7679 Res = WidenVecOp_Convert(
N);
7684 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7702 Res = WidenVecOp_VECREDUCE(
N);
7706 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7708 case ISD::VP_REDUCE_FADD:
7709 case ISD::VP_REDUCE_SEQ_FADD:
7710 case ISD::VP_REDUCE_FMUL:
7711 case ISD::VP_REDUCE_SEQ_FMUL:
7712 case ISD::VP_REDUCE_ADD:
7713 case ISD::VP_REDUCE_MUL:
7714 case ISD::VP_REDUCE_AND:
7715 case ISD::VP_REDUCE_OR:
7716 case ISD::VP_REDUCE_XOR:
7717 case ISD::VP_REDUCE_SMAX:
7718 case ISD::VP_REDUCE_SMIN:
7719 case ISD::VP_REDUCE_UMAX:
7720 case ISD::VP_REDUCE_UMIN:
7721 case ISD::VP_REDUCE_FMAX:
7722 case ISD::VP_REDUCE_FMIN:
7723 case ISD::VP_REDUCE_FMAXIMUM:
7724 case ISD::VP_REDUCE_FMINIMUM:
7725 Res = WidenVecOp_VP_REDUCE(
N);
7729 Res = WidenVecOp_CttzElements(
N);
7731 case ISD::VP_CTTZ_ELTS:
7732 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7733 Res = WidenVecOp_VP_CttzElements(
N);
7736 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7741 if (!Res.
getNode())
return false;
7749 if (
N->isStrictFPOpcode())
7751 "Invalid operand expansion");
7754 "Invalid operand expansion");
7756 ReplaceValueWith(
SDValue(
N, 0), Res);
7762 EVT VT =
N->getValueType(0);
7767 "Unexpected type action");
7768 InOp = GetWidenedVector(InOp);
7771 "Input wasn't widened!");
7779 EVT FixedEltVT = FixedVT.getVectorElementType();
7780 if (TLI.isTypeLegal(FixedVT) &&
7782 FixedEltVT == InEltVT) {
7784 "Not enough elements in the fixed type for the operand!");
7786 "We can't have the same type as we started with!");
7788 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7790 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7799 return WidenVecOp_Convert(
N);
7804 switch (
N->getOpcode()) {
7819 EVT OpVT =
N->getOperand(0).getValueType();
7820 EVT ResVT =
N->getValueType(0);
7827 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7828 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7834 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7835 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7837 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7844 return DAG.UnrollVectorOp(
N);
7849 EVT ResultVT =
N->getValueType(0);
7851 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7854 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7860 {WideArg,
Test},
N->getFlags());
7866 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7868 EVT OpVT =
N->getOperand(0).getValueType();
7871 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7876 EVT VT =
N->getValueType(0);
7882 "Unexpected type action");
7883 InOp = GetWidenedVector(InOp);
7885 unsigned Opcode =
N->getOpcode();
7890 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7893 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7894 return DAG.getNode(Opcode, dl, VT,
Op);
7901 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7903 if (
N->isStrictFPOpcode()) {
7905 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7908 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7909 {
N->getOperand(0), InOp });
7914 Res = MakeConvertNode(WideVT, InOp);
7916 return DAG.getExtractSubvector(dl, VT, Res, 0);
7924 if (
N->isStrictFPOpcode()) {
7927 for (
unsigned i=0; i < NumElts; ++i) {
7928 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7929 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7933 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7935 for (
unsigned i = 0; i < NumElts; ++i) {
7936 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7937 Ops[i] = MakeConvertNode(EltVT, Elt);
7941 return DAG.getBuildVector(VT, dl,
Ops);
7945 EVT DstVT =
N->getValueType(0);
7946 SDValue Src = GetWidenedVector(
N->getOperand(0));
7947 EVT SrcVT = Src.getValueType();
7954 if (TLI.isTypeLegal(WideDstVT)) {
7956 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7959 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7963 return DAG.UnrollVectorOp(
N);
7967 EVT VT =
N->getValueType(0);
7968 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7976 if (!VT.
isVector() && VT != MVT::x86mmx &&
7980 if (TLI.isTypeLegal(NewVT)) {
7982 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7994 ElementCount NewNumElts =
7996 .divideCoefficientBy(EltSize);
7998 if (TLI.isTypeLegal(NewVT)) {
8000 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8005 return CreateStackStoreLoad(InOp, VT);
8013 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8014 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8019 EVT VT =
N->getValueType(0);
8021 EVT InVT =
N->getOperand(0).getValueType();
8026 unsigned NumOperands =
N->getNumOperands();
8027 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8029 for (i = 1; i < NumOperands; ++i)
8030 if (!
N->getOperand(i).isUndef())
8033 if (i == NumOperands)
8034 return GetWidenedVector(
N->getOperand(0));
8044 for (
unsigned i=0; i < NumOperands; ++i) {
8048 "Unexpected type action");
8049 InOp = GetWidenedVector(InOp);
8050 for (
unsigned j = 0;
j < NumInElts; ++
j)
8051 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8053 return DAG.getBuildVector(VT, dl,
Ops);
8056SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8057 EVT VT =
N->getValueType(0);
8062 SubVec = GetWidenedVector(SubVec);
8067 bool IndicesValid =
false;
8070 IndicesValid =
true;
8074 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8075 Attribute::VScaleRange);
8080 IndicesValid =
true;
8086 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8092 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8099 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8106 Align Alignment = DAG.getReducedAlign(VT,
false);
8108 MachineFunction &MF = DAG.getMachineFunction();
8121 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8129 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8130 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8135 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8140 unsigned Idx =
N->getConstantOperandVal(2);
8146 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8152SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8153 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8155 N->getValueType(0), InOp,
N->getOperand(1));
8158SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8159 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8161 N->getValueType(0), InOp,
N->getOperand(1));
8164SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8166 EVT ResVT =
N->getValueType(0);
8169 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8175 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8183 "Widened input size must be a multiple of result element size");
8186 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8188 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8189 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8197 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8198 return TLI.scalarizeVectorStore(ST, DAG);
8200 if (
ST->isTruncatingStore())
8201 return TLI.scalarizeVectorStore(ST, DAG);
8211 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8212 EVT WideMaskVT = getSetCCResultType(WideVT);
8214 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8215 TLI.isTypeLegal(WideMaskVT)) {
8218 StVal = GetWidenedVector(StVal);
8220 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8222 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8223 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8224 ST->getAddressingMode());
8228 if (GenWidenVectorStores(StChain, ST)) {
8229 if (StChain.
size() == 1)
8238 SDValue WideStVal = GetWidenedVector(StVal);
8242 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8243 ST->getOffset(), Mask,
ST->getMemoryVT(),
8244 ST->getMemOperand(),
ST->getAddressingMode(),
8245 ST->isTruncatingStore());
8252 EVT StVT =
ST->getMemoryVT();
8255 SDValue StVal = GetWidenedVector(
ST->getVal());
8260 TypeSize WidthDiff = WidenWidth - StWidth;
8266 std::optional<EVT> FirstVT =
8267 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8272 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8278 ST->getBasePtr(),
ST->getMemOperand());
8281SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8282 assert((OpNo == 1 || OpNo == 3) &&
8283 "Can widen only data or mask operand of vp_store");
8291 StVal = GetWidenedVector(StVal);
8297 "Unable to widen VP store");
8298 Mask = GetWidenedVector(Mask);
8300 Mask = GetWidenedVector(Mask);
8306 "Unable to widen VP store");
8307 StVal = GetWidenedVector(StVal);
8310 assert(
Mask.getValueType().getVectorElementCount() ==
8312 "Mask and data vectors should have the same number of elements");
8313 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8314 ST->getOffset(), Mask,
ST->getVectorLength(),
8315 ST->getMemoryVT(),
ST->getMemOperand(),
8316 ST->getAddressingMode(),
ST->isTruncatingStore(),
8317 ST->isCompressingStore());
8322 assert((OpNo == 1 || OpNo == 4) &&
8323 "Can widen only data or mask operand of vp_strided_store");
8332 "Unable to widen VP strided store");
8336 "Unable to widen VP strided store");
8338 StVal = GetWidenedVector(StVal);
8339 Mask = GetWidenedVector(Mask);
8342 Mask.getValueType().getVectorElementCount() &&
8343 "Data and mask vectors should have the same number of elements");
8345 return DAG.getStridedStoreVP(
8352SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8353 assert((OpNo == 1 || OpNo == 4) &&
8354 "Can widen only data or mask operand of mstore");
8357 EVT MaskVT =
Mask.getValueType();
8362 EVT WideVT, WideMaskVT;
8365 StVal = GetWidenedVector(StVal);
8372 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8379 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8381 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8382 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8391 Mask = ModifyToType(Mask, WideMaskVT,
true);
8394 Mask = ModifyToType(Mask, WideMaskVT,
true);
8396 StVal = ModifyToType(StVal, WideVT);
8399 assert(
Mask.getValueType().getVectorElementCount() ==
8401 "Mask and data vectors should have the same number of elements");
8408SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8409 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8411 SDValue DataOp = MG->getPassThru();
8413 SDValue Scale = MG->getScale();
8421 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8422 MG->getMemOperand(), MG->getIndexType(),
8423 MG->getExtensionType());
8429SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8438 DataOp = GetWidenedVector(DataOp);
8442 EVT IndexVT =
Index.getValueType();
8445 Index = ModifyToType(Index, WideIndexVT);
8448 EVT MaskVT =
Mask.getValueType();
8451 Mask = ModifyToType(Mask, WideMaskVT,
true);
8456 }
else if (OpNo == 4) {
8458 Index = GetWidenedVector(Index);
8464 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8469SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8478 DataOp = GetWidenedVector(DataOp);
8479 Index = GetWidenedVector(Index);
8481 Mask = GetWidenedMask(Mask, WideEC);
8484 }
else if (OpNo == 3) {
8486 Index = GetWidenedVector(Index);
8493 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8498 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8499 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8501 EVT VT =
N->getValueType(0);
8516 SVT, InOp0, InOp1,
N->getOperand(2));
8522 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8524 EVT OpVT =
N->getOperand(0).getValueType();
8527 return DAG.getNode(ExtendCode, dl, VT, CC);
8537 EVT VT =
N->getValueType(0);
8539 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8546 for (
unsigned i = 0; i != NumElts; ++i) {
8547 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8548 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8550 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8551 {Chain, LHSElem, RHSElem, CC});
8552 Chains[i] = Scalars[i].getValue(1);
8553 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8554 DAG.getBoolConstant(
true, dl, EltVT, VT),
8555 DAG.getBoolConstant(
false, dl, EltVT, VT));
8559 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8561 return DAG.getBuildVector(VT, dl, Scalars);
8585 SDValue Op = GetWidenedVector(
N->getOperand(0));
8586 EVT VT =
N->getValueType(0);
8587 EVT OrigVT =
N->getOperand(0).getValueType();
8588 EVT WideVT =
Op.getValueType();
8590 SDNodeFlags
Flags =
N->getFlags();
8592 unsigned Opc =
N->getOpcode();
8594 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8595 assert(NeutralElem &&
"Neutral element must exist");
8605 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8612 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8613 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8619 unsigned GCD = std::gcd(OrigElts, WideElts);
8622 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8623 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8624 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8625 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8628 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8629 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8631 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8640 EVT VT =
N->getValueType(0);
8642 EVT WideVT =
Op.getValueType();
8644 SDNodeFlags
Flags =
N->getFlags();
8646 unsigned Opc =
N->getOpcode();
8648 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8658 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8661 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8662 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8668 unsigned GCD = std::gcd(OrigElts, WideElts);
8671 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8672 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8673 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8674 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8677 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8678 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8680 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8684 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8687 SDValue Op = GetWidenedVector(
N->getOperand(1));
8689 Op.getValueType().getVectorElementCount());
8691 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8692 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8700 EVT VT =
N->getValueType(0);
8704 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8705 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8710 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8717 TLI.getTypeToTransformTo(*DAG.getContext(),
Source.getValueType());
8721 WideSource = GetWidenedVector(Source);
8726 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8729 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8736 EVT SrcVT =
Source.getValueType();
8740 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8741 {Source, Mask, N->getOperand(2)},
N->getFlags());
8744SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8747 EVT OrigMaskVT =
Mask.getValueType();
8748 SDValue WideMask = GetWidenedVector(Mask);
8754 if (OrigElts != WideElts) {
8755 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8757 Mask, DAG.getVectorIdxConstant(0,
DL));
8778 unsigned WidenEx = 0) {
8783 unsigned AlignInBits =
Align*8;
8785 EVT RetVT = WidenEltVT;
8790 if (Width == WidenEltWidth)
8801 (WidenWidth % MemVTWidth) == 0 &&
8803 (MemVTWidth <= Width ||
8804 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8805 if (MemVTWidth == WidenWidth)
8824 (WidenWidth % MemVTWidth) == 0 &&
8826 (MemVTWidth <= Width ||
8827 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8836 return std::nullopt;
8847 unsigned Start,
unsigned End) {
8848 SDLoc dl(LdOps[Start]);
8849 EVT LdTy = LdOps[Start].getValueType();
8857 for (
unsigned i = Start + 1; i != End; ++i) {
8858 EVT NewLdTy = LdOps[i].getValueType();
8859 if (NewLdTy != LdTy) {
8878 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8879 EVT LdVT =
LD->getMemoryVT();
8889 AAMDNodes AAInfo =
LD->getAAInfo();
8893 TypeSize WidthDiff = WidenWidth - LdWidth;
8900 std::optional<EVT> FirstVT =
8901 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8908 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8913 std::optional<EVT> NewVT = FirstVT;
8914 TypeSize RemainingWidth = LdWidth;
8915 TypeSize NewVTWidth = FirstVTWidth;
8917 RemainingWidth -= NewVTWidth;
8924 NewVTWidth = NewVT->getSizeInBits();
8930 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8931 LD->getBaseAlign(), MMOFlags, AAInfo);
8943 uint64_t ScaledOffset = 0;
8944 MachinePointerInfo MPI =
LD->getPointerInfo();
8950 for (EVT MemVT : MemVTs) {
8951 Align NewAlign = ScaledOffset == 0
8952 ?
LD->getBaseAlign()
8955 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8963 unsigned End = LdOps.
size();
8974 EVT LdTy = LdOps[i].getValueType();
8977 for (--i; i >= 0; --i) {
8978 LdTy = LdOps[i].getValueType();
8985 ConcatOps[--Idx] = LdOps[i];
8986 for (--i; i >= 0; --i) {
8987 EVT NewLdTy = LdOps[i].getValueType();
8988 if (NewLdTy != LdTy) {
8998 for (;
j != End-Idx; ++
j)
8999 WidenOps[j] = ConcatOps[Idx+j];
9001 WidenOps[j] = DAG.getPOISON(LdTy);
9008 ConcatOps[--Idx] = LdOps[i];
9013 ArrayRef(&ConcatOps[Idx], End - Idx));
9019 SDValue UndefVal = DAG.getPOISON(LdTy);
9022 for (; i != End-Idx; ++i)
9023 WidenOps[i] = ConcatOps[Idx+i];
9025 WidenOps[i] = UndefVal;
9036 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9037 EVT LdVT =
LD->getMemoryVT();
9046 AAMDNodes AAInfo =
LD->getAAInfo();
9060 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9061 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9067 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9068 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9069 LD->getBaseAlign(), MMOFlags, AAInfo);
9074 SDValue UndefVal = DAG.getPOISON(EltVT);
9075 for (; i != WidenNumElts; ++i)
9078 return DAG.getBuildVector(WidenVT, dl,
Ops);
9089 AAMDNodes AAInfo =
ST->getAAInfo();
9090 SDValue ValOp = GetWidenedVector(
ST->getValue());
9093 EVT StVT =
ST->getMemoryVT();
9101 "Mismatch between store and value types");
9105 MachinePointerInfo MPI =
ST->getPointerInfo();
9106 uint64_t ScaledOffset = 0;
9115 std::optional<EVT> NewVT =
9120 TypeSize NewVTWidth = NewVT->getSizeInBits();
9123 StWidth -= NewVTWidth;
9124 MemVTs.
back().second++;
9128 for (
const auto &Pair : MemVTs) {
9129 EVT NewVT = Pair.first;
9130 unsigned Count = Pair.second;
9136 Align NewAlign = ScaledOffset == 0
9137 ?
ST->getBaseAlign()
9139 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9140 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9156 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9157 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9158 ST->getBaseAlign(), MMOFlags, AAInfo);
9175 bool FillWithZeroes) {
9180 "input and widen element type must match");
9182 "cannot modify scalable vectors in this way");
9195 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9197 for (
unsigned i = 1; i != NumConcat; ++i)
9204 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9207 "Scalable vectors should have been handled already.");
9215 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9217 for (Idx = 0; Idx < MinNumElts; ++Idx)
9218 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9220 SDValue UndefVal = DAG.getPOISON(EltVT);
9221 for (; Idx < WidenNumElts; ++Idx)
9222 Ops[Idx] = UndefVal;
9224 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9225 if (!FillWithZeroes)
9229 "We expect to never want to FillWithZeroes for non-integral types.");
9232 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9233 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9235 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9236 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.