35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
47 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
50 switch (
N->getOpcode()) {
53 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
62 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
70 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
73 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
79 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
91 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
93 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
99 R = ScalarizeVecRes_VecInregOp(
N);
151 R = ScalarizeVecRes_UnaryOp(
N);
154 R = ScalarizeVecRes_ADDRSPACECAST(
N);
160 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
219 R = ScalarizeVecRes_BinOp(
N);
226 R = ScalarizeVecRes_MaskedBinOp(
N);
231 R = ScalarizeVecRes_CMP(
N);
237 R = ScalarizeVecRes_TernaryOp(
N);
240#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
241 case ISD::STRICT_##DAGN:
242#include "llvm/IR/ConstrainedOps.def"
243 R = ScalarizeVecRes_StrictFPOp(
N);
248 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
257 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
267 R = ScalarizeVecRes_FIX(
N);
273 SetScalarizedVector(
SDValue(
N, ResNo), R);
277 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
278 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
279 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
285 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
286 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
288 EVT MaskVT =
Mask.getValueType();
293 Mask = GetScalarizedVector(Mask);
302 DAG.getConstant(1,
DL,
LHS.getValueType()));
304 LHS.getValueType(),
LHS, Divisor);
312 if (getTypeAction(
LHS.getValueType()) ==
314 LHS = GetScalarizedVector(
LHS);
315 RHS = GetScalarizedVector(
RHS);
317 EVT VT =
LHS.getValueType().getVectorElementType();
318 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
319 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
322 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
323 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
327 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
328 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
329 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
330 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
335 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
336 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
343DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
345 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
346 "Unexpected vector type!");
347 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
349 EVT VT0 =
N->getValueType(0);
350 EVT VT1 =
N->getValueType(1);
354 DAG.getNode(
N->getOpcode(), dl,
355 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
359 unsigned OtherNo = 1 - ResNo;
360 EVT OtherVT =
N->getValueType(OtherNo);
362 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
366 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
369 return SDValue(ScalarNode, ResNo);
374 unsigned NumOpers =
N->getNumOperands();
376 EVT ValueVTs[] = {VT, MVT::Other};
385 for (
unsigned i = 1; i < NumOpers; ++i) {
391 Oper = GetScalarizedVector(Oper);
400 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
401 Opers,
N->getFlags());
412 EVT ResVT =
N->getValueType(0);
413 EVT OvVT =
N->getValueType(1);
417 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
418 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
421 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
422 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
423 ScalarLHS = ElemsLHS[0];
424 ScalarRHS = ElemsRHS[0];
427 SDVTList ScalarVTs = DAG.getVTList(
429 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
430 {ScalarLHS, ScalarRHS},
N->getFlags())
434 unsigned OtherNo = 1 - ResNo;
435 EVT OtherVT =
N->getValueType(OtherNo);
437 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
441 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
444 return SDValue(ScalarNode, ResNo);
449 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
450 return GetScalarizedVector(
Op);
453SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
455 SDValue SourceValue =
N->getOperand(0);
456 SDValue SinkValue =
N->getOperand(1);
457 SDValue EltSizeInBytes =
N->getOperand(2);
458 SDValue LaneOffset =
N->getOperand(3);
466 if (IsReadAfterWrite)
474 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
479 return DAG.getNode(
ISD::OR,
DL, CmpVT, Cmp,
486 Op = GetScalarizedVector(
Op);
487 EVT NewVT =
N->getValueType(0).getVectorElementType();
492SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
502SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
504 N->getValueType(0).getVectorElementType(),
505 N->getOperand(0),
N->getOperand(1));
511 EVT OpVT =
Op.getValueType();
515 Op = GetScalarizedVector(
Op);
518 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
521 N->getValueType(0).getVectorElementType(),
Op,
525SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
528 EVT OpVT =
Op.getValueType();
532 Op = GetScalarizedVector(
Op);
535 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
538 N->getValueType(0).getVectorElementType(),
Op,
542SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
545 EVT OpVT =
Op.getValueType();
548 Op = GetScalarizedVector(
Op);
551 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
554 N->getValueType(0).getVectorElementType(),
Op,
555 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
558SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
559 SDValue Op = GetScalarizedVector(
N->getOperand(0));
560 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
564SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
569 if (
Op.getValueType() != EltVT)
577 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
578 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
588 assert(
N->isUnindexed() &&
"Indexed vector load?");
592 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
593 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
594 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
595 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
607 EVT OpVT =
Op.getValueType();
617 Op = GetScalarizedVector(
Op);
620 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
622 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
628 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
629 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
630 LHS, DAG.getValueType(ExtVT));
637 EVT OpVT =
Op.getValueType();
642 Op = GetScalarizedVector(
Op);
644 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
647 switch (
N->getOpcode()) {
659SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
662 EVT OpVT =
Op.getValueType();
672 Op = GetScalarizedVector(
Op);
675 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
678 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
679 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
680 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
683SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
695 EVT OpVT =
Cond.getValueType();
704 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
707 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
709 TLI.getBooleanContents(
false,
false);
716 if (TLI.getBooleanContents(
false,
false) !=
717 TLI.getBooleanContents(
false,
true)) {
721 EVT OpVT =
Cond->getOperand(0).getValueType();
723 VecBool = TLI.getBooleanContents(OpVT);
728 EVT CondVT =
Cond.getValueType();
729 if (ScalarBool != VecBool) {
730 switch (ScalarBool) {
738 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
745 Cond, DAG.getValueType(MVT::i1));
751 auto BoolVT = getSetCCResultType(CondVT);
752 if (BoolVT.bitsLT(CondVT))
755 return DAG.getSelect(SDLoc(
N),
757 GetScalarizedVector(
N->getOperand(2)));
761 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
762 return DAG.getSelect(SDLoc(
N),
763 LHS.getValueType(),
N->getOperand(0),
LHS,
764 GetScalarizedVector(
N->getOperand(2)));
768 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
770 N->getOperand(0),
N->getOperand(1),
771 LHS, GetScalarizedVector(
N->getOperand(3)),
776 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
779SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
783 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
785 return GetScalarizedVector(
N->getOperand(
Op));
788SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
790 EVT SrcVT = Src.getValueType();
795 Src = GetScalarizedVector(Src);
799 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
801 EVT DstVT =
N->getValueType(0).getVectorElementType();
802 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
806 assert(
N->getValueType(0).isVector() &&
807 N->getOperand(0).getValueType().isVector() &&
808 "Operand types must be vectors");
811 EVT OpVT =
LHS.getValueType();
812 EVT NVT =
N->getValueType(0).getVectorElementType();
817 LHS = GetScalarizedVector(
LHS);
818 RHS = GetScalarizedVector(
RHS);
821 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
822 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
832 return DAG.getNode(ExtendCode,
DL, NVT, Res);
843 Arg = GetScalarizedVector(Arg);
846 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
855 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
862bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
868 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
871 switch (
N->getOpcode()) {
874 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
881 Res = ScalarizeVecOp_BITCAST(
N);
884 Res = ScalarizeVecOp_FAKE_USE(
N);
898 Res = ScalarizeVecOp_UnaryOp(
N);
903 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
906 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
907 "Unexpected vector type!");
908 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
910 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
911 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
919 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
922 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
925 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
928 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
931 Res = ScalarizeVecOp_VSELECT(
N);
934 Res = ScalarizeVecOp_VSETCC(
N);
938 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
947 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
950 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
953 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
956 Res = ScalarizeVecOp_FP_EXTEND(
N);
973 Res = ScalarizeVecOp_VECREDUCE(
N);
977 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
981 Res = ScalarizeVecOp_CMP(
N);
984 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
988 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
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::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1330 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1333 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1334 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1343 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1355void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1360 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1363 switch (
N->getOpcode()) {
1366 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1375 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1383 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1399 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1402 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1414 case ISD::VP_LOAD_FF:
1417 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1424 case ISD::VP_GATHER:
1428 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1432 SplitVecRes_SETCC(
N,
Lo,
Hi);
1435 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1442 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1445 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1448 SplitVecRes_VECTOR_INTERLEAVE(
N);
1451 SplitVecRes_VAARG(
N,
Lo,
Hi);
1457 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1464 case ISD::VP_BITREVERSE:
1472 case ISD::VP_CTLZ_ZERO_POISON:
1474 case ISD::VP_CTTZ_ZERO_POISON:
1489 case ISD::VP_FFLOOR:
1494 case ISD::VP_FNEARBYINT:
1499 case ISD::VP_FP_EXTEND:
1501 case ISD::VP_FP_ROUND:
1503 case ISD::VP_FP_TO_SINT:
1505 case ISD::VP_FP_TO_UINT:
1511 case ISD::VP_LLRINT:
1513 case ISD::VP_FROUND:
1515 case ISD::VP_FROUNDEVEN:
1524 case ISD::VP_FROUNDTOZERO:
1526 case ISD::VP_SINT_TO_FP:
1528 case ISD::VP_TRUNCATE:
1530 case ISD::VP_UINT_TO_FP:
1535 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1538 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1544 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1550 case ISD::VP_SIGN_EXTEND:
1551 case ISD::VP_ZERO_EXTEND:
1552 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1576 case ISD::VP_FMINNUM:
1579 case ISD::VP_FMAXNUM:
1581 case ISD::VP_FMINIMUM:
1583 case ISD::VP_FMAXIMUM:
1592 case ISD::OR:
case ISD::VP_OR:
1612 case ISD::VP_FCOPYSIGN:
1613 SplitVecRes_BinOp(
N,
Lo,
Hi);
1619 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1626 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1630 SplitVecRes_CMP(
N,
Lo,
Hi);
1633#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1634 case ISD::STRICT_##DAGN:
1635#include "llvm/IR/ConstrainedOps.def"
1636 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1641 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1650 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1660 SplitVecRes_FIX(
N,
Lo,
Hi);
1662 case ISD::EXPERIMENTAL_VP_SPLICE:
1663 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1665 case ISD::EXPERIMENTAL_VP_REVERSE:
1666 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1672 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1675 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1684void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1686 uint64_t *ScaledOffset) {
1691 SDValue BytesIncrement = DAG.getVScale(
1694 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1696 *ScaledOffset += IncrementSize;
1706std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1707 return SplitMask(Mask, SDLoc(Mask));
1710std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1713 EVT MaskVT =
Mask.getValueType();
1715 GetSplitVector(Mask, MaskLo, MaskHi);
1717 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1718 return std::make_pair(MaskLo, MaskHi);
1723 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1725 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1728 const SDNodeFlags
Flags =
N->getFlags();
1729 unsigned Opcode =
N->getOpcode();
1730 if (
N->getNumOperands() == 2) {
1731 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1732 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1736 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1737 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1740 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1743 std::tie(EVLLo, EVLHi) =
1744 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1747 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1749 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1755 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1757 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1758 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(2));
1761 const SDNodeFlags
Flags =
N->getFlags();
1762 unsigned Opcode =
N->getOpcode();
1763 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1765 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1772 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1774 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1776 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1779 const SDNodeFlags
Flags =
N->getFlags();
1780 unsigned Opcode =
N->getOpcode();
1781 if (
N->getNumOperands() == 3) {
1782 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1783 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1787 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1788 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1791 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1794 std::tie(EVLLo, EVLHi) =
1795 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1798 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1800 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1804 LLVMContext &Ctxt = *DAG.getContext();
1810 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1812 GetSplitVector(
LHS, LHSLo, LHSHi);
1813 GetSplitVector(
RHS, RHSLo, RHSHi);
1815 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1816 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1820 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1821 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1826 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1828 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1832 unsigned Opcode =
N->getOpcode();
1833 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1835 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1844 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1851 switch (getTypeAction(InVT)) {
1865 GetExpandedOp(InOp,
Lo,
Hi);
1866 if (DAG.getDataLayout().isBigEndian())
1876 GetSplitVector(InOp,
Lo,
Hi);
1885 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1894 if (DAG.getDataLayout().isBigEndian())
1897 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1899 if (DAG.getDataLayout().isBigEndian())
1905void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1911 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1914 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1919 unsigned LaneOffset =
1922 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1924 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1931 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1934 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1937 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1942 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1944 unsigned NumSubvectors =
N->getNumOperands() / 2;
1945 if (NumSubvectors == 1) {
1946 Lo =
N->getOperand(0);
1947 Hi =
N->getOperand(1);
1952 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1961void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1968 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1983 GetSplitVector(Vec,
Lo,
Hi);
1986 EVT LoVT =
Lo.getValueType();
1996 if (IdxVal + SubElems <= LoElems) {
2004 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
2006 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
2012 SDValue WideSubVec = GetWidenedVector(SubVec);
2014 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2022 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2024 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2025 auto &MF = DAG.getMachineFunction();
2029 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2034 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2035 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
2039 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
2044 MachinePointerInfo MPI =
Load->getPointerInfo();
2045 IncrementPointer(Load, LoVT, MPI, StackPtr);
2048 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
2057 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2062 EVT RHSVT =
RHS.getValueType();
2065 GetSplitVector(
RHS, RHSLo, RHSHi);
2067 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2082 SDValue FpValue =
N->getOperand(0);
2084 GetSplitVector(FpValue, ArgLo, ArgHi);
2086 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2088 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2097 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2101 std::tie(LoVT, HiVT) =
2105 DAG.getValueType(LoVT));
2107 DAG.getValueType(HiVT));
2112 unsigned Opcode =
N->getOpcode();
2119 GetSplitVector(N0, InLo, InHi);
2121 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2126 EVT OutLoVT, OutHiVT;
2127 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2129 assert((2 * OutNumElements) <= InNumElements &&
2130 "Illegal extend vector in reg split");
2139 SmallVector<int, 8> SplitHi(InNumElements, -1);
2140 for (
unsigned i = 0; i != OutNumElements; ++i)
2141 SplitHi[i] = i + OutNumElements;
2142 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2144 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2145 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2150 unsigned NumOps =
N->getNumOperands();
2154 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2164 for (
unsigned i = 1; i <
NumOps; ++i) {
2169 EVT InVT =
Op.getValueType();
2174 GetSplitVector(
Op, OpLo, OpHi);
2176 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2183 EVT LoValueVTs[] = {LoVT, MVT::Other};
2184 EVT HiValueVTs[] = {HiVT, MVT::Other};
2185 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2187 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2193 Lo.getValue(1),
Hi.getValue(1));
2197 ReplaceValueWith(
SDValue(
N, 1), Chain);
2200SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2202 EVT VT =
N->getValueType(0);
2213 else if (NE > ResNE)
2217 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2221 for (i = 0; i !=
NE; ++i) {
2222 Operands[0] = Chain;
2223 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2224 SDValue Operand =
N->getOperand(j);
2228 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2230 Operands[
j] = Operand;
2234 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2242 for (; i < ResNE; ++i)
2243 Scalars.
push_back(DAG.getPOISON(EltVT));
2247 ReplaceValueWith(
SDValue(
N, 1), Chain);
2251 return DAG.getBuildVector(VecVT, dl, Scalars);
2254void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2257 EVT ResVT =
N->getValueType(0);
2258 EVT OvVT =
N->getValueType(1);
2259 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2260 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2261 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2263 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2265 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2266 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2268 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2269 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2272 unsigned Opcode =
N->getOpcode();
2273 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2274 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2276 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2278 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2284 unsigned OtherNo = 1 - ResNo;
2285 EVT OtherVT =
N->getValueType(OtherNo);
2287 SetSplitVector(
SDValue(
N, OtherNo),
2293 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2297void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2303 GetSplitVector(Vec,
Lo,
Hi);
2306 unsigned IdxVal = CIdx->getZExtValue();
2307 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2308 if (IdxVal < LoNumElts) {
2310 Lo.getValueType(),
Lo, Elt, Idx);
2313 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2333 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2335 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2336 auto &MF = DAG.getMachineFunction();
2340 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2345 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2346 Store = DAG.getTruncStore(
2352 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2355 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2359 MachinePointerInfo MPI =
Load->getPointerInfo();
2360 IncrementPointer(Load, LoVT, MPI, StackPtr);
2362 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2365 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2366 if (LoVT !=
Lo.getValueType())
2368 if (HiVT !=
Hi.getValueType())
2376 assert(
N->getValueType(0).isScalableVector() &&
2377 "Only scalable vectors are supported for STEP_VECTOR");
2378 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2399 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2400 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2402 Hi = DAG.getPOISON(HiVT);
2412 "Extended load during type legalization!");
2414 EVT VT =
LD->getValueType(0);
2416 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2424 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2425 Ch, Ptr,
LD->getMemOperand());
2430 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2432 Lo = DAG.getBitcast(LoVT, ExtractLo);
2433 Hi = DAG.getBitcast(HiVT, ExtractHi);
2445 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2451 EVT MemoryVT =
LD->getMemoryVT();
2453 AAMDNodes AAInfo =
LD->getAAInfo();
2455 EVT LoMemVT, HiMemVT;
2456 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2460 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2461 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2462 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2467 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2470 MachinePointerInfo MPI;
2471 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2474 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2483 ReplaceValueWith(
SDValue(LD, 1), Ch);
2488 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2491 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2497 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2498 Align Alignment =
LD->getBaseAlign();
2501 EVT MemoryVT =
LD->getMemoryVT();
2503 EVT LoMemVT, HiMemVT;
2504 bool HiIsEmpty =
false;
2505 std::tie(LoMemVT, HiMemVT) =
2506 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2511 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2514 GetSplitVector(Mask, MaskLo, MaskHi);
2516 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2521 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2523 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2529 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2530 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2538 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2539 LD->isExpandingLoad());
2541 MachinePointerInfo MPI;
2543 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2545 MPI =
LD->getPointerInfo().getWithOffset(
2548 MMO = DAG.getMachineFunction().getMachineMemOperand(
2550 Alignment,
LD->getAAInfo(),
LD->getRanges());
2552 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2553 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2554 LD->isExpandingLoad());
2564 ReplaceValueWith(
SDValue(LD, 1), Ch);
2570 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2574 Align Alignment =
LD->getBaseAlign();
2581 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2584 GetSplitVector(Mask, MaskLo, MaskHi);
2586 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2590 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2592 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2597 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2600 Hi = DAG.getPOISON(HiVT);
2602 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2603 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2609 "Indexed VP strided load during type legalization!");
2611 "Unexpected indexed variable-length load offset");
2616 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2618 EVT LoMemVT, HiMemVT;
2619 bool HiIsEmpty =
false;
2620 std::tie(LoMemVT, HiMemVT) =
2621 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2626 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2629 GetSplitVector(Mask, LoMask, HiMask);
2631 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2635 std::tie(LoEVL, HiEVL) =
2639 Lo = DAG.getStridedLoadVP(
2666 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2673 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2684 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2692 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2697 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2707 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2710 GetSplitVector(Mask, MaskLo, MaskHi);
2712 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2716 EVT LoMemVT, HiMemVT;
2717 bool HiIsEmpty =
false;
2718 std::tie(LoMemVT, HiMemVT) =
2719 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2721 SDValue PassThruLo, PassThruHi;
2723 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2725 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2727 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2731 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2741 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2744 MachinePointerInfo MPI;
2751 MMO = DAG.getMachineFunction().getMachineMemOperand(
2755 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2767 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2775 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2783 }
Ops = [&]() -> Operands {
2785 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2788 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2791 EVT MemoryVT =
N->getMemoryVT();
2792 Align Alignment =
N->getBaseAlign();
2797 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2799 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2802 EVT LoMemVT, HiMemVT;
2804 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2807 if (getTypeAction(
Ops.Index.getValueType()) ==
2809 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2811 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2814 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2816 Alignment,
N->getAAInfo(),
N->getRanges());
2819 SDValue PassThru = MGT->getPassThru();
2820 SDValue PassThruLo, PassThruHi;
2823 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2825 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2830 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2831 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2832 OpsLo, MMO, IndexTy, ExtType);
2834 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2835 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2836 OpsHi, MMO, IndexTy, ExtType);
2840 std::tie(EVLLo, EVLHi) =
2841 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2843 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2844 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2845 MMO, VPGT->getIndexType());
2847 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2848 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2849 MMO, VPGT->getIndexType());
2859 ReplaceValueWith(
SDValue(
N, 1), Ch);
2873 EVT VecVT =
N->getValueType(0);
2875 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2876 bool HasCustomLowering =
false;
2883 HasCustomLowering =
true;
2889 SDValue Passthru =
N->getOperand(2);
2890 if (!HasCustomLowering) {
2891 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2892 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2899 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2900 std::tie(LoMask, HiMask) = SplitMask(Mask);
2902 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2907 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2908 MachineFunction &MF = DAG.getMachineFunction();
2920 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2922 SDValue Chain = DAG.getEntryNode();
2923 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2927 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2932 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2936 assert(
N->getValueType(0).isVector() &&
2937 N->getOperand(0).getValueType().isVector() &&
2938 "Operand types must be vectors");
2942 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2946 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2948 GetSplitVector(
N->getOperand(0), LL, LH);
2950 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2952 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2954 GetSplitVector(
N->getOperand(1), RL, RH);
2956 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2959 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2960 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2962 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2963 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2964 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2965 std::tie(EVLLo, EVLHi) =
2966 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2967 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2969 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2979 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2983 EVT InVT =
N->getOperand(0).getValueType();
2985 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2987 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2989 const SDNodeFlags
Flags =
N->getFlags();
2990 unsigned Opcode =
N->getOpcode();
2992 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
2993 N->getOperand(3), Flags);
2994 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
2995 N->getOperand(3), Flags);
2998 if (
N->getNumOperands() <= 2) {
3001 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
3002 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
3004 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
3005 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
3010 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
3011 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3014 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3017 std::tie(EVLLo, EVLHi) =
3018 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3021 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
3027 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3031 EVT InVT =
N->getOperand(0).getValueType();
3033 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3035 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3038 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3039 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3040 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
3041 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
3044void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3049 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3050 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3054 EVT InVT =
N->getOperand(0).getValueType();
3056 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3058 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3060 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3061 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3063 SDNode *HiNode =
Hi.getNode();
3064 SDNode *LoNode =
Lo.getNode();
3067 unsigned OtherNo = 1 - ResNo;
3068 EVT OtherVT =
N->getValueType(OtherNo);
3076 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3083 EVT SrcVT =
N->getOperand(0).getValueType();
3084 EVT DestVT =
N->getValueType(0);
3086 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3103 LLVMContext &Ctx = *DAG.getContext();
3107 EVT SplitLoVT, SplitHiVT;
3108 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3109 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3110 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3111 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3112 N->dump(&DAG);
dbgs() <<
"\n");
3113 if (!
N->isVPOpcode()) {
3116 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3118 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3120 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3121 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3127 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
3128 N->getOperand(1),
N->getOperand(2));
3130 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3133 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3136 std::tie(EVLLo, EVLHi) =
3137 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3139 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
3140 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
3145 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3153 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3154 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3160 return N.getResNo() == 0 &&
3164 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3166 ArrayRef<int>
Mask) {
3169 "Expected build vector node.");
3172 for (
unsigned I = 0;
I < NewElts; ++
I) {
3175 unsigned Idx =
Mask[
I];
3177 Ops[
I] = Input2.getOperand(Idx - NewElts);
3179 Ops[
I] = Input1.getOperand(Idx);
3184 return DAG.getBuildVector(NewVT,
DL,
Ops);
3190 SmallVector<int> OrigMask(
N->getMask());
3192 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3193 &
DL](SmallVectorImpl<int> &
Mask) {
3195 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3196 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3207 for (
auto &
P : ShufflesIdxs) {
3208 if (
P.second.size() < 2)
3212 for (
int &Idx : Mask) {
3215 unsigned SrcRegIdx = Idx / NewElts;
3216 if (Inputs[SrcRegIdx].
isUndef()) {
3224 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3229 Idx = MaskElt % NewElts +
3230 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3236 Inputs[
P.second[0]] =
P.first.first;
3237 Inputs[
P.second[1]] =
P.first.second;
3240 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3243 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3244 for (
int &Idx : Mask) {
3247 unsigned SrcRegIdx = Idx / NewElts;
3248 if (Inputs[SrcRegIdx].
isUndef()) {
3255 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3256 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3259 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3261 if (UsedSubVector.count() > 1) {
3263 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3264 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3266 if (Pairs.
empty() || Pairs.
back().size() == 2)
3268 if (UsedSubVector.test(2 *
I)) {
3269 Pairs.
back().emplace_back(
I, 0);
3271 assert(UsedSubVector.test(2 *
I + 1) &&
3272 "Expected to be used one of the subvectors.");
3273 Pairs.
back().emplace_back(
I, 1);
3276 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3278 for (
int &Idx : Mask) {
3281 unsigned SrcRegIdx = Idx / NewElts;
3283 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3284 return Idxs.front().first == SrcRegIdx ||
3285 Idxs.back().first == SrcRegIdx;
3287 if (It == Pairs.
end())
3289 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3290 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3293 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3294 Inputs[Idxs.front().first] = DAG.
getNode(
3296 Inputs[Idxs.front().first].getValueType(),
3297 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3298 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3307 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3311 if (Shuffle->getOperand(0).getValueType() != NewVT)
3314 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3315 !Shuffle->isSplat()) {
3317 }
else if (!Inputs[
I].hasOneUse() &&
3318 !Shuffle->getOperand(1).isUndef()) {
3320 for (
int &Idx : Mask) {
3323 unsigned SrcRegIdx = Idx / NewElts;
3326 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3331 int OpIdx = MaskElt / NewElts;
3345 if (Shuffle->getOperand(
OpIdx).isUndef())
3347 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3348 if (It == std::end(Inputs))
3350 int FoundOp = std::distance(std::begin(Inputs), It);
3353 for (
int &Idx : Mask) {
3356 unsigned SrcRegIdx = Idx / NewElts;
3359 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3364 int MaskIdx = MaskElt / NewElts;
3365 if (
OpIdx == MaskIdx)
3366 Idx = MaskElt % NewElts + FoundOp * NewElts;
3377 for (
int &Idx : Mask) {
3380 unsigned SrcRegIdx = Idx / NewElts;
3383 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3384 int OpIdx = MaskElt / NewElts;
3387 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3393 TryPeekThroughShufflesInputs(OrigMask);
3395 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3396 NewElts](SmallVectorImpl<int> &
Mask) {
3397 SetVector<SDValue> UniqueInputs;
3398 SetVector<SDValue> UniqueConstantInputs;
3399 for (
const auto &
I : Inputs) {
3401 UniqueConstantInputs.
insert(
I);
3402 else if (!
I.isUndef())
3407 if (UniqueInputs.
size() != std::size(Inputs)) {
3408 auto &&UniqueVec = UniqueInputs.
takeVector();
3409 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3410 unsigned ConstNum = UniqueConstantVec.size();
3411 for (
int &Idx : Mask) {
3414 unsigned SrcRegIdx = Idx / NewElts;
3415 if (Inputs[SrcRegIdx].
isUndef()) {
3419 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3420 if (It != UniqueConstantVec.end()) {
3421 Idx = (Idx % NewElts) +
3422 NewElts * std::distance(UniqueConstantVec.begin(), It);
3423 assert(Idx >= 0 &&
"Expected defined mask idx.");
3426 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3427 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3428 Idx = (Idx % NewElts) +
3429 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3430 assert(Idx >= 0 &&
"Expected defined mask idx.");
3432 copy(UniqueConstantVec, std::begin(Inputs));
3433 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3436 MakeUniqueInputs(OrigMask);
3438 copy(Inputs, std::begin(OrigInputs));
3444 unsigned FirstMaskIdx =
High * NewElts;
3447 assert(!Output &&
"Expected default initialized initial value.");
3448 TryPeekThroughShufflesInputs(Mask);
3449 MakeUniqueInputs(Mask);
3451 copy(Inputs, std::begin(TmpInputs));
3454 bool SecondIteration =
false;
3455 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3460 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3461 SecondIteration =
true;
3462 return SecondIteration;
3465 Mask, std::size(Inputs), std::size(Inputs),
3467 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3468 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3469 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3471 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3473 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3474 DAG.getPOISON(NewVT), Mask);
3475 Inputs[Idx] = Output;
3477 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3478 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3479 unsigned Idx2,
bool ) {
3480 if (AccumulateResults(Idx1)) {
3483 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3485 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3486 Inputs[Idx2], Mask);
3490 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3492 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3493 TmpInputs[Idx2], Mask);
3495 Inputs[Idx1] = Output;
3497 copy(OrigInputs, std::begin(Inputs));
3502 EVT OVT =
N->getValueType(0);
3509 const Align Alignment =
3510 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3512 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3513 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3518 ReplaceValueWith(
SDValue(
N, 1), Chain);
3523 EVT DstVTLo, DstVTHi;
3524 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3528 EVT SrcVT =
N->getOperand(0).getValueType();
3530 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3532 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3534 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3535 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3541 GetSplitVector(
N->getOperand(0), InLo, InHi);
3552 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3553 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3558 EVT VT =
N->getValueType(0);
3576 Align Alignment = DAG.getReducedAlign(VT,
false);
3581 EVT PtrVT =
StackPtr.getValueType();
3582 auto &MF = DAG.getMachineFunction();
3586 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3589 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3595 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3596 DAG.getConstant(1,
DL, PtrVT));
3598 DAG.getConstant(EltWidth,
DL, PtrVT));
3600 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3602 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3603 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3604 DAG.getPOISON(PtrVT), Stride, TrueMask,
3607 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3613 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3618 EVT VT =
N->getValueType(0);
3630 EVL1 = ZExtPromotedInteger(EVL1);
3644 Align Alignment = DAG.getReducedAlign(VT,
false);
3649 EVT PtrVT =
StackPtr.getValueType();
3650 auto &MF = DAG.getMachineFunction();
3654 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3657 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3663 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3668 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3669 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3671 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3673 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3677 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3682 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3683 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3685 uint64_t TrailingElts = -
Imm;
3687 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3696 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3704 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3706 DAG.getVectorIdxConstant(0,
DL));
3712void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3720 GetSplitVector(Acc, AccLo, AccHi);
3721 unsigned Opcode =
N->getOpcode();
3733 GetSplitVector(Input1, Input1Lo, Input1Hi);
3734 GetSplitVector(Input2, Input2Lo, Input2Hi);
3737 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3738 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3741void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3749 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3757void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3758 unsigned Factor =
N->getNumOperands();
3761 for (
unsigned i = 0; i != Factor; ++i) {
3763 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3765 Ops[i * 2 + 1] = OpHi;
3776 for (
unsigned i = 0; i != Factor; ++i)
3780void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3781 unsigned Factor =
N->getNumOperands();
3784 for (
unsigned i = 0; i != Factor; ++i) {
3786 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3788 Ops[i + Factor] = OpHi;
3799 for (
unsigned i = 0; i != Factor; ++i) {
3800 unsigned IdxLo = 2 * i;
3801 unsigned IdxHi = 2 * i + 1;
3802 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3803 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3815bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3820 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3823 switch (
N->getOpcode()) {
3826 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3836 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3843 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3845 case ISD::VP_TRUNCATE:
3847 Res = SplitVecOp_TruncateHelper(
N);
3850 case ISD::VP_FP_ROUND:
3854 Res = SplitVecOp_FP_ROUND(
N);
3866 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3873 case ISD::VP_SCATTER:
3877 case ISD::VP_GATHER:
3881 Res = SplitVecOp_VSELECT(
N, OpNo);
3884 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3890 case ISD::VP_SINT_TO_FP:
3891 case ISD::VP_UINT_TO_FP:
3892 if (
N->getValueType(0).bitsLT(
3893 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3894 Res = SplitVecOp_TruncateHelper(
N);
3896 Res = SplitVecOp_UnaryOp(
N);
3900 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3904 case ISD::VP_FP_TO_SINT:
3905 case ISD::VP_FP_TO_UINT:
3918 Res = SplitVecOp_UnaryOp(
N);
3921 Res = SplitVecOp_FPOpDifferentTypes(
N);
3926 Res = SplitVecOp_CMP(
N);
3930 Res = SplitVecOp_FAKE_USE(
N);
3935 Res = SplitVecOp_ExtVecInRegOp(
N);
3953 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3957 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3959 case ISD::VP_REDUCE_FADD:
3960 case ISD::VP_REDUCE_SEQ_FADD:
3961 case ISD::VP_REDUCE_FMUL:
3962 case ISD::VP_REDUCE_SEQ_FMUL:
3963 case ISD::VP_REDUCE_ADD:
3964 case ISD::VP_REDUCE_MUL:
3965 case ISD::VP_REDUCE_AND:
3966 case ISD::VP_REDUCE_OR:
3967 case ISD::VP_REDUCE_XOR:
3968 case ISD::VP_REDUCE_SMAX:
3969 case ISD::VP_REDUCE_SMIN:
3970 case ISD::VP_REDUCE_UMAX:
3971 case ISD::VP_REDUCE_UMIN:
3972 case ISD::VP_REDUCE_FMAX:
3973 case ISD::VP_REDUCE_FMIN:
3974 case ISD::VP_REDUCE_FMAXIMUM:
3975 case ISD::VP_REDUCE_FMINIMUM:
3976 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3980 Res = SplitVecOp_CttzElts(
N);
3982 case ISD::VP_CTTZ_ELTS:
3983 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3984 Res = SplitVecOp_VP_CttzElements(
N);
3987 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3993 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3998 if (!Res.
getNode())
return false;
4005 if (
N->isStrictFPOpcode())
4007 "Invalid operand expansion");
4010 "Invalid operand expansion");
4012 ReplaceValueWith(
SDValue(
N, 0), Res);
4016SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4020 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4022 EVT VT =
N->getValueType(0);
4035 getSetCCResultType(MVT::i1), MVT::i1);
4040 DAG.getElementCount(
DL, VT, SplitEC)),
4044SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4047 assert(OpNo == 0 &&
"Illegal operand must be mask");
4054 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4057 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4058 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4059 "Lo and Hi have differing types");
4062 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4063 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4065 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4066 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4067 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4068 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4078SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4081 assert(OpNo == 1 &&
"Illegal operand must be mask");
4086 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4088 EVT VecVT =
N->getValueType(0);
4092SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4093 EVT ResVT =
N->getValueType(0);
4099 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4100 GetSplitVector(VecOp,
Lo,
Hi);
4102 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4107 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4108 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4112 EVT ResVT =
N->getValueType(0);
4118 SDNodeFlags
Flags =
N->getFlags();
4121 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4122 GetSplitVector(VecOp,
Lo,
Hi);
4124 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4130 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4133SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4134 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4135 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4137 unsigned Opc =
N->getOpcode();
4138 EVT ResVT =
N->getValueType(0);
4144 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4145 GetSplitVector(VecOp,
Lo,
Hi);
4148 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4151 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4153 const SDNodeFlags
Flags =
N->getFlags();
4157 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4162 EVT ResVT =
N->getValueType(0);
4165 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4166 EVT InVT =
Lo.getValueType();
4171 if (
N->isStrictFPOpcode()) {
4172 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4173 {N->getOperand(0), Lo});
4174 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4175 {N->getOperand(0), Hi});
4184 ReplaceValueWith(
SDValue(
N, 1), Ch);
4185 }
else if (
N->getNumOperands() == 3) {
4186 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4187 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4188 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4189 std::tie(EVLLo, EVLHi) =
4190 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4191 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4192 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4194 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4195 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4204 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4214 EVT ResVT =
N->getValueType(0);
4216 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4220 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4226 Lo = BitConvertToInteger(
Lo);
4227 Hi = BitConvertToInteger(
Hi);
4229 if (DAG.getDataLayout().isBigEndian())
4237 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4239 EVT ResVT =
N->getValueType(0);
4247 GetSplitVector(SubVec,
Lo,
Hi);
4256 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4258 return SecondInsertion;
4261SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4268 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4270 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4272 ElementCount IdxVal =
4276 EVT SrcVT =
N->getOperand(0).getValueType();
4295 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4296 LoEltsMin - IdxValMin);
4297 DAG.ExtractVectorElements(
Hi, Elts, 0,
4300 return DAG.getBuildVector(SubVT, dl, Elts);
4304 ElementCount ExtractIdx = IdxVal - LoElts;
4306 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4309 EVT HiVT =
Hi.getValueType();
4311 "Only fixed-vector extracts are supported in this case");
4321 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4322 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4328 "Extracting scalable subvector from fixed-width unsupported");
4336 "subvector from a scalable predicate vector");
4342 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4344 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4345 auto &MF = DAG.getMachineFunction();
4349 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4353 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4356 SubVT, dl, Store, StackPtr,
4360SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4366 uint64_t IdxVal =
Index->getZExtValue();
4369 GetSplitVector(Vec,
Lo,
Hi);
4371 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4373 if (IdxVal < LoElts)
4374 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4377 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4382 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4394 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4400 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4402 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4403 auto &MF = DAG.getMachineFunction();
4406 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4410 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4414 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4416 return DAG.getExtLoad(
4427 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4435 SplitVecRes_Gather(
N,
Lo,
Hi);
4438 ReplaceValueWith(
SDValue(
N, 0), Res);
4443 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4447 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4449 SDValue EVL =
N->getVectorLength();
4451 Align Alignment =
N->getBaseAlign();
4457 GetSplitVector(
Data, DataLo, DataHi);
4459 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4464 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4467 GetSplitVector(Mask, MaskLo, MaskHi);
4469 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4472 EVT MemoryVT =
N->getMemoryVT();
4473 EVT LoMemVT, HiMemVT;
4474 bool HiIsEmpty =
false;
4475 std::tie(LoMemVT, HiMemVT) =
4476 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4480 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4483 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4488 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4489 N->getAddressingMode(),
N->isTruncatingStore(),
4490 N->isCompressingStore());
4496 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4497 N->isCompressingStore());
4499 MachinePointerInfo MPI;
4503 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4508 MMO = DAG.getMachineFunction().getMachineMemOperand(
4510 Alignment,
N->getAAInfo(),
N->getRanges());
4512 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4513 N->getAddressingMode(),
N->isTruncatingStore(),
4514 N->isCompressingStore());
4523 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4524 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4531 GetSplitVector(
Data, LoData, HiData);
4533 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4535 EVT LoMemVT, HiMemVT;
4536 bool HiIsEmpty =
false;
4537 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4543 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4544 else if (getTypeAction(
Mask.getValueType()) ==
4546 GetSplitVector(Mask, LoMask, HiMask);
4548 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4551 std::tie(LoEVL, HiEVL) =
4552 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4556 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4557 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4558 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4569 EVT PtrVT =
N->getBasePtr().getValueType();
4572 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4575 Align Alignment =
N->getBaseAlign();
4580 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4581 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4583 Alignment,
N->getAAInfo(),
N->getRanges());
4586 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4587 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4588 N->isCompressingStore());
4597 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4601 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4604 Align Alignment =
N->getBaseAlign();
4610 GetSplitVector(
Data, DataLo, DataHi);
4612 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4617 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4620 GetSplitVector(Mask, MaskLo, MaskHi);
4622 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4625 EVT MemoryVT =
N->getMemoryVT();
4626 EVT LoMemVT, HiMemVT;
4627 bool HiIsEmpty =
false;
4628 std::tie(LoMemVT, HiMemVT) =
4629 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4632 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4637 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4638 N->getAddressingMode(),
N->isTruncatingStore(),
4639 N->isCompressingStore());
4647 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4648 N->isCompressingStore());
4650 MachinePointerInfo MPI;
4654 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4659 MMO = DAG.getMachineFunction().getMachineMemOperand(
4661 Alignment,
N->getAAInfo(),
N->getRanges());
4663 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4664 N->getAddressingMode(),
N->isTruncatingStore(),
4665 N->isCompressingStore());
4678 EVT MemoryVT =
N->getMemoryVT();
4679 Align Alignment =
N->getBaseAlign();
4686 }
Ops = [&]() -> Operands {
4688 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4692 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4697 EVT LoMemVT, HiMemVT;
4698 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4703 GetSplitVector(
Ops.Data, DataLo, DataHi);
4705 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4710 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4712 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4716 if (getTypeAction(
Ops.Index.getValueType()) ==
4718 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4720 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4724 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4726 Alignment,
N->getAAInfo(),
N->getRanges());
4729 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4731 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4732 MSC->getIndexType(), MSC->isTruncatingStore());
4737 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4738 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4739 MMO, MSC->getIndexType(),
4740 MSC->isTruncatingStore());
4744 std::tie(EVLLo, EVLHi) =
4745 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4747 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4748 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4749 VPSC->getIndexType());
4754 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4755 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4756 VPSC->getIndexType());
4760 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4761 assert(OpNo == 1 &&
"Can only split the stored value");
4764 bool isTruncating =
N->isTruncatingStore();
4767 EVT MemoryVT =
N->getMemoryVT();
4768 Align Alignment =
N->getBaseAlign();
4770 AAMDNodes AAInfo =
N->getAAInfo();
4772 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4774 EVT LoMemVT, HiMemVT;
4775 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4779 return TLI.scalarizeVectorStore(
N, DAG);
4782 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4783 Alignment, MMOFlags, AAInfo);
4785 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4788 MachinePointerInfo MPI;
4789 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4792 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4793 HiMemVT, Alignment, MMOFlags, AAInfo);
4795 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4802 LLVMContext &Ctx = *DAG.getContext();
4820 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4821 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4825 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4828 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4829 DAG.getBitcast(MemVecVT, Wide), 0);
4831 N->getBasePtr(),
N->getMemOperand());
4839 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4841 N->getBasePtr(),
N->getMemOperand());
4855 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4861 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4882 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4883 SDValue InVec =
N->getOperand(OpNo);
4885 EVT OutVT =
N->getValueType(0);
4893 EVT LoOutVT, HiOutVT;
4894 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4895 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4900 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4902 return SplitVecOp_UnaryOp(
N);
4911 return SplitVecOp_UnaryOp(
N);
4915 GetSplitVector(InVec, InLoVec, InHiVec);
4921 EVT HalfElementVT = IsFloat ?
4923 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4930 if (
N->isStrictFPOpcode()) {
4931 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4932 {N->getOperand(0), InLoVec});
4933 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4934 {N->getOperand(0), InHiVec});
4940 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4941 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4945 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4953 if (
N->isStrictFPOpcode()) {
4957 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4965 DAG.getTargetConstant(
4966 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4973 assert(
N->getValueType(0).isVector() &&
4974 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4975 "Operand types must be vectors");
4977 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4979 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4980 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4982 EVT VT =
N->getValueType(0);
4983 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4988 }
else if (isStrict) {
4989 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4990 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4991 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4992 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4995 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4997 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4998 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4999 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
5000 std::tie(EVLLo, EVLHi) =
5001 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
5002 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
5003 N->getOperand(2), MaskLo, EVLLo);
5004 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
5005 N->getOperand(2), MaskHi, EVLHi);
5013 EVT OpVT =
N->getOperand(0).getValueType();
5016 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5022 EVT ResVT =
N->getValueType(0);
5025 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5026 EVT InVT =
Lo.getValueType();
5031 if (
N->isStrictFPOpcode()) {
5032 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5033 {N->getOperand(0), Lo, N->getOperand(2)});
5034 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5035 {N->getOperand(0), Hi, N->getOperand(2)});
5039 Lo.getValue(1),
Hi.getValue(1));
5040 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5041 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
5042 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
5043 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
5044 std::tie(EVLLo, EVLHi) =
5045 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
5046 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
5047 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
5049 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5050 N->getOperand(2),
N->getOperand(3));
5051 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5052 N->getOperand(2),
N->getOperand(3));
5054 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5055 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5066SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5069 EVT LHSLoVT, LHSHiVT;
5070 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5072 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5073 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5076 std::tie(LHSLo, LHSHi) =
5077 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5080 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5083 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5089 LLVMContext &Ctxt = *DAG.getContext();
5092 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5093 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5094 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5096 EVT ResVT =
N->getValueType(0);
5101 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5102 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5108 EVT ResVT =
N->getValueType(0);
5111 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5112 EVT InVT =
Lo.getValueType();
5118 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5119 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5126 EVT ResVT =
N->getValueType(0);
5130 GetSplitVector(VecOp,
Lo,
Hi);
5136 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5138 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5140 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5141 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5146 EVT ResVT =
N->getValueType(0);
5150 GetSplitVector(VecOp,
Lo,
Hi);
5152 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5153 auto [EVLLo, EVLHi] =
5155 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5161 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5163 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5164 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5167SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5178 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5179 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5180 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5181 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5182 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5183 OpsLo, MMO, IndexType);
5184 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5185 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5189SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5192 "Accumulator should already be a legal type, and shouldn't need "
5193 "further splitting");
5196 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5197 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5198 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5199 unsigned Opcode =
N->getOpcode();
5202 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5203 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5210void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5211 unsigned WidenResNo) {
5212 unsigned NumResults =
N->getNumValues();
5213 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5214 if (ResNo == WidenResNo)
5216 EVT ResVT =
N->getValueType(ResNo);
5222 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5223 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5228void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5229 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5232 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5237 auto unrollExpandedOp = [&]() {
5242 EVT VT =
N->getValueType(0);
5243 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5244 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5245 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5247 if (
N->getNumValues() > 1)
5248 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5254 switch (
N->getOpcode()) {
5257 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5265 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5269 Res = WidenVecRes_ADDRSPACECAST(
N);
5276 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5283 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5287 Res = WidenVecRes_ScalarOp(
N);
5292 case ISD::VP_SELECT:
5294 Res = WidenVecRes_Select(
N);
5298 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5300 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5307 case ISD::VP_LOAD_FF:
5310 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5314 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5322 case ISD::VP_GATHER:
5326 Res = WidenVecRes_VECTOR_REVERSE(
N);
5329 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5332 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5342 case ISD::OR:
case ISD::VP_OR:
5355 case ISD::VP_FMINNUM:
5358 case ISD::VP_FMAXNUM:
5360 case ISD::VP_FMINIMUM:
5362 case ISD::VP_FMAXIMUM:
5395 case ISD::VP_FCOPYSIGN:
5396 Res = WidenVecRes_Binary(
N);
5403 Res = WidenVecRes_MaskedBinary(
N);
5408 Res = WidenVecRes_CMP(
N);
5414 if (unrollExpandedOp())
5429 Res = WidenVecRes_BinaryCanTrap(
N);
5438 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5441#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5442 case ISD::STRICT_##DAGN:
5443#include "llvm/IR/ConstrainedOps.def"
5444 Res = WidenVecRes_StrictFP(
N);
5453 Res = WidenVecRes_OverflowOp(
N, ResNo);
5457 Res = WidenVecRes_FCOPYSIGN(
N);
5462 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5467 if (!unrollExpandedOp())
5468 Res = WidenVecRes_ExpOp(
N);
5474 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5479 case ISD::VP_FP_EXTEND:
5481 case ISD::VP_FP_ROUND:
5483 case ISD::VP_FP_TO_SINT:
5485 case ISD::VP_FP_TO_UINT:
5487 case ISD::VP_SIGN_EXTEND:
5489 case ISD::VP_SINT_TO_FP:
5490 case ISD::VP_TRUNCATE:
5493 case ISD::VP_UINT_TO_FP:
5495 case ISD::VP_ZERO_EXTEND:
5498 Res = WidenVecRes_Convert(
N);
5503 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5509 case ISD::VP_LLRINT:
5512 Res = WidenVecRes_XROUND(
N);
5538 if (unrollExpandedOp())
5549 case ISD::VP_BITREVERSE:
5555 case ISD::VP_CTLZ_ZERO_POISON:
5561 case ISD::VP_CTTZ_ZERO_POISON:
5566 case ISD::VP_FFLOOR:
5568 case ISD::VP_FNEARBYINT:
5569 case ISD::VP_FROUND:
5570 case ISD::VP_FROUNDEVEN:
5571 case ISD::VP_FROUNDTOZERO:
5576 Res = WidenVecRes_Unary(
N);
5583 Res = WidenVecRes_Ternary(
N);
5589 if (!unrollExpandedOp())
5590 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5597 SetWidenedVector(
SDValue(
N, ResNo), Res);
5603 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5604 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5605 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5606 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5607 if (
N->getNumOperands() == 3)
5608 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5610 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5611 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5615 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5616 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5622 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5623 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5624 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5625 if (
N->getNumOperands() == 2)
5626 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5629 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5630 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5634 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5635 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5640 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5641 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5642 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5645 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5646 Mask = ModifyToType(Mask, WideMaskVT,
true);
5647 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5652 LLVMContext &Ctxt = *DAG.getContext();
5657 EVT OpVT =
LHS.getValueType();
5659 LHS = GetWidenedVector(
LHS);
5660 RHS = GetWidenedVector(
RHS);
5661 OpVT =
LHS.getValueType();
5664 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5667 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5673SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5676 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5677 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5678 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5680 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5689 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5692 if (ConcatEnd == 1) {
5693 VT = ConcatOps[0].getValueType();
5695 return ConcatOps[0];
5698 SDLoc dl(ConcatOps[0]);
5705 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5706 int Idx = ConcatEnd - 1;
5707 VT = ConcatOps[Idx--].getValueType();
5708 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5721 unsigned NumToInsert = ConcatEnd - Idx - 1;
5722 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5724 ConcatOps[Idx+1] = VecOp;
5725 ConcatEnd = Idx + 2;
5731 unsigned RealVals = ConcatEnd - Idx - 1;
5732 unsigned SubConcatEnd = 0;
5733 unsigned SubConcatIdx = Idx + 1;
5734 while (SubConcatEnd < RealVals)
5735 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5736 while (SubConcatEnd < OpsToConcat)
5737 SubConcatOps[SubConcatEnd++] = undefVec;
5739 NextVT, SubConcatOps);
5740 ConcatEnd = SubConcatIdx + 1;
5745 if (ConcatEnd == 1) {
5746 VT = ConcatOps[0].getValueType();
5748 return ConcatOps[0];
5753 if (
NumOps != ConcatEnd ) {
5755 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5756 ConcatOps[j] = UndefVal;
5764 unsigned Opcode =
N->getOpcode();
5766 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5770 const SDNodeFlags
Flags =
N->getFlags();
5771 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5772 NumElts = NumElts / 2;
5776 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5778 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5779 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5780 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5788 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5791 TLI.isTypeLegal(WideMaskVT)) {
5792 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5793 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5794 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5796 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5797 N->getValueType(0).getVectorElementCount());
5798 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5812 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5813 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5814 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5817 unsigned ConcatEnd = 0;
5825 while (CurNumElts != 0) {
5826 while (CurNumElts >= NumElts) {
5827 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5828 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5829 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5831 CurNumElts -= NumElts;
5834 NumElts = NumElts / 2;
5836 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5839 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5840 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5841 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5842 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5853 switch (
N->getOpcode()) {
5856 return WidenVecRes_STRICT_FSETCC(
N);
5863 return WidenVecRes_Convert_StrictFP(
N);
5870 unsigned Opcode =
N->getOpcode();
5872 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5876 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5877 NumElts = NumElts / 2;
5888 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5892 unsigned ConcatEnd = 0;
5899 for (
unsigned i = 1; i < NumOpers; ++i) {
5905 Oper = GetWidenedVector(Oper);
5911 DAG.getPOISON(WideOpVT), Oper,
5912 DAG.getVectorIdxConstant(0, dl));
5924 while (CurNumElts != 0) {
5925 while (CurNumElts >= NumElts) {
5928 for (
unsigned i = 0; i < NumOpers; ++i) {
5931 EVT OpVT =
Op.getValueType();
5936 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5942 EVT OperVT[] = {VT, MVT::Other};
5944 ConcatOps[ConcatEnd++] = Oper;
5947 CurNumElts -= NumElts;
5950 NumElts = NumElts / 2;
5952 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5955 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5958 for (
unsigned i = 0; i < NumOpers; ++i) {
5961 EVT OpVT =
Op.getValueType();
5969 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5971 ConcatOps[ConcatEnd++] = Oper;
5980 if (Chains.
size() == 1)
5981 NewChain = Chains[0];
5984 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5989SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5991 EVT ResVT =
N->getValueType(0);
5992 EVT OvVT =
N->getValueType(1);
5993 EVT WideResVT, WideOvVT;
5998 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6003 WideLHS = GetWidenedVector(
N->getOperand(0));
6004 WideRHS = GetWidenedVector(
N->getOperand(1));
6006 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6015 N->getOperand(0), Zero);
6017 N->getOperand(1), Zero);
6020 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6021 SDNode *WideNode = DAG.getNode(
6022 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6025 unsigned OtherNo = 1 - ResNo;
6026 EVT OtherVT =
N->getValueType(OtherNo);
6033 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
6036 return SDValue(WideNode, ResNo);
6040 LLVMContext &Ctx = *DAG.getContext();
6044 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6049 unsigned Opcode =
N->getOpcode();
6050 const SDNodeFlags
Flags =
N->getFlags();
6056 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6058 InOp = ZExtPromotedInteger(InOp);
6070 if (
N->getNumOperands() == 1)
6071 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6073 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6074 N->getOperand(3), Flags);
6075 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6079 InOp = GetWidenedVector(
N->getOperand(0));
6082 if (InVTEC == WidenEC) {
6083 if (
N->getNumOperands() == 3 &&
N->isVPOpcode()) {
6086 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
6088 return MakeConvertNode(WidenVT, InOp);
6114 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6118 if (TLI.isTypeLegal(InWidenVT)) {
6126 unsigned NumConcat =
6131 return MakeConvertNode(WidenVT, InVec);
6135 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6137 return MakeConvertNode(WidenVT, InVal);
6146 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6147 for (
unsigned i=0; i < MinElts; ++i) {
6148 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6149 Ops[i] = MakeConvertNode(EltVT, Val);
6152 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6157 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6161 EVT SrcVT = Src.getValueType();
6165 Src = GetWidenedVector(Src);
6166 SrcVT = Src.getValueType();
6173 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6178 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6182 EVT SrcVT = Src.getValueType();
6186 Src = GetWidenedVector(Src);
6187 SrcVT = Src.getValueType();
6194 if (
N->getNumOperands() == 1)
6195 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6197 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6198 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6202 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6205SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6210 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6216 unsigned Opcode =
N->getOpcode();
6222 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6227 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6228 for (
unsigned i=0; i < MinElts; ++i) {
6229 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6230 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6234 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6236 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6239SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6240 unsigned Opcode =
N->getOpcode();
6244 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6253 InOp = GetWidenedVector(InOp);
6260 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6267 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6268 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6285 while (
Ops.size() != WidenNumElts)
6286 Ops.push_back(DAG.getPOISON(WidenSVT));
6288 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6294 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6295 return WidenVecRes_BinaryCanTrap(
N);
6298 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6305SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6307 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6310 SDValue Arg = GetWidenedVector(FpValue);
6311 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6316 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6317 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6319 EVT ExpVT =
RHS.getValueType();
6324 ExpOp = ModifyToType(
RHS, WideExpVT);
6327 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6332 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6333 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6334 if (
N->getNumOperands() == 1)
6335 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6337 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6338 N->getOperand(1),
N->getFlags());
6340 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6341 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6345 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6346 {InOp,
Mask,
N->getOperand(2)});
6350 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6355 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6356 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6357 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6360SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6362 EVT VT0 =
N->getValueType(0);
6363 EVT VT1 =
N->getValueType(1);
6367 "expected both results to be vectors of matching element count");
6369 LLVMContext &Ctx = *DAG.getContext();
6370 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6372 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6379 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6382 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6383 return SDValue(WidenNode, ResNo);
6386SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6387 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6388 return GetWidenedVector(WidenVec);
6392 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6393 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6396 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6397 AddrSpaceCastN->getSrcAddressSpace(),
6398 AddrSpaceCastN->getDestAddressSpace());
6404 EVT VT =
N->getValueType(0);
6405 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6408 switch (getTypeAction(InVT)) {
6422 SDValue NInOp = GetPromotedInteger(InOp);
6424 if (WidenVT.
bitsEq(NInVT)) {
6427 if (DAG.getDataLayout().isBigEndian()) {
6430 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6448 InOp = GetWidenedVector(InOp);
6450 if (WidenVT.
bitsEq(InVT))
6460 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6465 unsigned NewNumParts = WidenSize / InSize;
6478 EVT OrigInVT =
N->getOperand(0).getValueType();
6483 if (TLI.isTypeLegal(NewInVT)) {
6491 if (WidenSize % InSize == 0) {
6498 DAG.ExtractVectorElements(InOp,
Ops);
6499 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6511 return CreateStackStoreLoad(InOp, WidenVT);
6514SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6516 N->getOpcode(), SDLoc(
N),
6517 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6518 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6524 EVT VT =
N->getValueType(0);
6528 EVT EltVT =
N->getOperand(0).getValueType();
6531 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6535 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6536 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6538 return DAG.getBuildVector(WidenVT, dl, NewOps);
6542 EVT InVT =
N->getOperand(0).getValueType();
6543 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6545 unsigned NumOperands =
N->getNumOperands();
6547 bool InputWidened =
false;
6551 if (WidenNumElts % NumInElts == 0) {
6553 unsigned NumConcat = WidenNumElts / NumInElts;
6554 SDValue UndefVal = DAG.getPOISON(InVT);
6556 for (
unsigned i=0; i < NumOperands; ++i)
6557 Ops[i] =
N->getOperand(i);
6558 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6563 InputWidened =
true;
6564 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6567 for (i=1; i < NumOperands; ++i)
6568 if (!
N->getOperand(i).isUndef())
6571 if (i == NumOperands)
6574 return GetWidenedVector(
N->getOperand(0));
6576 if (NumOperands == 2) {
6578 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6583 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6584 for (
unsigned i = 0; i < NumInElts; ++i) {
6586 MaskOps[i + NumInElts] = i + WidenNumElts;
6588 return DAG.getVectorShuffle(WidenVT, dl,
6589 GetWidenedVector(
N->getOperand(0)),
6590 GetWidenedVector(
N->getOperand(1)),
6597 "Cannot use build vectors to widen CONCAT_VECTOR result");
6605 for (
unsigned i=0; i < NumOperands; ++i) {
6608 InOp = GetWidenedVector(InOp);
6609 for (
unsigned j = 0;
j < NumInElts; ++
j)
6610 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6612 SDValue UndefVal = DAG.getPOISON(EltVT);
6613 for (; Idx < WidenNumElts; ++Idx)
6614 Ops[Idx] = UndefVal;
6615 return DAG.getBuildVector(WidenVT, dl,
Ops);
6618SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6619 EVT VT =
N->getValueType(0);
6620 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6621 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6628SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6629 EVT VT =
N->getValueType(0);
6631 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6636 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6638 InOp = GetWidenedVector(InOp);
6644 if (IdxVal == 0 && InVT == WidenVT)
6651 assert(IdxVal % VTNumElts == 0 &&
6652 "Expected Idx to be a multiple of subvector minimum vector length");
6653 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6666 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6667 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6668 "down type's element count");
6675 for (;
I < VTNumElts / GCD; ++
I)
6677 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6678 for (;
I < WidenNumElts / GCD; ++
I)
6686 Align Alignment = DAG.getReducedAlign(InVT,
false);
6688 MachineFunction &MF = DAG.getMachineFunction();
6700 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6707 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6708 return DAG.getMaskedLoad(
6709 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6717 for (i = 0; i < VTNumElts; ++i)
6718 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6720 SDValue UndefVal = DAG.getPOISON(EltVT);
6721 for (; i < WidenNumElts; ++i)
6723 return DAG.getBuildVector(WidenVT, dl,
Ops);
6729 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6734SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6735 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6738 N->getOperand(1),
N->getOperand(2));
6747 "Load width must be less than or equal to first value type width");
6756 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6773 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6784 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6785 EVT LdVT =
LD->getMemoryVT();
6794 TypeSize WidthDiff = WidenWidth - LdWidth;
6797 std::optional<EVT> FirstVT =
6798 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6805 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6808 Chain, BasePtr,
LD->getMemOperand());
6812 FirstVTWidth, dl, DAG);
6830 if (!
LD->getMemoryVT().isByteSized()) {
6832 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6834 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6843 EVT VT =
LD->getValueType(0);
6844 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6845 EVT WideMaskVT = getSetCCResultType(WideVT);
6848 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6849 TLI.isTypeLegal(WideMaskVT)) {
6852 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6856 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6857 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6869 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6871 Result = GenWidenVectorLoads(LdChain, LD);
6878 if (LdChain.
size() == 1)
6879 NewChain = LdChain[0];
6885 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6896 SDValue NewLoad = DAG.getMaskedLoad(
6897 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6898 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6899 LD->getAddressingMode(),
LD->getExtensionType());
6909 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6911 SDValue EVL =
N->getVectorLength();
6918 "Unable to widen binary VP op");
6919 Mask = GetWidenedVector(Mask);
6920 assert(
Mask.getValueType().getVectorElementCount() ==
6921 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6922 .getVectorElementCount() &&
6923 "Unable to widen vector load");
6926 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6927 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6928 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6936 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6938 SDValue EVL =
N->getVectorLength();
6944 "Unable to widen binary VP op");
6945 Mask = GetWidenedVector(Mask);
6946 assert(
Mask.getValueType().getVectorElementCount() ==
6947 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6948 .getVectorElementCount() &&
6949 "Unable to widen vector load");
6951 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6952 Mask, EVL,
N->getMemOperand());
6965 "Unable to widen VP strided load");
6966 Mask = GetWidenedVector(Mask);
6968 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6969 assert(
Mask.getValueType().getVectorElementCount() ==
6971 "Data and mask vectors should have the same number of elements");
6973 SDValue Res = DAG.getStridedLoadVP(
6974 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6975 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6976 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6977 N->isExpandingLoad());
6985SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6990 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6992 Mask.getValueType().getVectorElementType(),
6995 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6996 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6997 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6999 WideMask, WidePassthru);
7003 EVT VT =
N->getValueType(0);
7004 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7006 EVT MaskVT =
Mask.getValueType();
7007 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7016 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7017 TLI.isTypeLegal(WideMaskVT) &&
7023 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7024 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7028 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7029 N->getMemoryVT(),
N->getMemOperand());
7033 if (!
N->getPassThru()->isUndef()) {
7037 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7038 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7039 DAG.getPOISON(WidenVT), EVL);
7050 Mask = ModifyToType(Mask, WideMaskVT,
true);
7052 SDValue Res = DAG.getMaskedLoad(
7053 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7054 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7055 ExtType,
N->isExpandingLoad());
7064 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7066 EVT MaskVT =
Mask.getValueType();
7067 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7075 Mask = ModifyToType(Mask, WideMaskVT,
true);
7080 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7081 Index = ModifyToType(Index, WideIndexVT);
7087 N->getMemoryVT().getScalarType(), WideEC);
7088 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7089 WideMemVT, dl,
Ops,
N->getMemOperand(),
7090 N->getIndexType(),
N->getExtensionType());
7099 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7107 N->getMemoryVT().getScalarType(), WideEC);
7108 Mask = GetWidenedMask(Mask, WideEC);
7111 Mask,
N->getVectorLength()};
7112 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7113 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7122 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7123 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7151 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7152 return N->getOperand(OpNo).getValueType();
7160 N =
N.getOperand(0);
7162 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7163 if (!
N->getOperand(i)->isUndef())
7165 N =
N.getOperand(0);
7169 N =
N.getOperand(0);
7171 N =
N.getOperand(0);
7198 { MaskVT, MVT::Other },
Ops);
7199 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7207 LLVMContext &Ctx = *DAG.getContext();
7210 if (MaskScalarBits < ToMaskScalBits) {
7214 }
else if (MaskScalarBits > ToMaskScalBits) {
7220 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7222 "Mask should have the right element size by now.");
7225 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7227 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7230 EVT SubVT =
Mask->getValueType(0);
7236 assert((
Mask->getValueType(0) == ToMaskVT) &&
7237 "A mask of ToMaskVT should have been produced by now.");
7247 LLVMContext &Ctx = *DAG.getContext();
7258 EVT CondVT =
Cond->getValueType(0);
7262 EVT VSelVT =
N->getValueType(0);
7274 EVT FinalVT = VSelVT;
7285 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7286 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7293 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7301 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7304 EVT ToMaskVT = VSelVT;
7311 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7327 if (ScalarBits0 != ScalarBits1) {
7328 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7329 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7341 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7342 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7343 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7346 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7354 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7359 unsigned Opcode =
N->getOpcode();
7361 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7362 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7363 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7365 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7371 Cond1 = GetWidenedVector(Cond1);
7379 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7380 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7385 Cond1 = ModifyToType(Cond1, CondWidenVT);
7388 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7389 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7391 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7392 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7394 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7398 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7399 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7402 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7406 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7407 return DAG.getUNDEF(WidenVT);
7411 EVT VT =
N->getValueType(0);
7414 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7418 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7419 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7422 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7423 for (
unsigned i = 0; i != NumElts; ++i) {
7424 int Idx =
N->getMaskElt(i);
7425 if (Idx < (
int)NumElts)
7428 NewMask[i] = Idx - NumElts + WidenNumElts;
7430 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7434 EVT VT =
N->getValueType(0);
7438 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7439 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7445 unsigned IdxVal = WidenNumElts - VTNumElts;
7458 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7461 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7462 "down type's element count");
7465 for (; i < VTNumElts / GCD; ++i)
7467 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7468 for (; i < WidenNumElts / GCD; ++i)
7476 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7477 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7479 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7483SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7484 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7488void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7489 EVT VT =
N->getValueType(0);
7492 unsigned Factor =
N->getNumOperands();
7495 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7508 SDValue PackedWidenVec = DAG.getInsertSubvector(
7509 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7513 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7514 NewOps[Idx] = DAG.getExtractSubvector(
7515 DL, WidenVT, PackedWidenVec,
7522 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7527 assert(
N->getValueType(0).isVector() &&
7528 N->getOperand(0).getValueType().isVector() &&
7529 "Operands must be vectors");
7530 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7543 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7544 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7551 InOp1 = GetWidenedVector(InOp1);
7552 InOp2 = GetWidenedVector(InOp2);
7555 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7566 "Input not widened to expected type!");
7568 if (
N->getOpcode() == ISD::VP_SETCC) {
7571 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7572 N->getOperand(2), Mask,
N->getOperand(4));
7574 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7579 assert(
N->getValueType(0).isVector() &&
7580 N->getOperand(1).getValueType().isVector() &&
7581 "Operands must be vectors");
7582 EVT VT =
N->getValueType(0);
7583 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7593 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7598 for (
unsigned i = 0; i != NumElts; ++i) {
7599 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7600 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7602 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7603 {Chain, LHSElem, RHSElem, CC});
7604 Chains[i] = Scalars[i].getValue(1);
7605 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7606 DAG.getBoolConstant(
true, dl, EltVT, VT),
7607 DAG.getBoolConstant(
false, dl, EltVT, VT));
7611 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7613 return DAG.getBuildVector(WidenVT, dl, Scalars);
7619bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7620 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7624 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7627 switch (
N->getOpcode()) {
7630 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7638 Res = WidenVecOp_FAKE_USE(
N);
7644 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7648 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7649 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7650 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7655 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7657 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7658 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7660 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7661 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7671 Res = WidenVecOp_UnrollVectorOp(
N);
7678 Res = WidenVecOp_EXTEND(
N);
7683 Res = WidenVecOp_CMP(
N);
7701 Res = WidenVecOp_Convert(
N);
7706 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7724 Res = WidenVecOp_VECREDUCE(
N);
7728 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7730 case ISD::VP_REDUCE_FADD:
7731 case ISD::VP_REDUCE_SEQ_FADD:
7732 case ISD::VP_REDUCE_FMUL:
7733 case ISD::VP_REDUCE_SEQ_FMUL:
7734 case ISD::VP_REDUCE_ADD:
7735 case ISD::VP_REDUCE_MUL:
7736 case ISD::VP_REDUCE_AND:
7737 case ISD::VP_REDUCE_OR:
7738 case ISD::VP_REDUCE_XOR:
7739 case ISD::VP_REDUCE_SMAX:
7740 case ISD::VP_REDUCE_SMIN:
7741 case ISD::VP_REDUCE_UMAX:
7742 case ISD::VP_REDUCE_UMIN:
7743 case ISD::VP_REDUCE_FMAX:
7744 case ISD::VP_REDUCE_FMIN:
7745 case ISD::VP_REDUCE_FMAXIMUM:
7746 case ISD::VP_REDUCE_FMINIMUM:
7747 Res = WidenVecOp_VP_REDUCE(
N);
7751 Res = WidenVecOp_CttzElements(
N);
7753 case ISD::VP_CTTZ_ELTS:
7754 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7755 Res = WidenVecOp_VP_CttzElements(
N);
7758 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7763 if (!Res.
getNode())
return false;
7771 if (
N->isStrictFPOpcode())
7773 "Invalid operand expansion");
7776 "Invalid operand expansion");
7778 ReplaceValueWith(
SDValue(
N, 0), Res);
7784 EVT VT =
N->getValueType(0);
7789 "Unexpected type action");
7790 InOp = GetWidenedVector(InOp);
7793 "Input wasn't widened!");
7801 EVT FixedEltVT = FixedVT.getVectorElementType();
7802 if (TLI.isTypeLegal(FixedVT) &&
7804 FixedEltVT == InEltVT) {
7806 "Not enough elements in the fixed type for the operand!");
7808 "We can't have the same type as we started with!");
7810 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7812 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7821 return WidenVecOp_Convert(
N);
7826 switch (
N->getOpcode()) {
7841 EVT OpVT =
N->getOperand(0).getValueType();
7842 EVT ResVT =
N->getValueType(0);
7849 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7850 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7856 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7857 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7859 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7866 return DAG.UnrollVectorOp(
N);
7871 EVT ResultVT =
N->getValueType(0);
7873 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7876 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7882 {WideArg,
Test},
N->getFlags());
7888 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7890 EVT OpVT =
N->getOperand(0).getValueType();
7893 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7898 EVT VT =
N->getValueType(0);
7904 "Unexpected type action");
7905 InOp = GetWidenedVector(InOp);
7907 unsigned Opcode =
N->getOpcode();
7912 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7915 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7916 return DAG.getNode(Opcode, dl, VT,
Op);
7923 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7925 if (
N->isStrictFPOpcode()) {
7927 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7930 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7931 {
N->getOperand(0), InOp });
7936 Res = MakeConvertNode(WideVT, InOp);
7938 return DAG.getExtractSubvector(dl, VT, Res, 0);
7946 if (
N->isStrictFPOpcode()) {
7949 for (
unsigned i=0; i < NumElts; ++i) {
7950 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7951 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7955 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7957 for (
unsigned i = 0; i < NumElts; ++i) {
7958 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7959 Ops[i] = MakeConvertNode(EltVT, Elt);
7963 return DAG.getBuildVector(VT, dl,
Ops);
7967 EVT DstVT =
N->getValueType(0);
7968 SDValue Src = GetWidenedVector(
N->getOperand(0));
7969 EVT SrcVT = Src.getValueType();
7976 if (TLI.isTypeLegal(WideDstVT)) {
7978 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7981 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7985 return DAG.UnrollVectorOp(
N);
7989 EVT VT =
N->getValueType(0);
7990 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7998 if (!VT.
isVector() && VT != MVT::x86mmx &&
8002 if (TLI.isTypeLegal(NewVT)) {
8004 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8016 ElementCount NewNumElts =
8018 .divideCoefficientBy(EltSize);
8020 if (TLI.isTypeLegal(NewVT)) {
8022 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8027 return CreateStackStoreLoad(InOp, VT);
8035 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8036 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8041 EVT VT =
N->getValueType(0);
8043 EVT InVT =
N->getOperand(0).getValueType();
8048 unsigned NumOperands =
N->getNumOperands();
8049 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8051 for (i = 1; i < NumOperands; ++i)
8052 if (!
N->getOperand(i).isUndef())
8055 if (i == NumOperands)
8056 return GetWidenedVector(
N->getOperand(0));
8066 for (
unsigned i=0; i < NumOperands; ++i) {
8070 "Unexpected type action");
8071 InOp = GetWidenedVector(InOp);
8072 for (
unsigned j = 0;
j < NumInElts; ++
j)
8073 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8075 return DAG.getBuildVector(VT, dl,
Ops);
8078SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8079 EVT VT =
N->getValueType(0);
8084 SubVec = GetWidenedVector(SubVec);
8089 bool IndicesValid =
false;
8092 IndicesValid =
true;
8096 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8097 Attribute::VScaleRange);
8102 IndicesValid =
true;
8108 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8114 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8121 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8128 Align Alignment = DAG.getReducedAlign(VT,
false);
8130 MachineFunction &MF = DAG.getMachineFunction();
8143 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8151 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8152 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8157 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8162 unsigned Idx =
N->getConstantOperandVal(2);
8168 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8174SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8175 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8177 N->getValueType(0), InOp,
N->getOperand(1));
8180SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8181 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8183 N->getValueType(0), InOp,
N->getOperand(1));
8186SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8188 EVT ResVT =
N->getValueType(0);
8191 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8197 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8205 "Widened input size must be a multiple of result element size");
8208 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8210 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8211 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8219 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8220 return TLI.scalarizeVectorStore(ST, DAG);
8222 if (
ST->isTruncatingStore())
8223 return TLI.scalarizeVectorStore(ST, DAG);
8233 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8234 EVT WideMaskVT = getSetCCResultType(WideVT);
8236 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8237 TLI.isTypeLegal(WideMaskVT)) {
8240 StVal = GetWidenedVector(StVal);
8242 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8244 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8245 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8246 ST->getAddressingMode());
8250 if (GenWidenVectorStores(StChain, ST)) {
8251 if (StChain.
size() == 1)
8260 SDValue WideStVal = GetWidenedVector(StVal);
8264 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8265 ST->getOffset(), Mask,
ST->getMemoryVT(),
8266 ST->getMemOperand(),
ST->getAddressingMode(),
8267 ST->isTruncatingStore());
8274 EVT StVT =
ST->getMemoryVT();
8277 SDValue StVal = GetWidenedVector(
ST->getVal());
8282 TypeSize WidthDiff = WidenWidth - StWidth;
8288 std::optional<EVT> FirstVT =
8289 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8294 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8300 ST->getBasePtr(),
ST->getMemOperand());
8303SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8304 assert((OpNo == 1 || OpNo == 3) &&
8305 "Can widen only data or mask operand of vp_store");
8313 StVal = GetWidenedVector(StVal);
8319 "Unable to widen VP store");
8320 Mask = GetWidenedVector(Mask);
8322 Mask = GetWidenedVector(Mask);
8328 "Unable to widen VP store");
8329 StVal = GetWidenedVector(StVal);
8332 assert(
Mask.getValueType().getVectorElementCount() ==
8334 "Mask and data vectors should have the same number of elements");
8335 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8336 ST->getOffset(), Mask,
ST->getVectorLength(),
8337 ST->getMemoryVT(),
ST->getMemOperand(),
8338 ST->getAddressingMode(),
ST->isTruncatingStore(),
8339 ST->isCompressingStore());
8344 assert((OpNo == 1 || OpNo == 4) &&
8345 "Can widen only data or mask operand of vp_strided_store");
8354 "Unable to widen VP strided store");
8358 "Unable to widen VP strided store");
8360 StVal = GetWidenedVector(StVal);
8361 Mask = GetWidenedVector(Mask);
8364 Mask.getValueType().getVectorElementCount() &&
8365 "Data and mask vectors should have the same number of elements");
8367 return DAG.getStridedStoreVP(
8374SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8375 assert((OpNo == 1 || OpNo == 4) &&
8376 "Can widen only data or mask operand of mstore");
8379 EVT MaskVT =
Mask.getValueType();
8384 EVT WideVT, WideMaskVT;
8387 StVal = GetWidenedVector(StVal);
8394 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8401 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8403 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8404 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8413 Mask = ModifyToType(Mask, WideMaskVT,
true);
8416 Mask = ModifyToType(Mask, WideMaskVT,
true);
8418 StVal = ModifyToType(StVal, WideVT);
8421 assert(
Mask.getValueType().getVectorElementCount() ==
8423 "Mask and data vectors should have the same number of elements");
8430SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8431 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8433 SDValue DataOp = MG->getPassThru();
8435 SDValue Scale = MG->getScale();
8443 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8444 MG->getMemOperand(), MG->getIndexType(),
8445 MG->getExtensionType());
8451SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8460 DataOp = GetWidenedVector(DataOp);
8464 EVT IndexVT =
Index.getValueType();
8467 Index = ModifyToType(Index, WideIndexVT);
8470 EVT MaskVT =
Mask.getValueType();
8473 Mask = ModifyToType(Mask, WideMaskVT,
true);
8478 }
else if (OpNo == 4) {
8480 Index = GetWidenedVector(Index);
8486 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8491SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8500 DataOp = GetWidenedVector(DataOp);
8501 Index = GetWidenedVector(Index);
8503 Mask = GetWidenedMask(Mask, WideEC);
8506 }
else if (OpNo == 3) {
8508 Index = GetWidenedVector(Index);
8515 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8520 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8521 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8523 EVT VT =
N->getValueType(0);
8538 SVT, InOp0, InOp1,
N->getOperand(2));
8544 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8546 EVT OpVT =
N->getOperand(0).getValueType();
8549 return DAG.getNode(ExtendCode, dl, VT, CC);
8559 EVT VT =
N->getValueType(0);
8561 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8568 for (
unsigned i = 0; i != NumElts; ++i) {
8569 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8570 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8572 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8573 {Chain, LHSElem, RHSElem, CC});
8574 Chains[i] = Scalars[i].getValue(1);
8575 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8576 DAG.getBoolConstant(
true, dl, EltVT, VT),
8577 DAG.getBoolConstant(
false, dl, EltVT, VT));
8581 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8583 return DAG.getBuildVector(VT, dl, Scalars);
8607 SDValue Op = GetWidenedVector(
N->getOperand(0));
8608 EVT VT =
N->getValueType(0);
8609 EVT OrigVT =
N->getOperand(0).getValueType();
8610 EVT WideVT =
Op.getValueType();
8612 SDNodeFlags
Flags =
N->getFlags();
8614 unsigned Opc =
N->getOpcode();
8616 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8617 assert(NeutralElem &&
"Neutral element must exist");
8627 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8634 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8635 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8641 unsigned GCD = std::gcd(OrigElts, WideElts);
8644 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8645 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8646 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8647 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8650 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8651 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8653 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8662 EVT VT =
N->getValueType(0);
8664 EVT WideVT =
Op.getValueType();
8666 SDNodeFlags
Flags =
N->getFlags();
8668 unsigned Opc =
N->getOpcode();
8670 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8680 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8683 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8684 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8690 unsigned GCD = std::gcd(OrigElts, WideElts);
8693 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8694 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8695 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8696 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8699 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8700 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8702 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8706 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8709 SDValue Op = GetWidenedVector(
N->getOperand(1));
8711 Op.getValueType().getVectorElementCount());
8713 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8714 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8722 EVT VT =
N->getValueType(0);
8726 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8727 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8732 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8739 TLI.getTypeToTransformTo(*DAG.getContext(),
Source.getValueType());
8743 WideSource = GetWidenedVector(Source);
8748 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8751 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8758 EVT SrcVT =
Source.getValueType();
8762 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8763 {Source, Mask, N->getOperand(2)},
N->getFlags());
8766SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8769 EVT OrigMaskVT =
Mask.getValueType();
8770 SDValue WideMask = GetWidenedVector(Mask);
8776 if (OrigElts != WideElts) {
8777 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8779 Mask, DAG.getVectorIdxConstant(0,
DL));
8800 unsigned WidenEx = 0) {
8805 unsigned AlignInBits =
Align*8;
8807 EVT RetVT = WidenEltVT;
8812 if (Width == WidenEltWidth)
8823 (WidenWidth % MemVTWidth) == 0 &&
8825 (MemVTWidth <= Width ||
8826 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8827 if (MemVTWidth == WidenWidth)
8846 (WidenWidth % MemVTWidth) == 0 &&
8848 (MemVTWidth <= Width ||
8849 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8858 return std::nullopt;
8869 unsigned Start,
unsigned End) {
8870 SDLoc dl(LdOps[Start]);
8871 EVT LdTy = LdOps[Start].getValueType();
8879 for (
unsigned i = Start + 1; i != End; ++i) {
8880 EVT NewLdTy = LdOps[i].getValueType();
8881 if (NewLdTy != LdTy) {
8900 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8901 EVT LdVT =
LD->getMemoryVT();
8911 AAMDNodes AAInfo =
LD->getAAInfo();
8915 TypeSize WidthDiff = WidenWidth - LdWidth;
8922 std::optional<EVT> FirstVT =
8923 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8930 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8935 std::optional<EVT> NewVT = FirstVT;
8936 TypeSize RemainingWidth = LdWidth;
8937 TypeSize NewVTWidth = FirstVTWidth;
8939 RemainingWidth -= NewVTWidth;
8946 NewVTWidth = NewVT->getSizeInBits();
8952 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8953 LD->getBaseAlign(), MMOFlags, AAInfo);
8965 uint64_t ScaledOffset = 0;
8966 MachinePointerInfo MPI =
LD->getPointerInfo();
8972 for (EVT MemVT : MemVTs) {
8973 Align NewAlign = ScaledOffset == 0
8974 ?
LD->getBaseAlign()
8977 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8985 unsigned End = LdOps.
size();
8996 EVT LdTy = LdOps[i].getValueType();
8999 for (--i; i >= 0; --i) {
9000 LdTy = LdOps[i].getValueType();
9007 ConcatOps[--Idx] = LdOps[i];
9008 for (--i; i >= 0; --i) {
9009 EVT NewLdTy = LdOps[i].getValueType();
9010 if (NewLdTy != LdTy) {
9020 for (;
j != End-Idx; ++
j)
9021 WidenOps[j] = ConcatOps[Idx+j];
9023 WidenOps[j] = DAG.getPOISON(LdTy);
9030 ConcatOps[--Idx] = LdOps[i];
9035 ArrayRef(&ConcatOps[Idx], End - Idx));
9041 SDValue UndefVal = DAG.getPOISON(LdTy);
9044 for (; i != End-Idx; ++i)
9045 WidenOps[i] = ConcatOps[Idx+i];
9047 WidenOps[i] = UndefVal;
9058 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9059 EVT LdVT =
LD->getMemoryVT();
9068 AAMDNodes AAInfo =
LD->getAAInfo();
9082 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9083 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9089 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9090 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9091 LD->getBaseAlign(), MMOFlags, AAInfo);
9096 SDValue UndefVal = DAG.getPOISON(EltVT);
9097 for (; i != WidenNumElts; ++i)
9100 return DAG.getBuildVector(WidenVT, dl,
Ops);
9111 AAMDNodes AAInfo =
ST->getAAInfo();
9112 SDValue ValOp = GetWidenedVector(
ST->getValue());
9115 EVT StVT =
ST->getMemoryVT();
9123 "Mismatch between store and value types");
9127 MachinePointerInfo MPI =
ST->getPointerInfo();
9128 uint64_t ScaledOffset = 0;
9137 std::optional<EVT> NewVT =
9142 TypeSize NewVTWidth = NewVT->getSizeInBits();
9145 StWidth -= NewVTWidth;
9146 MemVTs.
back().second++;
9150 for (
const auto &Pair : MemVTs) {
9151 EVT NewVT = Pair.first;
9152 unsigned Count = Pair.second;
9158 Align NewAlign = ScaledOffset == 0
9159 ?
ST->getBaseAlign()
9161 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9162 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9178 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9179 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9180 ST->getBaseAlign(), MMOFlags, AAInfo);
9197 bool FillWithZeroes) {
9202 "input and widen element type must match");
9204 "cannot modify scalable vectors in this way");
9217 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9219 for (
unsigned i = 1; i != NumConcat; ++i)
9226 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9229 "Scalable vectors should have been handled already.");
9237 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9239 for (Idx = 0; Idx < MinNumElts; ++Idx)
9240 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9242 SDValue UndefVal = DAG.getPOISON(EltVT);
9243 for (; Idx < WidenNumElts; ++Idx)
9244 Ops[Idx] = UndefVal;
9246 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9247 if (!FillWithZeroes)
9251 "We expect to never want to FillWithZeroes for non-integral types.");
9254 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9255 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9257 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9258 DAG.getBuildVector(NVT, dl, MaskOps));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT, TypeSize FirstVTWidth, const SDLoc &dl, SelectionDAG &DAG)
Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the widened value so it can b...
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V, bool LookThroughCmp=false)
Returns the "element type" of the given value/instruction V.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file implements the SmallBitVector class.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtractVectorElt(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Extract element at Idx from Vec.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr LeafTy multiplyCoefficientBy(ScalarTy RHS) const
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by OFFSET elements an...
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ MASKED_UDIV
Masked vector arithmetic that returns poison on disabled lanes.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
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.
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.