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);
3527 Align Alignment = DAG.getReducedAlign(VT,
false);
3532 EVT PtrVT =
StackPtr.getValueType();
3533 auto &MF = DAG.getMachineFunction();
3537 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3540 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3546 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3547 DAG.getConstant(1,
DL, PtrVT));
3549 DAG.getConstant(EltWidth,
DL, PtrVT));
3551 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3553 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3554 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3555 DAG.getPOISON(PtrVT), Stride, TrueMask,
3558 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3564 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3569 EVT VT =
N->getValueType(0);
3581 EVL1 = ZExtPromotedInteger(EVL1);
3595 Align Alignment = DAG.getReducedAlign(VT,
false);
3600 EVT PtrVT =
StackPtr.getValueType();
3601 auto &MF = DAG.getMachineFunction();
3605 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3608 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3612 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3613 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3615 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3617 DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr, PoisonPtr, TrueMask,
3621 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3626 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3627 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3629 uint64_t TrailingElts = -
Imm;
3631 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3640 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3648 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3650 DAG.getVectorIdxConstant(0,
DL));
3656void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3664 GetSplitVector(Acc, AccLo, AccHi);
3665 unsigned Opcode =
N->getOpcode();
3677 GetSplitVector(Input1, Input1Lo, Input1Hi);
3678 GetSplitVector(Input2, Input2Lo, Input2Hi);
3681 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3682 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3685void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3693 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3701void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3702 unsigned Factor =
N->getNumOperands();
3705 for (
unsigned i = 0; i != Factor; ++i) {
3707 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3709 Ops[i * 2 + 1] = OpHi;
3720 for (
unsigned i = 0; i != Factor; ++i)
3724void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3725 unsigned Factor =
N->getNumOperands();
3728 for (
unsigned i = 0; i != Factor; ++i) {
3730 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3732 Ops[i + Factor] = OpHi;
3743 for (
unsigned i = 0; i != Factor; ++i) {
3744 unsigned IdxLo = 2 * i;
3745 unsigned IdxHi = 2 * i + 1;
3746 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3747 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3759bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3764 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3767 switch (
N->getOpcode()) {
3770 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3780 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3787 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3789 case ISD::VP_TRUNCATE:
3791 Res = SplitVecOp_TruncateHelper(
N);
3794 case ISD::VP_FP_ROUND:
3797 Res = SplitVecOp_FP_ROUND(
N);
3806 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3813 case ISD::VP_SCATTER:
3817 case ISD::VP_GATHER:
3821 Res = SplitVecOp_VSELECT(
N, OpNo);
3824 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3830 case ISD::VP_SINT_TO_FP:
3831 case ISD::VP_UINT_TO_FP:
3832 if (
N->getValueType(0).bitsLT(
3833 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3834 Res = SplitVecOp_TruncateHelper(
N);
3836 Res = SplitVecOp_UnaryOp(
N);
3840 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3844 case ISD::VP_FP_TO_SINT:
3845 case ISD::VP_FP_TO_UINT:
3858 Res = SplitVecOp_UnaryOp(
N);
3861 Res = SplitVecOp_FPOpDifferentTypes(
N);
3866 Res = SplitVecOp_CMP(
N);
3870 Res = SplitVecOp_FAKE_USE(
N);
3875 Res = SplitVecOp_ExtVecInRegOp(
N);
3893 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3897 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3899 case ISD::VP_REDUCE_FADD:
3900 case ISD::VP_REDUCE_SEQ_FADD:
3901 case ISD::VP_REDUCE_FMUL:
3902 case ISD::VP_REDUCE_SEQ_FMUL:
3903 case ISD::VP_REDUCE_ADD:
3904 case ISD::VP_REDUCE_MUL:
3905 case ISD::VP_REDUCE_AND:
3906 case ISD::VP_REDUCE_OR:
3907 case ISD::VP_REDUCE_XOR:
3908 case ISD::VP_REDUCE_SMAX:
3909 case ISD::VP_REDUCE_SMIN:
3910 case ISD::VP_REDUCE_UMAX:
3911 case ISD::VP_REDUCE_UMIN:
3912 case ISD::VP_REDUCE_FMAX:
3913 case ISD::VP_REDUCE_FMIN:
3914 case ISD::VP_REDUCE_FMAXIMUM:
3915 case ISD::VP_REDUCE_FMINIMUM:
3916 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3920 Res = SplitVecOp_CttzElts(
N);
3922 case ISD::VP_CTTZ_ELTS:
3923 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3924 Res = SplitVecOp_VP_CttzElements(
N);
3927 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3933 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3938 if (!Res.
getNode())
return false;
3945 if (
N->isStrictFPOpcode())
3947 "Invalid operand expansion");
3950 "Invalid operand expansion");
3952 ReplaceValueWith(
SDValue(
N, 0), Res);
3956SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3960 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3962 EVT VT =
N->getValueType(0);
3975 getSetCCResultType(MVT::i1), MVT::i1);
3980 DAG.getElementCount(
DL, VT, SplitEC)),
3984SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3987 assert(OpNo == 0 &&
"Illegal operand must be mask");
3994 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3997 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3998 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3999 "Lo and Hi have differing types");
4002 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4003 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4005 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4006 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4007 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4008 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4018SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4021 assert(OpNo == 1 &&
"Illegal operand must be mask");
4026 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4028 EVT VecVT =
N->getValueType(0);
4032SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4033 EVT ResVT =
N->getValueType(0);
4039 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4040 GetSplitVector(VecOp,
Lo,
Hi);
4042 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4047 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4048 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4052 EVT ResVT =
N->getValueType(0);
4058 SDNodeFlags
Flags =
N->getFlags();
4061 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4062 GetSplitVector(VecOp,
Lo,
Hi);
4064 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4070 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4073SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4074 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4075 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4077 unsigned Opc =
N->getOpcode();
4078 EVT ResVT =
N->getValueType(0);
4084 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4085 GetSplitVector(VecOp,
Lo,
Hi);
4088 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4091 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4093 const SDNodeFlags
Flags =
N->getFlags();
4097 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4102 EVT ResVT =
N->getValueType(0);
4105 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4106 EVT InVT =
Lo.getValueType();
4111 if (
N->isStrictFPOpcode()) {
4112 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4113 {N->getOperand(0), Lo});
4114 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4115 {N->getOperand(0), Hi});
4124 ReplaceValueWith(
SDValue(
N, 1), Ch);
4125 }
else if (
N->getNumOperands() == 3) {
4126 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4127 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4128 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4129 std::tie(EVLLo, EVLHi) =
4130 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4131 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4132 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4134 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4135 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4144 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4154 EVT ResVT =
N->getValueType(0);
4156 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4160 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4166 Lo = BitConvertToInteger(
Lo);
4167 Hi = BitConvertToInteger(
Hi);
4169 if (DAG.getDataLayout().isBigEndian())
4177 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4179 EVT ResVT =
N->getValueType(0);
4187 GetSplitVector(SubVec,
Lo,
Hi);
4196 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4198 return SecondInsertion;
4201SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4208 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4210 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4212 ElementCount IdxVal =
4216 EVT SrcVT =
N->getOperand(0).getValueType();
4235 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4236 LoEltsMin - IdxValMin);
4237 DAG.ExtractVectorElements(
Hi, Elts, 0,
4240 return DAG.getBuildVector(SubVT, dl, Elts);
4244 ElementCount ExtractIdx = IdxVal - LoElts;
4246 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4249 EVT HiVT =
Hi.getValueType();
4251 "Only fixed-vector extracts are supported in this case");
4261 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4262 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4268 "Extracting scalable subvector from fixed-width unsupported");
4276 "subvector from a scalable predicate vector");
4282 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4284 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4285 auto &MF = DAG.getMachineFunction();
4289 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4293 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4296 SubVT, dl, Store, StackPtr,
4300SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4306 uint64_t IdxVal =
Index->getZExtValue();
4309 GetSplitVector(Vec,
Lo,
Hi);
4311 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4313 if (IdxVal < LoElts)
4314 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4317 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4322 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4334 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4340 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4342 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4343 auto &MF = DAG.getMachineFunction();
4346 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4350 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4354 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4356 return DAG.getExtLoad(
4367 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4375 SplitVecRes_Gather(
N,
Lo,
Hi);
4378 ReplaceValueWith(
SDValue(
N, 0), Res);
4383 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4387 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4389 SDValue EVL =
N->getVectorLength();
4391 Align Alignment =
N->getBaseAlign();
4397 GetSplitVector(
Data, DataLo, DataHi);
4399 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4404 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4407 GetSplitVector(Mask, MaskLo, MaskHi);
4409 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4412 EVT MemoryVT =
N->getMemoryVT();
4413 EVT LoMemVT, HiMemVT;
4414 bool HiIsEmpty =
false;
4415 std::tie(LoMemVT, HiMemVT) =
4416 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4420 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4423 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4428 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4429 N->getAddressingMode(),
N->isTruncatingStore(),
4430 N->isCompressingStore());
4436 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4437 N->isCompressingStore());
4439 MachinePointerInfo MPI;
4443 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4448 MMO = DAG.getMachineFunction().getMachineMemOperand(
4450 Alignment,
N->getAAInfo(),
N->getRanges());
4452 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4453 N->getAddressingMode(),
N->isTruncatingStore(),
4454 N->isCompressingStore());
4463 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4464 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4471 GetSplitVector(
Data, LoData, HiData);
4473 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4475 EVT LoMemVT, HiMemVT;
4476 bool HiIsEmpty =
false;
4477 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4483 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4484 else if (getTypeAction(
Mask.getValueType()) ==
4486 GetSplitVector(Mask, LoMask, HiMask);
4488 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4491 std::tie(LoEVL, HiEVL) =
4492 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4496 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4497 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4498 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4509 EVT PtrVT =
N->getBasePtr().getValueType();
4512 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4515 Align Alignment =
N->getBaseAlign();
4520 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4521 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4523 Alignment,
N->getAAInfo(),
N->getRanges());
4526 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4527 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4528 N->isCompressingStore());
4537 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4541 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4544 Align Alignment =
N->getBaseAlign();
4550 GetSplitVector(
Data, DataLo, DataHi);
4552 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4557 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4560 GetSplitVector(Mask, MaskLo, MaskHi);
4562 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4565 EVT MemoryVT =
N->getMemoryVT();
4566 EVT LoMemVT, HiMemVT;
4567 bool HiIsEmpty =
false;
4568 std::tie(LoMemVT, HiMemVT) =
4569 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4572 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4577 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4578 N->getAddressingMode(),
N->isTruncatingStore(),
4579 N->isCompressingStore());
4587 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4588 N->isCompressingStore());
4590 MachinePointerInfo MPI;
4594 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4599 MMO = DAG.getMachineFunction().getMachineMemOperand(
4601 Alignment,
N->getAAInfo(),
N->getRanges());
4603 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4604 N->getAddressingMode(),
N->isTruncatingStore(),
4605 N->isCompressingStore());
4618 EVT MemoryVT =
N->getMemoryVT();
4619 Align Alignment =
N->getBaseAlign();
4626 }
Ops = [&]() -> Operands {
4628 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4632 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4637 EVT LoMemVT, HiMemVT;
4638 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4643 GetSplitVector(
Ops.Data, DataLo, DataHi);
4645 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4650 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4652 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4656 if (getTypeAction(
Ops.Index.getValueType()) ==
4658 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4660 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4664 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4666 Alignment,
N->getAAInfo(),
N->getRanges());
4669 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4671 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4672 MSC->getIndexType(), MSC->isTruncatingStore());
4677 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4678 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4679 MMO, MSC->getIndexType(),
4680 MSC->isTruncatingStore());
4684 std::tie(EVLLo, EVLHi) =
4685 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4687 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4688 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4689 VPSC->getIndexType());
4694 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4695 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4696 VPSC->getIndexType());
4700 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4701 assert(OpNo == 1 &&
"Can only split the stored value");
4704 bool isTruncating =
N->isTruncatingStore();
4707 EVT MemoryVT =
N->getMemoryVT();
4708 Align Alignment =
N->getBaseAlign();
4710 AAMDNodes AAInfo =
N->getAAInfo();
4712 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4714 EVT LoMemVT, HiMemVT;
4715 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4719 return TLI.scalarizeVectorStore(
N, DAG);
4722 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4723 Alignment, MMOFlags, AAInfo);
4725 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4728 MachinePointerInfo MPI;
4729 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4732 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4733 HiMemVT, Alignment, MMOFlags, AAInfo);
4735 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4751 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4757 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4778 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4779 SDValue InVec =
N->getOperand(OpNo);
4781 EVT OutVT =
N->getValueType(0);
4789 EVT LoOutVT, HiOutVT;
4790 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4791 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4796 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4798 return SplitVecOp_UnaryOp(
N);
4807 return SplitVecOp_UnaryOp(
N);
4811 GetSplitVector(InVec, InLoVec, InHiVec);
4817 EVT HalfElementVT = IsFloat ?
4819 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4826 if (
N->isStrictFPOpcode()) {
4827 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4828 {N->getOperand(0), InLoVec});
4829 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4830 {N->getOperand(0), InHiVec});
4836 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4837 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4841 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4849 if (
N->isStrictFPOpcode()) {
4853 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4861 DAG.getTargetConstant(
4862 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4869 assert(
N->getValueType(0).isVector() &&
4870 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4871 "Operand types must be vectors");
4873 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4875 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4876 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4878 EVT VT =
N->getValueType(0);
4879 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4884 }
else if (isStrict) {
4885 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4886 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4887 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4888 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4891 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4893 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4894 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4895 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4896 std::tie(EVLLo, EVLHi) =
4897 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4898 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4899 N->getOperand(2), MaskLo, EVLLo);
4900 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4901 N->getOperand(2), MaskHi, EVLHi);
4909 EVT OpVT =
N->getOperand(0).getValueType();
4912 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4918 EVT ResVT =
N->getValueType(0);
4921 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4922 EVT InVT =
Lo.getValueType();
4927 if (
N->isStrictFPOpcode()) {
4928 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4929 {N->getOperand(0), Lo, N->getOperand(2)});
4930 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4931 {N->getOperand(0), Hi, N->getOperand(2)});
4935 Lo.getValue(1),
Hi.getValue(1));
4936 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4937 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4938 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4939 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4940 std::tie(EVLLo, EVLHi) =
4941 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4942 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4943 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4945 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4946 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
4957SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4960 EVT LHSLoVT, LHSHiVT;
4961 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4963 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4964 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4967 std::tie(LHSLo, LHSHi) =
4968 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4971 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4974 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4980 LLVMContext &Ctxt = *DAG.getContext();
4983 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4984 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4985 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4987 EVT ResVT =
N->getValueType(0);
4992 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4993 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4999 EVT ResVT =
N->getValueType(0);
5002 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5003 EVT InVT =
Lo.getValueType();
5009 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5010 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5017 EVT ResVT =
N->getValueType(0);
5021 GetSplitVector(VecOp,
Lo,
Hi);
5027 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5029 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5031 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5032 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5037 EVT ResVT =
N->getValueType(0);
5041 GetSplitVector(VecOp,
Lo,
Hi);
5043 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5044 auto [EVLLo, EVLHi] =
5046 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5052 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5054 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5055 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5058SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5069 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5070 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5071 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5072 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5073 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5074 OpsLo, MMO, IndexType);
5075 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5076 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5080SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5083 "Accumulator should already be a legal type, and shouldn't need "
5084 "further splitting");
5087 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5088 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5089 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5090 unsigned Opcode =
N->getOpcode();
5093 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5094 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5101void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5102 unsigned WidenResNo) {
5103 unsigned NumResults =
N->getNumValues();
5104 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5105 if (ResNo == WidenResNo)
5107 EVT ResVT =
N->getValueType(ResNo);
5113 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5114 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5119void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5120 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5123 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5128 auto unrollExpandedOp = [&]() {
5133 EVT VT =
N->getValueType(0);
5134 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5135 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5136 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5138 if (
N->getNumValues() > 1)
5139 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5145 switch (
N->getOpcode()) {
5148 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5156 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5160 Res = WidenVecRes_ADDRSPACECAST(
N);
5167 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5174 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5178 Res = WidenVecRes_ScalarOp(
N);
5183 case ISD::VP_SELECT:
5185 Res = WidenVecRes_Select(
N);
5189 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5191 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5198 case ISD::VP_LOAD_FF:
5201 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5205 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5213 case ISD::VP_GATHER:
5217 Res = WidenVecRes_VECTOR_REVERSE(
N);
5220 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5230 case ISD::OR:
case ISD::VP_OR:
5241 case ISD::VP_FMINNUM:
5244 case ISD::VP_FMAXNUM:
5246 case ISD::VP_FMINIMUM:
5248 case ISD::VP_FMAXIMUM:
5281 case ISD::VP_FCOPYSIGN:
5282 Res = WidenVecRes_Binary(
N);
5289 Res = WidenVecRes_MaskedBinary(
N);
5294 Res = WidenVecRes_CMP(
N);
5300 if (unrollExpandedOp())
5315 Res = WidenVecRes_BinaryCanTrap(
N);
5324 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5327#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5328 case ISD::STRICT_##DAGN:
5329#include "llvm/IR/ConstrainedOps.def"
5330 Res = WidenVecRes_StrictFP(
N);
5339 Res = WidenVecRes_OverflowOp(
N, ResNo);
5343 Res = WidenVecRes_FCOPYSIGN(
N);
5348 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5353 if (!unrollExpandedOp())
5354 Res = WidenVecRes_ExpOp(
N);
5360 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5365 case ISD::VP_FP_EXTEND:
5367 case ISD::VP_FP_ROUND:
5369 case ISD::VP_FP_TO_SINT:
5371 case ISD::VP_FP_TO_UINT:
5373 case ISD::VP_SIGN_EXTEND:
5375 case ISD::VP_SINT_TO_FP:
5376 case ISD::VP_TRUNCATE:
5379 case ISD::VP_UINT_TO_FP:
5381 case ISD::VP_ZERO_EXTEND:
5383 Res = WidenVecRes_Convert(
N);
5388 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5394 case ISD::VP_LLRINT:
5397 Res = WidenVecRes_XROUND(
N);
5423 if (unrollExpandedOp())
5434 case ISD::VP_BITREVERSE:
5440 case ISD::VP_CTLZ_ZERO_POISON:
5446 case ISD::VP_CTTZ_ZERO_POISON:
5451 case ISD::VP_FFLOOR:
5453 case ISD::VP_FNEARBYINT:
5454 case ISD::VP_FROUND:
5455 case ISD::VP_FROUNDEVEN:
5456 case ISD::VP_FROUNDTOZERO:
5461 Res = WidenVecRes_Unary(
N);
5468 Res = WidenVecRes_Ternary(
N);
5474 if (!unrollExpandedOp())
5475 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5482 SetWidenedVector(
SDValue(
N, ResNo), Res);
5488 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5489 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5490 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5491 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5492 if (
N->getNumOperands() == 3)
5493 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5495 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5496 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5500 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5501 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5507 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5508 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5509 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5510 if (
N->getNumOperands() == 2)
5511 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5514 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5515 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5519 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5520 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5525 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5526 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5527 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5530 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5531 Mask = ModifyToType(Mask, WideMaskVT,
true);
5532 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5537 LLVMContext &Ctxt = *DAG.getContext();
5542 EVT OpVT =
LHS.getValueType();
5544 LHS = GetWidenedVector(
LHS);
5545 RHS = GetWidenedVector(
RHS);
5546 OpVT =
LHS.getValueType();
5549 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5552 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5558SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5561 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5562 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5563 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5565 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5574 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5577 if (ConcatEnd == 1) {
5578 VT = ConcatOps[0].getValueType();
5580 return ConcatOps[0];
5583 SDLoc dl(ConcatOps[0]);
5590 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5591 int Idx = ConcatEnd - 1;
5592 VT = ConcatOps[Idx--].getValueType();
5593 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5606 unsigned NumToInsert = ConcatEnd - Idx - 1;
5607 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5609 ConcatOps[Idx+1] = VecOp;
5610 ConcatEnd = Idx + 2;
5616 unsigned RealVals = ConcatEnd - Idx - 1;
5617 unsigned SubConcatEnd = 0;
5618 unsigned SubConcatIdx = Idx + 1;
5619 while (SubConcatEnd < RealVals)
5620 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5621 while (SubConcatEnd < OpsToConcat)
5622 SubConcatOps[SubConcatEnd++] = undefVec;
5624 NextVT, SubConcatOps);
5625 ConcatEnd = SubConcatIdx + 1;
5630 if (ConcatEnd == 1) {
5631 VT = ConcatOps[0].getValueType();
5633 return ConcatOps[0];
5638 if (
NumOps != ConcatEnd ) {
5640 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5641 ConcatOps[j] = UndefVal;
5649 unsigned Opcode =
N->getOpcode();
5651 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5655 const SDNodeFlags
Flags =
N->getFlags();
5656 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5657 NumElts = NumElts / 2;
5661 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5663 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5664 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5665 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5673 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5676 TLI.isTypeLegal(WideMaskVT)) {
5677 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5678 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5679 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5681 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5682 N->getValueType(0).getVectorElementCount());
5683 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5697 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5698 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5699 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5702 unsigned ConcatEnd = 0;
5710 while (CurNumElts != 0) {
5711 while (CurNumElts >= NumElts) {
5712 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5713 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5714 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5716 CurNumElts -= NumElts;
5719 NumElts = NumElts / 2;
5721 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5724 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5725 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5726 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5727 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5738 switch (
N->getOpcode()) {
5741 return WidenVecRes_STRICT_FSETCC(
N);
5748 return WidenVecRes_Convert_StrictFP(
N);
5755 unsigned Opcode =
N->getOpcode();
5757 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5761 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5762 NumElts = NumElts / 2;
5773 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5777 unsigned ConcatEnd = 0;
5784 for (
unsigned i = 1; i < NumOpers; ++i) {
5790 Oper = GetWidenedVector(Oper);
5796 DAG.getPOISON(WideOpVT), Oper,
5797 DAG.getVectorIdxConstant(0, dl));
5809 while (CurNumElts != 0) {
5810 while (CurNumElts >= NumElts) {
5813 for (
unsigned i = 0; i < NumOpers; ++i) {
5816 EVT OpVT =
Op.getValueType();
5821 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5827 EVT OperVT[] = {VT, MVT::Other};
5829 ConcatOps[ConcatEnd++] = Oper;
5832 CurNumElts -= NumElts;
5835 NumElts = NumElts / 2;
5837 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5840 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5843 for (
unsigned i = 0; i < NumOpers; ++i) {
5846 EVT OpVT =
Op.getValueType();
5854 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5856 ConcatOps[ConcatEnd++] = Oper;
5865 if (Chains.
size() == 1)
5866 NewChain = Chains[0];
5869 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5874SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5876 EVT ResVT =
N->getValueType(0);
5877 EVT OvVT =
N->getValueType(1);
5878 EVT WideResVT, WideOvVT;
5883 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5888 WideLHS = GetWidenedVector(
N->getOperand(0));
5889 WideRHS = GetWidenedVector(
N->getOperand(1));
5891 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5900 N->getOperand(0), Zero);
5902 N->getOperand(1), Zero);
5905 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5906 SDNode *WideNode = DAG.getNode(
5907 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5910 unsigned OtherNo = 1 - ResNo;
5911 EVT OtherVT =
N->getValueType(OtherNo);
5918 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5921 return SDValue(WideNode, ResNo);
5925 LLVMContext &Ctx = *DAG.getContext();
5929 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5934 unsigned Opcode =
N->getOpcode();
5935 const SDNodeFlags
Flags =
N->getFlags();
5941 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5943 InOp = ZExtPromotedInteger(InOp);
5954 InOp = GetWidenedVector(
N->getOperand(0));
5957 if (InVTEC == WidenEC) {
5958 if (
N->getNumOperands() == 1)
5959 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5960 if (
N->getNumOperands() == 3) {
5961 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5964 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5966 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5992 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5996 if (TLI.isTypeLegal(InWidenVT)) {
6004 unsigned NumConcat =
6009 if (
N->getNumOperands() == 1)
6010 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
6011 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
6015 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6017 if (
N->getNumOperands() == 1)
6018 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
6019 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
6028 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6029 for (
unsigned i=0; i < MinElts; ++i) {
6030 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6031 if (
N->getNumOperands() == 1)
6034 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
6037 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6042 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6046 EVT SrcVT = Src.getValueType();
6050 Src = GetWidenedVector(Src);
6051 SrcVT = Src.getValueType();
6058 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6063 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6067 EVT SrcVT = Src.getValueType();
6071 Src = GetWidenedVector(Src);
6072 SrcVT = Src.getValueType();
6079 if (
N->getNumOperands() == 1)
6080 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6082 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6083 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6087 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6090SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6095 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6101 unsigned Opcode =
N->getOpcode();
6107 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6112 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6113 for (
unsigned i=0; i < MinElts; ++i) {
6114 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6115 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6119 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6121 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6124SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6125 unsigned Opcode =
N->getOpcode();
6129 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6138 InOp = GetWidenedVector(InOp);
6145 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6152 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6153 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6170 while (
Ops.size() != WidenNumElts)
6171 Ops.push_back(DAG.getPOISON(WidenSVT));
6173 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6179 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6180 return WidenVecRes_BinaryCanTrap(
N);
6183 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6190SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6192 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6195 SDValue Arg = GetWidenedVector(FpValue);
6196 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6201 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6202 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6204 EVT ExpVT =
RHS.getValueType();
6209 ExpOp = ModifyToType(
RHS, WideExpVT);
6212 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6217 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6218 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6219 if (
N->getNumOperands() == 1)
6220 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6222 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6223 N->getOperand(1),
N->getFlags());
6225 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6226 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6230 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6231 {InOp,
Mask,
N->getOperand(2)});
6235 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6240 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6241 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6242 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6245SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6247 EVT VT0 =
N->getValueType(0);
6248 EVT VT1 =
N->getValueType(1);
6252 "expected both results to be vectors of matching element count");
6254 LLVMContext &Ctx = *DAG.getContext();
6255 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6257 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6264 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6267 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6268 return SDValue(WidenNode, ResNo);
6271SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6272 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6273 return GetWidenedVector(WidenVec);
6277 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6278 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6281 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6282 AddrSpaceCastN->getSrcAddressSpace(),
6283 AddrSpaceCastN->getDestAddressSpace());
6289 EVT VT =
N->getValueType(0);
6290 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6293 switch (getTypeAction(InVT)) {
6307 SDValue NInOp = GetPromotedInteger(InOp);
6309 if (WidenVT.
bitsEq(NInVT)) {
6312 if (DAG.getDataLayout().isBigEndian()) {
6315 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6333 InOp = GetWidenedVector(InOp);
6335 if (WidenVT.
bitsEq(InVT))
6345 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6350 unsigned NewNumParts = WidenSize / InSize;
6363 EVT OrigInVT =
N->getOperand(0).getValueType();
6368 if (TLI.isTypeLegal(NewInVT)) {
6376 if (WidenSize % InSize == 0) {
6383 DAG.ExtractVectorElements(InOp,
Ops);
6384 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6396 return CreateStackStoreLoad(InOp, WidenVT);
6399SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6401 N->getOpcode(), SDLoc(
N),
6402 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6403 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6409 EVT VT =
N->getValueType(0);
6413 EVT EltVT =
N->getOperand(0).getValueType();
6416 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6420 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6421 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6423 return DAG.getBuildVector(WidenVT, dl, NewOps);
6427 EVT InVT =
N->getOperand(0).getValueType();
6428 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6430 unsigned NumOperands =
N->getNumOperands();
6432 bool InputWidened =
false;
6436 if (WidenNumElts % NumInElts == 0) {
6438 unsigned NumConcat = WidenNumElts / NumInElts;
6439 SDValue UndefVal = DAG.getPOISON(InVT);
6441 for (
unsigned i=0; i < NumOperands; ++i)
6442 Ops[i] =
N->getOperand(i);
6443 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6448 InputWidened =
true;
6449 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6452 for (i=1; i < NumOperands; ++i)
6453 if (!
N->getOperand(i).isUndef())
6456 if (i == NumOperands)
6459 return GetWidenedVector(
N->getOperand(0));
6461 if (NumOperands == 2) {
6463 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6468 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6469 for (
unsigned i = 0; i < NumInElts; ++i) {
6471 MaskOps[i + NumInElts] = i + WidenNumElts;
6473 return DAG.getVectorShuffle(WidenVT, dl,
6474 GetWidenedVector(
N->getOperand(0)),
6475 GetWidenedVector(
N->getOperand(1)),
6482 "Cannot use build vectors to widen CONCAT_VECTOR result");
6490 for (
unsigned i=0; i < NumOperands; ++i) {
6493 InOp = GetWidenedVector(InOp);
6494 for (
unsigned j = 0;
j < NumInElts; ++
j)
6495 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6497 SDValue UndefVal = DAG.getPOISON(EltVT);
6498 for (; Idx < WidenNumElts; ++Idx)
6499 Ops[Idx] = UndefVal;
6500 return DAG.getBuildVector(WidenVT, dl,
Ops);
6503SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6504 EVT VT =
N->getValueType(0);
6505 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6506 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6513SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6514 EVT VT =
N->getValueType(0);
6516 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6521 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6523 InOp = GetWidenedVector(InOp);
6529 if (IdxVal == 0 && InVT == WidenVT)
6536 assert(IdxVal % VTNumElts == 0 &&
6537 "Expected Idx to be a multiple of subvector minimum vector length");
6538 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6551 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6552 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6553 "down type's element count");
6560 for (;
I < VTNumElts / GCD; ++
I)
6562 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6563 for (;
I < WidenNumElts / GCD; ++
I)
6571 Align Alignment = DAG.getReducedAlign(InVT,
false);
6573 MachineFunction &MF = DAG.getMachineFunction();
6585 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6592 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6593 return DAG.getMaskedLoad(
6594 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6602 for (i = 0; i < VTNumElts; ++i)
6603 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6605 SDValue UndefVal = DAG.getPOISON(EltVT);
6606 for (; i < WidenNumElts; ++i)
6608 return DAG.getBuildVector(WidenVT, dl,
Ops);
6614 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6619SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6620 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6623 N->getOperand(1),
N->getOperand(2));
6632 "Load width must be less than or equal to first value type width");
6641 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6658 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6669 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6670 EVT LdVT =
LD->getMemoryVT();
6679 TypeSize WidthDiff = WidenWidth - LdWidth;
6682 std::optional<EVT> FirstVT =
6683 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6690 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6693 Chain, BasePtr,
LD->getMemOperand());
6697 FirstVTWidth, dl, DAG);
6715 if (!
LD->getMemoryVT().isByteSized()) {
6717 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6719 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6728 EVT VT =
LD->getValueType(0);
6729 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6730 EVT WideMaskVT = getSetCCResultType(WideVT);
6733 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6734 TLI.isTypeLegal(WideMaskVT)) {
6737 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6741 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6742 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6754 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6756 Result = GenWidenVectorLoads(LdChain, LD);
6763 if (LdChain.
size() == 1)
6764 NewChain = LdChain[0];
6770 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6781 SDValue NewLoad = DAG.getMaskedLoad(
6782 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6783 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6784 LD->getAddressingMode(),
LD->getExtensionType());
6794 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6796 SDValue EVL =
N->getVectorLength();
6803 "Unable to widen binary VP op");
6804 Mask = GetWidenedVector(Mask);
6805 assert(
Mask.getValueType().getVectorElementCount() ==
6806 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6807 .getVectorElementCount() &&
6808 "Unable to widen vector load");
6811 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6812 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6813 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6821 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6823 SDValue EVL =
N->getVectorLength();
6829 "Unable to widen binary VP op");
6830 Mask = GetWidenedVector(Mask);
6831 assert(
Mask.getValueType().getVectorElementCount() ==
6832 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6833 .getVectorElementCount() &&
6834 "Unable to widen vector load");
6836 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6837 Mask, EVL,
N->getMemOperand());
6850 "Unable to widen VP strided load");
6851 Mask = GetWidenedVector(Mask);
6853 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6854 assert(
Mask.getValueType().getVectorElementCount() ==
6856 "Data and mask vectors should have the same number of elements");
6858 SDValue Res = DAG.getStridedLoadVP(
6859 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6860 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6861 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6862 N->isExpandingLoad());
6870SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6875 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6877 Mask.getValueType().getVectorElementType(),
6880 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6881 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6882 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6884 WideMask, WidePassthru);
6888 EVT VT =
N->getValueType(0);
6889 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6891 EVT MaskVT =
Mask.getValueType();
6892 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6901 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6902 TLI.isTypeLegal(WideMaskVT) &&
6908 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6909 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6913 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6914 N->getMemoryVT(),
N->getMemOperand());
6918 if (!
N->getPassThru()->isUndef()) {
6922 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6923 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6924 DAG.getPOISON(WidenVT), EVL);
6935 Mask = ModifyToType(Mask, WideMaskVT,
true);
6937 SDValue Res = DAG.getMaskedLoad(
6938 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6939 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6940 ExtType,
N->isExpandingLoad());
6949 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6951 EVT MaskVT =
Mask.getValueType();
6952 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6961 Mask = ModifyToType(Mask, WideMaskVT,
true);
6966 Index.getValueType().getScalarType(),
6968 Index = ModifyToType(Index, WideIndexVT);
6974 N->getMemoryVT().getScalarType(), NumElts);
6975 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6976 WideMemVT, dl,
Ops,
N->getMemOperand(),
6977 N->getIndexType(),
N->getExtensionType());
6986 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6994 N->getMemoryVT().getScalarType(), WideEC);
6995 Mask = GetWidenedMask(Mask, WideEC);
6998 Mask,
N->getVectorLength()};
6999 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7000 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7009 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7010 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7038 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7039 return N->getOperand(OpNo).getValueType();
7047 N =
N.getOperand(0);
7049 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7050 if (!
N->getOperand(i)->isUndef())
7052 N =
N.getOperand(0);
7056 N =
N.getOperand(0);
7058 N =
N.getOperand(0);
7085 { MaskVT, MVT::Other },
Ops);
7086 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7094 LLVMContext &Ctx = *DAG.getContext();
7097 if (MaskScalarBits < ToMaskScalBits) {
7101 }
else if (MaskScalarBits > ToMaskScalBits) {
7107 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7109 "Mask should have the right element size by now.");
7112 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7114 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7117 EVT SubVT =
Mask->getValueType(0);
7123 assert((
Mask->getValueType(0) == ToMaskVT) &&
7124 "A mask of ToMaskVT should have been produced by now.");
7134 LLVMContext &Ctx = *DAG.getContext();
7145 EVT CondVT =
Cond->getValueType(0);
7149 EVT VSelVT =
N->getValueType(0);
7161 EVT FinalVT = VSelVT;
7172 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7173 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7180 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7188 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7191 EVT ToMaskVT = VSelVT;
7198 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7214 if (ScalarBits0 != ScalarBits1) {
7215 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7216 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7228 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7229 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7230 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7233 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7241 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7246 unsigned Opcode =
N->getOpcode();
7248 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7249 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7250 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7252 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7258 Cond1 = GetWidenedVector(Cond1);
7266 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7267 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7272 Cond1 = ModifyToType(Cond1, CondWidenVT);
7275 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7276 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7278 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7279 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7281 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7285 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7286 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7289 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7293 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7294 return DAG.getUNDEF(WidenVT);
7298 EVT VT =
N->getValueType(0);
7301 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7305 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7306 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7309 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7310 for (
unsigned i = 0; i != NumElts; ++i) {
7311 int Idx =
N->getMaskElt(i);
7312 if (Idx < (
int)NumElts)
7315 NewMask[i] = Idx - NumElts + WidenNumElts;
7317 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7321 EVT VT =
N->getValueType(0);
7325 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7326 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7332 unsigned IdxVal = WidenNumElts - VTNumElts;
7345 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7348 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7349 "down type's element count");
7352 for (; i < VTNumElts / GCD; ++i)
7354 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7355 for (; i < WidenNumElts / GCD; ++i)
7363 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7364 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7366 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7370SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7371 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7376 assert(
N->getValueType(0).isVector() &&
7377 N->getOperand(0).getValueType().isVector() &&
7378 "Operands must be vectors");
7379 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7392 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7393 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7400 InOp1 = GetWidenedVector(InOp1);
7401 InOp2 = GetWidenedVector(InOp2);
7404 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7415 "Input not widened to expected type!");
7417 if (
N->getOpcode() == ISD::VP_SETCC) {
7420 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7421 N->getOperand(2), Mask,
N->getOperand(4));
7423 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7428 assert(
N->getValueType(0).isVector() &&
7429 N->getOperand(1).getValueType().isVector() &&
7430 "Operands must be vectors");
7431 EVT VT =
N->getValueType(0);
7432 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7442 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7447 for (
unsigned i = 0; i != NumElts; ++i) {
7448 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7449 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7451 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7452 {Chain, LHSElem, RHSElem, CC});
7453 Chains[i] = Scalars[i].getValue(1);
7454 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7455 DAG.getBoolConstant(
true, dl, EltVT, VT),
7456 DAG.getBoolConstant(
false, dl, EltVT, VT));
7460 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7462 return DAG.getBuildVector(WidenVT, dl, Scalars);
7468bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7469 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7473 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7476 switch (
N->getOpcode()) {
7479 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7487 Res = WidenVecOp_FAKE_USE(
N);
7493 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7497 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7498 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7499 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7504 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7506 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7507 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7509 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7510 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7520 Res = WidenVecOp_UnrollVectorOp(
N);
7527 Res = WidenVecOp_EXTEND(
N);
7532 Res = WidenVecOp_CMP(
N);
7549 Res = WidenVecOp_Convert(
N);
7554 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7572 Res = WidenVecOp_VECREDUCE(
N);
7576 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7578 case ISD::VP_REDUCE_FADD:
7579 case ISD::VP_REDUCE_SEQ_FADD:
7580 case ISD::VP_REDUCE_FMUL:
7581 case ISD::VP_REDUCE_SEQ_FMUL:
7582 case ISD::VP_REDUCE_ADD:
7583 case ISD::VP_REDUCE_MUL:
7584 case ISD::VP_REDUCE_AND:
7585 case ISD::VP_REDUCE_OR:
7586 case ISD::VP_REDUCE_XOR:
7587 case ISD::VP_REDUCE_SMAX:
7588 case ISD::VP_REDUCE_SMIN:
7589 case ISD::VP_REDUCE_UMAX:
7590 case ISD::VP_REDUCE_UMIN:
7591 case ISD::VP_REDUCE_FMAX:
7592 case ISD::VP_REDUCE_FMIN:
7593 case ISD::VP_REDUCE_FMAXIMUM:
7594 case ISD::VP_REDUCE_FMINIMUM:
7595 Res = WidenVecOp_VP_REDUCE(
N);
7597 case ISD::VP_CTTZ_ELTS:
7598 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7599 Res = WidenVecOp_VP_CttzElements(
N);
7602 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7607 if (!Res.
getNode())
return false;
7615 if (
N->isStrictFPOpcode())
7617 "Invalid operand expansion");
7620 "Invalid operand expansion");
7622 ReplaceValueWith(
SDValue(
N, 0), Res);
7628 EVT VT =
N->getValueType(0);
7633 "Unexpected type action");
7634 InOp = GetWidenedVector(InOp);
7637 "Input wasn't widened!");
7645 EVT FixedEltVT = FixedVT.getVectorElementType();
7646 if (TLI.isTypeLegal(FixedVT) &&
7648 FixedEltVT == InEltVT) {
7650 "Not enough elements in the fixed type for the operand!");
7652 "We can't have the same type as we started with!");
7654 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7656 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7665 return WidenVecOp_Convert(
N);
7670 switch (
N->getOpcode()) {
7685 EVT OpVT =
N->getOperand(0).getValueType();
7686 EVT ResVT =
N->getValueType(0);
7693 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7694 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7700 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7701 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7703 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7710 return DAG.UnrollVectorOp(
N);
7715 EVT ResultVT =
N->getValueType(0);
7717 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7720 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7726 {WideArg,
Test},
N->getFlags());
7732 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7734 EVT OpVT =
N->getOperand(0).getValueType();
7737 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7742 EVT VT =
N->getValueType(0);
7748 "Unexpected type action");
7749 InOp = GetWidenedVector(InOp);
7751 unsigned Opcode =
N->getOpcode();
7757 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7759 if (
N->isStrictFPOpcode()) {
7761 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7764 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7765 {
N->getOperand(0), InOp });
7771 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7773 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7775 return DAG.getExtractSubvector(dl, VT, Res, 0);
7783 if (
N->isStrictFPOpcode()) {
7786 for (
unsigned i=0; i < NumElts; ++i) {
7787 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7788 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7792 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7794 for (
unsigned i = 0; i < NumElts; ++i) {
7795 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7797 Ops[i] = DAG.
getNode(Opcode, dl, EltVT, Elt,
N->getOperand(1));
7799 Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
7803 return DAG.getBuildVector(VT, dl,
Ops);
7807 EVT DstVT =
N->getValueType(0);
7808 SDValue Src = GetWidenedVector(
N->getOperand(0));
7809 EVT SrcVT = Src.getValueType();
7816 if (TLI.isTypeLegal(WideDstVT)) {
7818 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7821 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7825 return DAG.UnrollVectorOp(
N);
7829 EVT VT =
N->getValueType(0);
7830 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7838 if (!VT.
isVector() && VT != MVT::x86mmx &&
7842 if (TLI.isTypeLegal(NewVT)) {
7844 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7856 ElementCount NewNumElts =
7858 .divideCoefficientBy(EltSize);
7860 if (TLI.isTypeLegal(NewVT)) {
7862 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7867 return CreateStackStoreLoad(InOp, VT);
7875 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7876 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7881 EVT VT =
N->getValueType(0);
7883 EVT InVT =
N->getOperand(0).getValueType();
7888 unsigned NumOperands =
N->getNumOperands();
7889 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7891 for (i = 1; i < NumOperands; ++i)
7892 if (!
N->getOperand(i).isUndef())
7895 if (i == NumOperands)
7896 return GetWidenedVector(
N->getOperand(0));
7906 for (
unsigned i=0; i < NumOperands; ++i) {
7910 "Unexpected type action");
7911 InOp = GetWidenedVector(InOp);
7912 for (
unsigned j = 0;
j < NumInElts; ++
j)
7913 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7915 return DAG.getBuildVector(VT, dl,
Ops);
7918SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7919 EVT VT =
N->getValueType(0);
7924 SubVec = GetWidenedVector(SubVec);
7929 bool IndicesValid =
false;
7932 IndicesValid =
true;
7936 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7937 Attribute::VScaleRange);
7942 IndicesValid =
true;
7948 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7954 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7961 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7968 Align Alignment = DAG.getReducedAlign(VT,
false);
7970 MachineFunction &MF = DAG.getMachineFunction();
7983 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7991 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7992 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7997 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8002 unsigned Idx =
N->getConstantOperandVal(2);
8008 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8014SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8015 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8017 N->getValueType(0), InOp,
N->getOperand(1));
8020SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8021 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8023 N->getValueType(0), InOp,
N->getOperand(1));
8026SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8028 EVT ResVT =
N->getValueType(0);
8031 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8037 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8045 "Widened input size must be a multiple of result element size");
8048 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8050 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8051 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8059 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8060 return TLI.scalarizeVectorStore(ST, DAG);
8062 if (
ST->isTruncatingStore())
8063 return TLI.scalarizeVectorStore(ST, DAG);
8073 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8074 EVT WideMaskVT = getSetCCResultType(WideVT);
8076 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8077 TLI.isTypeLegal(WideMaskVT)) {
8080 StVal = GetWidenedVector(StVal);
8082 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8084 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8085 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8086 ST->getAddressingMode());
8090 if (GenWidenVectorStores(StChain, ST)) {
8091 if (StChain.
size() == 1)
8100 SDValue WideStVal = GetWidenedVector(StVal);
8104 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8105 ST->getOffset(), Mask,
ST->getMemoryVT(),
8106 ST->getMemOperand(),
ST->getAddressingMode(),
8107 ST->isTruncatingStore());
8114 EVT StVT =
ST->getMemoryVT();
8117 SDValue StVal = GetWidenedVector(
ST->getVal());
8122 TypeSize WidthDiff = WidenWidth - StWidth;
8128 std::optional<EVT> FirstVT =
8129 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8134 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8140 ST->getBasePtr(),
ST->getMemOperand());
8143SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8144 assert((OpNo == 1 || OpNo == 3) &&
8145 "Can widen only data or mask operand of vp_store");
8153 StVal = GetWidenedVector(StVal);
8159 "Unable to widen VP store");
8160 Mask = GetWidenedVector(Mask);
8162 Mask = GetWidenedVector(Mask);
8168 "Unable to widen VP store");
8169 StVal = GetWidenedVector(StVal);
8172 assert(
Mask.getValueType().getVectorElementCount() ==
8174 "Mask and data vectors should have the same number of elements");
8175 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8176 ST->getOffset(), Mask,
ST->getVectorLength(),
8177 ST->getMemoryVT(),
ST->getMemOperand(),
8178 ST->getAddressingMode(),
ST->isTruncatingStore(),
8179 ST->isCompressingStore());
8184 assert((OpNo == 1 || OpNo == 4) &&
8185 "Can widen only data or mask operand of vp_strided_store");
8194 "Unable to widen VP strided store");
8198 "Unable to widen VP strided store");
8200 StVal = GetWidenedVector(StVal);
8201 Mask = GetWidenedVector(Mask);
8204 Mask.getValueType().getVectorElementCount() &&
8205 "Data and mask vectors should have the same number of elements");
8207 return DAG.getStridedStoreVP(
8214SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8215 assert((OpNo == 1 || OpNo == 4) &&
8216 "Can widen only data or mask operand of mstore");
8219 EVT MaskVT =
Mask.getValueType();
8224 EVT WideVT, WideMaskVT;
8227 StVal = GetWidenedVector(StVal);
8234 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8241 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8243 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8244 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8253 Mask = ModifyToType(Mask, WideMaskVT,
true);
8256 Mask = ModifyToType(Mask, WideMaskVT,
true);
8258 StVal = ModifyToType(StVal, WideVT);
8261 assert(
Mask.getValueType().getVectorElementCount() ==
8263 "Mask and data vectors should have the same number of elements");
8270SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8271 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8273 SDValue DataOp = MG->getPassThru();
8275 SDValue Scale = MG->getScale();
8283 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8284 MG->getMemOperand(), MG->getIndexType(),
8285 MG->getExtensionType());
8291SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8300 DataOp = GetWidenedVector(DataOp);
8304 EVT IndexVT =
Index.getValueType();
8307 Index = ModifyToType(Index, WideIndexVT);
8310 EVT MaskVT =
Mask.getValueType();
8313 Mask = ModifyToType(Mask, WideMaskVT,
true);
8318 }
else if (OpNo == 4) {
8320 Index = GetWidenedVector(Index);
8326 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8331SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8340 DataOp = GetWidenedVector(DataOp);
8341 Index = GetWidenedVector(Index);
8343 Mask = GetWidenedMask(Mask, WideEC);
8346 }
else if (OpNo == 3) {
8348 Index = GetWidenedVector(Index);
8355 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8360 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8361 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8363 EVT VT =
N->getValueType(0);
8378 SVT, InOp0, InOp1,
N->getOperand(2));
8384 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8386 EVT OpVT =
N->getOperand(0).getValueType();
8389 return DAG.getNode(ExtendCode, dl, VT, CC);
8399 EVT VT =
N->getValueType(0);
8401 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8408 for (
unsigned i = 0; i != NumElts; ++i) {
8409 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8410 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8412 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8413 {Chain, LHSElem, RHSElem, CC});
8414 Chains[i] = Scalars[i].getValue(1);
8415 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8416 DAG.getBoolConstant(
true, dl, EltVT, VT),
8417 DAG.getBoolConstant(
false, dl, EltVT, VT));
8421 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8423 return DAG.getBuildVector(VT, dl, Scalars);
8447 SDValue Op = GetWidenedVector(
N->getOperand(0));
8448 EVT VT =
N->getValueType(0);
8449 EVT OrigVT =
N->getOperand(0).getValueType();
8450 EVT WideVT =
Op.getValueType();
8452 SDNodeFlags
Flags =
N->getFlags();
8454 unsigned Opc =
N->getOpcode();
8456 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8457 assert(NeutralElem &&
"Neutral element must exist");
8467 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8474 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8475 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8481 unsigned GCD = std::gcd(OrigElts, WideElts);
8484 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8485 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8486 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8487 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8490 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8491 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8493 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8502 EVT VT =
N->getValueType(0);
8504 EVT WideVT =
Op.getValueType();
8506 SDNodeFlags
Flags =
N->getFlags();
8508 unsigned Opc =
N->getOpcode();
8510 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8520 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8523 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8524 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8530 unsigned GCD = std::gcd(OrigElts, WideElts);
8533 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8534 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8535 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8536 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8539 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8540 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8542 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8546 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8549 SDValue Op = GetWidenedVector(
N->getOperand(1));
8551 Op.getValueType().getVectorElementCount());
8553 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8554 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8562 EVT VT =
N->getValueType(0);
8566 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8567 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8572 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8578 EVT SrcVT =
Source.getValueType();
8582 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8583 {Source, Mask, N->getOperand(2)},
N->getFlags());
8586SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8589 EVT OrigMaskVT =
Mask.getValueType();
8590 SDValue WideMask = GetWidenedVector(Mask);
8596 if (OrigElts != WideElts) {
8597 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8599 Mask, DAG.getVectorIdxConstant(0,
DL));
8620 unsigned WidenEx = 0) {
8625 unsigned AlignInBits =
Align*8;
8627 EVT RetVT = WidenEltVT;
8632 if (Width == WidenEltWidth)
8643 (WidenWidth % MemVTWidth) == 0 &&
8645 (MemVTWidth <= Width ||
8646 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8647 if (MemVTWidth == WidenWidth)
8666 (WidenWidth % MemVTWidth) == 0 &&
8668 (MemVTWidth <= Width ||
8669 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8678 return std::nullopt;
8689 unsigned Start,
unsigned End) {
8690 SDLoc dl(LdOps[Start]);
8691 EVT LdTy = LdOps[Start].getValueType();
8699 for (
unsigned i = Start + 1; i != End; ++i) {
8700 EVT NewLdTy = LdOps[i].getValueType();
8701 if (NewLdTy != LdTy) {
8720 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8721 EVT LdVT =
LD->getMemoryVT();
8731 AAMDNodes AAInfo =
LD->getAAInfo();
8735 TypeSize WidthDiff = WidenWidth - LdWidth;
8742 std::optional<EVT> FirstVT =
8743 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8750 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8755 std::optional<EVT> NewVT = FirstVT;
8756 TypeSize RemainingWidth = LdWidth;
8757 TypeSize NewVTWidth = FirstVTWidth;
8759 RemainingWidth -= NewVTWidth;
8766 NewVTWidth = NewVT->getSizeInBits();
8772 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8773 LD->getBaseAlign(), MMOFlags, AAInfo);
8785 uint64_t ScaledOffset = 0;
8786 MachinePointerInfo MPI =
LD->getPointerInfo();
8792 for (EVT MemVT : MemVTs) {
8793 Align NewAlign = ScaledOffset == 0
8794 ?
LD->getBaseAlign()
8797 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8805 unsigned End = LdOps.
size();
8816 EVT LdTy = LdOps[i].getValueType();
8819 for (--i; i >= 0; --i) {
8820 LdTy = LdOps[i].getValueType();
8827 ConcatOps[--Idx] = LdOps[i];
8828 for (--i; i >= 0; --i) {
8829 EVT NewLdTy = LdOps[i].getValueType();
8830 if (NewLdTy != LdTy) {
8840 for (;
j != End-Idx; ++
j)
8841 WidenOps[j] = ConcatOps[Idx+j];
8843 WidenOps[j] = DAG.getPOISON(LdTy);
8850 ConcatOps[--Idx] = LdOps[i];
8855 ArrayRef(&ConcatOps[Idx], End - Idx));
8861 SDValue UndefVal = DAG.getPOISON(LdTy);
8864 for (; i != End-Idx; ++i)
8865 WidenOps[i] = ConcatOps[Idx+i];
8867 WidenOps[i] = UndefVal;
8878 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8879 EVT LdVT =
LD->getMemoryVT();
8888 AAMDNodes AAInfo =
LD->getAAInfo();
8902 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8903 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8909 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8910 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8911 LD->getBaseAlign(), MMOFlags, AAInfo);
8916 SDValue UndefVal = DAG.getPOISON(EltVT);
8917 for (; i != WidenNumElts; ++i)
8920 return DAG.getBuildVector(WidenVT, dl,
Ops);
8931 AAMDNodes AAInfo =
ST->getAAInfo();
8932 SDValue ValOp = GetWidenedVector(
ST->getValue());
8935 EVT StVT =
ST->getMemoryVT();
8943 "Mismatch between store and value types");
8947 MachinePointerInfo MPI =
ST->getPointerInfo();
8948 uint64_t ScaledOffset = 0;
8957 std::optional<EVT> NewVT =
8962 TypeSize NewVTWidth = NewVT->getSizeInBits();
8965 StWidth -= NewVTWidth;
8966 MemVTs.
back().second++;
8970 for (
const auto &Pair : MemVTs) {
8971 EVT NewVT = Pair.first;
8972 unsigned Count = Pair.second;
8978 Align NewAlign = ScaledOffset == 0
8979 ?
ST->getBaseAlign()
8981 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8982 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8998 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8999 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9000 ST->getBaseAlign(), MMOFlags, AAInfo);
9017 bool FillWithZeroes) {
9022 "input and widen element type must match");
9024 "cannot modify scalable vectors in this way");
9037 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9039 for (
unsigned i = 1; i != NumConcat; ++i)
9046 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9049 "Scalable vectors should have been handled already.");
9057 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9059 for (Idx = 0; Idx < MinNumElts; ++Idx)
9060 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9062 SDValue UndefVal = DAG.getPOISON(EltVT);
9063 for (; Idx < WidenNumElts; ++Idx)
9064 Ops[Idx] = UndefVal;
9066 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9067 if (!FillWithZeroes)
9071 "We expect to never want to FillWithZeroes for non-integral types.");
9074 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9075 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9077 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9078 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)
static Value * getOpcode(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT, TypeSize FirstVTWidth, const SDLoc &dl, SelectionDAG &DAG)
Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the widened value so it can b...
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V, bool LookThroughCmp=false)
Returns the "element type" of the given value/instruction V.
This file implements the SmallBitVector class.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtractVectorElt(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Extract element at Idx from Vec.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr 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.