35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
46 switch (
N->getOpcode()) {
49 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
58 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
66 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
72 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
84 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
86 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
92 R = ScalarizeVecRes_VecInregOp(
N);
144 R = ScalarizeVecRes_UnaryOp(
N);
147 R = ScalarizeVecRes_ADDRSPACECAST(
N);
153 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
210 R = ScalarizeVecRes_BinOp(
N);
217 R = ScalarizeVecRes_MaskedBinOp(
N);
222 R = ScalarizeVecRes_CMP(
N);
228 R = ScalarizeVecRes_TernaryOp(
N);
231#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
232 case ISD::STRICT_##DAGN:
233#include "llvm/IR/ConstrainedOps.def"
234 R = ScalarizeVecRes_StrictFPOp(
N);
239 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
248 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
258 R = ScalarizeVecRes_FIX(
N);
264 SetScalarizedVector(
SDValue(
N, ResNo), R);
268 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
269 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
270 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
276 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
277 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
279 EVT MaskVT =
Mask.getValueType();
284 Mask = GetScalarizedVector(Mask);
293 DAG.getConstant(1,
DL,
LHS.getValueType()));
295 LHS.getValueType(),
LHS, Divisor);
303 if (getTypeAction(
LHS.getValueType()) ==
305 LHS = GetScalarizedVector(
LHS);
306 RHS = GetScalarizedVector(
RHS);
308 EVT VT =
LHS.getValueType().getVectorElementType();
309 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
310 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
313 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
314 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
318 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
319 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
320 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
321 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
326 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
327 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
334DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
336 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
337 "Unexpected vector type!");
338 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
340 EVT VT0 =
N->getValueType(0);
341 EVT VT1 =
N->getValueType(1);
345 DAG.getNode(
N->getOpcode(), dl,
346 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
350 unsigned OtherNo = 1 - ResNo;
351 EVT OtherVT =
N->getValueType(OtherNo);
353 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
357 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
360 return SDValue(ScalarNode, ResNo);
365 unsigned NumOpers =
N->getNumOperands();
367 EVT ValueVTs[] = {VT, MVT::Other};
376 for (
unsigned i = 1; i < NumOpers; ++i) {
382 Oper = GetScalarizedVector(Oper);
391 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
392 Opers,
N->getFlags());
403 EVT ResVT =
N->getValueType(0);
404 EVT OvVT =
N->getValueType(1);
408 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
409 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
412 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
413 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
414 ScalarLHS = ElemsLHS[0];
415 ScalarRHS = ElemsRHS[0];
418 SDVTList ScalarVTs = DAG.getVTList(
420 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
421 {ScalarLHS, ScalarRHS},
N->getFlags())
425 unsigned OtherNo = 1 - ResNo;
426 EVT OtherVT =
N->getValueType(OtherNo);
428 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
432 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
435 return SDValue(ScalarNode, ResNo);
440 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
441 return GetScalarizedVector(
Op);
444SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
446 SDValue SourceValue =
N->getOperand(0);
447 SDValue SinkValue =
N->getOperand(1);
448 SDValue EltSizeInBytes =
N->getOperand(2);
449 SDValue LaneOffset =
N->getOperand(3);
457 if (IsReadAfterWrite)
465 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
470 return DAG.getNode(
ISD::OR,
DL, CmpVT, Cmp,
477 Op = GetScalarizedVector(
Op);
478 EVT NewVT =
N->getValueType(0).getVectorElementType();
483SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
493SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
495 N->getValueType(0).getVectorElementType(),
496 N->getOperand(0),
N->getOperand(1));
502 EVT OpVT =
Op.getValueType();
506 Op = GetScalarizedVector(
Op);
509 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
512 N->getValueType(0).getVectorElementType(),
Op,
516SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
519 EVT OpVT =
Op.getValueType();
523 Op = GetScalarizedVector(
Op);
526 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
529 N->getValueType(0).getVectorElementType(),
Op,
533SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
534 SDValue Op = GetScalarizedVector(
N->getOperand(0));
535 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
539SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
544 if (
Op.getValueType() != EltVT)
552 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
553 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
563 assert(
N->isUnindexed() &&
"Indexed vector load?");
567 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
568 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
569 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
570 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
582 EVT OpVT =
Op.getValueType();
592 Op = GetScalarizedVector(
Op);
595 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
597 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
603 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
604 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
605 LHS, DAG.getValueType(ExtVT));
612 EVT OpVT =
Op.getValueType();
617 Op = GetScalarizedVector(
Op);
619 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
622 switch (
N->getOpcode()) {
634SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
637 EVT OpVT =
Op.getValueType();
647 Op = GetScalarizedVector(
Op);
650 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
653 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
654 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
655 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
658SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
670 EVT OpVT =
Cond.getValueType();
679 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
682 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
684 TLI.getBooleanContents(
false,
false);
691 if (TLI.getBooleanContents(
false,
false) !=
692 TLI.getBooleanContents(
false,
true)) {
696 EVT OpVT =
Cond->getOperand(0).getValueType();
698 VecBool = TLI.getBooleanContents(OpVT);
703 EVT CondVT =
Cond.getValueType();
704 if (ScalarBool != VecBool) {
705 switch (ScalarBool) {
713 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
720 Cond, DAG.getValueType(MVT::i1));
726 auto BoolVT = getSetCCResultType(CondVT);
727 if (BoolVT.bitsLT(CondVT))
730 return DAG.getSelect(SDLoc(
N),
732 GetScalarizedVector(
N->getOperand(2)));
736 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
737 return DAG.getSelect(SDLoc(
N),
738 LHS.getValueType(),
N->getOperand(0),
LHS,
739 GetScalarizedVector(
N->getOperand(2)));
743 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
745 N->getOperand(0),
N->getOperand(1),
746 LHS, GetScalarizedVector(
N->getOperand(3)),
751 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
754SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
758 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
760 return GetScalarizedVector(
N->getOperand(
Op));
763SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
765 EVT SrcVT = Src.getValueType();
770 Src = GetScalarizedVector(Src);
774 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
776 EVT DstVT =
N->getValueType(0).getVectorElementType();
777 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
781 assert(
N->getValueType(0).isVector() &&
782 N->getOperand(0).getValueType().isVector() &&
783 "Operand types must be vectors");
786 EVT OpVT =
LHS.getValueType();
787 EVT NVT =
N->getValueType(0).getVectorElementType();
792 LHS = GetScalarizedVector(
LHS);
793 RHS = GetScalarizedVector(
RHS);
796 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
797 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
807 return DAG.getNode(ExtendCode,
DL, NVT, Res);
818 Arg = GetScalarizedVector(Arg);
821 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
830 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
837bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
842 switch (
N->getOpcode()) {
845 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
852 Res = ScalarizeVecOp_BITCAST(
N);
855 Res = ScalarizeVecOp_FAKE_USE(
N);
869 Res = ScalarizeVecOp_UnaryOp(
N);
874 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
880 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
883 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
886 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
889 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
892 Res = ScalarizeVecOp_VSELECT(
N);
895 Res = ScalarizeVecOp_VSETCC(
N);
899 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
908 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
911 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
914 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
917 Res = ScalarizeVecOp_FP_EXTEND(
N);
934 Res = ScalarizeVecOp_VECREDUCE(
N);
938 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
942 Res = ScalarizeVecOp_CMP(
N);
945 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
949 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
955 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
960 if (!Res.
getNode())
return false;
968 "Invalid operand expansion");
970 ReplaceValueWith(
SDValue(
N, 0), Res);
977 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
979 N->getValueType(0), Elt);
984 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
985 "Fake Use: Unexpected vector type!");
986 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
987 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
993 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
994 "Unexpected vector type!");
995 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
997 N->getValueType(0).getScalarType(), Elt);
1005SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1006 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1007 "Unexpected vector type!");
1008 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1010 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1011 Elt,
N->getOperand(1));
1019SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1020 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1021 "Unexpected vector type!");
1022 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1024 {
N->getValueType(0).getScalarType(), MVT::Other },
1025 {
N->getOperand(0), Elt });
1035 ReplaceValueWith(
SDValue(
N, 0), Res);
1040SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1042 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1043 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1044 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1049SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1053 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1054 SDValue ContainingVec =
N->getOperand(0);
1062SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1063 EVT VT =
N->getValueType(0);
1064 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1076 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1077 EVT VT =
N->getValueType(0);
1079 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1087 assert(
N->getValueType(0).isVector() &&
1088 N->getOperand(0).getValueType().isVector() &&
1089 "Operand types must be vectors");
1090 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1092 EVT VT =
N->getValueType(0);
1093 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1094 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1096 EVT OpVT =
N->getOperand(0).getValueType();
1108 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1114SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1116 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1117 assert(
N->getValueType(0).isVector() &&
1118 N->getOperand(1).getValueType().isVector() &&
1119 "Operand types must be vectors");
1120 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1122 EVT VT =
N->getValueType(0);
1124 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1125 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1128 EVT OpVT =
N->getOperand(1).getValueType();
1132 {Ch, LHS, RHS, CC});
1141 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1146 ReplaceValueWith(
SDValue(
N, 0), Res);
1153 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1154 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1157 if (
N->isTruncatingStore())
1158 return DAG.getTruncStore(
1159 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1160 N->getBasePtr(),
N->getPointerInfo(),
1161 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1162 N->getMemOperand()->getFlags(),
N->getAAInfo());
1164 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1165 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1166 N->getMemOperand()->getFlags(),
N->getAAInfo());
1172 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1174 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1175 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1180SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1181 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1182 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1184 N->getValueType(0).getVectorElementType(), Elt,
1189SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1191 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1192 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1195 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1205 ReplaceValueWith(
SDValue(
N, 0), Res);
1212 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1214 N->getValueType(0).getVectorElementType(), Elt);
1220SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1221 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1224 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1225 {
N->getOperand(0), Elt});
1234 ReplaceValueWith(
SDValue(
N, 0), Res);
1239 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1246SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1252 SDValue Op = GetScalarizedVector(VecOp);
1253 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1254 AccOp,
Op,
N->getFlags());
1258 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1259 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1266SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1274 EVT VT =
N->getValueType(0);
1275 return DAG.getConstant(0, SDLoc(
N), VT);
1282 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1283 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1285 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1286 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1287 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1290SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1291 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1294 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1295 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1304 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1316void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1321 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1324 switch (
N->getOpcode()) {
1327 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1336 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1344 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1360 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1363 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1375 case ISD::VP_LOAD_FF:
1378 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1385 case ISD::VP_GATHER:
1389 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1393 SplitVecRes_SETCC(
N,
Lo,
Hi);
1396 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1403 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1406 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1409 SplitVecRes_VECTOR_INTERLEAVE(
N);
1412 SplitVecRes_VAARG(
N,
Lo,
Hi);
1418 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1425 case ISD::VP_BITREVERSE:
1433 case ISD::VP_CTLZ_ZERO_POISON:
1435 case ISD::VP_CTTZ_ZERO_POISON:
1450 case ISD::VP_FFLOOR:
1455 case ISD::VP_FNEARBYINT:
1460 case ISD::VP_FP_EXTEND:
1462 case ISD::VP_FP_ROUND:
1464 case ISD::VP_FP_TO_SINT:
1466 case ISD::VP_FP_TO_UINT:
1472 case ISD::VP_LLRINT:
1474 case ISD::VP_FROUND:
1476 case ISD::VP_FROUNDEVEN:
1485 case ISD::VP_FROUNDTOZERO:
1487 case ISD::VP_SINT_TO_FP:
1489 case ISD::VP_TRUNCATE:
1491 case ISD::VP_UINT_TO_FP:
1495 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1498 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1504 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1510 case ISD::VP_SIGN_EXTEND:
1511 case ISD::VP_ZERO_EXTEND:
1512 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1534 case ISD::VP_FMINNUM:
1537 case ISD::VP_FMAXNUM:
1539 case ISD::VP_FMINIMUM:
1541 case ISD::VP_FMAXIMUM:
1550 case ISD::OR:
case ISD::VP_OR:
1570 case ISD::VP_FCOPYSIGN:
1571 SplitVecRes_BinOp(
N,
Lo,
Hi);
1577 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1584 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1588 SplitVecRes_CMP(
N,
Lo,
Hi);
1591#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1592 case ISD::STRICT_##DAGN:
1593#include "llvm/IR/ConstrainedOps.def"
1594 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1599 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1608 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1618 SplitVecRes_FIX(
N,
Lo,
Hi);
1620 case ISD::EXPERIMENTAL_VP_SPLICE:
1621 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1623 case ISD::EXPERIMENTAL_VP_REVERSE:
1624 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1630 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1633 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1642void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1644 uint64_t *ScaledOffset) {
1649 SDValue BytesIncrement = DAG.getVScale(
1652 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1654 *ScaledOffset += IncrementSize;
1664std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1665 return SplitMask(Mask, SDLoc(Mask));
1668std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1671 EVT MaskVT =
Mask.getValueType();
1673 GetSplitVector(Mask, MaskLo, MaskHi);
1675 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1676 return std::make_pair(MaskLo, MaskHi);
1681 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1683 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1686 const SDNodeFlags
Flags =
N->getFlags();
1687 unsigned Opcode =
N->getOpcode();
1688 if (
N->getNumOperands() == 2) {
1689 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1690 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1694 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1695 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1698 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1701 std::tie(EVLLo, EVLHi) =
1702 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1705 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1707 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1713 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1715 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1716 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(2));
1719 const SDNodeFlags
Flags =
N->getFlags();
1720 unsigned Opcode =
N->getOpcode();
1721 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1723 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1730 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1732 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1734 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1737 const SDNodeFlags
Flags =
N->getFlags();
1738 unsigned Opcode =
N->getOpcode();
1739 if (
N->getNumOperands() == 3) {
1740 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1741 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1745 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1746 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1749 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1752 std::tie(EVLLo, EVLHi) =
1753 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1756 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1758 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1762 LLVMContext &Ctxt = *DAG.getContext();
1768 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1770 GetSplitVector(
LHS, LHSLo, LHSHi);
1771 GetSplitVector(
RHS, RHSLo, RHSHi);
1773 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1774 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1778 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1779 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1784 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1786 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1790 unsigned Opcode =
N->getOpcode();
1791 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1793 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1802 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1809 switch (getTypeAction(InVT)) {
1823 GetExpandedOp(InOp,
Lo,
Hi);
1824 if (DAG.getDataLayout().isBigEndian())
1834 GetSplitVector(InOp,
Lo,
Hi);
1843 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1852 if (DAG.getDataLayout().isBigEndian())
1855 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1857 if (DAG.getDataLayout().isBigEndian())
1863void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1869 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1872 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1877 unsigned LaneOffset =
1880 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1882 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1889 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1892 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1895 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1900 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1902 unsigned NumSubvectors =
N->getNumOperands() / 2;
1903 if (NumSubvectors == 1) {
1904 Lo =
N->getOperand(0);
1905 Hi =
N->getOperand(1);
1910 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1919void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1926 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1941 GetSplitVector(Vec,
Lo,
Hi);
1944 EVT LoVT =
Lo.getValueType();
1954 if (IdxVal + SubElems <= LoElems) {
1962 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1964 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1970 SDValue WideSubVec = GetWidenedVector(SubVec);
1972 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1980 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1982 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1983 auto &MF = DAG.getMachineFunction();
1987 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1992 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1993 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1997 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
2002 MachinePointerInfo MPI =
Load->getPointerInfo();
2003 IncrementPointer(Load, LoVT, MPI, StackPtr);
2006 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
2015 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2020 EVT RHSVT =
RHS.getValueType();
2023 GetSplitVector(
RHS, RHSLo, RHSHi);
2025 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2040 SDValue FpValue =
N->getOperand(0);
2042 GetSplitVector(FpValue, ArgLo, ArgHi);
2044 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2046 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2055 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2059 std::tie(LoVT, HiVT) =
2063 DAG.getValueType(LoVT));
2065 DAG.getValueType(HiVT));
2070 unsigned Opcode =
N->getOpcode();
2077 GetSplitVector(N0, InLo, InHi);
2079 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2084 EVT OutLoVT, OutHiVT;
2085 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2087 assert((2 * OutNumElements) <= InNumElements &&
2088 "Illegal extend vector in reg split");
2097 SmallVector<int, 8> SplitHi(InNumElements, -1);
2098 for (
unsigned i = 0; i != OutNumElements; ++i)
2099 SplitHi[i] = i + OutNumElements;
2100 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2102 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2103 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2108 unsigned NumOps =
N->getNumOperands();
2112 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2122 for (
unsigned i = 1; i <
NumOps; ++i) {
2127 EVT InVT =
Op.getValueType();
2132 GetSplitVector(
Op, OpLo, OpHi);
2134 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2141 EVT LoValueVTs[] = {LoVT, MVT::Other};
2142 EVT HiValueVTs[] = {HiVT, MVT::Other};
2143 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2145 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2151 Lo.getValue(1),
Hi.getValue(1));
2155 ReplaceValueWith(
SDValue(
N, 1), Chain);
2158SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2160 EVT VT =
N->getValueType(0);
2171 else if (NE > ResNE)
2175 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2179 for (i = 0; i !=
NE; ++i) {
2180 Operands[0] = Chain;
2181 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2182 SDValue Operand =
N->getOperand(j);
2186 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2188 Operands[
j] = Operand;
2192 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2200 for (; i < ResNE; ++i)
2201 Scalars.
push_back(DAG.getPOISON(EltVT));
2205 ReplaceValueWith(
SDValue(
N, 1), Chain);
2209 return DAG.getBuildVector(VecVT, dl, Scalars);
2212void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2215 EVT ResVT =
N->getValueType(0);
2216 EVT OvVT =
N->getValueType(1);
2217 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2218 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2219 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2221 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2223 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2224 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2226 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2227 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2230 unsigned Opcode =
N->getOpcode();
2231 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2232 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2234 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2236 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2242 unsigned OtherNo = 1 - ResNo;
2243 EVT OtherVT =
N->getValueType(OtherNo);
2245 SetSplitVector(
SDValue(
N, OtherNo),
2251 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2255void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2261 GetSplitVector(Vec,
Lo,
Hi);
2264 unsigned IdxVal = CIdx->getZExtValue();
2265 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2266 if (IdxVal < LoNumElts) {
2268 Lo.getValueType(),
Lo, Elt, Idx);
2271 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2291 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2293 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2294 auto &MF = DAG.getMachineFunction();
2298 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2303 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2304 Store = DAG.getTruncStore(
2310 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2313 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2317 MachinePointerInfo MPI =
Load->getPointerInfo();
2318 IncrementPointer(Load, LoVT, MPI, StackPtr);
2320 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2323 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2324 if (LoVT !=
Lo.getValueType())
2326 if (HiVT !=
Hi.getValueType())
2334 assert(
N->getValueType(0).isScalableVector() &&
2335 "Only scalable vectors are supported for STEP_VECTOR");
2336 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2357 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2358 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2360 Hi = DAG.getPOISON(HiVT);
2370 "Extended load during type legalization!");
2372 EVT VT =
LD->getValueType(0);
2374 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2382 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2383 Ch, Ptr,
LD->getMemOperand());
2388 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2390 Lo = DAG.getBitcast(LoVT, ExtractLo);
2391 Hi = DAG.getBitcast(HiVT, ExtractHi);
2403 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2409 EVT MemoryVT =
LD->getMemoryVT();
2411 AAMDNodes AAInfo =
LD->getAAInfo();
2413 EVT LoMemVT, HiMemVT;
2414 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2418 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2419 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2420 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2425 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2428 MachinePointerInfo MPI;
2429 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2432 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2441 ReplaceValueWith(
SDValue(LD, 1), Ch);
2446 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2449 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2455 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2456 Align Alignment =
LD->getBaseAlign();
2459 EVT MemoryVT =
LD->getMemoryVT();
2461 EVT LoMemVT, HiMemVT;
2462 bool HiIsEmpty =
false;
2463 std::tie(LoMemVT, HiMemVT) =
2464 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2469 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2472 GetSplitVector(Mask, MaskLo, MaskHi);
2474 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2479 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2481 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2487 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2488 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2496 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2497 LD->isExpandingLoad());
2499 MachinePointerInfo MPI;
2501 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2503 MPI =
LD->getPointerInfo().getWithOffset(
2506 MMO = DAG.getMachineFunction().getMachineMemOperand(
2508 Alignment,
LD->getAAInfo(),
LD->getRanges());
2510 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2511 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2512 LD->isExpandingLoad());
2522 ReplaceValueWith(
SDValue(LD, 1), Ch);
2528 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2532 Align Alignment =
LD->getBaseAlign();
2539 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2542 GetSplitVector(Mask, MaskLo, MaskHi);
2544 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2548 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2550 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2555 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2558 Hi = DAG.getPOISON(HiVT);
2560 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2561 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2567 "Indexed VP strided load during type legalization!");
2569 "Unexpected indexed variable-length load offset");
2574 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2576 EVT LoMemVT, HiMemVT;
2577 bool HiIsEmpty =
false;
2578 std::tie(LoMemVT, HiMemVT) =
2579 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2584 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2587 GetSplitVector(Mask, LoMask, HiMask);
2589 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2593 std::tie(LoEVL, HiEVL) =
2597 Lo = DAG.getStridedLoadVP(
2624 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2631 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2642 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2650 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2655 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2665 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2668 GetSplitVector(Mask, MaskLo, MaskHi);
2670 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2674 EVT LoMemVT, HiMemVT;
2675 bool HiIsEmpty =
false;
2676 std::tie(LoMemVT, HiMemVT) =
2677 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2679 SDValue PassThruLo, PassThruHi;
2681 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2683 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2685 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2689 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2699 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2702 MachinePointerInfo MPI;
2709 MMO = DAG.getMachineFunction().getMachineMemOperand(
2713 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2725 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2733 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2741 }
Ops = [&]() -> Operands {
2743 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2746 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2749 EVT MemoryVT =
N->getMemoryVT();
2750 Align Alignment =
N->getBaseAlign();
2755 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2757 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2760 EVT LoMemVT, HiMemVT;
2762 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2765 if (getTypeAction(
Ops.Index.getValueType()) ==
2767 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2769 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2772 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2774 Alignment,
N->getAAInfo(),
N->getRanges());
2777 SDValue PassThru = MGT->getPassThru();
2778 SDValue PassThruLo, PassThruHi;
2781 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2783 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2788 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2789 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2790 OpsLo, MMO, IndexTy, ExtType);
2792 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2793 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2794 OpsHi, MMO, IndexTy, ExtType);
2798 std::tie(EVLLo, EVLHi) =
2799 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2801 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2802 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2803 MMO, VPGT->getIndexType());
2805 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2806 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2807 MMO, VPGT->getIndexType());
2817 ReplaceValueWith(
SDValue(
N, 1), Ch);
2831 EVT VecVT =
N->getValueType(0);
2833 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2834 bool HasCustomLowering =
false;
2841 HasCustomLowering =
true;
2847 SDValue Passthru =
N->getOperand(2);
2848 if (!HasCustomLowering) {
2849 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2850 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2857 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2858 std::tie(LoMask, HiMask) = SplitMask(Mask);
2860 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2865 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2866 MachineFunction &MF = DAG.getMachineFunction();
2878 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2880 SDValue Chain = DAG.getEntryNode();
2881 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2885 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2890 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2894 assert(
N->getValueType(0).isVector() &&
2895 N->getOperand(0).getValueType().isVector() &&
2896 "Operand types must be vectors");
2900 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2904 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2906 GetSplitVector(
N->getOperand(0), LL, LH);
2908 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2910 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2912 GetSplitVector(
N->getOperand(1), RL, RH);
2914 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2917 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2918 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2920 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2921 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2922 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2923 std::tie(EVLLo, EVLHi) =
2924 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2925 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2927 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2937 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2941 EVT InVT =
N->getOperand(0).getValueType();
2943 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2945 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2947 const SDNodeFlags
Flags =
N->getFlags();
2948 unsigned Opcode =
N->getOpcode();
2949 if (
N->getNumOperands() <= 2) {
2952 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2953 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2955 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2956 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2961 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2962 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2965 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2968 std::tie(EVLLo, EVLHi) =
2969 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2972 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2978 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2982 EVT InVT =
N->getOperand(0).getValueType();
2984 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2986 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2989 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2990 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2991 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2992 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2995void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3000 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3001 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3005 EVT InVT =
N->getOperand(0).getValueType();
3007 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3009 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3011 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3012 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3014 SDNode *HiNode =
Hi.getNode();
3015 SDNode *LoNode =
Lo.getNode();
3018 unsigned OtherNo = 1 - ResNo;
3019 EVT OtherVT =
N->getValueType(OtherNo);
3027 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3034 EVT SrcVT =
N->getOperand(0).getValueType();
3035 EVT DestVT =
N->getValueType(0);
3037 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3054 LLVMContext &Ctx = *DAG.getContext();
3058 EVT SplitLoVT, SplitHiVT;
3059 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3060 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3061 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3062 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3063 N->dump(&DAG);
dbgs() <<
"\n");
3064 if (!
N->isVPOpcode()) {
3067 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3069 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3071 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3072 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3078 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
3079 N->getOperand(1),
N->getOperand(2));
3081 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3084 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3087 std::tie(EVLLo, EVLHi) =
3088 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3090 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
3091 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
3096 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3104 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3105 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3111 return N.getResNo() == 0 &&
3115 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3117 ArrayRef<int>
Mask) {
3120 "Expected build vector node.");
3123 for (
unsigned I = 0;
I < NewElts; ++
I) {
3126 unsigned Idx =
Mask[
I];
3128 Ops[
I] = Input2.getOperand(Idx - NewElts);
3130 Ops[
I] = Input1.getOperand(Idx);
3135 return DAG.getBuildVector(NewVT,
DL,
Ops);
3141 SmallVector<int> OrigMask(
N->getMask());
3143 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3144 &
DL](SmallVectorImpl<int> &
Mask) {
3146 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3147 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3158 for (
auto &
P : ShufflesIdxs) {
3159 if (
P.second.size() < 2)
3163 for (
int &Idx : Mask) {
3166 unsigned SrcRegIdx = Idx / NewElts;
3167 if (Inputs[SrcRegIdx].
isUndef()) {
3175 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3180 Idx = MaskElt % NewElts +
3181 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3187 Inputs[
P.second[0]] =
P.first.first;
3188 Inputs[
P.second[1]] =
P.first.second;
3191 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3194 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3195 for (
int &Idx : Mask) {
3198 unsigned SrcRegIdx = Idx / NewElts;
3199 if (Inputs[SrcRegIdx].
isUndef()) {
3206 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3207 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3210 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3212 if (UsedSubVector.count() > 1) {
3214 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3215 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3217 if (Pairs.
empty() || Pairs.
back().size() == 2)
3219 if (UsedSubVector.test(2 *
I)) {
3220 Pairs.
back().emplace_back(
I, 0);
3222 assert(UsedSubVector.test(2 *
I + 1) &&
3223 "Expected to be used one of the subvectors.");
3224 Pairs.
back().emplace_back(
I, 1);
3227 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3229 for (
int &Idx : Mask) {
3232 unsigned SrcRegIdx = Idx / NewElts;
3234 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3235 return Idxs.front().first == SrcRegIdx ||
3236 Idxs.back().first == SrcRegIdx;
3238 if (It == Pairs.
end())
3240 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3241 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3244 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3245 Inputs[Idxs.front().first] = DAG.
getNode(
3247 Inputs[Idxs.front().first].getValueType(),
3248 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3249 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3258 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3262 if (Shuffle->getOperand(0).getValueType() != NewVT)
3265 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3266 !Shuffle->isSplat()) {
3268 }
else if (!Inputs[
I].hasOneUse() &&
3269 !Shuffle->getOperand(1).isUndef()) {
3271 for (
int &Idx : Mask) {
3274 unsigned SrcRegIdx = Idx / NewElts;
3277 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3282 int OpIdx = MaskElt / NewElts;
3296 if (Shuffle->getOperand(
OpIdx).isUndef())
3298 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3299 if (It == std::end(Inputs))
3301 int FoundOp = std::distance(std::begin(Inputs), It);
3304 for (
int &Idx : Mask) {
3307 unsigned SrcRegIdx = Idx / NewElts;
3310 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3315 int MaskIdx = MaskElt / NewElts;
3316 if (
OpIdx == MaskIdx)
3317 Idx = MaskElt % NewElts + FoundOp * NewElts;
3328 for (
int &Idx : Mask) {
3331 unsigned SrcRegIdx = Idx / NewElts;
3334 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3335 int OpIdx = MaskElt / NewElts;
3338 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3344 TryPeekThroughShufflesInputs(OrigMask);
3346 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3347 NewElts](SmallVectorImpl<int> &
Mask) {
3348 SetVector<SDValue> UniqueInputs;
3349 SetVector<SDValue> UniqueConstantInputs;
3350 for (
const auto &
I : Inputs) {
3352 UniqueConstantInputs.
insert(
I);
3353 else if (!
I.isUndef())
3358 if (UniqueInputs.
size() != std::size(Inputs)) {
3359 auto &&UniqueVec = UniqueInputs.
takeVector();
3360 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3361 unsigned ConstNum = UniqueConstantVec.size();
3362 for (
int &Idx : Mask) {
3365 unsigned SrcRegIdx = Idx / NewElts;
3366 if (Inputs[SrcRegIdx].
isUndef()) {
3370 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3371 if (It != UniqueConstantVec.end()) {
3372 Idx = (Idx % NewElts) +
3373 NewElts * std::distance(UniqueConstantVec.begin(), It);
3374 assert(Idx >= 0 &&
"Expected defined mask idx.");
3377 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3378 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3379 Idx = (Idx % NewElts) +
3380 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3381 assert(Idx >= 0 &&
"Expected defined mask idx.");
3383 copy(UniqueConstantVec, std::begin(Inputs));
3384 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3387 MakeUniqueInputs(OrigMask);
3389 copy(Inputs, std::begin(OrigInputs));
3395 unsigned FirstMaskIdx =
High * NewElts;
3398 assert(!Output &&
"Expected default initialized initial value.");
3399 TryPeekThroughShufflesInputs(Mask);
3400 MakeUniqueInputs(Mask);
3402 copy(Inputs, std::begin(TmpInputs));
3405 bool SecondIteration =
false;
3406 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3411 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3412 SecondIteration =
true;
3413 return SecondIteration;
3416 Mask, std::size(Inputs), std::size(Inputs),
3418 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3419 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3420 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3422 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3424 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3425 DAG.getPOISON(NewVT), Mask);
3426 Inputs[Idx] = Output;
3428 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3429 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3430 unsigned Idx2,
bool ) {
3431 if (AccumulateResults(Idx1)) {
3434 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3436 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3437 Inputs[Idx2], Mask);
3441 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3443 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3444 TmpInputs[Idx2], Mask);
3446 Inputs[Idx1] = Output;
3448 copy(OrigInputs, std::begin(Inputs));
3453 EVT OVT =
N->getValueType(0);
3460 const Align Alignment =
3461 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3463 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3464 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3469 ReplaceValueWith(
SDValue(
N, 1), Chain);
3474 EVT DstVTLo, DstVTHi;
3475 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3479 EVT SrcVT =
N->getOperand(0).getValueType();
3481 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3483 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3485 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3486 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3492 GetSplitVector(
N->getOperand(0), InLo, InHi);
3503 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3504 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3509 EVT VT =
N->getValueType(0);
3516 Align Alignment = DAG.getReducedAlign(VT,
false);
3521 EVT PtrVT =
StackPtr.getValueType();
3522 auto &MF = DAG.getMachineFunction();
3526 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3529 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3535 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3536 DAG.getConstant(1,
DL, PtrVT));
3538 DAG.getConstant(EltWidth,
DL, PtrVT));
3540 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3542 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3543 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3544 DAG.getPOISON(PtrVT), Stride, TrueMask,
3547 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3549 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3554 EVT VT =
N->getValueType(0);
3566 EVL1 = ZExtPromotedInteger(EVL1);
3568 Align Alignment = DAG.getReducedAlign(VT,
false);
3573 EVT PtrVT =
StackPtr.getValueType();
3574 auto &MF = DAG.getMachineFunction();
3578 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3581 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3585 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3586 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3588 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3590 DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr, PoisonPtr, TrueMask,
3594 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3599 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3600 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3602 uint64_t TrailingElts = -
Imm;
3604 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3613 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3617 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3619 DAG.getVectorIdxConstant(0,
DL));
3625void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3633 GetSplitVector(Acc, AccLo, AccHi);
3634 unsigned Opcode =
N->getOpcode();
3646 GetSplitVector(Input1, Input1Lo, Input1Hi);
3647 GetSplitVector(Input2, Input2Lo, Input2Hi);
3650 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3651 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3654void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3662 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3670void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3671 unsigned Factor =
N->getNumOperands();
3674 for (
unsigned i = 0; i != Factor; ++i) {
3676 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3678 Ops[i * 2 + 1] = OpHi;
3689 for (
unsigned i = 0; i != Factor; ++i)
3693void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3694 unsigned Factor =
N->getNumOperands();
3697 for (
unsigned i = 0; i != Factor; ++i) {
3699 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3701 Ops[i + Factor] = OpHi;
3712 for (
unsigned i = 0; i != Factor; ++i) {
3713 unsigned IdxLo = 2 * i;
3714 unsigned IdxHi = 2 * i + 1;
3715 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3716 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3728bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3733 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3736 switch (
N->getOpcode()) {
3739 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3749 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3756 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3758 case ISD::VP_TRUNCATE:
3760 Res = SplitVecOp_TruncateHelper(
N);
3763 case ISD::VP_FP_ROUND:
3766 Res = SplitVecOp_FP_ROUND(
N);
3775 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3782 case ISD::VP_SCATTER:
3786 case ISD::VP_GATHER:
3790 Res = SplitVecOp_VSELECT(
N, OpNo);
3793 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3799 case ISD::VP_SINT_TO_FP:
3800 case ISD::VP_UINT_TO_FP:
3801 if (
N->getValueType(0).bitsLT(
3802 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3803 Res = SplitVecOp_TruncateHelper(
N);
3805 Res = SplitVecOp_UnaryOp(
N);
3809 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3813 case ISD::VP_FP_TO_SINT:
3814 case ISD::VP_FP_TO_UINT:
3827 Res = SplitVecOp_UnaryOp(
N);
3830 Res = SplitVecOp_FPOpDifferentTypes(
N);
3835 Res = SplitVecOp_CMP(
N);
3839 Res = SplitVecOp_FAKE_USE(
N);
3844 Res = SplitVecOp_ExtVecInRegOp(
N);
3862 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3866 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3868 case ISD::VP_REDUCE_FADD:
3869 case ISD::VP_REDUCE_SEQ_FADD:
3870 case ISD::VP_REDUCE_FMUL:
3871 case ISD::VP_REDUCE_SEQ_FMUL:
3872 case ISD::VP_REDUCE_ADD:
3873 case ISD::VP_REDUCE_MUL:
3874 case ISD::VP_REDUCE_AND:
3875 case ISD::VP_REDUCE_OR:
3876 case ISD::VP_REDUCE_XOR:
3877 case ISD::VP_REDUCE_SMAX:
3878 case ISD::VP_REDUCE_SMIN:
3879 case ISD::VP_REDUCE_UMAX:
3880 case ISD::VP_REDUCE_UMIN:
3881 case ISD::VP_REDUCE_FMAX:
3882 case ISD::VP_REDUCE_FMIN:
3883 case ISD::VP_REDUCE_FMAXIMUM:
3884 case ISD::VP_REDUCE_FMINIMUM:
3885 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3889 Res = SplitVecOp_CttzElts(
N);
3891 case ISD::VP_CTTZ_ELTS:
3892 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3893 Res = SplitVecOp_VP_CttzElements(
N);
3896 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3902 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3907 if (!Res.
getNode())
return false;
3914 if (
N->isStrictFPOpcode())
3916 "Invalid operand expansion");
3919 "Invalid operand expansion");
3921 ReplaceValueWith(
SDValue(
N, 0), Res);
3925SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3929 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3931 EVT VT =
N->getValueType(0);
3944 getSetCCResultType(MVT::i1), MVT::i1);
3949 DAG.getElementCount(
DL, VT, SplitEC)),
3953SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3956 assert(OpNo == 0 &&
"Illegal operand must be mask");
3963 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3966 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3967 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3968 "Lo and Hi have differing types");
3971 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3972 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3974 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3975 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3976 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3977 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3987SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3990 assert(OpNo == 1 &&
"Illegal operand must be mask");
3995 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3997 EVT VecVT =
N->getValueType(0);
4001SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4002 EVT ResVT =
N->getValueType(0);
4008 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4009 GetSplitVector(VecOp,
Lo,
Hi);
4011 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4016 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4017 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4021 EVT ResVT =
N->getValueType(0);
4027 SDNodeFlags
Flags =
N->getFlags();
4030 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4031 GetSplitVector(VecOp,
Lo,
Hi);
4033 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4039 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4042SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4043 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4044 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4046 unsigned Opc =
N->getOpcode();
4047 EVT ResVT =
N->getValueType(0);
4053 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4054 GetSplitVector(VecOp,
Lo,
Hi);
4057 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4060 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4062 const SDNodeFlags
Flags =
N->getFlags();
4066 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4071 EVT ResVT =
N->getValueType(0);
4074 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4075 EVT InVT =
Lo.getValueType();
4080 if (
N->isStrictFPOpcode()) {
4081 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4082 {N->getOperand(0), Lo});
4083 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4084 {N->getOperand(0), Hi});
4093 ReplaceValueWith(
SDValue(
N, 1), Ch);
4094 }
else if (
N->getNumOperands() == 3) {
4095 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4096 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4097 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4098 std::tie(EVLLo, EVLHi) =
4099 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4100 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4101 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4103 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4104 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4113 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4123 EVT ResVT =
N->getValueType(0);
4125 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4129 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4135 Lo = BitConvertToInteger(
Lo);
4136 Hi = BitConvertToInteger(
Hi);
4138 if (DAG.getDataLayout().isBigEndian())
4146 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4148 EVT ResVT =
N->getValueType(0);
4156 GetSplitVector(SubVec,
Lo,
Hi);
4165 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4167 return SecondInsertion;
4170SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4177 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4179 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4181 ElementCount IdxVal =
4185 EVT SrcVT =
N->getOperand(0).getValueType();
4204 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4205 LoEltsMin - IdxValMin);
4206 DAG.ExtractVectorElements(
Hi, Elts, 0,
4209 return DAG.getBuildVector(SubVT, dl, Elts);
4213 ElementCount ExtractIdx = IdxVal - LoElts;
4215 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4218 EVT HiVT =
Hi.getValueType();
4220 "Only fixed-vector extracts are supported in this case");
4230 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4231 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4237 "Extracting scalable subvector from fixed-width unsupported");
4245 "subvector from a scalable predicate vector");
4251 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4253 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4254 auto &MF = DAG.getMachineFunction();
4258 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4262 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4265 SubVT, dl, Store, StackPtr,
4269SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4275 uint64_t IdxVal =
Index->getZExtValue();
4278 GetSplitVector(Vec,
Lo,
Hi);
4280 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4282 if (IdxVal < LoElts)
4283 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4286 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4291 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4303 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4309 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4311 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4312 auto &MF = DAG.getMachineFunction();
4315 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4319 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4323 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4325 return DAG.getExtLoad(
4336 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4344 SplitVecRes_Gather(
N,
Lo,
Hi);
4347 ReplaceValueWith(
SDValue(
N, 0), Res);
4352 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4356 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4358 SDValue EVL =
N->getVectorLength();
4360 Align Alignment =
N->getBaseAlign();
4366 GetSplitVector(
Data, DataLo, DataHi);
4368 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4373 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4376 GetSplitVector(Mask, MaskLo, MaskHi);
4378 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4381 EVT MemoryVT =
N->getMemoryVT();
4382 EVT LoMemVT, HiMemVT;
4383 bool HiIsEmpty =
false;
4384 std::tie(LoMemVT, HiMemVT) =
4385 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4389 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4392 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4397 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4398 N->getAddressingMode(),
N->isTruncatingStore(),
4399 N->isCompressingStore());
4405 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4406 N->isCompressingStore());
4408 MachinePointerInfo MPI;
4412 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4417 MMO = DAG.getMachineFunction().getMachineMemOperand(
4419 Alignment,
N->getAAInfo(),
N->getRanges());
4421 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4422 N->getAddressingMode(),
N->isTruncatingStore(),
4423 N->isCompressingStore());
4432 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4433 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4440 GetSplitVector(
Data, LoData, HiData);
4442 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4444 EVT LoMemVT, HiMemVT;
4445 bool HiIsEmpty =
false;
4446 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4452 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4453 else if (getTypeAction(
Mask.getValueType()) ==
4455 GetSplitVector(Mask, LoMask, HiMask);
4457 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4460 std::tie(LoEVL, HiEVL) =
4461 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4465 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4466 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4467 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4478 EVT PtrVT =
N->getBasePtr().getValueType();
4481 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4484 Align Alignment =
N->getBaseAlign();
4489 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4490 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4492 Alignment,
N->getAAInfo(),
N->getRanges());
4495 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4496 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4497 N->isCompressingStore());
4506 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4510 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4513 Align Alignment =
N->getBaseAlign();
4519 GetSplitVector(
Data, DataLo, DataHi);
4521 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4526 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4529 GetSplitVector(Mask, MaskLo, MaskHi);
4531 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4534 EVT MemoryVT =
N->getMemoryVT();
4535 EVT LoMemVT, HiMemVT;
4536 bool HiIsEmpty =
false;
4537 std::tie(LoMemVT, HiMemVT) =
4538 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4541 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4546 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4547 N->getAddressingMode(),
N->isTruncatingStore(),
4548 N->isCompressingStore());
4556 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4557 N->isCompressingStore());
4559 MachinePointerInfo MPI;
4563 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4568 MMO = DAG.getMachineFunction().getMachineMemOperand(
4570 Alignment,
N->getAAInfo(),
N->getRanges());
4572 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4573 N->getAddressingMode(),
N->isTruncatingStore(),
4574 N->isCompressingStore());
4587 EVT MemoryVT =
N->getMemoryVT();
4588 Align Alignment =
N->getBaseAlign();
4595 }
Ops = [&]() -> Operands {
4597 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4601 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4606 EVT LoMemVT, HiMemVT;
4607 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4612 GetSplitVector(
Ops.Data, DataLo, DataHi);
4614 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4619 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4621 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4625 if (getTypeAction(
Ops.Index.getValueType()) ==
4627 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4629 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4633 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4635 Alignment,
N->getAAInfo(),
N->getRanges());
4638 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4640 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4641 MSC->getIndexType(), MSC->isTruncatingStore());
4646 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4647 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4648 MMO, MSC->getIndexType(),
4649 MSC->isTruncatingStore());
4653 std::tie(EVLLo, EVLHi) =
4654 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4656 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4657 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4658 VPSC->getIndexType());
4663 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4664 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4665 VPSC->getIndexType());
4669 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4670 assert(OpNo == 1 &&
"Can only split the stored value");
4673 bool isTruncating =
N->isTruncatingStore();
4676 EVT MemoryVT =
N->getMemoryVT();
4677 Align Alignment =
N->getBaseAlign();
4679 AAMDNodes AAInfo =
N->getAAInfo();
4681 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4683 EVT LoMemVT, HiMemVT;
4684 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4688 return TLI.scalarizeVectorStore(
N, DAG);
4691 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4692 Alignment, MMOFlags, AAInfo);
4694 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4697 MachinePointerInfo MPI;
4698 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4701 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4702 HiMemVT, Alignment, MMOFlags, AAInfo);
4704 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4720 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4726 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4747 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4748 SDValue InVec =
N->getOperand(OpNo);
4750 EVT OutVT =
N->getValueType(0);
4758 EVT LoOutVT, HiOutVT;
4759 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4760 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4765 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4767 return SplitVecOp_UnaryOp(
N);
4776 return SplitVecOp_UnaryOp(
N);
4780 GetSplitVector(InVec, InLoVec, InHiVec);
4786 EVT HalfElementVT = IsFloat ?
4788 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4795 if (
N->isStrictFPOpcode()) {
4796 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4797 {N->getOperand(0), InLoVec});
4798 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4799 {N->getOperand(0), InHiVec});
4805 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4806 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4810 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4818 if (
N->isStrictFPOpcode()) {
4822 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4830 DAG.getTargetConstant(
4831 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4838 assert(
N->getValueType(0).isVector() &&
4839 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4840 "Operand types must be vectors");
4842 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4844 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4845 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4847 EVT VT =
N->getValueType(0);
4848 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4853 }
else if (isStrict) {
4854 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4855 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4856 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4857 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4860 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4862 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4863 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4864 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4865 std::tie(EVLLo, EVLHi) =
4866 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4867 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4868 N->getOperand(2), MaskLo, EVLLo);
4869 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4870 N->getOperand(2), MaskHi, EVLHi);
4878 EVT OpVT =
N->getOperand(0).getValueType();
4881 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4887 EVT ResVT =
N->getValueType(0);
4890 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4891 EVT InVT =
Lo.getValueType();
4896 if (
N->isStrictFPOpcode()) {
4897 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4898 {N->getOperand(0), Lo, N->getOperand(2)});
4899 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4900 {N->getOperand(0), Hi, N->getOperand(2)});
4904 Lo.getValue(1),
Hi.getValue(1));
4905 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4906 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4907 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4908 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4909 std::tie(EVLLo, EVLHi) =
4910 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4911 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4912 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4914 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4915 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
4926SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4929 EVT LHSLoVT, LHSHiVT;
4930 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4932 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4933 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4936 std::tie(LHSLo, LHSHi) =
4937 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4940 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4943 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4949 LLVMContext &Ctxt = *DAG.getContext();
4952 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4953 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4954 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4956 EVT ResVT =
N->getValueType(0);
4961 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4962 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4968 EVT ResVT =
N->getValueType(0);
4971 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4972 EVT InVT =
Lo.getValueType();
4978 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4979 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4986 EVT ResVT =
N->getValueType(0);
4990 GetSplitVector(VecOp,
Lo,
Hi);
4996 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
4998 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5000 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5001 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5006 EVT ResVT =
N->getValueType(0);
5010 GetSplitVector(VecOp,
Lo,
Hi);
5012 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5013 auto [EVLLo, EVLHi] =
5015 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5021 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5023 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5024 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5027SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5038 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5039 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5040 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5041 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5042 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5043 OpsLo, MMO, IndexType);
5044 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5045 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5049SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5052 "Accumulator should already be a legal type, and shouldn't need "
5053 "further splitting");
5056 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5057 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5058 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5059 unsigned Opcode =
N->getOpcode();
5062 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5063 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5070void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5071 unsigned WidenResNo) {
5072 unsigned NumResults =
N->getNumValues();
5073 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5074 if (ResNo == WidenResNo)
5076 EVT ResVT =
N->getValueType(ResNo);
5082 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5083 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5088void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5089 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5092 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5097 auto unrollExpandedOp = [&]() {
5102 EVT VT =
N->getValueType(0);
5103 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5104 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5105 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5107 if (
N->getNumValues() > 1)
5108 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5114 switch (
N->getOpcode()) {
5117 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5125 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5129 Res = WidenVecRes_ADDRSPACECAST(
N);
5136 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5143 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5147 Res = WidenVecRes_ScalarOp(
N);
5152 case ISD::VP_SELECT:
5154 Res = WidenVecRes_Select(
N);
5158 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5160 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5167 case ISD::VP_LOAD_FF:
5170 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5174 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5182 case ISD::VP_GATHER:
5186 Res = WidenVecRes_VECTOR_REVERSE(
N);
5189 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5199 case ISD::OR:
case ISD::VP_OR:
5210 case ISD::VP_FMINNUM:
5213 case ISD::VP_FMAXNUM:
5215 case ISD::VP_FMINIMUM:
5217 case ISD::VP_FMAXIMUM:
5250 case ISD::VP_FCOPYSIGN:
5251 Res = WidenVecRes_Binary(
N);
5258 Res = WidenVecRes_MaskedBinary(
N);
5263 Res = WidenVecRes_CMP(
N);
5269 if (unrollExpandedOp())
5284 Res = WidenVecRes_BinaryCanTrap(
N);
5293 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5296#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5297 case ISD::STRICT_##DAGN:
5298#include "llvm/IR/ConstrainedOps.def"
5299 Res = WidenVecRes_StrictFP(
N);
5308 Res = WidenVecRes_OverflowOp(
N, ResNo);
5312 Res = WidenVecRes_FCOPYSIGN(
N);
5317 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5322 if (!unrollExpandedOp())
5323 Res = WidenVecRes_ExpOp(
N);
5329 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5334 case ISD::VP_FP_EXTEND:
5336 case ISD::VP_FP_ROUND:
5338 case ISD::VP_FP_TO_SINT:
5340 case ISD::VP_FP_TO_UINT:
5342 case ISD::VP_SIGN_EXTEND:
5344 case ISD::VP_SINT_TO_FP:
5345 case ISD::VP_TRUNCATE:
5348 case ISD::VP_UINT_TO_FP:
5350 case ISD::VP_ZERO_EXTEND:
5352 Res = WidenVecRes_Convert(
N);
5357 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5363 case ISD::VP_LLRINT:
5366 Res = WidenVecRes_XROUND(
N);
5392 if (unrollExpandedOp())
5403 case ISD::VP_BITREVERSE:
5409 case ISD::VP_CTLZ_ZERO_POISON:
5415 case ISD::VP_CTTZ_ZERO_POISON:
5420 case ISD::VP_FFLOOR:
5422 case ISD::VP_FNEARBYINT:
5423 case ISD::VP_FROUND:
5424 case ISD::VP_FROUNDEVEN:
5425 case ISD::VP_FROUNDTOZERO:
5430 Res = WidenVecRes_Unary(
N);
5437 Res = WidenVecRes_Ternary(
N);
5443 if (!unrollExpandedOp())
5444 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5451 SetWidenedVector(
SDValue(
N, ResNo), Res);
5457 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5458 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5459 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5460 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5461 if (
N->getNumOperands() == 3)
5462 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5464 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5465 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5469 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5470 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5476 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5477 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5478 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5479 if (
N->getNumOperands() == 2)
5480 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5483 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5484 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5488 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5489 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5494 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5495 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5496 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5499 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5500 Mask = ModifyToType(Mask, WideMaskVT,
true);
5501 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5506 LLVMContext &Ctxt = *DAG.getContext();
5511 EVT OpVT =
LHS.getValueType();
5513 LHS = GetWidenedVector(
LHS);
5514 RHS = GetWidenedVector(
RHS);
5515 OpVT =
LHS.getValueType();
5518 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5521 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5527SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5530 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5531 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5532 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5534 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5543 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5546 if (ConcatEnd == 1) {
5547 VT = ConcatOps[0].getValueType();
5549 return ConcatOps[0];
5552 SDLoc dl(ConcatOps[0]);
5559 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5560 int Idx = ConcatEnd - 1;
5561 VT = ConcatOps[Idx--].getValueType();
5562 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5575 unsigned NumToInsert = ConcatEnd - Idx - 1;
5576 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5578 ConcatOps[Idx+1] = VecOp;
5579 ConcatEnd = Idx + 2;
5585 unsigned RealVals = ConcatEnd - Idx - 1;
5586 unsigned SubConcatEnd = 0;
5587 unsigned SubConcatIdx = Idx + 1;
5588 while (SubConcatEnd < RealVals)
5589 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5590 while (SubConcatEnd < OpsToConcat)
5591 SubConcatOps[SubConcatEnd++] = undefVec;
5593 NextVT, SubConcatOps);
5594 ConcatEnd = SubConcatIdx + 1;
5599 if (ConcatEnd == 1) {
5600 VT = ConcatOps[0].getValueType();
5602 return ConcatOps[0];
5607 if (
NumOps != ConcatEnd ) {
5609 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5610 ConcatOps[j] = UndefVal;
5618 unsigned Opcode =
N->getOpcode();
5620 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5624 const SDNodeFlags
Flags =
N->getFlags();
5625 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5626 NumElts = NumElts / 2;
5630 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5632 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5633 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5634 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5642 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5645 TLI.isTypeLegal(WideMaskVT)) {
5646 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5647 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5648 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5650 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5651 N->getValueType(0).getVectorElementCount());
5652 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5666 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5667 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5668 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5671 unsigned ConcatEnd = 0;
5679 while (CurNumElts != 0) {
5680 while (CurNumElts >= NumElts) {
5681 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5682 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5683 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5685 CurNumElts -= NumElts;
5688 NumElts = NumElts / 2;
5690 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5693 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5694 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5695 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5696 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5707 switch (
N->getOpcode()) {
5710 return WidenVecRes_STRICT_FSETCC(
N);
5717 return WidenVecRes_Convert_StrictFP(
N);
5724 unsigned Opcode =
N->getOpcode();
5726 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5730 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5731 NumElts = NumElts / 2;
5742 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5746 unsigned ConcatEnd = 0;
5753 for (
unsigned i = 1; i < NumOpers; ++i) {
5759 Oper = GetWidenedVector(Oper);
5765 DAG.getPOISON(WideOpVT), Oper,
5766 DAG.getVectorIdxConstant(0, dl));
5778 while (CurNumElts != 0) {
5779 while (CurNumElts >= NumElts) {
5782 for (
unsigned i = 0; i < NumOpers; ++i) {
5785 EVT OpVT =
Op.getValueType();
5790 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5796 EVT OperVT[] = {VT, MVT::Other};
5798 ConcatOps[ConcatEnd++] = Oper;
5801 CurNumElts -= NumElts;
5804 NumElts = NumElts / 2;
5806 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5809 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5812 for (
unsigned i = 0; i < NumOpers; ++i) {
5815 EVT OpVT =
Op.getValueType();
5823 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5825 ConcatOps[ConcatEnd++] = Oper;
5834 if (Chains.
size() == 1)
5835 NewChain = Chains[0];
5838 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5843SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5845 EVT ResVT =
N->getValueType(0);
5846 EVT OvVT =
N->getValueType(1);
5847 EVT WideResVT, WideOvVT;
5852 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5857 WideLHS = GetWidenedVector(
N->getOperand(0));
5858 WideRHS = GetWidenedVector(
N->getOperand(1));
5860 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5869 N->getOperand(0), Zero);
5871 N->getOperand(1), Zero);
5874 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5875 SDNode *WideNode = DAG.getNode(
5876 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5879 unsigned OtherNo = 1 - ResNo;
5880 EVT OtherVT =
N->getValueType(OtherNo);
5887 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5890 return SDValue(WideNode, ResNo);
5894 LLVMContext &Ctx = *DAG.getContext();
5898 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5903 unsigned Opcode =
N->getOpcode();
5904 const SDNodeFlags
Flags =
N->getFlags();
5910 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5912 InOp = ZExtPromotedInteger(InOp);
5923 InOp = GetWidenedVector(
N->getOperand(0));
5926 if (InVTEC == WidenEC) {
5927 if (
N->getNumOperands() == 1)
5928 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5929 if (
N->getNumOperands() == 3) {
5930 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5933 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5935 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5961 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5965 if (TLI.isTypeLegal(InWidenVT)) {
5973 unsigned NumConcat =
5978 if (
N->getNumOperands() == 1)
5979 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5980 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5984 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5986 if (
N->getNumOperands() == 1)
5987 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5988 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5997 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5998 for (
unsigned i=0; i < MinElts; ++i) {
5999 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6000 if (
N->getNumOperands() == 1)
6003 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
6006 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6011 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6015 EVT SrcVT = Src.getValueType();
6019 Src = GetWidenedVector(Src);
6020 SrcVT = Src.getValueType();
6027 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6032 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6036 EVT SrcVT = Src.getValueType();
6040 Src = GetWidenedVector(Src);
6041 SrcVT = Src.getValueType();
6048 if (
N->getNumOperands() == 1)
6049 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6051 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6052 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6056 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6059SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6064 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6070 unsigned Opcode =
N->getOpcode();
6076 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6081 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6082 for (
unsigned i=0; i < MinElts; ++i) {
6083 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6084 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6088 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6090 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6093SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6094 unsigned Opcode =
N->getOpcode();
6098 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6107 InOp = GetWidenedVector(InOp);
6114 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6121 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6122 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6139 while (
Ops.size() != WidenNumElts)
6140 Ops.push_back(DAG.getPOISON(WidenSVT));
6142 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6148 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6149 return WidenVecRes_BinaryCanTrap(
N);
6152 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6159SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6161 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6164 SDValue Arg = GetWidenedVector(FpValue);
6165 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6170 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6171 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6173 EVT ExpVT =
RHS.getValueType();
6178 ExpOp = ModifyToType(
RHS, WideExpVT);
6181 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6186 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6187 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6188 if (
N->getNumOperands() == 1)
6189 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6191 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6192 N->getOperand(1),
N->getFlags());
6194 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6195 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6199 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6200 {InOp,
Mask,
N->getOperand(2)});
6204 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6209 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6210 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6211 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6214SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6216 EVT VT0 =
N->getValueType(0);
6217 EVT VT1 =
N->getValueType(1);
6221 "expected both results to be vectors of matching element count");
6223 LLVMContext &Ctx = *DAG.getContext();
6224 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6226 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6233 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6236 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6237 return SDValue(WidenNode, ResNo);
6240SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6241 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6242 return GetWidenedVector(WidenVec);
6246 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6247 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6250 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6251 AddrSpaceCastN->getSrcAddressSpace(),
6252 AddrSpaceCastN->getDestAddressSpace());
6258 EVT VT =
N->getValueType(0);
6259 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6262 switch (getTypeAction(InVT)) {
6276 SDValue NInOp = GetPromotedInteger(InOp);
6278 if (WidenVT.
bitsEq(NInVT)) {
6281 if (DAG.getDataLayout().isBigEndian()) {
6284 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6302 InOp = GetWidenedVector(InOp);
6304 if (WidenVT.
bitsEq(InVT))
6314 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6319 unsigned NewNumParts = WidenSize / InSize;
6332 EVT OrigInVT =
N->getOperand(0).getValueType();
6337 if (TLI.isTypeLegal(NewInVT)) {
6345 if (WidenSize % InSize == 0) {
6352 DAG.ExtractVectorElements(InOp,
Ops);
6353 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6365 return CreateStackStoreLoad(InOp, WidenVT);
6368SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6370 N->getOpcode(), SDLoc(
N),
6371 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6372 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6378 EVT VT =
N->getValueType(0);
6382 EVT EltVT =
N->getOperand(0).getValueType();
6385 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6389 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6390 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6392 return DAG.getBuildVector(WidenVT, dl, NewOps);
6396 EVT InVT =
N->getOperand(0).getValueType();
6397 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6399 unsigned NumOperands =
N->getNumOperands();
6401 bool InputWidened =
false;
6405 if (WidenNumElts % NumInElts == 0) {
6407 unsigned NumConcat = WidenNumElts / NumInElts;
6408 SDValue UndefVal = DAG.getPOISON(InVT);
6410 for (
unsigned i=0; i < NumOperands; ++i)
6411 Ops[i] =
N->getOperand(i);
6412 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6417 InputWidened =
true;
6418 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6421 for (i=1; i < NumOperands; ++i)
6422 if (!
N->getOperand(i).isUndef())
6425 if (i == NumOperands)
6428 return GetWidenedVector(
N->getOperand(0));
6430 if (NumOperands == 2) {
6432 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6437 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6438 for (
unsigned i = 0; i < NumInElts; ++i) {
6440 MaskOps[i + NumInElts] = i + WidenNumElts;
6442 return DAG.getVectorShuffle(WidenVT, dl,
6443 GetWidenedVector(
N->getOperand(0)),
6444 GetWidenedVector(
N->getOperand(1)),
6451 "Cannot use build vectors to widen CONCAT_VECTOR result");
6459 for (
unsigned i=0; i < NumOperands; ++i) {
6462 InOp = GetWidenedVector(InOp);
6463 for (
unsigned j = 0;
j < NumInElts; ++
j)
6464 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6466 SDValue UndefVal = DAG.getPOISON(EltVT);
6467 for (; Idx < WidenNumElts; ++Idx)
6468 Ops[Idx] = UndefVal;
6469 return DAG.getBuildVector(WidenVT, dl,
Ops);
6472SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6473 EVT VT =
N->getValueType(0);
6474 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6475 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6482SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6483 EVT VT =
N->getValueType(0);
6485 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6490 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6492 InOp = GetWidenedVector(InOp);
6498 if (IdxVal == 0 && InVT == WidenVT)
6505 assert(IdxVal % VTNumElts == 0 &&
6506 "Expected Idx to be a multiple of subvector minimum vector length");
6507 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6520 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6521 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6522 "down type's element count");
6529 for (;
I < VTNumElts / GCD; ++
I)
6531 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6532 for (;
I < WidenNumElts / GCD; ++
I)
6540 Align Alignment = DAG.getReducedAlign(InVT,
false);
6542 MachineFunction &MF = DAG.getMachineFunction();
6554 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6561 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6562 return DAG.getMaskedLoad(
6563 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6571 for (i = 0; i < VTNumElts; ++i)
6572 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6574 SDValue UndefVal = DAG.getPOISON(EltVT);
6575 for (; i < WidenNumElts; ++i)
6577 return DAG.getBuildVector(WidenVT, dl,
Ops);
6583 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6588SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6589 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6592 N->getOperand(1),
N->getOperand(2));
6601 "Load width must be less than or equal to first value type width");
6610 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6621 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6622 EVT LdVT =
LD->getMemoryVT();
6626 "Must be scalable");
6628 "Expected equivalent element types");
6636 TypeSize WidthDiff = WidenWidth - LdWidth;
6639 std::optional<EVT> FirstVT =
6640 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6647 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6650 Chain, BasePtr,
LD->getMemOperand());
6654 FirstVTWidth, dl, DAG);
6672 if (!
LD->getMemoryVT().isByteSized()) {
6674 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6676 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6685 EVT VT =
LD->getValueType(0);
6686 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6687 EVT WideMaskVT = getSetCCResultType(WideVT);
6690 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6691 TLI.isTypeLegal(WideMaskVT)) {
6694 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6698 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6699 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6711 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6713 Result = GenWidenVectorLoads(LdChain, LD);
6720 if (LdChain.
size() == 1)
6721 NewChain = LdChain[0];
6727 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6738 SDValue NewLoad = DAG.getMaskedLoad(
6739 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6740 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6741 LD->getAddressingMode(),
LD->getExtensionType());
6751 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6753 SDValue EVL =
N->getVectorLength();
6760 "Unable to widen binary VP op");
6761 Mask = GetWidenedVector(Mask);
6762 assert(
Mask.getValueType().getVectorElementCount() ==
6763 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6764 .getVectorElementCount() &&
6765 "Unable to widen vector load");
6768 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6769 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6770 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6778 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6780 SDValue EVL =
N->getVectorLength();
6786 "Unable to widen binary VP op");
6787 Mask = GetWidenedVector(Mask);
6788 assert(
Mask.getValueType().getVectorElementCount() ==
6789 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6790 .getVectorElementCount() &&
6791 "Unable to widen vector load");
6793 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6794 Mask, EVL,
N->getMemOperand());
6807 "Unable to widen VP strided load");
6808 Mask = GetWidenedVector(Mask);
6810 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6811 assert(
Mask.getValueType().getVectorElementCount() ==
6813 "Data and mask vectors should have the same number of elements");
6815 SDValue Res = DAG.getStridedLoadVP(
6816 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6817 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6818 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6819 N->isExpandingLoad());
6827SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6832 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6834 Mask.getValueType().getVectorElementType(),
6837 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6838 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6839 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6841 WideMask, WidePassthru);
6845 EVT VT =
N->getValueType(0);
6846 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6848 EVT MaskVT =
Mask.getValueType();
6849 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6858 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6859 TLI.isTypeLegal(WideMaskVT) &&
6865 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6866 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6870 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6871 N->getMemoryVT(),
N->getMemOperand());
6875 if (!
N->getPassThru()->isUndef()) {
6879 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6880 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6881 DAG.getPOISON(WidenVT), EVL);
6892 Mask = ModifyToType(Mask, WideMaskVT,
true);
6894 SDValue Res = DAG.getMaskedLoad(
6895 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6896 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6897 ExtType,
N->isExpandingLoad());
6906 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6908 EVT MaskVT =
Mask.getValueType();
6909 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6918 Mask = ModifyToType(Mask, WideMaskVT,
true);
6923 Index.getValueType().getScalarType(),
6925 Index = ModifyToType(Index, WideIndexVT);
6931 N->getMemoryVT().getScalarType(), NumElts);
6932 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6933 WideMemVT, dl,
Ops,
N->getMemOperand(),
6934 N->getIndexType(),
N->getExtensionType());
6943 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6951 N->getMemoryVT().getScalarType(), WideEC);
6952 Mask = GetWidenedMask(Mask, WideEC);
6955 Mask,
N->getVectorLength()};
6956 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6957 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6966 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6967 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6995 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6996 return N->getOperand(OpNo).getValueType();
7004 N =
N.getOperand(0);
7006 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7007 if (!
N->getOperand(i)->isUndef())
7009 N =
N.getOperand(0);
7013 N =
N.getOperand(0);
7015 N =
N.getOperand(0);
7042 { MaskVT, MVT::Other },
Ops);
7043 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7051 LLVMContext &Ctx = *DAG.getContext();
7054 if (MaskScalarBits < ToMaskScalBits) {
7058 }
else if (MaskScalarBits > ToMaskScalBits) {
7064 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7066 "Mask should have the right element size by now.");
7069 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7071 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7074 EVT SubVT =
Mask->getValueType(0);
7080 assert((
Mask->getValueType(0) == ToMaskVT) &&
7081 "A mask of ToMaskVT should have been produced by now.");
7091 LLVMContext &Ctx = *DAG.getContext();
7102 EVT CondVT =
Cond->getValueType(0);
7106 EVT VSelVT =
N->getValueType(0);
7118 EVT FinalVT = VSelVT;
7129 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7130 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7137 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7145 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7148 EVT ToMaskVT = VSelVT;
7155 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7171 if (ScalarBits0 != ScalarBits1) {
7172 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7173 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7185 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7186 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7187 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7190 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7198 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7203 unsigned Opcode =
N->getOpcode();
7205 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7206 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7207 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7209 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7215 Cond1 = GetWidenedVector(Cond1);
7223 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7224 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7229 Cond1 = ModifyToType(Cond1, CondWidenVT);
7232 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7233 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7235 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7236 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7238 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7242 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7243 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7246 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7250 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7251 return DAG.getUNDEF(WidenVT);
7255 EVT VT =
N->getValueType(0);
7258 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7262 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7263 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7266 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7267 for (
unsigned i = 0; i != NumElts; ++i) {
7268 int Idx =
N->getMaskElt(i);
7269 if (Idx < (
int)NumElts)
7272 NewMask[i] = Idx - NumElts + WidenNumElts;
7274 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7278 EVT VT =
N->getValueType(0);
7282 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7283 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7289 unsigned IdxVal = WidenNumElts - VTNumElts;
7302 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7305 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7306 "down type's element count");
7309 for (; i < VTNumElts / GCD; ++i)
7311 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7312 for (; i < WidenNumElts / GCD; ++i)
7320 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7321 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7323 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7327SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7328 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7333 assert(
N->getValueType(0).isVector() &&
7334 N->getOperand(0).getValueType().isVector() &&
7335 "Operands must be vectors");
7336 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7349 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7350 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7357 InOp1 = GetWidenedVector(InOp1);
7358 InOp2 = GetWidenedVector(InOp2);
7361 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7372 "Input not widened to expected type!");
7374 if (
N->getOpcode() == ISD::VP_SETCC) {
7377 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7378 N->getOperand(2), Mask,
N->getOperand(4));
7380 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7385 assert(
N->getValueType(0).isVector() &&
7386 N->getOperand(1).getValueType().isVector() &&
7387 "Operands must be vectors");
7388 EVT VT =
N->getValueType(0);
7389 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7399 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7404 for (
unsigned i = 0; i != NumElts; ++i) {
7405 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7406 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7408 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7409 {Chain, LHSElem, RHSElem, CC});
7410 Chains[i] = Scalars[i].getValue(1);
7411 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7412 DAG.getBoolConstant(
true, dl, EltVT, VT),
7413 DAG.getBoolConstant(
false, dl, EltVT, VT));
7417 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7419 return DAG.getBuildVector(WidenVT, dl, Scalars);
7425bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7426 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7430 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7433 switch (
N->getOpcode()) {
7436 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7444 Res = WidenVecOp_FAKE_USE(
N);
7450 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7451 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7452 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7453 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7458 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7460 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7461 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7463 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7464 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7474 Res = WidenVecOp_UnrollVectorOp(
N);
7481 Res = WidenVecOp_EXTEND(
N);
7486 Res = WidenVecOp_CMP(
N);
7503 Res = WidenVecOp_Convert(
N);
7508 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7526 Res = WidenVecOp_VECREDUCE(
N);
7530 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7532 case ISD::VP_REDUCE_FADD:
7533 case ISD::VP_REDUCE_SEQ_FADD:
7534 case ISD::VP_REDUCE_FMUL:
7535 case ISD::VP_REDUCE_SEQ_FMUL:
7536 case ISD::VP_REDUCE_ADD:
7537 case ISD::VP_REDUCE_MUL:
7538 case ISD::VP_REDUCE_AND:
7539 case ISD::VP_REDUCE_OR:
7540 case ISD::VP_REDUCE_XOR:
7541 case ISD::VP_REDUCE_SMAX:
7542 case ISD::VP_REDUCE_SMIN:
7543 case ISD::VP_REDUCE_UMAX:
7544 case ISD::VP_REDUCE_UMIN:
7545 case ISD::VP_REDUCE_FMAX:
7546 case ISD::VP_REDUCE_FMIN:
7547 case ISD::VP_REDUCE_FMAXIMUM:
7548 case ISD::VP_REDUCE_FMINIMUM:
7549 Res = WidenVecOp_VP_REDUCE(
N);
7551 case ISD::VP_CTTZ_ELTS:
7552 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7553 Res = WidenVecOp_VP_CttzElements(
N);
7556 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7561 if (!Res.
getNode())
return false;
7569 if (
N->isStrictFPOpcode())
7571 "Invalid operand expansion");
7574 "Invalid operand expansion");
7576 ReplaceValueWith(
SDValue(
N, 0), Res);
7582 EVT VT =
N->getValueType(0);
7587 "Unexpected type action");
7588 InOp = GetWidenedVector(InOp);
7591 "Input wasn't widened!");
7599 EVT FixedEltVT = FixedVT.getVectorElementType();
7600 if (TLI.isTypeLegal(FixedVT) &&
7602 FixedEltVT == InEltVT) {
7604 "Not enough elements in the fixed type for the operand!");
7606 "We can't have the same type as we started with!");
7608 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7610 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7619 return WidenVecOp_Convert(
N);
7624 switch (
N->getOpcode()) {
7639 EVT OpVT =
N->getOperand(0).getValueType();
7640 EVT ResVT =
N->getValueType(0);
7647 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7648 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7654 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7655 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7657 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7664 return DAG.UnrollVectorOp(
N);
7669 EVT ResultVT =
N->getValueType(0);
7671 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7674 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7680 {WideArg,
Test},
N->getFlags());
7686 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7688 EVT OpVT =
N->getOperand(0).getValueType();
7691 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7696 EVT VT =
N->getValueType(0);
7702 "Unexpected type action");
7703 InOp = GetWidenedVector(InOp);
7705 unsigned Opcode =
N->getOpcode();
7711 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7713 if (
N->isStrictFPOpcode()) {
7715 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7718 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7719 {
N->getOperand(0), InOp });
7725 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7727 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7729 return DAG.getExtractSubvector(dl, VT, Res, 0);
7737 if (
N->isStrictFPOpcode()) {
7740 for (
unsigned i=0; i < NumElts; ++i) {
7741 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7742 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7746 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7748 for (
unsigned i = 0; i < NumElts; ++i) {
7749 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7751 Ops[i] = DAG.
getNode(Opcode, dl, EltVT, Elt,
N->getOperand(1));
7753 Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
7757 return DAG.getBuildVector(VT, dl,
Ops);
7761 EVT DstVT =
N->getValueType(0);
7762 SDValue Src = GetWidenedVector(
N->getOperand(0));
7763 EVT SrcVT = Src.getValueType();
7770 if (TLI.isTypeLegal(WideDstVT)) {
7772 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7775 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7779 return DAG.UnrollVectorOp(
N);
7783 EVT VT =
N->getValueType(0);
7784 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7792 if (!VT.
isVector() && VT != MVT::x86mmx &&
7796 if (TLI.isTypeLegal(NewVT)) {
7798 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7810 ElementCount NewNumElts =
7812 .divideCoefficientBy(EltSize);
7814 if (TLI.isTypeLegal(NewVT)) {
7816 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7821 return CreateStackStoreLoad(InOp, VT);
7829 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7830 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7835 EVT VT =
N->getValueType(0);
7837 EVT InVT =
N->getOperand(0).getValueType();
7842 unsigned NumOperands =
N->getNumOperands();
7843 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7845 for (i = 1; i < NumOperands; ++i)
7846 if (!
N->getOperand(i).isUndef())
7849 if (i == NumOperands)
7850 return GetWidenedVector(
N->getOperand(0));
7860 for (
unsigned i=0; i < NumOperands; ++i) {
7864 "Unexpected type action");
7865 InOp = GetWidenedVector(InOp);
7866 for (
unsigned j = 0;
j < NumInElts; ++
j)
7867 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7869 return DAG.getBuildVector(VT, dl,
Ops);
7872SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7873 EVT VT =
N->getValueType(0);
7878 SubVec = GetWidenedVector(SubVec);
7883 bool IndicesValid =
false;
7886 IndicesValid =
true;
7890 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7891 Attribute::VScaleRange);
7896 IndicesValid =
true;
7902 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7908 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7915 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7922 Align Alignment = DAG.getReducedAlign(VT,
false);
7924 MachineFunction &MF = DAG.getMachineFunction();
7937 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7945 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7946 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7951 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7956 unsigned Idx =
N->getConstantOperandVal(2);
7962 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7968SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7969 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7971 N->getValueType(0), InOp,
N->getOperand(1));
7974SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7975 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7977 N->getValueType(0), InOp,
N->getOperand(1));
7980SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7982 EVT ResVT =
N->getValueType(0);
7985 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
7991 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
7999 "Widened input size must be a multiple of result element size");
8002 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8004 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8005 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8013 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8014 return TLI.scalarizeVectorStore(ST, DAG);
8016 if (
ST->isTruncatingStore())
8017 return TLI.scalarizeVectorStore(ST, DAG);
8027 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8028 EVT WideMaskVT = getSetCCResultType(WideVT);
8030 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8031 TLI.isTypeLegal(WideMaskVT)) {
8034 StVal = GetWidenedVector(StVal);
8036 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8038 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8039 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8040 ST->getAddressingMode());
8044 if (GenWidenVectorStores(StChain, ST)) {
8045 if (StChain.
size() == 1)
8054 SDValue WideStVal = GetWidenedVector(StVal);
8058 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8059 ST->getOffset(), Mask,
ST->getMemoryVT(),
8060 ST->getMemOperand(),
ST->getAddressingMode(),
8061 ST->isTruncatingStore());
8067SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8068 assert((OpNo == 1 || OpNo == 3) &&
8069 "Can widen only data or mask operand of vp_store");
8077 StVal = GetWidenedVector(StVal);
8083 "Unable to widen VP store");
8084 Mask = GetWidenedVector(Mask);
8086 Mask = GetWidenedVector(Mask);
8092 "Unable to widen VP store");
8093 StVal = GetWidenedVector(StVal);
8096 assert(
Mask.getValueType().getVectorElementCount() ==
8098 "Mask and data vectors should have the same number of elements");
8099 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8100 ST->getOffset(), Mask,
ST->getVectorLength(),
8101 ST->getMemoryVT(),
ST->getMemOperand(),
8102 ST->getAddressingMode(),
ST->isTruncatingStore(),
8103 ST->isCompressingStore());
8108 assert((OpNo == 1 || OpNo == 4) &&
8109 "Can widen only data or mask operand of vp_strided_store");
8118 "Unable to widen VP strided store");
8122 "Unable to widen VP strided store");
8124 StVal = GetWidenedVector(StVal);
8125 Mask = GetWidenedVector(Mask);
8128 Mask.getValueType().getVectorElementCount() &&
8129 "Data and mask vectors should have the same number of elements");
8131 return DAG.getStridedStoreVP(
8138SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8139 assert((OpNo == 1 || OpNo == 4) &&
8140 "Can widen only data or mask operand of mstore");
8143 EVT MaskVT =
Mask.getValueType();
8148 EVT WideVT, WideMaskVT;
8151 StVal = GetWidenedVector(StVal);
8158 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8165 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8167 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8168 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8177 Mask = ModifyToType(Mask, WideMaskVT,
true);
8180 Mask = ModifyToType(Mask, WideMaskVT,
true);
8182 StVal = ModifyToType(StVal, WideVT);
8185 assert(
Mask.getValueType().getVectorElementCount() ==
8187 "Mask and data vectors should have the same number of elements");
8194SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8195 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8197 SDValue DataOp = MG->getPassThru();
8199 SDValue Scale = MG->getScale();
8207 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8208 MG->getMemOperand(), MG->getIndexType(),
8209 MG->getExtensionType());
8215SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8224 DataOp = GetWidenedVector(DataOp);
8228 EVT IndexVT =
Index.getValueType();
8231 Index = ModifyToType(Index, WideIndexVT);
8234 EVT MaskVT =
Mask.getValueType();
8237 Mask = ModifyToType(Mask, WideMaskVT,
true);
8242 }
else if (OpNo == 4) {
8244 Index = GetWidenedVector(Index);
8250 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8255SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8264 DataOp = GetWidenedVector(DataOp);
8265 Index = GetWidenedVector(Index);
8267 Mask = GetWidenedMask(Mask, WideEC);
8270 }
else if (OpNo == 3) {
8272 Index = GetWidenedVector(Index);
8279 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8284 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8285 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8287 EVT VT =
N->getValueType(0);
8302 SVT, InOp0, InOp1,
N->getOperand(2));
8308 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8310 EVT OpVT =
N->getOperand(0).getValueType();
8313 return DAG.getNode(ExtendCode, dl, VT, CC);
8323 EVT VT =
N->getValueType(0);
8325 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8332 for (
unsigned i = 0; i != NumElts; ++i) {
8333 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8334 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8336 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8337 {Chain, LHSElem, RHSElem, CC});
8338 Chains[i] = Scalars[i].getValue(1);
8339 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8340 DAG.getBoolConstant(
true, dl, EltVT, VT),
8341 DAG.getBoolConstant(
false, dl, EltVT, VT));
8345 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8347 return DAG.getBuildVector(VT, dl, Scalars);
8371 SDValue Op = GetWidenedVector(
N->getOperand(0));
8372 EVT VT =
N->getValueType(0);
8373 EVT OrigVT =
N->getOperand(0).getValueType();
8374 EVT WideVT =
Op.getValueType();
8376 SDNodeFlags
Flags =
N->getFlags();
8378 unsigned Opc =
N->getOpcode();
8380 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8381 assert(NeutralElem &&
"Neutral element must exist");
8391 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8398 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8399 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8405 unsigned GCD = std::gcd(OrigElts, WideElts);
8408 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8409 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8410 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8411 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8414 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8415 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8417 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8426 EVT VT =
N->getValueType(0);
8428 EVT WideVT =
Op.getValueType();
8430 SDNodeFlags
Flags =
N->getFlags();
8432 unsigned Opc =
N->getOpcode();
8434 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8444 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8447 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8448 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8454 unsigned GCD = std::gcd(OrigElts, WideElts);
8457 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8458 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8459 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8460 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8463 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8464 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8466 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8470 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8473 SDValue Op = GetWidenedVector(
N->getOperand(1));
8475 Op.getValueType().getVectorElementCount());
8477 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8478 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8486 EVT VT =
N->getValueType(0);
8490 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8491 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8496 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8502 EVT SrcVT =
Source.getValueType();
8506 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8507 {Source, Mask, N->getOperand(2)},
N->getFlags());
8510SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8513 EVT OrigMaskVT =
Mask.getValueType();
8514 SDValue WideMask = GetWidenedVector(Mask);
8520 if (OrigElts != WideElts) {
8521 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8523 Mask, DAG.getVectorIdxConstant(0,
DL));
8544 unsigned WidenEx = 0) {
8549 unsigned AlignInBits =
Align*8;
8551 EVT RetVT = WidenEltVT;
8556 if (Width == WidenEltWidth)
8567 (WidenWidth % MemVTWidth) == 0 &&
8569 (MemVTWidth <= Width ||
8570 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8571 if (MemVTWidth == WidenWidth)
8590 (WidenWidth % MemVTWidth) == 0 &&
8592 (MemVTWidth <= Width ||
8593 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8602 return std::nullopt;
8613 unsigned Start,
unsigned End) {
8614 SDLoc dl(LdOps[Start]);
8615 EVT LdTy = LdOps[Start].getValueType();
8623 for (
unsigned i = Start + 1; i != End; ++i) {
8624 EVT NewLdTy = LdOps[i].getValueType();
8625 if (NewLdTy != LdTy) {
8644 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8645 EVT LdVT =
LD->getMemoryVT();
8655 AAMDNodes AAInfo =
LD->getAAInfo();
8659 TypeSize WidthDiff = WidenWidth - LdWidth;
8666 std::optional<EVT> FirstVT =
8667 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8674 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8679 std::optional<EVT> NewVT = FirstVT;
8680 TypeSize RemainingWidth = LdWidth;
8681 TypeSize NewVTWidth = FirstVTWidth;
8683 RemainingWidth -= NewVTWidth;
8690 NewVTWidth = NewVT->getSizeInBits();
8696 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8697 LD->getBaseAlign(), MMOFlags, AAInfo);
8709 uint64_t ScaledOffset = 0;
8710 MachinePointerInfo MPI =
LD->getPointerInfo();
8716 for (EVT MemVT : MemVTs) {
8717 Align NewAlign = ScaledOffset == 0
8718 ?
LD->getBaseAlign()
8721 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8729 unsigned End = LdOps.
size();
8740 EVT LdTy = LdOps[i].getValueType();
8743 for (--i; i >= 0; --i) {
8744 LdTy = LdOps[i].getValueType();
8751 ConcatOps[--Idx] = LdOps[i];
8752 for (--i; i >= 0; --i) {
8753 EVT NewLdTy = LdOps[i].getValueType();
8754 if (NewLdTy != LdTy) {
8764 for (;
j != End-Idx; ++
j)
8765 WidenOps[j] = ConcatOps[Idx+j];
8767 WidenOps[j] = DAG.getPOISON(LdTy);
8774 ConcatOps[--Idx] = LdOps[i];
8779 ArrayRef(&ConcatOps[Idx], End - Idx));
8785 SDValue UndefVal = DAG.getPOISON(LdTy);
8788 for (; i != End-Idx; ++i)
8789 WidenOps[i] = ConcatOps[Idx+i];
8791 WidenOps[i] = UndefVal;
8802 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8803 EVT LdVT =
LD->getMemoryVT();
8812 AAMDNodes AAInfo =
LD->getAAInfo();
8826 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8827 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8833 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8834 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8835 LD->getBaseAlign(), MMOFlags, AAInfo);
8840 SDValue UndefVal = DAG.getPOISON(EltVT);
8841 for (; i != WidenNumElts; ++i)
8844 return DAG.getBuildVector(WidenVT, dl,
Ops);
8855 AAMDNodes AAInfo =
ST->getAAInfo();
8856 SDValue ValOp = GetWidenedVector(
ST->getValue());
8859 EVT StVT =
ST->getMemoryVT();
8867 "Mismatch between store and value types");
8871 MachinePointerInfo MPI =
ST->getPointerInfo();
8872 uint64_t ScaledOffset = 0;
8881 std::optional<EVT> NewVT =
8886 TypeSize NewVTWidth = NewVT->getSizeInBits();
8889 StWidth -= NewVTWidth;
8890 MemVTs.
back().second++;
8894 for (
const auto &Pair : MemVTs) {
8895 EVT NewVT = Pair.first;
8896 unsigned Count = Pair.second;
8902 Align NewAlign = ScaledOffset == 0
8903 ?
ST->getBaseAlign()
8905 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8906 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8922 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8923 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8924 ST->getBaseAlign(), MMOFlags, AAInfo);
8941 bool FillWithZeroes) {
8946 "input and widen element type must match");
8948 "cannot modify scalable vectors in this way");
8961 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
8963 for (
unsigned i = 1; i != NumConcat; ++i)
8970 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8973 "Scalable vectors should have been handled already.");
8981 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8983 for (Idx = 0; Idx < MinNumElts; ++Idx)
8984 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8986 SDValue UndefVal = DAG.getPOISON(EltVT);
8987 for (; Idx < WidenNumElts; ++Idx)
8988 Ops[Idx] = UndefVal;
8990 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8991 if (!FillWithZeroes)
8995 "We expect to never want to FillWithZeroes for non-integral types.");
8998 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8999 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9001 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9002 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 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.
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 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 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...
@ 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.
@ 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.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
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.