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);
89 R = ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
N);
95 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
97 R = ScalarizeVecRes_VECTOR_MATCH(
N);
100 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
106 R = ScalarizeVecRes_VecInregOp(
N);
158 R = ScalarizeVecRes_UnaryOp(
N);
161 R = ScalarizeVecRes_ADDRSPACECAST(
N);
167 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
226 R = ScalarizeVecRes_BinOp(
N);
233 R = ScalarizeVecRes_MaskedBinOp(
N);
238 R = ScalarizeVecRes_CMP(
N);
244 R = ScalarizeVecRes_TernaryOp(
N);
247#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
248 case ISD::STRICT_##DAGN:
249#include "llvm/IR/ConstrainedOps.def"
250 R = ScalarizeVecRes_StrictFPOp(
N);
255 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
264 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
274 R = ScalarizeVecRes_FIX(
N);
280 SetScalarizedVector(
SDValue(
N, ResNo), R);
284 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
285 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
286 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
292 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
293 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
295 EVT MaskVT =
Mask.getValueType();
300 Mask = GetScalarizedVector(Mask);
309 DAG.getConstant(1,
DL,
LHS.getValueType()));
311 LHS.getValueType(),
LHS, Divisor);
319 if (getTypeAction(
LHS.getValueType()) ==
321 LHS = GetScalarizedVector(
LHS);
322 RHS = GetScalarizedVector(
RHS);
324 EVT VT =
LHS.getValueType().getVectorElementType();
325 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
326 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
329 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
330 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
334 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
335 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
336 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
337 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
342 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
343 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
350DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
352 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
353 "Unexpected vector type!");
354 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
356 EVT VT0 =
N->getValueType(0);
357 EVT VT1 =
N->getValueType(1);
361 DAG.getNode(
N->getOpcode(), dl,
362 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
366 unsigned OtherNo = 1 - ResNo;
367 EVT OtherVT =
N->getValueType(OtherNo);
369 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
373 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
376 return SDValue(ScalarNode, ResNo);
381 unsigned NumOpers =
N->getNumOperands();
383 EVT ValueVTs[] = {VT, MVT::Other};
392 for (
unsigned i = 1; i < NumOpers; ++i) {
398 Oper = GetScalarizedVector(Oper);
407 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
408 Opers,
N->getFlags());
419 EVT ResVT =
N->getValueType(0);
420 EVT OvVT =
N->getValueType(1);
424 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
425 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
428 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
429 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
430 ScalarLHS = ElemsLHS[0];
431 ScalarRHS = ElemsRHS[0];
434 SDVTList ScalarVTs = DAG.getVTList(
436 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
437 {ScalarLHS, ScalarRHS},
N->getFlags())
441 unsigned OtherNo = 1 - ResNo;
442 EVT OtherVT =
N->getValueType(OtherNo);
444 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
448 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
451 return SDValue(ScalarNode, ResNo);
456 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
457 return GetScalarizedVector(
Op);
460SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
465 N->getValueType(0).getScalarType(), Mask,
466 DAG.getVectorIdxConstant(0,
DL));
472 Op = GetScalarizedVector(
Op);
473 EVT NewVT =
N->getValueType(0).getVectorElementType();
478SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
488SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
490 N->getValueType(0).getVectorElementType(),
491 N->getOperand(0),
N->getOperand(1));
497 EVT OpVT =
Op.getValueType();
501 Op = GetScalarizedVector(
Op);
504 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
507 N->getValueType(0).getVectorElementType(),
Op,
511SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
514 EVT OpVT =
Op.getValueType();
518 Op = GetScalarizedVector(
Op);
521 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
524 N->getValueType(0).getVectorElementType(),
Op,
528SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
531 EVT OpVT =
Op.getValueType();
534 Op = GetScalarizedVector(
Op);
537 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
540 N->getValueType(0).getVectorElementType(),
Op,
541 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
544SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
545 SDValue Op = GetScalarizedVector(
N->getOperand(0));
546 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
550SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
555 if (
Op.getValueType() != EltVT)
563 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
564 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
574 assert(
N->isUnindexed() &&
"Indexed vector load?");
578 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
579 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
580 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
581 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
593 EVT OpVT =
Op.getValueType();
603 Op = GetScalarizedVector(
Op);
606 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
608 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
614 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
615 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
616 LHS, DAG.getValueType(ExtVT));
623 EVT OpVT =
Op.getValueType();
628 Op = GetScalarizedVector(
Op);
630 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
633 switch (
N->getOpcode()) {
645SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
648 EVT OpVT =
Op.getValueType();
658 Op = GetScalarizedVector(
Op);
661 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
664 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
665 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
666 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
669SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
680DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
681 assert(
N->getNumValues() ==
N->getNumOperands() &&
682 "Expected one result per operand");
686 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
687 SetScalarizedVector(
SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
693 EVT OpVT =
Cond.getValueType();
702 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
705 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
707 TLI.getBooleanContents(
false,
false);
714 if (TLI.getBooleanContents(
false,
false) !=
715 TLI.getBooleanContents(
false,
true)) {
719 EVT OpVT =
Cond->getOperand(0).getValueType();
721 VecBool = TLI.getBooleanContents(OpVT);
726 EVT CondVT =
Cond.getValueType();
727 if (ScalarBool != VecBool) {
728 switch (ScalarBool) {
736 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
743 Cond, DAG.getValueType(MVT::i1));
749 auto BoolVT = getSetCCResultType(CondVT);
750 if (BoolVT.bitsLT(CondVT))
753 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
754 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
758 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
759 return DAG.getSelect(SDLoc(
N),
760 LHS.getValueType(),
N->getOperand(0),
LHS,
761 GetScalarizedVector(
N->getOperand(2)));
765 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
767 N->getOperand(0),
N->getOperand(1),
768 LHS, GetScalarizedVector(
N->getOperand(3)),
773 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
776SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
780 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
782 return GetScalarizedVector(
N->getOperand(
Op));
785SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
787 EVT SrcVT = Src.getValueType();
792 Src = GetScalarizedVector(Src);
796 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
798 EVT DstVT =
N->getValueType(0).getVectorElementType();
799 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
803 assert(
N->getValueType(0).isVector() &&
804 N->getOperand(0).getValueType().isVector() &&
805 "Operand types must be vectors");
808 EVT OpVT =
LHS.getValueType();
809 EVT NVT =
N->getValueType(0).getVectorElementType();
814 LHS = GetScalarizedVector(
LHS);
815 RHS = GetScalarizedVector(
RHS);
818 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
819 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
829 return DAG.getNode(ExtendCode,
DL, NVT, Res);
840 Arg = GetScalarizedVector(Arg);
843 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
852 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
859bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
865 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
868 switch (
N->getOpcode()) {
871 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
878 Res = ScalarizeVecOp_BITCAST(
N);
881 Res = ScalarizeVecOp_FAKE_USE(
N);
895 Res = ScalarizeVecOp_UnaryOp(
N);
900 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
903 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
904 "Unexpected vector type!");
905 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
907 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
908 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
916 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
919 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
922 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
925 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
928 Res = ScalarizeVecOp_VSELECT(
N);
931 Res = ScalarizeVecOp_VSETCC(
N);
935 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
944 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
947 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
950 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
953 Res = ScalarizeVecOp_FP_EXTEND(
N);
970 Res = ScalarizeVecOp_VECREDUCE(
N);
974 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
978 Res = ScalarizeVecOp_CMP(
N);
981 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
985 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
988 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
994 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
999 if (!Res.
getNode())
return false;
1007 "Invalid operand expansion");
1009 ReplaceValueWith(
SDValue(
N, 0), Res);
1016 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1018 N->getValueType(0), Elt);
1023 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1024 "Fake Use: Unexpected vector type!");
1025 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1026 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1032 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1033 "Unexpected vector type!");
1034 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1035 SDValue Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1036 N->getValueType(0).getScalarType(), Elt);
1044SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1045 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1046 "Unexpected vector type!");
1047 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1049 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1050 Elt,
N->getOperand(1));
1058SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1059 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1060 "Unexpected vector type!");
1061 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1063 {
N->getValueType(0).getScalarType(), MVT::Other },
1064 {
N->getOperand(0), Elt });
1074 ReplaceValueWith(
SDValue(
N, 0), Res);
1079SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1081 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1082 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1083 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1088SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1092 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1093 SDValue ContainingVec =
N->getOperand(0);
1101SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1102 EVT VT =
N->getValueType(0);
1103 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1115 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1116 EVT VT =
N->getValueType(0);
1118 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1126 assert(
N->getValueType(0).isVector() &&
1127 N->getOperand(0).getValueType().isVector() &&
1128 "Operand types must be vectors");
1129 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1131 EVT VT =
N->getValueType(0);
1132 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1133 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1135 EVT OpVT =
N->getOperand(0).getValueType();
1147 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1153SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1155 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1156 assert(
N->getValueType(0).isVector() &&
1157 N->getOperand(1).getValueType().isVector() &&
1158 "Operand types must be vectors");
1159 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1161 EVT VT =
N->getValueType(0);
1163 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1164 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1167 EVT OpVT =
N->getOperand(1).getValueType();
1171 {Ch, LHS, RHS, CC});
1180 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1185 ReplaceValueWith(
SDValue(
N, 0), Res);
1192 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1193 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1196 if (
N->isTruncatingStore())
1197 return DAG.getTruncStore(
1198 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1199 N->getBasePtr(),
N->getPointerInfo(),
1200 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1201 N->getMemOperand()->getFlags(),
N->getAAInfo());
1203 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1204 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1205 N->getMemOperand()->getFlags(),
N->getAAInfo());
1211 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1213 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1214 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1219SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1220 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1221 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1223 N->getValueType(0).getVectorElementType(), Elt,
1228SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1230 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1231 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1234 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1244 ReplaceValueWith(
SDValue(
N, 0), Res);
1251 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1253 N->getValueType(0).getVectorElementType(), Elt);
1259SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1260 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1263 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1264 {
N->getOperand(0), Elt});
1273 ReplaceValueWith(
SDValue(
N, 0), Res);
1278 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1285SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1291 SDValue Op = GetScalarizedVector(VecOp);
1292 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1293 AccOp,
Op,
N->getFlags());
1297 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1298 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1305SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1313 EVT VT =
N->getValueType(0);
1314 return DAG.getConstant(0, SDLoc(
N), VT);
1321 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1322 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1324 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1325 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1326 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1329SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1334 N->getValueType(0).getScalarType(), Mask,
1335 DAG.getVectorIdxConstant(0,
DL));
1340 return TLI.expandVectorMatch(
N, DAG);
1343SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1344 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1347 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1348 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1357 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1369void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1374 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1377 switch (
N->getOpcode()) {
1380 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1389 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1397 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1413 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1416 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1428 case ISD::VP_LOAD_FF:
1431 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1438 case ISD::VP_GATHER:
1442 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1446 SplitVecRes_SETCC(
N,
Lo,
Hi);
1449 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1456 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1459 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1462 SplitVecRes_VECTOR_INTERLEAVE(
N);
1465 SplitVecRes_VAARG(
N,
Lo,
Hi);
1471 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1478 case ISD::VP_BITREVERSE:
1486 case ISD::VP_CTLZ_ZERO_POISON:
1488 case ISD::VP_CTTZ_ZERO_POISON:
1503 case ISD::VP_FFLOOR:
1508 case ISD::VP_FNEARBYINT:
1513 case ISD::VP_FP_EXTEND:
1515 case ISD::VP_FP_ROUND:
1517 case ISD::VP_FP_TO_SINT:
1519 case ISD::VP_FP_TO_UINT:
1525 case ISD::VP_LLRINT:
1527 case ISD::VP_FROUND:
1529 case ISD::VP_FROUNDEVEN:
1538 case ISD::VP_FROUNDTOZERO:
1540 case ISD::VP_SINT_TO_FP:
1542 case ISD::VP_TRUNCATE:
1544 case ISD::VP_UINT_TO_FP:
1549 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1552 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1558 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1564 case ISD::VP_SIGN_EXTEND:
1565 case ISD::VP_ZERO_EXTEND:
1566 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1590 case ISD::VP_FMINNUM:
1593 case ISD::VP_FMAXNUM:
1595 case ISD::VP_FMINIMUM:
1597 case ISD::VP_FMAXIMUM:
1606 case ISD::OR:
case ISD::VP_OR:
1626 case ISD::VP_FCOPYSIGN:
1627 SplitVecRes_BinOp(
N,
Lo,
Hi);
1633 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1640 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1644 SplitVecRes_CMP(
N,
Lo,
Hi);
1647#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1648 case ISD::STRICT_##DAGN:
1649#include "llvm/IR/ConstrainedOps.def"
1650 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1655 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1664 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1674 SplitVecRes_FIX(
N,
Lo,
Hi);
1676 case ISD::EXPERIMENTAL_VP_SPLICE:
1677 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1679 case ISD::EXPERIMENTAL_VP_REVERSE:
1680 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1686 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1689 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1692 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1701void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1703 uint64_t *ScaledOffset) {
1708 SDValue BytesIncrement = DAG.getVScale(
1711 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1713 *ScaledOffset += IncrementSize;
1723std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1724 return SplitMask(Mask, SDLoc(Mask));
1727std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1730 EVT MaskVT =
Mask.getValueType();
1732 GetSplitVector(Mask, MaskLo, MaskHi);
1734 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1735 return std::make_pair(MaskLo, MaskHi);
1740 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1742 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1745 const SDNodeFlags
Flags =
N->getFlags();
1746 unsigned Opcode =
N->getOpcode();
1747 if (
N->getNumOperands() == 2) {
1748 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1749 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1753 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1754 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1757 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1760 std::tie(EVLLo, EVLHi) =
1761 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1764 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1766 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1772 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1774 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1778 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1780 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1784 const SDNodeFlags
Flags =
N->getFlags();
1785 unsigned Opcode =
N->getOpcode();
1786 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1788 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1795 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1797 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1799 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1802 const SDNodeFlags
Flags =
N->getFlags();
1803 unsigned Opcode =
N->getOpcode();
1804 if (
N->getNumOperands() == 3) {
1805 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1806 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1810 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1811 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1814 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1817 std::tie(EVLLo, EVLHi) =
1818 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1821 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1823 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1827 LLVMContext &Ctxt = *DAG.getContext();
1833 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1835 GetSplitVector(
LHS, LHSLo, LHSHi);
1836 GetSplitVector(
RHS, RHSLo, RHSHi);
1838 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1839 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1843 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1844 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1849 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1851 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1855 unsigned Opcode =
N->getOpcode();
1856 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1858 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1867 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1874 switch (getTypeAction(InVT)) {
1888 GetExpandedOp(InOp,
Lo,
Hi);
1889 if (DAG.getDataLayout().isBigEndian())
1899 GetSplitVector(InOp,
Lo,
Hi);
1908 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1917 if (DAG.getDataLayout().isBigEndian())
1920 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1922 if (DAG.getDataLayout().isBigEndian())
1928void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1934 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1937 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1942 unsigned LaneOffset =
1945 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1947 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1954 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1957 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1960 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1965 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1967 unsigned NumSubvectors =
N->getNumOperands() / 2;
1968 if (NumSubvectors == 1) {
1969 Lo =
N->getOperand(0);
1970 Hi =
N->getOperand(1);
1975 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1984void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1991 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2006 GetSplitVector(Vec,
Lo,
Hi);
2009 EVT LoVT =
Lo.getValueType();
2019 if (IdxVal + SubElems <= LoElems) {
2027 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
2029 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
2035 SDValue WideSubVec = GetWidenedVector(SubVec);
2037 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2045 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2047 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2048 auto &MF = DAG.getMachineFunction();
2052 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2057 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2058 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2062 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2067 MachinePointerInfo MPI =
Load->getPointerInfo();
2068 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2071 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2080 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2085 EVT RHSVT =
RHS.getValueType();
2088 GetSplitVector(
RHS, RHSLo, RHSHi);
2090 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2105 SDValue FpValue =
N->getOperand(0);
2107 GetSplitVector(FpValue, ArgLo, ArgHi);
2109 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2111 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2120 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2124 std::tie(LoVT, HiVT) =
2128 DAG.getValueType(LoVT));
2130 DAG.getValueType(HiVT));
2135 unsigned Opcode =
N->getOpcode();
2142 GetSplitVector(N0, InLo, InHi);
2144 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2149 EVT OutLoVT, OutHiVT;
2150 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2152 assert((2 * OutNumElements) <= InNumElements &&
2153 "Illegal extend vector in reg split");
2162 SmallVector<int, 8> SplitHi(InNumElements, -1);
2163 for (
unsigned i = 0; i != OutNumElements; ++i)
2164 SplitHi[i] = i + OutNumElements;
2165 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2167 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2168 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2173 unsigned NumOps =
N->getNumOperands();
2177 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2187 for (
unsigned i = 1; i <
NumOps; ++i) {
2192 EVT InVT =
Op.getValueType();
2197 GetSplitVector(
Op, OpLo, OpHi);
2199 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2206 EVT LoValueVTs[] = {LoVT, MVT::Other};
2207 EVT HiValueVTs[] = {HiVT, MVT::Other};
2208 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2210 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2216 Lo.getValue(1),
Hi.getValue(1));
2220 ReplaceValueWith(
SDValue(
N, 1), Chain);
2223SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2225 EVT VT =
N->getValueType(0);
2236 else if (NE > ResNE)
2240 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2244 for (i = 0; i !=
NE; ++i) {
2246 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2247 SDValue Operand =
N->getOperand(j);
2251 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2257 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2265 for (; i < ResNE; ++i)
2266 Scalars.
push_back(DAG.getPOISON(EltVT));
2270 ReplaceValueWith(
SDValue(
N, 1), Chain);
2274 return DAG.getBuildVector(VecVT, dl, Scalars);
2277void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2280 EVT ResVT =
N->getValueType(0);
2281 EVT OvVT =
N->getValueType(1);
2282 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2283 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2284 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2286 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2288 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2289 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2291 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2292 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2295 unsigned Opcode =
N->getOpcode();
2296 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2297 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2299 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2301 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2307 unsigned OtherNo = 1 - ResNo;
2308 EVT OtherVT =
N->getValueType(OtherNo);
2310 SetSplitVector(
SDValue(
N, OtherNo),
2316 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2320void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2326 GetSplitVector(Vec,
Lo,
Hi);
2329 unsigned IdxVal = CIdx->getZExtValue();
2330 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2331 if (IdxVal < LoNumElts) {
2333 Lo.getValueType(),
Lo, Elt, Idx);
2336 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2356 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2358 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2359 auto &MF = DAG.getMachineFunction();
2363 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2368 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2369 Store = DAG.getTruncStore(
2375 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2378 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2382 MachinePointerInfo MPI =
Load->getPointerInfo();
2383 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2385 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2388 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2389 if (LoVT !=
Lo.getValueType())
2391 if (HiVT !=
Hi.getValueType())
2399 assert(
N->getValueType(0).isScalableVector() &&
2400 "Only scalable vectors are supported for STEP_VECTOR");
2401 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2422 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2423 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2425 Hi = DAG.getPOISON(HiVT);
2435 "Extended load during type legalization!");
2437 EVT VT =
LD->getValueType(0);
2439 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2447 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2448 Ch, Ptr,
LD->getMemOperand());
2453 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2455 Lo = DAG.getBitcast(LoVT, ExtractLo);
2456 Hi = DAG.getBitcast(HiVT, ExtractHi);
2468 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2474 EVT MemoryVT =
LD->getMemoryVT();
2476 AAMDNodes AAInfo =
LD->getAAInfo();
2478 EVT LoMemVT, HiMemVT;
2479 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2483 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2484 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2485 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2490 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2493 MachinePointerInfo MPI;
2494 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2497 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2506 ReplaceValueWith(
SDValue(LD, 1), Ch);
2511 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2514 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2520 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2521 Align Alignment =
LD->getBaseAlign();
2524 EVT MemoryVT =
LD->getMemoryVT();
2526 EVT LoMemVT, HiMemVT;
2527 bool HiIsEmpty =
false;
2528 std::tie(LoMemVT, HiMemVT) =
2529 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2534 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2537 GetSplitVector(Mask, MaskLo, MaskHi);
2539 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2544 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2546 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2549 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2552 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2553 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2561 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2562 LD->isExpandingLoad());
2564 MachinePointerInfo MPI;
2566 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2568 MPI =
LD->getPointerInfo().getWithOffset(
2571 MMO = DAG.getMachineFunction().getMachineMemOperand(
2573 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2575 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2576 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2577 LD->isExpandingLoad());
2587 ReplaceValueWith(
SDValue(LD, 1), Ch);
2593 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2597 Align Alignment =
LD->getBaseAlign();
2604 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2607 GetSplitVector(Mask, MaskLo, MaskHi);
2609 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2613 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2615 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2618 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2620 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2623 Hi = DAG.getPOISON(HiVT);
2625 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2626 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2632 "Indexed VP strided load during type legalization!");
2634 "Unexpected indexed variable-length load offset");
2639 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2641 EVT LoMemVT, HiMemVT;
2642 bool HiIsEmpty =
false;
2643 std::tie(LoMemVT, HiMemVT) =
2644 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2649 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2652 GetSplitVector(Mask, LoMask, HiMask);
2654 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2658 std::tie(LoEVL, HiEVL) =
2662 Lo = DAG.getStridedLoadVP(
2689 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2696 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2707 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2715 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2720 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2730 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2733 GetSplitVector(Mask, MaskLo, MaskHi);
2735 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2739 EVT LoMemVT, HiMemVT;
2740 bool HiIsEmpty =
false;
2741 std::tie(LoMemVT, HiMemVT) =
2742 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2744 SDValue PassThruLo, PassThruHi;
2746 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2748 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2750 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2754 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2764 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2767 MachinePointerInfo MPI;
2774 MMO = DAG.getMachineFunction().getMachineMemOperand(
2778 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2790 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2798 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2808 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2811 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2814 EVT MemoryVT =
N->getMemoryVT();
2815 Align Alignment =
N->getBaseAlign();
2820 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2822 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2825 EVT LoMemVT, HiMemVT;
2827 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2830 if (getTypeAction(
Ops.Index.getValueType()) ==
2832 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2834 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2837 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2839 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2842 SDValue PassThru = MGT->getPassThru();
2843 SDValue PassThruLo, PassThruHi;
2846 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2848 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2853 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2854 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2855 OpsLo, MMO, IndexTy, ExtType);
2857 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2858 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2859 OpsHi, MMO, IndexTy, ExtType);
2863 std::tie(EVLLo, EVLHi) =
2864 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2866 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2867 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2868 MMO, VPGT->getIndexType());
2870 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2871 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2872 MMO, VPGT->getIndexType());
2882 ReplaceValueWith(
SDValue(
N, 1), Ch);
2896 EVT VecVT =
N->getValueType(0);
2898 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2899 bool HasCustomLowering =
false;
2906 HasCustomLowering =
true;
2912 SDValue Passthru =
N->getOperand(2);
2913 if (!HasCustomLowering) {
2914 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2915 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2922 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2923 std::tie(LoMask, HiMask) = SplitMask(Mask);
2925 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2930 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2943 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2945 SDValue Chain = DAG.getEntryNode();
2946 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2950 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2955 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2959 assert(
N->getValueType(0).isVector() &&
2960 N->getOperand(0).getValueType().isVector() &&
2961 "Operand types must be vectors");
2965 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2969 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2971 GetSplitVector(
N->getOperand(0), LL, LH);
2973 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2975 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2977 GetSplitVector(
N->getOperand(1), RL, RH);
2979 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2982 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2983 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2985 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2986 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2987 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2988 std::tie(EVLLo, EVLHi) =
2989 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2990 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2992 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
3002 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3006 EVT InVT =
N->getOperand(0).getValueType();
3008 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3010 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3012 const SDNodeFlags
Flags =
N->getFlags();
3013 unsigned Opcode =
N->getOpcode();
3015 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
3016 N->getOperand(3), Flags);
3017 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
3018 N->getOperand(3), Flags);
3021 if (
N->getNumOperands() <= 2) {
3024 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
3025 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
3027 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
3028 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
3033 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
3034 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3037 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3040 std::tie(EVLLo, EVLHi) =
3041 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3044 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
3050 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3054 EVT InVT =
N->getOperand(0).getValueType();
3056 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3058 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3061 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3062 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3063 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
3064 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
3067void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3072 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3073 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3077 EVT InVT =
N->getOperand(0).getValueType();
3079 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3081 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3083 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3084 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3086 SDNode *HiNode =
Hi.getNode();
3087 SDNode *LoNode =
Lo.getNode();
3090 unsigned OtherNo = 1 - ResNo;
3091 EVT OtherVT =
N->getValueType(OtherNo);
3099 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3106 EVT SrcVT =
N->getOperand(0).getValueType();
3107 EVT DestVT =
N->getValueType(0);
3109 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3126 LLVMContext &Ctx = *DAG.getContext();
3130 EVT SplitLoVT, SplitHiVT;
3131 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3132 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3133 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3134 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3135 N->dump(&DAG);
dbgs() <<
"\n");
3136 if (!
N->isVPOpcode()) {
3139 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3141 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3143 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3144 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3150 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
3151 N->getOperand(1),
N->getOperand(2));
3153 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3156 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3159 std::tie(EVLLo, EVLHi) =
3160 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3162 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
3163 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
3168 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3176 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3177 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3183 return N.getResNo() == 0 &&
3187 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3189 ArrayRef<int>
Mask) {
3192 "Expected build vector node.");
3195 for (
unsigned I = 0;
I < NewElts; ++
I) {
3198 unsigned Idx =
Mask[
I];
3200 Ops[
I] = Input2.getOperand(Idx - NewElts);
3202 Ops[
I] = Input1.getOperand(Idx);
3207 return DAG.getBuildVector(NewVT,
DL,
Ops);
3213 SmallVector<int> OrigMask(
N->getMask());
3215 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3216 &
DL](SmallVectorImpl<int> &
Mask) {
3218 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3219 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3230 for (
auto &
P : ShufflesIdxs) {
3231 if (
P.second.size() < 2)
3235 for (
int &Idx : Mask) {
3238 unsigned SrcRegIdx = Idx / NewElts;
3239 if (Inputs[SrcRegIdx].
isUndef()) {
3247 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3252 Idx = MaskElt % NewElts +
3253 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3259 Inputs[
P.second[0]] =
P.first.first;
3260 Inputs[
P.second[1]] =
P.first.second;
3263 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3266 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3267 for (
int &Idx : Mask) {
3270 unsigned SrcRegIdx = Idx / NewElts;
3271 if (Inputs[SrcRegIdx].
isUndef()) {
3278 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3279 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3282 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3284 if (UsedSubVector.count() > 1) {
3286 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3287 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3289 if (Pairs.
empty() || Pairs.
back().size() == 2)
3291 if (UsedSubVector.test(2 *
I)) {
3292 Pairs.
back().emplace_back(
I, 0);
3294 assert(UsedSubVector.test(2 *
I + 1) &&
3295 "Expected to be used one of the subvectors.");
3296 Pairs.
back().emplace_back(
I, 1);
3299 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3301 for (
int &Idx : Mask) {
3304 unsigned SrcRegIdx = Idx / NewElts;
3306 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3307 return Idxs.front().first == SrcRegIdx ||
3308 Idxs.back().first == SrcRegIdx;
3310 if (It == Pairs.
end())
3312 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3313 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3316 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3317 Inputs[Idxs.front().first] = DAG.
getNode(
3319 Inputs[Idxs.front().first].getValueType(),
3320 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3321 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3330 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3334 if (Shuffle->getOperand(0).getValueType() != NewVT)
3337 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3338 !Shuffle->isSplat()) {
3340 }
else if (!Inputs[
I].hasOneUse() &&
3341 !Shuffle->getOperand(1).isUndef()) {
3343 for (
int &Idx : Mask) {
3346 unsigned SrcRegIdx = Idx / NewElts;
3349 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3354 int OpIdx = MaskElt / NewElts;
3367 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3368 if (Shuffle->getOperand(OpIdx).isUndef())
3370 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3371 if (It == std::end(Inputs))
3373 int FoundOp = std::distance(std::begin(Inputs), It);
3376 for (
int &Idx : Mask) {
3379 unsigned SrcRegIdx = Idx / NewElts;
3382 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3387 int MaskIdx = MaskElt / NewElts;
3388 if (OpIdx == MaskIdx)
3389 Idx = MaskElt % NewElts + FoundOp * NewElts;
3392 Op = (OpIdx + 1) % 2;
3400 for (
int &Idx : Mask) {
3403 unsigned SrcRegIdx = Idx / NewElts;
3406 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3407 int OpIdx = MaskElt / NewElts;
3410 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3416 TryPeekThroughShufflesInputs(OrigMask);
3418 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3419 NewElts](SmallVectorImpl<int> &
Mask) {
3420 SetVector<SDValue> UniqueInputs;
3421 SetVector<SDValue> UniqueConstantInputs;
3422 for (
const auto &
I : Inputs) {
3424 UniqueConstantInputs.
insert(
I);
3425 else if (!
I.isUndef())
3430 if (UniqueInputs.
size() != std::size(Inputs)) {
3431 auto &&UniqueVec = UniqueInputs.
takeVector();
3432 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3433 unsigned ConstNum = UniqueConstantVec.size();
3434 for (
int &Idx : Mask) {
3437 unsigned SrcRegIdx = Idx / NewElts;
3438 if (Inputs[SrcRegIdx].
isUndef()) {
3442 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3443 if (It != UniqueConstantVec.end()) {
3444 Idx = (Idx % NewElts) +
3445 NewElts * std::distance(UniqueConstantVec.begin(), It);
3446 assert(Idx >= 0 &&
"Expected defined mask idx.");
3449 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3450 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3451 Idx = (Idx % NewElts) +
3452 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3453 assert(Idx >= 0 &&
"Expected defined mask idx.");
3455 copy(UniqueConstantVec, std::begin(Inputs));
3456 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3459 MakeUniqueInputs(OrigMask);
3461 copy(Inputs, std::begin(OrigInputs));
3467 unsigned FirstMaskIdx =
High * NewElts;
3470 assert(!Output &&
"Expected default initialized initial value.");
3471 TryPeekThroughShufflesInputs(Mask);
3472 MakeUniqueInputs(Mask);
3474 copy(Inputs, std::begin(TmpInputs));
3477 bool SecondIteration =
false;
3478 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3483 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3484 SecondIteration =
true;
3485 return SecondIteration;
3488 Mask, std::size(Inputs), std::size(Inputs),
3490 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3491 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3492 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3494 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3496 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3497 DAG.getPOISON(NewVT), Mask);
3498 Inputs[Idx] = Output;
3500 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3501 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3502 unsigned Idx2,
bool ) {
3503 if (AccumulateResults(Idx1)) {
3506 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3508 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3509 Inputs[Idx2], Mask);
3513 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3515 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3516 TmpInputs[Idx2], Mask);
3518 Inputs[Idx1] = Output;
3520 copy(OrigInputs, std::begin(Inputs));
3525 EVT OVT =
N->getValueType(0);
3532 const Align Alignment =
3533 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3535 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3536 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3541 ReplaceValueWith(
SDValue(
N, 1), Chain);
3546 EVT DstVTLo, DstVTHi;
3547 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3551 EVT SrcVT =
N->getOperand(0).getValueType();
3553 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3555 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3557 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3558 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3564 GetSplitVector(
N->getOperand(0), InLo, InHi);
3575 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3576 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3581 EVT VT =
N->getValueType(0);
3599 Align Alignment = DAG.getReducedAlign(VT,
false);
3604 EVT PtrVT =
StackPtr.getValueType();
3605 auto &MF = DAG.getMachineFunction();
3609 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3612 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3618 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3619 DAG.getConstant(1,
DL, PtrVT));
3621 DAG.getConstant(EltWidth,
DL, PtrVT));
3623 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3625 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3626 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3627 DAG.getPOISON(PtrVT), Stride, TrueMask,
3636 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3641 EVT VT =
N->getValueType(0);
3653 EVL1 = ZExtPromotedInteger(EVL1);
3667 Align Alignment = DAG.getReducedAlign(VT,
false);
3672 EVT PtrVT =
StackPtr.getValueType();
3673 auto &MF = DAG.getMachineFunction();
3677 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3680 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3686 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3691 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3692 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3694 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3696 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3700 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3705 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3706 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3708 uint64_t TrailingElts = -
Imm;
3710 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3719 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3727 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3729 DAG.getVectorIdxConstant(0,
DL));
3735void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3743 GetSplitVector(Acc, AccLo, AccHi);
3744 unsigned Opcode =
N->getOpcode();
3756 GetSplitVector(Input1, Input1Lo, Input1Hi);
3757 GetSplitVector(Input2, Input2Lo, Input2Hi);
3760 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3761 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3764void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3772 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3783 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3785 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3789 N->getOperand(1), MaskLo,
N->getFlags());
3791 N->getOperand(1), MaskHi,
N->getFlags());
3794void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3795 unsigned Factor =
N->getNumOperands();
3798 for (
unsigned i = 0; i != Factor; ++i) {
3800 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3802 Ops[i * 2 + 1] = OpHi;
3813 for (
unsigned i = 0; i != Factor; ++i)
3817void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3818 unsigned Factor =
N->getNumOperands();
3821 for (
unsigned i = 0; i != Factor; ++i) {
3823 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3825 Ops[i + Factor] = OpHi;
3836 for (
unsigned i = 0; i != Factor; ++i) {
3837 unsigned IdxLo = 2 * i;
3838 unsigned IdxHi = 2 * i + 1;
3839 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3840 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3852bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3857 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3860 switch (
N->getOpcode()) {
3863 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3873 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3880 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3882 case ISD::VP_TRUNCATE:
3884 Res = SplitVecOp_TruncateHelper(
N);
3887 case ISD::VP_FP_ROUND:
3891 Res = SplitVecOp_FP_ROUND(
N);
3903 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3910 case ISD::VP_SCATTER:
3914 case ISD::VP_GATHER:
3918 Res = SplitVecOp_VSELECT(
N, OpNo);
3924 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3927 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3933 case ISD::VP_SINT_TO_FP:
3934 case ISD::VP_UINT_TO_FP:
3935 if (
N->getValueType(0).bitsLT(
3936 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3937 Res = SplitVecOp_TruncateHelper(
N);
3939 Res = SplitVecOp_UnaryOp(
N);
3943 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3947 case ISD::VP_FP_TO_SINT:
3948 case ISD::VP_FP_TO_UINT:
3961 Res = SplitVecOp_UnaryOp(
N);
3964 Res = SplitVecOp_FPOpDifferentTypes(
N);
3969 Res = SplitVecOp_CMP(
N);
3973 Res = SplitVecOp_FAKE_USE(
N);
3978 Res = SplitVecOp_ExtVecInRegOp(
N);
3996 Res = SplitVecOp_VECREDUCE(
N, OpNo);
4000 Res = SplitVecOp_VECREDUCE_SEQ(
N);
4002 case ISD::VP_REDUCE_FADD:
4003 case ISD::VP_REDUCE_SEQ_FADD:
4004 case ISD::VP_REDUCE_FMUL:
4005 case ISD::VP_REDUCE_SEQ_FMUL:
4006 case ISD::VP_REDUCE_ADD:
4007 case ISD::VP_REDUCE_MUL:
4008 case ISD::VP_REDUCE_AND:
4009 case ISD::VP_REDUCE_OR:
4010 case ISD::VP_REDUCE_XOR:
4011 case ISD::VP_REDUCE_SMAX:
4012 case ISD::VP_REDUCE_SMIN:
4013 case ISD::VP_REDUCE_UMAX:
4014 case ISD::VP_REDUCE_UMIN:
4015 case ISD::VP_REDUCE_FMAX:
4016 case ISD::VP_REDUCE_FMIN:
4017 case ISD::VP_REDUCE_FMAXIMUM:
4018 case ISD::VP_REDUCE_FMINIMUM:
4019 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
4023 Res = SplitVecOp_CttzElts(
N);
4025 case ISD::VP_CTTZ_ELTS:
4026 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
4027 Res = SplitVecOp_VP_CttzElements(
N);
4030 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
4036 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
4039 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
4044 if (!Res.
getNode())
return false;
4051 if (
N->isStrictFPOpcode())
4053 "Invalid operand expansion");
4056 "Invalid operand expansion");
4058 ReplaceValueWith(
SDValue(
N, 0), Res);
4062SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4066 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4068 EVT VT =
N->getValueType(0);
4081 getSetCCResultType(MVT::i1), MVT::i1);
4086 DAG.getElementCount(
DL, VT, SplitEC)),
4090SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4093 assert(OpNo == 0 &&
"Illegal operand must be mask");
4100 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4103 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4104 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4105 "Lo and Hi have differing types");
4108 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4109 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4111 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4112 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4113 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4114 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4124SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4125 assert(OpNo == 2 &&
"Illegal operand must be mask");
4128 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4129 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4131 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4134 RHSLo, MaskLo,
N->getFlags());
4136 RHSHi, MaskHi,
N->getFlags());
4140SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4143 assert(OpNo == 1 &&
"Illegal operand must be mask");
4148 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4150 EVT VecVT =
N->getValueType(0);
4154SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4155 EVT ResVT =
N->getValueType(0);
4161 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4162 GetSplitVector(VecOp,
Lo,
Hi);
4164 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4169 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4170 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4174 EVT ResVT =
N->getValueType(0);
4180 SDNodeFlags
Flags =
N->getFlags();
4183 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4184 GetSplitVector(VecOp,
Lo,
Hi);
4186 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4192 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4195SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4196 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4197 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4199 unsigned Opc =
N->getOpcode();
4200 EVT ResVT =
N->getValueType(0);
4206 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4207 GetSplitVector(VecOp,
Lo,
Hi);
4210 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4213 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4215 const SDNodeFlags
Flags =
N->getFlags();
4219 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4224 EVT ResVT =
N->getValueType(0);
4227 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4228 EVT InVT =
Lo.getValueType();
4233 if (
N->isStrictFPOpcode()) {
4234 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4235 {N->getOperand(0), Lo});
4236 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4237 {N->getOperand(0), Hi});
4246 ReplaceValueWith(
SDValue(
N, 1), Ch);
4247 }
else if (
N->getNumOperands() == 3) {
4248 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4249 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4250 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4251 std::tie(EVLLo, EVLHi) =
4252 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4253 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4254 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4256 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4257 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4266 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4276 EVT ResVT =
N->getValueType(0);
4278 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4282 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4288 Lo = BitConvertToInteger(
Lo);
4289 Hi = BitConvertToInteger(
Hi);
4291 if (DAG.getDataLayout().isBigEndian())
4299 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4301 EVT ResVT =
N->getValueType(0);
4309 GetSplitVector(SubVec,
Lo,
Hi);
4318 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4320 return SecondInsertion;
4323SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4330 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4332 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4334 ElementCount IdxVal =
4338 EVT SrcVT =
N->getOperand(0).getValueType();
4357 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4358 LoEltsMin - IdxValMin);
4359 DAG.ExtractVectorElements(
Hi, Elts, 0,
4362 return DAG.getBuildVector(SubVT, dl, Elts);
4366 ElementCount ExtractIdx = IdxVal - LoElts;
4368 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4371 EVT HiVT =
Hi.getValueType();
4373 "Only fixed-vector extracts are supported in this case");
4383 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4384 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4390 "Extracting scalable subvector from fixed-width unsupported");
4398 "subvector from a scalable predicate vector");
4404 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4406 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4407 auto &MF = DAG.getMachineFunction();
4411 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4415 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4418 SubVT, dl,
Store, StackPtr,
4422SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4428 uint64_t IdxVal =
Index->getZExtValue();
4431 GetSplitVector(Vec,
Lo,
Hi);
4433 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4435 if (IdxVal < LoElts)
4436 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4439 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4444 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4456 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4462 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4464 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4465 auto &MF = DAG.getMachineFunction();
4468 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4472 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4476 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4478 return DAG.getExtLoad(
4489 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4497 SplitVecRes_Gather(
N,
Lo,
Hi);
4500 ReplaceValueWith(
SDValue(
N, 0), Res);
4505 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4509 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4511 SDValue EVL =
N->getVectorLength();
4513 Align Alignment =
N->getBaseAlign();
4519 GetSplitVector(
Data, DataLo, DataHi);
4521 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4526 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4529 GetSplitVector(Mask, MaskLo, MaskHi);
4531 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4534 EVT MemoryVT =
N->getMemoryVT();
4535 EVT LoMemVT, HiMemVT;
4536 bool HiIsEmpty =
false;
4537 std::tie(LoMemVT, HiMemVT) =
4538 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4542 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4545 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4548 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4550 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4551 N->getAddressingMode(),
N->isTruncatingStore(),
4552 N->isCompressingStore());
4558 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4559 N->isCompressingStore());
4561 MachinePointerInfo MPI;
4565 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4570 MMO = DAG.getMachineFunction().getMachineMemOperand(
4572 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4574 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4575 N->getAddressingMode(),
N->isTruncatingStore(),
4576 N->isCompressingStore());
4585 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4586 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4593 GetSplitVector(
Data, LoData, HiData);
4595 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4597 EVT LoMemVT, HiMemVT;
4598 bool HiIsEmpty =
false;
4599 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4605 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4606 else if (getTypeAction(
Mask.getValueType()) ==
4608 GetSplitVector(Mask, LoMask, HiMask);
4610 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4613 std::tie(LoEVL, HiEVL) =
4614 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4618 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4619 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4620 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4631 EVT PtrVT =
N->getBasePtr().getValueType();
4634 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4637 Align Alignment =
N->getBaseAlign();
4642 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4643 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4645 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4648 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4649 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4650 N->isCompressingStore());
4659 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4663 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4666 Align Alignment =
N->getBaseAlign();
4672 GetSplitVector(
Data, DataLo, DataHi);
4674 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4679 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4682 GetSplitVector(Mask, MaskLo, MaskHi);
4684 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4687 EVT MemoryVT =
N->getMemoryVT();
4688 EVT LoMemVT, HiMemVT;
4689 bool HiIsEmpty =
false;
4690 std::tie(LoMemVT, HiMemVT) =
4691 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4694 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4697 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4699 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4700 N->getAddressingMode(),
N->isTruncatingStore(),
4701 N->isCompressingStore());
4709 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4710 N->isCompressingStore());
4712 MachinePointerInfo MPI;
4716 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4721 MMO = DAG.getMachineFunction().getMachineMemOperand(
4723 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4725 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4726 N->getAddressingMode(),
N->isTruncatingStore(),
4727 N->isCompressingStore());
4740 EVT MemoryVT =
N->getMemoryVT();
4741 Align Alignment =
N->getBaseAlign();
4750 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4754 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4759 EVT LoMemVT, HiMemVT;
4760 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4765 GetSplitVector(
Ops.Data, DataLo, DataHi);
4767 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4772 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4774 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4778 if (getTypeAction(
Ops.Index.getValueType()) ==
4780 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4782 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4786 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4788 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4791 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4793 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4794 MSC->getIndexType(), MSC->isTruncatingStore());
4799 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4800 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4801 MMO, MSC->getIndexType(),
4802 MSC->isTruncatingStore());
4806 std::tie(EVLLo, EVLHi) =
4807 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4809 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4810 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4811 VPSC->getIndexType());
4816 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4817 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4818 VPSC->getIndexType());
4822 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4823 assert(OpNo == 1 &&
"Can only split the stored value");
4826 bool isTruncating =
N->isTruncatingStore();
4829 EVT MemoryVT =
N->getMemoryVT();
4830 Align Alignment =
N->getBaseAlign();
4832 AAMDNodes AAInfo =
N->getAAInfo();
4834 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4836 EVT LoMemVT, HiMemVT;
4837 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4841 return TLI.scalarizeVectorStore(
N, DAG);
4844 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4845 Alignment, MMOFlags, AAInfo);
4847 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4850 MachinePointerInfo MPI;
4851 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4854 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4855 HiMemVT, Alignment, MMOFlags, AAInfo);
4857 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4864 LLVMContext &Ctx = *DAG.getContext();
4882 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4883 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4887 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4890 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4891 DAG.getBitcast(MemVecVT, Wide), 0);
4893 N->getBasePtr(),
N->getMemOperand());
4901 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4903 N->getBasePtr(),
N->getMemOperand());
4917 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4923 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4944 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4945 SDValue InVec =
N->getOperand(OpNo);
4947 EVT OutVT =
N->getValueType(0);
4955 EVT LoOutVT, HiOutVT;
4956 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4957 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4962 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4964 return SplitVecOp_UnaryOp(
N);
4973 return SplitVecOp_UnaryOp(
N);
4977 GetSplitVector(InVec, InLoVec, InHiVec);
4983 EVT HalfElementVT = IsFloat ?
4985 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4992 if (
N->isStrictFPOpcode()) {
4993 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4994 {N->getOperand(0), InLoVec});
4995 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4996 {N->getOperand(0), InHiVec});
5002 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
5003 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
5007 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
5015 if (
N->isStrictFPOpcode()) {
5019 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
5027 DAG.getTargetConstant(
5028 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
5035 assert(
N->getValueType(0).isVector() &&
5036 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
5037 "Operand types must be vectors");
5039 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
5041 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
5042 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
5044 EVT VT =
N->getValueType(0);
5045 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
5050 }
else if (isStrict) {
5051 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5052 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
5053 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5054 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
5057 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5059 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
5060 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
5061 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
5062 std::tie(EVLLo, EVLHi) =
5063 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
5064 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
5065 N->getOperand(2), MaskLo, EVLLo);
5066 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
5067 N->getOperand(2), MaskHi, EVLHi);
5075 EVT OpVT =
N->getOperand(0).getValueType();
5078 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5084 EVT ResVT =
N->getValueType(0);
5087 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5088 EVT InVT =
Lo.getValueType();
5093 if (
N->isStrictFPOpcode()) {
5094 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5095 {N->getOperand(0), Lo, N->getOperand(2)});
5096 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5097 {N->getOperand(0), Hi, N->getOperand(2)});
5101 Lo.getValue(1),
Hi.getValue(1));
5102 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5103 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
5104 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
5105 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
5106 std::tie(EVLLo, EVLHi) =
5107 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
5108 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
5109 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
5111 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5112 N->getOperand(2),
N->getOperand(3));
5113 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5114 N->getOperand(2),
N->getOperand(3));
5116 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5117 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5128SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5131 EVT LHSLoVT, LHSHiVT;
5132 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5134 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5135 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5138 std::tie(LHSLo, LHSHi) =
5139 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5142 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5145 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5151 LLVMContext &Ctxt = *DAG.getContext();
5154 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5155 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5156 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5158 EVT ResVT =
N->getValueType(0);
5163 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5164 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5170 EVT ResVT =
N->getValueType(0);
5173 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5174 EVT InVT =
Lo.getValueType();
5180 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5181 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5188 EVT ResVT =
N->getValueType(0);
5192 GetSplitVector(VecOp,
Lo,
Hi);
5198 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5200 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5202 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5203 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5208 EVT ResVT =
N->getValueType(0);
5212 GetSplitVector(VecOp,
Lo,
Hi);
5214 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5215 auto [EVLLo, EVLHi] =
5217 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5223 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5225 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5226 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5229SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5240 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5241 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5242 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5243 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5244 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5245 OpsLo, MMO, IndexType);
5246 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5247 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5251SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5255 EVT LoResVT, HiResVT;
5256 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5258 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5260 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5263 N->getOperand(1), MaskLo,
N->getFlags());
5265 N->getOperand(1), MaskHi,
N->getFlags());
5271 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5274 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5278 NeedleLo,
N->getOperand(2),
N->getFlags());
5281 NeedleHi,
N->getOperand(2),
N->getFlags());
5282 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5285SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5288 "Accumulator should already be a legal type, and shouldn't need "
5289 "further splitting");
5292 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5293 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5294 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5295 unsigned Opcode =
N->getOpcode();
5298 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5299 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5306void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5307 unsigned WidenResNo) {
5308 unsigned NumResults =
N->getNumValues();
5309 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5310 if (ResNo == WidenResNo)
5312 EVT ResVT =
N->getValueType(ResNo);
5318 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5319 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5324void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5325 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5328 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5333 auto unrollExpandedOp = [&]() {
5338 EVT VT =
N->getValueType(0);
5339 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5340 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5341 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5343 if (
N->getNumValues() > 1)
5344 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5350 switch (
N->getOpcode()) {
5353 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5361 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5365 Res = WidenVecRes_ADDRSPACECAST(
N);
5372 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5379 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5383 Res = WidenVecRes_ScalarOp(
N);
5388 case ISD::VP_SELECT:
5390 Res = WidenVecRes_Select(
N);
5394 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5396 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5403 case ISD::VP_LOAD_FF:
5406 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5410 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5418 case ISD::VP_GATHER:
5422 Res = WidenVecRes_VECTOR_REVERSE(
N);
5425 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5428 WidenVecRes_VECTOR_INTERLEAVE(
N);
5431 Res = WidenVecRes_VECTOR_MATCH(
N);
5434 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5444 case ISD::OR:
case ISD::VP_OR:
5457 case ISD::VP_FMINNUM:
5460 case ISD::VP_FMAXNUM:
5462 case ISD::VP_FMINIMUM:
5464 case ISD::VP_FMAXIMUM:
5497 case ISD::VP_FCOPYSIGN:
5498 Res = WidenVecRes_Binary(
N);
5505 Res = WidenVecRes_MaskedBinary(
N);
5510 Res = WidenVecRes_CMP(
N);
5516 if (unrollExpandedOp())
5531 Res = WidenVecRes_BinaryCanTrap(
N);
5540 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5543#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5544 case ISD::STRICT_##DAGN:
5545#include "llvm/IR/ConstrainedOps.def"
5546 Res = WidenVecRes_StrictFP(
N);
5555 Res = WidenVecRes_OverflowOp(
N, ResNo);
5559 Res = WidenVecRes_FCOPYSIGN(
N);
5564 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5569 if (!unrollExpandedOp())
5570 Res = WidenVecRes_ExpOp(
N);
5576 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5581 case ISD::VP_FP_EXTEND:
5583 case ISD::VP_FP_ROUND:
5585 case ISD::VP_FP_TO_SINT:
5587 case ISD::VP_FP_TO_UINT:
5589 case ISD::VP_SIGN_EXTEND:
5591 case ISD::VP_SINT_TO_FP:
5592 case ISD::VP_TRUNCATE:
5595 case ISD::VP_UINT_TO_FP:
5597 case ISD::VP_ZERO_EXTEND:
5600 Res = WidenVecRes_Convert(
N);
5605 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5611 case ISD::VP_LLRINT:
5614 Res = WidenVecRes_XROUND(
N);
5640 if (unrollExpandedOp())
5651 case ISD::VP_BITREVERSE:
5657 case ISD::VP_CTLZ_ZERO_POISON:
5663 case ISD::VP_CTTZ_ZERO_POISON:
5668 case ISD::VP_FFLOOR:
5670 case ISD::VP_FNEARBYINT:
5671 case ISD::VP_FROUND:
5672 case ISD::VP_FROUNDEVEN:
5673 case ISD::VP_FROUNDTOZERO:
5678 Res = WidenVecRes_Unary(
N);
5685 Res = WidenVecRes_Ternary(
N);
5691 if (!unrollExpandedOp())
5692 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5699 SetWidenedVector(
SDValue(
N, ResNo), Res);
5705 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5706 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5707 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5708 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5709 if (
N->getNumOperands() == 3)
5710 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5712 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5713 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5717 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5718 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5724 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5725 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5726 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5727 if (
N->getNumOperands() == 2)
5728 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5731 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5732 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5736 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5737 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5742 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5743 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5744 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5747 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5748 Mask = ModifyToType(Mask, WideMaskVT,
true);
5749 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5754 LLVMContext &Ctxt = *DAG.getContext();
5759 EVT OpVT =
LHS.getValueType();
5761 LHS = GetWidenedVector(
LHS);
5762 RHS = GetWidenedVector(
RHS);
5763 OpVT =
LHS.getValueType();
5766 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5769 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5775SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5778 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5779 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5780 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5782 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5791 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5794 if (ConcatEnd == 1) {
5795 VT = ConcatOps[0].getValueType();
5797 return ConcatOps[0];
5800 SDLoc dl(ConcatOps[0]);
5807 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5808 int Idx = ConcatEnd - 1;
5809 VT = ConcatOps[Idx--].getValueType();
5810 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5823 unsigned NumToInsert = ConcatEnd - Idx - 1;
5824 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5826 ConcatOps[Idx+1] = VecOp;
5827 ConcatEnd = Idx + 2;
5833 unsigned RealVals = ConcatEnd - Idx - 1;
5834 unsigned SubConcatEnd = 0;
5835 unsigned SubConcatIdx = Idx + 1;
5836 while (SubConcatEnd < RealVals)
5837 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5838 while (SubConcatEnd < OpsToConcat)
5839 SubConcatOps[SubConcatEnd++] = undefVec;
5841 NextVT, SubConcatOps);
5842 ConcatEnd = SubConcatIdx + 1;
5847 if (ConcatEnd == 1) {
5848 VT = ConcatOps[0].getValueType();
5850 return ConcatOps[0];
5855 if (
NumOps != ConcatEnd ) {
5857 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5858 ConcatOps[j] = UndefVal;
5866 unsigned Opcode =
N->getOpcode();
5868 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5872 const SDNodeFlags
Flags =
N->getFlags();
5873 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5874 NumElts = NumElts / 2;
5878 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5880 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5881 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5882 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5890 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5893 TLI.isTypeLegal(WideMaskVT)) {
5894 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5895 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5896 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5898 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5899 N->getValueType(0).getVectorElementCount());
5900 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5914 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5915 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5916 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5919 unsigned ConcatEnd = 0;
5927 while (CurNumElts != 0) {
5928 while (CurNumElts >= NumElts) {
5929 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5930 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5931 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5933 CurNumElts -= NumElts;
5936 NumElts = NumElts / 2;
5938 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5941 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5942 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5943 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5944 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5955 switch (
N->getOpcode()) {
5958 return WidenVecRes_STRICT_FSETCC(
N);
5965 return WidenVecRes_Convert_StrictFP(
N);
5972 unsigned Opcode =
N->getOpcode();
5974 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5978 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5979 NumElts = NumElts / 2;
5990 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5994 unsigned ConcatEnd = 0;
6001 for (
unsigned i = 1; i < NumOpers; ++i) {
6007 Oper = GetWidenedVector(Oper);
6013 DAG.getPOISON(WideOpVT), Oper,
6014 DAG.getVectorIdxConstant(0, dl));
6026 while (CurNumElts != 0) {
6027 while (CurNumElts >= NumElts) {
6030 for (
unsigned i = 0; i < NumOpers; ++i) {
6033 EVT OpVT =
Op.getValueType();
6038 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
6044 EVT OperVT[] = {VT, MVT::Other};
6046 ConcatOps[ConcatEnd++] = Oper;
6049 CurNumElts -= NumElts;
6052 NumElts = NumElts / 2;
6054 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
6057 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
6060 for (
unsigned i = 0; i < NumOpers; ++i) {
6063 EVT OpVT =
Op.getValueType();
6071 EVT WidenVT[] = {WidenEltVT, MVT::Other};
6073 ConcatOps[ConcatEnd++] = Oper;
6082 if (Chains.
size() == 1)
6083 NewChain = Chains[0];
6086 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6091SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
6093 EVT ResVT =
N->getValueType(0);
6094 EVT OvVT =
N->getValueType(1);
6095 EVT WideResVT, WideOvVT;
6100 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6105 WideLHS = GetWidenedVector(
N->getOperand(0));
6106 WideRHS = GetWidenedVector(
N->getOperand(1));
6108 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6117 N->getOperand(0), Zero);
6119 N->getOperand(1), Zero);
6122 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6123 SDNode *WideNode = DAG.getNode(
6124 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6127 unsigned OtherNo = 1 - ResNo;
6128 EVT OtherVT =
N->getValueType(OtherNo);
6135 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
6138 return SDValue(WideNode, ResNo);
6142 LLVMContext &Ctx = *DAG.getContext();
6146 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6151 unsigned Opcode =
N->getOpcode();
6152 const SDNodeFlags
Flags =
N->getFlags();
6158 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6160 InOp = ZExtPromotedInteger(InOp);
6172 if (
N->getNumOperands() == 1)
6173 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6175 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6176 N->getOperand(3), Flags);
6177 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6181 InOp = GetWidenedVector(
N->getOperand(0));
6184 if (InVTEC == WidenEC) {
6185 if (
N->getNumOperands() == 3 &&
N->isVPOpcode()) {
6188 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
6190 return MakeConvertNode(WidenVT, InOp);
6216 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6220 if (TLI.isTypeLegal(InWidenVT)) {
6228 unsigned NumConcat =
6233 return MakeConvertNode(WidenVT, InVec);
6237 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6239 return MakeConvertNode(WidenVT, InVal);
6248 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6249 for (
unsigned i=0; i < MinElts; ++i) {
6250 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6251 Ops[i] = MakeConvertNode(EltVT, Val);
6254 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6259 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6263 EVT SrcVT = Src.getValueType();
6267 Src = GetWidenedVector(Src);
6268 SrcVT = Src.getValueType();
6275 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6280 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6284 EVT SrcVT = Src.getValueType();
6288 Src = GetWidenedVector(Src);
6289 SrcVT = Src.getValueType();
6296 if (
N->getNumOperands() == 1)
6297 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6299 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6300 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6304 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6307SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6312 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6318 unsigned Opcode =
N->getOpcode();
6324 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6329 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6330 for (
unsigned i=0; i < MinElts; ++i) {
6331 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6332 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6336 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6338 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6341SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6342 unsigned Opcode =
N->getOpcode();
6346 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6355 InOp = GetWidenedVector(InOp);
6362 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6369 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6370 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6387 while (
Ops.size() != WidenNumElts)
6388 Ops.push_back(DAG.getPOISON(WidenSVT));
6390 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6396 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6397 return WidenVecRes_BinaryCanTrap(
N);
6400 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6407SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6409 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6412 SDValue Arg = GetWidenedVector(FpValue);
6413 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6418 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6419 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6421 EVT ExpVT =
RHS.getValueType();
6426 ExpOp = ModifyToType(
RHS, WideExpVT);
6429 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6434 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6435 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6436 if (
N->getNumOperands() == 1)
6437 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6439 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6440 N->getOperand(1),
N->getFlags());
6442 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6443 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6447 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6448 {InOp,
Mask,
N->getOperand(2)});
6452 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6457 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6458 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6459 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6462SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6464 EVT VT0 =
N->getValueType(0);
6465 EVT VT1 =
N->getValueType(1);
6469 "expected both results to be vectors of matching element count");
6471 LLVMContext &Ctx = *DAG.getContext();
6472 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6474 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6481 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6484 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6485 return SDValue(WidenNode, ResNo);
6488SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6489 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6490 return GetWidenedVector(WidenVec);
6494 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6495 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6498 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6499 AddrSpaceCastN->getSrcAddressSpace(),
6500 AddrSpaceCastN->getDestAddressSpace());
6506 EVT VT =
N->getValueType(0);
6507 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6510 switch (getTypeAction(InVT)) {
6524 SDValue NInOp = GetPromotedInteger(InOp);
6526 if (WidenVT.
bitsEq(NInVT)) {
6529 if (DAG.getDataLayout().isBigEndian()) {
6532 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6550 InOp = GetWidenedVector(InOp);
6552 if (WidenVT.
bitsEq(InVT))
6562 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6567 unsigned NewNumParts = WidenSize / InSize;
6580 EVT OrigInVT =
N->getOperand(0).getValueType();
6585 if (TLI.isTypeLegal(NewInVT)) {
6593 if (WidenSize % InSize == 0) {
6600 DAG.ExtractVectorElements(InOp,
Ops);
6601 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6613 return CreateStackStoreLoad(InOp, WidenVT);
6616SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6618 N->getOpcode(), SDLoc(
N),
6619 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6620 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6626 EVT VT =
N->getValueType(0);
6630 EVT EltVT =
N->getOperand(0).getValueType();
6633 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6637 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6638 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6640 return DAG.getBuildVector(WidenVT, dl, NewOps);
6644 EVT InVT =
N->getOperand(0).getValueType();
6645 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6647 unsigned NumOperands =
N->getNumOperands();
6649 bool InputWidened =
false;
6653 if (WidenNumElts % NumInElts == 0) {
6655 unsigned NumConcat = WidenNumElts / NumInElts;
6656 SDValue UndefVal = DAG.getPOISON(InVT);
6658 for (
unsigned i=0; i < NumOperands; ++i)
6659 Ops[i] =
N->getOperand(i);
6660 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6665 InputWidened =
true;
6666 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6669 for (i=1; i < NumOperands; ++i)
6670 if (!
N->getOperand(i).isUndef())
6673 if (i == NumOperands)
6676 return GetWidenedVector(
N->getOperand(0));
6678 if (NumOperands == 2) {
6680 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6685 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6686 for (
unsigned i = 0; i < NumInElts; ++i) {
6688 MaskOps[i + NumInElts] = i + WidenNumElts;
6690 return DAG.getVectorShuffle(WidenVT, dl,
6691 GetWidenedVector(
N->getOperand(0)),
6692 GetWidenedVector(
N->getOperand(1)),
6699 SDValue WideVec = DAG.getPOISON(WidenVT);
6701 for (
unsigned I = 0;
I < NumOperands; ++
I)
6703 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6714 for (
unsigned i=0; i < NumOperands; ++i) {
6717 InOp = GetWidenedVector(InOp);
6718 for (
unsigned j = 0;
j < NumInElts; ++
j)
6719 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6721 SDValue UndefVal = DAG.getPOISON(EltVT);
6722 for (; Idx < WidenNumElts; ++Idx)
6723 Ops[Idx] = UndefVal;
6724 return DAG.getBuildVector(WidenVT, dl,
Ops);
6727SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6728 EVT VT =
N->getValueType(0);
6729 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6730 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6737SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6738 EVT VT =
N->getValueType(0);
6740 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6745 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6747 InOp = GetWidenedVector(InOp);
6753 if (IdxVal == 0 && InVT == WidenVT)
6760 assert(IdxVal % VTNumElts == 0 &&
6761 "Expected Idx to be a multiple of subvector minimum vector length");
6762 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6775 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6776 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6777 "down type's element count");
6784 for (;
I < VTNumElts / GCD; ++
I)
6786 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6787 for (;
I < WidenNumElts / GCD; ++
I)
6795 Align Alignment = DAG.getReducedAlign(InVT,
false);
6809 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6816 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6817 return DAG.getMaskedLoad(
6818 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6826 for (i = 0; i < VTNumElts; ++i)
6827 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6829 SDValue UndefVal = DAG.getPOISON(EltVT);
6830 for (; i < WidenNumElts; ++i)
6832 return DAG.getBuildVector(WidenVT, dl,
Ops);
6838 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6843SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6844 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6847 N->getOperand(1),
N->getOperand(2));
6856 "Load width must be less than or equal to first value type width");
6865 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6882 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6893 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6894 EVT LdVT =
LD->getMemoryVT();
6903 TypeSize WidthDiff = WidenWidth - LdWidth;
6906 std::optional<EVT> FirstVT =
6907 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6914 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6917 Chain, BasePtr,
LD->getMemOperand());
6921 FirstVTWidth, dl, DAG);
6939 if (!
LD->getMemoryVT().isByteSized()) {
6941 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6943 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6952 EVT VT =
LD->getValueType(0);
6953 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6954 EVT WideMaskVT = getSetCCResultType(WideVT);
6957 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6958 TLI.isTypeLegal(WideMaskVT)) {
6961 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6965 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6966 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6978 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6980 Result = GenWidenVectorLoads(LdChain, LD);
6987 if (LdChain.
size() == 1)
6988 NewChain = LdChain[0];
6994 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7005 SDValue NewLoad = DAG.getMaskedLoad(
7006 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
7007 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
7008 LD->getAddressingMode(),
LD->getExtensionType());
7018 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7020 SDValue EVL =
N->getVectorLength();
7027 "Unable to widen binary VP op");
7028 Mask = GetWidenedVector(Mask);
7029 assert(
Mask.getValueType().getVectorElementCount() ==
7030 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7031 .getVectorElementCount() &&
7032 "Unable to widen vector load");
7035 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
7036 N->getBasePtr(),
N->getOffset(), Mask, EVL,
7037 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
7045 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7047 SDValue EVL =
N->getVectorLength();
7053 "Unable to widen binary VP op");
7054 Mask = GetWidenedVector(Mask);
7055 assert(
Mask.getValueType().getVectorElementCount() ==
7056 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7057 .getVectorElementCount() &&
7058 "Unable to widen vector load");
7060 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
7061 Mask, EVL,
N->getMemOperand());
7074 "Unable to widen VP strided load");
7075 Mask = GetWidenedVector(Mask);
7077 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7078 assert(
Mask.getValueType().getVectorElementCount() ==
7080 "Data and mask vectors should have the same number of elements");
7082 SDValue Res = DAG.getStridedLoadVP(
7083 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
7084 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
7085 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
7086 N->isExpandingLoad());
7094SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
7099 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
7101 Mask.getValueType().getVectorElementType(),
7104 SDValue WideVec = ModifyToType(Vec, WideVecVT);
7105 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
7106 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
7108 WideMask, WidePassthru);
7112 EVT VT =
N->getValueType(0);
7113 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7115 EVT MaskVT =
Mask.getValueType();
7116 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7125 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7126 TLI.isTypeLegal(WideMaskVT) &&
7132 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7133 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7137 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7138 N->getMemoryVT(),
N->getMemOperand());
7142 if (!
N->getPassThru()->isUndef()) {
7146 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7147 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7148 DAG.getPOISON(WidenVT), EVL);
7159 Mask = ModifyToType(Mask, WideMaskVT,
true);
7161 SDValue Res = DAG.getMaskedLoad(
7162 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7163 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7164 ExtType,
N->isExpandingLoad());
7173 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7175 EVT MaskVT =
Mask.getValueType();
7176 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7184 Mask = ModifyToType(Mask, WideMaskVT,
true);
7189 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7190 Index = ModifyToType(Index, WideIndexVT);
7196 N->getMemoryVT().getScalarType(), WideEC);
7197 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7198 WideMemVT, dl,
Ops,
N->getMemOperand(),
7199 N->getIndexType(),
N->getExtensionType());
7208 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7216 N->getMemoryVT().getScalarType(), WideEC);
7217 Mask = GetWidenedMask(Mask, WideEC);
7220 Mask,
N->getVectorLength()};
7221 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7222 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7231 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7232 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7260 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7261 return N->getOperand(OpNo).getValueType();
7269 N =
N.getOperand(0);
7271 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7272 if (!
N->getOperand(i)->isUndef())
7274 N =
N.getOperand(0);
7278 N =
N.getOperand(0);
7280 N =
N.getOperand(0);
7307 { MaskVT, MVT::Other },
Ops);
7308 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7316 LLVMContext &Ctx = *DAG.getContext();
7319 if (MaskScalarBits < ToMaskScalBits) {
7323 }
else if (MaskScalarBits > ToMaskScalBits) {
7329 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7331 "Mask should have the right element size by now.");
7334 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7336 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7339 EVT SubVT =
Mask->getValueType(0);
7345 assert((
Mask->getValueType(0) == ToMaskVT) &&
7346 "A mask of ToMaskVT should have been produced by now.");
7356 LLVMContext &Ctx = *DAG.getContext();
7367 EVT CondVT =
Cond->getValueType(0);
7371 EVT VSelVT =
N->getValueType(0);
7383 EVT FinalVT = VSelVT;
7394 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7395 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7402 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7410 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7413 EVT ToMaskVT = VSelVT;
7420 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7436 if (ScalarBits0 != ScalarBits1) {
7437 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7438 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7450 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7451 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7452 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7455 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7463 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7468 unsigned Opcode =
N->getOpcode();
7470 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7471 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7472 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7474 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7480 Cond1 = GetWidenedVector(Cond1);
7488 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7489 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7494 Cond1 = ModifyToType(Cond1, CondWidenVT);
7497 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7498 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7500 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7501 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7503 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7507 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7508 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7511 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7515 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7516 return DAG.getUNDEF(WidenVT);
7520 EVT VT =
N->getValueType(0);
7523 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7527 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7528 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7531 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7532 for (
unsigned i = 0; i != NumElts; ++i) {
7533 int Idx =
N->getMaskElt(i);
7534 if (Idx < (
int)NumElts)
7537 NewMask[i] = Idx - NumElts + WidenNumElts;
7539 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7543 EVT VT =
N->getValueType(0);
7547 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7548 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7554 unsigned IdxVal = WidenNumElts - VTNumElts;
7567 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7570 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7571 "down type's element count");
7574 for (; i < VTNumElts / GCD; ++i)
7576 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7577 for (; i < WidenNumElts / GCD; ++i)
7585 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7586 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7588 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7592SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7593 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7597void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7598 EVT VT =
N->getValueType(0);
7601 unsigned Factor =
N->getNumOperands();
7604 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7608 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7609 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7618 for (
unsigned Idx = 0; Idx != Factor; ++Idx)
7619 Slices[Idx] = Interleaved.
getValue(Idx);
7623 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7624 SDValue Narrow = DAG.getExtractSubvector(
7627 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7628 SetWidenedVector(
SDValue(
N, Idx), Wide);
7634 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7635 EVT SourceVT =
N->getOperand(0).getValueType();
7640 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7641 N->getOperand(0), 0);
7642 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7643 N->getOperand(2), 0);
7645 N->getOperand(1), WideMask,
N->getFlags());
7648void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7649 EVT VT =
N->getValueType(0);
7652 unsigned Factor =
N->getNumOperands();
7655 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7668 SDValue PackedWidenVec = DAG.getInsertSubvector(
7669 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7673 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7674 NewOps[Idx] = DAG.getExtractSubvector(
7675 DL, WidenVT, PackedWidenVec,
7682 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7687 assert(
N->getValueType(0).isVector() &&
7688 N->getOperand(0).getValueType().isVector() &&
7689 "Operands must be vectors");
7690 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7703 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7704 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7711 InOp1 = GetWidenedVector(InOp1);
7712 InOp2 = GetWidenedVector(InOp2);
7715 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7726 "Input not widened to expected type!");
7728 if (
N->getOpcode() == ISD::VP_SETCC) {
7731 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7732 N->getOperand(2), Mask,
N->getOperand(4));
7734 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7739 assert(
N->getValueType(0).isVector() &&
7740 N->getOperand(1).getValueType().isVector() &&
7741 "Operands must be vectors");
7742 EVT VT =
N->getValueType(0);
7743 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7753 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7758 for (
unsigned i = 0; i != NumElts; ++i) {
7759 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7760 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7762 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7763 {Chain, LHSElem, RHSElem, CC});
7764 Chains[i] = Scalars[i].getValue(1);
7765 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7766 DAG.getBoolConstant(
true, dl, EltVT, VT),
7767 DAG.getBoolConstant(
false, dl, EltVT, VT));
7771 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7773 return DAG.getBuildVector(WidenVT, dl, Scalars);
7779bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7780 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7784 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7787 switch (
N->getOpcode()) {
7790 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7798 Res = WidenVecOp_FAKE_USE(
N);
7804 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7808 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7809 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7810 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7815 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7817 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7818 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7820 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7821 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7831 Res = WidenVecOp_UnrollVectorOp(
N);
7838 Res = WidenVecOp_EXTEND(
N);
7843 Res = WidenVecOp_CMP(
N);
7861 Res = WidenVecOp_Convert(
N);
7866 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7884 Res = WidenVecOp_VECREDUCE(
N);
7888 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7890 case ISD::VP_REDUCE_FADD:
7891 case ISD::VP_REDUCE_SEQ_FADD:
7892 case ISD::VP_REDUCE_FMUL:
7893 case ISD::VP_REDUCE_SEQ_FMUL:
7894 case ISD::VP_REDUCE_ADD:
7895 case ISD::VP_REDUCE_MUL:
7896 case ISD::VP_REDUCE_AND:
7897 case ISD::VP_REDUCE_OR:
7898 case ISD::VP_REDUCE_XOR:
7899 case ISD::VP_REDUCE_SMAX:
7900 case ISD::VP_REDUCE_SMIN:
7901 case ISD::VP_REDUCE_UMAX:
7902 case ISD::VP_REDUCE_UMIN:
7903 case ISD::VP_REDUCE_FMAX:
7904 case ISD::VP_REDUCE_FMIN:
7905 case ISD::VP_REDUCE_FMAXIMUM:
7906 case ISD::VP_REDUCE_FMINIMUM:
7907 Res = WidenVecOp_VP_REDUCE(
N);
7911 Res = WidenVecOp_CttzElements(
N);
7913 case ISD::VP_CTTZ_ELTS:
7914 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7915 Res = WidenVecOp_VP_CttzElements(
N);
7918 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7921 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
7926 if (!Res.
getNode())
return false;
7934 if (
N->isStrictFPOpcode())
7936 "Invalid operand expansion");
7939 "Invalid operand expansion");
7941 ReplaceValueWith(
SDValue(
N, 0), Res);
7947 EVT VT =
N->getValueType(0);
7952 "Unexpected type action");
7953 InOp = GetWidenedVector(InOp);
7956 "Input wasn't widened!");
7964 EVT FixedEltVT = FixedVT.getVectorElementType();
7965 if (TLI.isTypeLegal(FixedVT) &&
7967 FixedEltVT == InEltVT) {
7969 "Not enough elements in the fixed type for the operand!");
7971 "We can't have the same type as we started with!");
7973 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7975 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7984 return WidenVecOp_Convert(
N);
7989 switch (
N->getOpcode()) {
8004 EVT OpVT =
N->getOperand(0).getValueType();
8005 EVT ResVT =
N->getValueType(0);
8012 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
8013 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
8019 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
8020 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
8022 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
8029 return DAG.UnrollVectorOp(
N);
8034 EVT ResultVT =
N->getValueType(0);
8036 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
8039 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
8045 {WideArg,
Test},
N->getFlags());
8051 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
8053 EVT OpVT =
N->getOperand(0).getValueType();
8056 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
8061 EVT VT =
N->getValueType(0);
8067 "Unexpected type action");
8068 InOp = GetWidenedVector(InOp);
8070 unsigned Opcode =
N->getOpcode();
8075 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
8078 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
8079 return DAG.getNode(Opcode, dl, VT,
Op);
8086 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
8088 if (
N->isStrictFPOpcode()) {
8090 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8093 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8094 {
N->getOperand(0), InOp });
8099 Res = MakeConvertNode(WideVT, InOp);
8101 return DAG.getExtractSubvector(dl, VT, Res, 0);
8109 if (
N->isStrictFPOpcode()) {
8112 for (
unsigned i=0; i < NumElts; ++i) {
8113 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8114 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
8118 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8120 for (
unsigned i = 0; i < NumElts; ++i) {
8121 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8122 Ops[i] = MakeConvertNode(EltVT, Elt);
8126 return DAG.getBuildVector(VT, dl,
Ops);
8130 EVT DstVT =
N->getValueType(0);
8131 SDValue Src = GetWidenedVector(
N->getOperand(0));
8132 EVT SrcVT = Src.getValueType();
8139 if (TLI.isTypeLegal(WideDstVT)) {
8141 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
8144 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
8148 return DAG.UnrollVectorOp(
N);
8152 EVT VT =
N->getValueType(0);
8153 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8161 if (!VT.
isVector() && VT != MVT::x86mmx &&
8165 if (TLI.isTypeLegal(NewVT)) {
8167 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8179 ElementCount NewNumElts =
8181 .divideCoefficientBy(EltSize);
8183 if (TLI.isTypeLegal(NewVT)) {
8185 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8190 return CreateStackStoreLoad(InOp, VT);
8198 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8199 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8204 EVT VT =
N->getValueType(0);
8206 EVT InVT =
N->getOperand(0).getValueType();
8211 unsigned NumOperands =
N->getNumOperands();
8212 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8214 for (i = 1; i < NumOperands; ++i)
8215 if (!
N->getOperand(i).isUndef())
8218 if (i == NumOperands)
8219 return GetWidenedVector(
N->getOperand(0));
8229 for (
unsigned i=0; i < NumOperands; ++i) {
8233 "Unexpected type action");
8234 InOp = GetWidenedVector(InOp);
8235 for (
unsigned j = 0;
j < NumInElts; ++
j)
8236 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8238 return DAG.getBuildVector(VT, dl,
Ops);
8241SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8242 EVT VT =
N->getValueType(0);
8247 SubVec = GetWidenedVector(SubVec);
8252 bool IndicesValid =
false;
8255 IndicesValid =
true;
8259 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8260 Attribute::VScaleRange);
8265 IndicesValid =
true;
8271 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8277 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8284 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8291 Align Alignment = DAG.getReducedAlign(VT,
false);
8306 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8314 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8315 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8320 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8325 unsigned Idx =
N->getConstantOperandVal(2);
8331 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8337SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8338 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8340 N->getValueType(0), InOp,
N->getOperand(1));
8343SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8344 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8346 N->getValueType(0), InOp,
N->getOperand(1));
8349SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8351 EVT ResVT =
N->getValueType(0);
8354 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8360 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8368 "Widened input size must be a multiple of result element size");
8371 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8373 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8374 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8382 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8383 return TLI.scalarizeVectorStore(ST, DAG);
8385 if (
ST->isTruncatingStore())
8386 return TLI.scalarizeVectorStore(ST, DAG);
8396 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8397 EVT WideMaskVT = getSetCCResultType(WideVT);
8399 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8400 TLI.isTypeLegal(WideMaskVT)) {
8403 StVal = GetWidenedVector(StVal);
8405 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8407 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8408 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8409 ST->getAddressingMode());
8413 if (GenWidenVectorStores(StChain, ST)) {
8414 if (StChain.
size() == 1)
8423 SDValue WideStVal = GetWidenedVector(StVal);
8427 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8428 ST->getOffset(), Mask,
ST->getMemoryVT(),
8429 ST->getMemOperand(),
ST->getAddressingMode(),
8430 ST->isTruncatingStore());
8437 EVT StVT =
ST->getMemoryVT();
8440 SDValue StVal = GetWidenedVector(
ST->getVal());
8445 TypeSize WidthDiff = WidenWidth - StWidth;
8451 std::optional<EVT> FirstVT =
8452 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8457 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8463 ST->getBasePtr(),
ST->getMemOperand());
8466SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8467 assert((OpNo == 1 || OpNo == 3) &&
8468 "Can widen only data or mask operand of vp_store");
8476 StVal = GetWidenedVector(StVal);
8482 "Unable to widen VP store");
8483 Mask = GetWidenedVector(Mask);
8485 Mask = GetWidenedVector(Mask);
8491 "Unable to widen VP store");
8492 StVal = GetWidenedVector(StVal);
8495 assert(
Mask.getValueType().getVectorElementCount() ==
8497 "Mask and data vectors should have the same number of elements");
8498 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8499 ST->getOffset(), Mask,
ST->getVectorLength(),
8500 ST->getMemoryVT(),
ST->getMemOperand(),
8501 ST->getAddressingMode(),
ST->isTruncatingStore(),
8502 ST->isCompressingStore());
8507 assert((OpNo == 1 || OpNo == 4) &&
8508 "Can widen only data or mask operand of vp_strided_store");
8517 "Unable to widen VP strided store");
8521 "Unable to widen VP strided store");
8523 StVal = GetWidenedVector(StVal);
8524 Mask = GetWidenedVector(Mask);
8527 Mask.getValueType().getVectorElementCount() &&
8528 "Data and mask vectors should have the same number of elements");
8530 return DAG.getStridedStoreVP(
8537SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8538 assert((OpNo == 1 || OpNo == 4) &&
8539 "Can widen only data or mask operand of mstore");
8542 EVT MaskVT =
Mask.getValueType();
8547 EVT WideVT, WideMaskVT;
8550 StVal = GetWidenedVector(StVal);
8557 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8564 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8566 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8567 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8576 Mask = ModifyToType(Mask, WideMaskVT,
true);
8579 Mask = ModifyToType(Mask, WideMaskVT,
true);
8581 StVal = ModifyToType(StVal, WideVT);
8584 assert(
Mask.getValueType().getVectorElementCount() ==
8586 "Mask and data vectors should have the same number of elements");
8593SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8594 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8596 SDValue DataOp = MG->getPassThru();
8598 SDValue Scale = MG->getScale();
8606 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8607 MG->getMemOperand(), MG->getIndexType(),
8608 MG->getExtensionType());
8614SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8623 DataOp = GetWidenedVector(DataOp);
8627 EVT IndexVT =
Index.getValueType();
8630 Index = ModifyToType(Index, WideIndexVT);
8633 EVT MaskVT =
Mask.getValueType();
8636 Mask = ModifyToType(Mask, WideMaskVT,
true);
8641 }
else if (OpNo == 4) {
8643 Index = GetWidenedVector(Index);
8649 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8654SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8663 DataOp = GetWidenedVector(DataOp);
8664 Index = GetWidenedVector(Index);
8666 Mask = GetWidenedMask(Mask, WideEC);
8669 }
else if (OpNo == 3) {
8671 Index = GetWidenedVector(Index);
8678 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8683 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8684 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8686 EVT VT =
N->getValueType(0);
8701 SVT, InOp0, InOp1,
N->getOperand(2));
8707 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8709 EVT OpVT =
N->getOperand(0).getValueType();
8712 return DAG.getNode(ExtendCode, dl, VT, CC);
8722 EVT VT =
N->getValueType(0);
8724 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8731 for (
unsigned i = 0; i != NumElts; ++i) {
8732 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8733 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8735 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8736 {Chain, LHSElem, RHSElem, CC});
8737 Chains[i] = Scalars[i].getValue(1);
8738 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8739 DAG.getBoolConstant(
true, dl, EltVT, VT),
8740 DAG.getBoolConstant(
false, dl, EltVT, VT));
8744 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8746 return DAG.getBuildVector(VT, dl, Scalars);
8770 SDValue Op = GetWidenedVector(
N->getOperand(0));
8771 EVT VT =
N->getValueType(0);
8772 EVT OrigVT =
N->getOperand(0).getValueType();
8773 EVT WideVT =
Op.getValueType();
8775 SDNodeFlags
Flags =
N->getFlags();
8777 unsigned Opc =
N->getOpcode();
8779 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8780 assert(NeutralElem &&
"Neutral element must exist");
8790 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8797 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8798 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8804 unsigned GCD = std::gcd(OrigElts, WideElts);
8807 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8808 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8809 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8810 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8813 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8814 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8816 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8825 EVT VT =
N->getValueType(0);
8827 EVT WideVT =
Op.getValueType();
8829 SDNodeFlags
Flags =
N->getFlags();
8831 unsigned Opc =
N->getOpcode();
8833 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8843 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8846 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8847 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8853 unsigned GCD = std::gcd(OrigElts, WideElts);
8856 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8857 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8858 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8859 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8862 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8863 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8865 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8869 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8872 SDValue Op = GetWidenedVector(
N->getOperand(1));
8874 Op.getValueType().getVectorElementCount());
8876 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8877 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8885 EVT VT =
N->getValueType(0);
8889 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8890 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8895 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8902 TLI.getTypeToTransformTo(*DAG.getContext(),
Source.getValueType());
8906 WideSource = GetWidenedVector(Source);
8911 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8914 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8921 EVT SrcVT =
Source.getValueType();
8925 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8926 {Source, Mask, N->getOperand(2)},
N->getFlags());
8929SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8932 EVT OrigMaskVT =
Mask.getValueType();
8933 SDValue WideMask = GetWidenedVector(Mask);
8939 if (OrigElts != WideElts) {
8940 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8942 Mask, DAG.getVectorIdxConstant(0,
DL));
8949SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
8952 EVT ResVT =
N->getValueType(0);
8953 EVT SourceVT =
N->getOperand(0).getValueType();
8954 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8959 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
8960 N->getOperand(0), 0);
8961 SDValue WideMask = DAG.getInsertSubvector(
8962 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
8964 N->getOperand(1), WideMask,
N->getFlags());
8965 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
8969 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
8975 return TLI.expandVectorMatch(
N, DAG);
8977 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
8981 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
8982 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
8985 N->getOperand(0), WideNeedle,
N->getOperand(2),
9003 unsigned WidenEx = 0) {
9008 unsigned AlignInBits =
Align*8;
9010 EVT RetVT = WidenEltVT;
9015 if (Width == WidenEltWidth)
9026 (WidenWidth % MemVTWidth) == 0 &&
9028 (MemVTWidth <= Width ||
9029 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9030 if (MemVTWidth == WidenWidth)
9049 (WidenWidth % MemVTWidth) == 0 &&
9051 (MemVTWidth <= Width ||
9052 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9061 return std::nullopt;
9072 unsigned Start,
unsigned End) {
9073 SDLoc dl(LdOps[Start]);
9074 EVT LdTy = LdOps[Start].getValueType();
9082 for (
unsigned i = Start + 1; i != End; ++i) {
9083 EVT NewLdTy = LdOps[i].getValueType();
9084 if (NewLdTy != LdTy) {
9103 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9104 EVT LdVT =
LD->getMemoryVT();
9114 AAMDNodes AAInfo =
LD->getAAInfo();
9118 TypeSize WidthDiff = WidenWidth - LdWidth;
9125 std::optional<EVT> FirstVT =
9126 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
9133 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
9138 std::optional<EVT> NewVT = FirstVT;
9139 TypeSize RemainingWidth = LdWidth;
9140 TypeSize NewVTWidth = FirstVTWidth;
9142 RemainingWidth -= NewVTWidth;
9149 NewVTWidth = NewVT->getSizeInBits();
9155 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9156 LD->getBaseAlign(), MMOFlags, AAInfo);
9168 uint64_t ScaledOffset = 0;
9169 MachinePointerInfo MPI =
LD->getPointerInfo();
9175 for (EVT MemVT : MemVTs) {
9176 Align NewAlign = ScaledOffset == 0
9177 ?
LD->getBaseAlign()
9180 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
9188 unsigned End = LdOps.
size();
9199 EVT LdTy = LdOps[i].getValueType();
9202 for (--i; i >= 0; --i) {
9203 LdTy = LdOps[i].getValueType();
9210 ConcatOps[--Idx] = LdOps[i];
9211 for (--i; i >= 0; --i) {
9212 EVT NewLdTy = LdOps[i].getValueType();
9213 if (NewLdTy != LdTy) {
9223 for (;
j != End-Idx; ++
j)
9224 WidenOps[j] = ConcatOps[Idx+j];
9226 WidenOps[j] = DAG.getPOISON(LdTy);
9233 ConcatOps[--Idx] = LdOps[i];
9238 ArrayRef(&ConcatOps[Idx], End - Idx));
9244 SDValue UndefVal = DAG.getPOISON(LdTy);
9247 for (; i != End-Idx; ++i)
9248 WidenOps[i] = ConcatOps[Idx+i];
9250 WidenOps[i] = UndefVal;
9261 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9262 EVT LdVT =
LD->getMemoryVT();
9271 AAMDNodes AAInfo =
LD->getAAInfo();
9285 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9286 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9292 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9293 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9294 LD->getBaseAlign(), MMOFlags, AAInfo);
9299 SDValue UndefVal = DAG.getPOISON(EltVT);
9300 for (; i != WidenNumElts; ++i)
9303 return DAG.getBuildVector(WidenVT, dl,
Ops);
9314 AAMDNodes AAInfo =
ST->getAAInfo();
9315 SDValue ValOp = GetWidenedVector(
ST->getValue());
9318 EVT StVT =
ST->getMemoryVT();
9326 "Mismatch between store and value types");
9330 MachinePointerInfo MPI =
ST->getPointerInfo();
9331 uint64_t ScaledOffset = 0;
9340 std::optional<EVT> NewVT =
9345 TypeSize NewVTWidth = NewVT->getSizeInBits();
9348 StWidth -= NewVTWidth;
9349 MemVTs.
back().second++;
9353 for (
const auto &Pair : MemVTs) {
9354 EVT NewVT = Pair.first;
9355 unsigned Count = Pair.second;
9361 Align NewAlign = ScaledOffset == 0
9362 ?
ST->getBaseAlign()
9364 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9365 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9381 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9382 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9383 ST->getBaseAlign(), MMOFlags, AAInfo);
9400 bool FillWithZeroes) {
9405 "input and widen element type must match");
9407 "cannot modify scalable vectors in this way");
9420 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9422 for (
unsigned i = 1; i != NumConcat; ++i)
9429 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9432 "Scalable vectors should have been handled already.");
9440 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9442 for (Idx = 0; Idx < MinNumElts; ++Idx)
9443 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9445 SDValue UndefVal = DAG.getPOISON(EltVT);
9446 for (; Idx < WidenNumElts; ++Idx)
9447 Ops[Idx] = UndefVal;
9449 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9450 if (!FillWithZeroes)
9454 "We expect to never want to FillWithZeroes for non-integral types.");
9457 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9458 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9460 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9461 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.
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 BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), 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_MATCH
VECTOR_MATCH - this corresponds to the llvm.experimental.vector.match intrinsic.
@ 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.