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);
3809 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3816 case ISD::VP_SCATTER:
3820 case ISD::VP_GATHER:
3824 Res = SplitVecOp_VSELECT(
N, OpNo);
3827 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3833 case ISD::VP_SINT_TO_FP:
3834 case ISD::VP_UINT_TO_FP:
3835 if (
N->getValueType(0).bitsLT(
3836 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3837 Res = SplitVecOp_TruncateHelper(
N);
3839 Res = SplitVecOp_UnaryOp(
N);
3843 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3847 case ISD::VP_FP_TO_SINT:
3848 case ISD::VP_FP_TO_UINT:
3861 Res = SplitVecOp_UnaryOp(
N);
3864 Res = SplitVecOp_FPOpDifferentTypes(
N);
3869 Res = SplitVecOp_CMP(
N);
3873 Res = SplitVecOp_FAKE_USE(
N);
3878 Res = SplitVecOp_ExtVecInRegOp(
N);
3896 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3900 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3902 case ISD::VP_REDUCE_FADD:
3903 case ISD::VP_REDUCE_SEQ_FADD:
3904 case ISD::VP_REDUCE_FMUL:
3905 case ISD::VP_REDUCE_SEQ_FMUL:
3906 case ISD::VP_REDUCE_ADD:
3907 case ISD::VP_REDUCE_MUL:
3908 case ISD::VP_REDUCE_AND:
3909 case ISD::VP_REDUCE_OR:
3910 case ISD::VP_REDUCE_XOR:
3911 case ISD::VP_REDUCE_SMAX:
3912 case ISD::VP_REDUCE_SMIN:
3913 case ISD::VP_REDUCE_UMAX:
3914 case ISD::VP_REDUCE_UMIN:
3915 case ISD::VP_REDUCE_FMAX:
3916 case ISD::VP_REDUCE_FMIN:
3917 case ISD::VP_REDUCE_FMAXIMUM:
3918 case ISD::VP_REDUCE_FMINIMUM:
3919 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3923 Res = SplitVecOp_CttzElts(
N);
3925 case ISD::VP_CTTZ_ELTS:
3926 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3927 Res = SplitVecOp_VP_CttzElements(
N);
3930 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3936 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3941 if (!Res.
getNode())
return false;
3948 if (
N->isStrictFPOpcode())
3950 "Invalid operand expansion");
3953 "Invalid operand expansion");
3955 ReplaceValueWith(
SDValue(
N, 0), Res);
3959SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3963 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3965 EVT VT =
N->getValueType(0);
3978 getSetCCResultType(MVT::i1), MVT::i1);
3983 DAG.getElementCount(
DL, VT, SplitEC)),
3987SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3990 assert(OpNo == 0 &&
"Illegal operand must be mask");
3997 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4000 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4001 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4002 "Lo and Hi have differing types");
4005 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4006 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4008 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4009 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4010 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4011 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4021SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4024 assert(OpNo == 1 &&
"Illegal operand must be mask");
4029 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4031 EVT VecVT =
N->getValueType(0);
4035SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4036 EVT ResVT =
N->getValueType(0);
4042 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4043 GetSplitVector(VecOp,
Lo,
Hi);
4045 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4050 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4051 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4055 EVT ResVT =
N->getValueType(0);
4061 SDNodeFlags
Flags =
N->getFlags();
4064 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4065 GetSplitVector(VecOp,
Lo,
Hi);
4067 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4073 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4076SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4077 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4078 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4080 unsigned Opc =
N->getOpcode();
4081 EVT ResVT =
N->getValueType(0);
4087 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4088 GetSplitVector(VecOp,
Lo,
Hi);
4091 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4094 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4096 const SDNodeFlags
Flags =
N->getFlags();
4100 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4105 EVT ResVT =
N->getValueType(0);
4108 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4109 EVT InVT =
Lo.getValueType();
4114 if (
N->isStrictFPOpcode()) {
4115 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4116 {N->getOperand(0), Lo});
4117 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4118 {N->getOperand(0), Hi});
4127 ReplaceValueWith(
SDValue(
N, 1), Ch);
4128 }
else if (
N->getNumOperands() == 3) {
4129 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4130 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4131 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4132 std::tie(EVLLo, EVLHi) =
4133 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4134 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4135 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4137 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4138 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4147 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4157 EVT ResVT =
N->getValueType(0);
4159 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4163 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4169 Lo = BitConvertToInteger(
Lo);
4170 Hi = BitConvertToInteger(
Hi);
4172 if (DAG.getDataLayout().isBigEndian())
4180 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4182 EVT ResVT =
N->getValueType(0);
4190 GetSplitVector(SubVec,
Lo,
Hi);
4199 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4201 return SecondInsertion;
4204SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4211 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4213 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4215 ElementCount IdxVal =
4219 EVT SrcVT =
N->getOperand(0).getValueType();
4238 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4239 LoEltsMin - IdxValMin);
4240 DAG.ExtractVectorElements(
Hi, Elts, 0,
4243 return DAG.getBuildVector(SubVT, dl, Elts);
4247 ElementCount ExtractIdx = IdxVal - LoElts;
4249 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4252 EVT HiVT =
Hi.getValueType();
4254 "Only fixed-vector extracts are supported in this case");
4264 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4265 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4271 "Extracting scalable subvector from fixed-width unsupported");
4279 "subvector from a scalable predicate vector");
4285 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4287 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4288 auto &MF = DAG.getMachineFunction();
4292 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4296 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4299 SubVT, dl, Store, StackPtr,
4303SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4309 uint64_t IdxVal =
Index->getZExtValue();
4312 GetSplitVector(Vec,
Lo,
Hi);
4314 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4316 if (IdxVal < LoElts)
4317 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4320 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4325 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4337 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4343 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4345 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4346 auto &MF = DAG.getMachineFunction();
4349 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4353 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4357 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4359 return DAG.getExtLoad(
4370 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4378 SplitVecRes_Gather(
N,
Lo,
Hi);
4381 ReplaceValueWith(
SDValue(
N, 0), Res);
4386 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4390 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4392 SDValue EVL =
N->getVectorLength();
4394 Align Alignment =
N->getBaseAlign();
4400 GetSplitVector(
Data, DataLo, DataHi);
4402 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4407 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4410 GetSplitVector(Mask, MaskLo, MaskHi);
4412 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4415 EVT MemoryVT =
N->getMemoryVT();
4416 EVT LoMemVT, HiMemVT;
4417 bool HiIsEmpty =
false;
4418 std::tie(LoMemVT, HiMemVT) =
4419 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4423 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4426 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4431 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4432 N->getAddressingMode(),
N->isTruncatingStore(),
4433 N->isCompressingStore());
4439 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4440 N->isCompressingStore());
4442 MachinePointerInfo MPI;
4446 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4451 MMO = DAG.getMachineFunction().getMachineMemOperand(
4453 Alignment,
N->getAAInfo(),
N->getRanges());
4455 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4456 N->getAddressingMode(),
N->isTruncatingStore(),
4457 N->isCompressingStore());
4466 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4467 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4474 GetSplitVector(
Data, LoData, HiData);
4476 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4478 EVT LoMemVT, HiMemVT;
4479 bool HiIsEmpty =
false;
4480 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4486 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4487 else if (getTypeAction(
Mask.getValueType()) ==
4489 GetSplitVector(Mask, LoMask, HiMask);
4491 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4494 std::tie(LoEVL, HiEVL) =
4495 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4499 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4500 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4501 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4512 EVT PtrVT =
N->getBasePtr().getValueType();
4515 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4518 Align Alignment =
N->getBaseAlign();
4523 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4524 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4526 Alignment,
N->getAAInfo(),
N->getRanges());
4529 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4530 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4531 N->isCompressingStore());
4540 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4544 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4547 Align Alignment =
N->getBaseAlign();
4553 GetSplitVector(
Data, DataLo, DataHi);
4555 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4560 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4563 GetSplitVector(Mask, MaskLo, MaskHi);
4565 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4568 EVT MemoryVT =
N->getMemoryVT();
4569 EVT LoMemVT, HiMemVT;
4570 bool HiIsEmpty =
false;
4571 std::tie(LoMemVT, HiMemVT) =
4572 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4575 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4580 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4581 N->getAddressingMode(),
N->isTruncatingStore(),
4582 N->isCompressingStore());
4590 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4591 N->isCompressingStore());
4593 MachinePointerInfo MPI;
4597 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4602 MMO = DAG.getMachineFunction().getMachineMemOperand(
4604 Alignment,
N->getAAInfo(),
N->getRanges());
4606 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4607 N->getAddressingMode(),
N->isTruncatingStore(),
4608 N->isCompressingStore());
4621 EVT MemoryVT =
N->getMemoryVT();
4622 Align Alignment =
N->getBaseAlign();
4629 }
Ops = [&]() -> Operands {
4631 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4635 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4640 EVT LoMemVT, HiMemVT;
4641 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4646 GetSplitVector(
Ops.Data, DataLo, DataHi);
4648 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4653 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4655 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4659 if (getTypeAction(
Ops.Index.getValueType()) ==
4661 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4663 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4667 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4669 Alignment,
N->getAAInfo(),
N->getRanges());
4672 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4674 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4675 MSC->getIndexType(), MSC->isTruncatingStore());
4680 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4681 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4682 MMO, MSC->getIndexType(),
4683 MSC->isTruncatingStore());
4687 std::tie(EVLLo, EVLHi) =
4688 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4690 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4691 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4692 VPSC->getIndexType());
4697 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4698 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4699 VPSC->getIndexType());
4703 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4704 assert(OpNo == 1 &&
"Can only split the stored value");
4707 bool isTruncating =
N->isTruncatingStore();
4710 EVT MemoryVT =
N->getMemoryVT();
4711 Align Alignment =
N->getBaseAlign();
4713 AAMDNodes AAInfo =
N->getAAInfo();
4715 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4717 EVT LoMemVT, HiMemVT;
4718 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4722 return TLI.scalarizeVectorStore(
N, DAG);
4725 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4726 Alignment, MMOFlags, AAInfo);
4728 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4731 MachinePointerInfo MPI;
4732 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4735 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4736 HiMemVT, Alignment, MMOFlags, AAInfo);
4738 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4755 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4757 N->getBasePtr(),
N->getMemOperand());
4771 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4777 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4798 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4799 SDValue InVec =
N->getOperand(OpNo);
4801 EVT OutVT =
N->getValueType(0);
4809 EVT LoOutVT, HiOutVT;
4810 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4811 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4816 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4818 return SplitVecOp_UnaryOp(
N);
4827 return SplitVecOp_UnaryOp(
N);
4831 GetSplitVector(InVec, InLoVec, InHiVec);
4837 EVT HalfElementVT = IsFloat ?
4839 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4846 if (
N->isStrictFPOpcode()) {
4847 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4848 {N->getOperand(0), InLoVec});
4849 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4850 {N->getOperand(0), InHiVec});
4856 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4857 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4861 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4869 if (
N->isStrictFPOpcode()) {
4873 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4881 DAG.getTargetConstant(
4882 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4889 assert(
N->getValueType(0).isVector() &&
4890 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4891 "Operand types must be vectors");
4893 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4895 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4896 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4898 EVT VT =
N->getValueType(0);
4899 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4904 }
else if (isStrict) {
4905 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4906 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4907 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4908 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4911 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4913 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4914 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4915 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4916 std::tie(EVLLo, EVLHi) =
4917 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4918 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4919 N->getOperand(2), MaskLo, EVLLo);
4920 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4921 N->getOperand(2), MaskHi, EVLHi);
4929 EVT OpVT =
N->getOperand(0).getValueType();
4932 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4938 EVT ResVT =
N->getValueType(0);
4941 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4942 EVT InVT =
Lo.getValueType();
4947 if (
N->isStrictFPOpcode()) {
4948 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4949 {N->getOperand(0), Lo, N->getOperand(2)});
4950 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4951 {N->getOperand(0), Hi, N->getOperand(2)});
4955 Lo.getValue(1),
Hi.getValue(1));
4956 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4957 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4958 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4959 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4960 std::tie(EVLLo, EVLHi) =
4961 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4962 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4963 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4965 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4966 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
4977SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4980 EVT LHSLoVT, LHSHiVT;
4981 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4983 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4984 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4987 std::tie(LHSLo, LHSHi) =
4988 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4991 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4994 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5000 LLVMContext &Ctxt = *DAG.getContext();
5003 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5004 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5005 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5007 EVT ResVT =
N->getValueType(0);
5012 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5013 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5019 EVT ResVT =
N->getValueType(0);
5022 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5023 EVT InVT =
Lo.getValueType();
5029 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5030 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5037 EVT ResVT =
N->getValueType(0);
5041 GetSplitVector(VecOp,
Lo,
Hi);
5047 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5049 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5051 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5052 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5057 EVT ResVT =
N->getValueType(0);
5061 GetSplitVector(VecOp,
Lo,
Hi);
5063 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5064 auto [EVLLo, EVLHi] =
5066 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5072 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5074 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5075 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5078SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5089 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5090 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5091 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5092 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5093 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5094 OpsLo, MMO, IndexType);
5095 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5096 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5100SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5103 "Accumulator should already be a legal type, and shouldn't need "
5104 "further splitting");
5107 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5108 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5109 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5110 unsigned Opcode =
N->getOpcode();
5113 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5114 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5121void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5122 unsigned WidenResNo) {
5123 unsigned NumResults =
N->getNumValues();
5124 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5125 if (ResNo == WidenResNo)
5127 EVT ResVT =
N->getValueType(ResNo);
5133 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5134 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5139void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5140 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5143 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5148 auto unrollExpandedOp = [&]() {
5153 EVT VT =
N->getValueType(0);
5154 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5155 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5156 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5158 if (
N->getNumValues() > 1)
5159 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5165 switch (
N->getOpcode()) {
5168 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5176 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5180 Res = WidenVecRes_ADDRSPACECAST(
N);
5187 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5194 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5198 Res = WidenVecRes_ScalarOp(
N);
5203 case ISD::VP_SELECT:
5205 Res = WidenVecRes_Select(
N);
5209 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5211 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5218 case ISD::VP_LOAD_FF:
5221 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5225 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5233 case ISD::VP_GATHER:
5237 Res = WidenVecRes_VECTOR_REVERSE(
N);
5240 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5250 case ISD::OR:
case ISD::VP_OR:
5261 case ISD::VP_FMINNUM:
5264 case ISD::VP_FMAXNUM:
5266 case ISD::VP_FMINIMUM:
5268 case ISD::VP_FMAXIMUM:
5301 case ISD::VP_FCOPYSIGN:
5302 Res = WidenVecRes_Binary(
N);
5309 Res = WidenVecRes_MaskedBinary(
N);
5314 Res = WidenVecRes_CMP(
N);
5320 if (unrollExpandedOp())
5335 Res = WidenVecRes_BinaryCanTrap(
N);
5344 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5347#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5348 case ISD::STRICT_##DAGN:
5349#include "llvm/IR/ConstrainedOps.def"
5350 Res = WidenVecRes_StrictFP(
N);
5359 Res = WidenVecRes_OverflowOp(
N, ResNo);
5363 Res = WidenVecRes_FCOPYSIGN(
N);
5368 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5373 if (!unrollExpandedOp())
5374 Res = WidenVecRes_ExpOp(
N);
5380 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5385 case ISD::VP_FP_EXTEND:
5387 case ISD::VP_FP_ROUND:
5389 case ISD::VP_FP_TO_SINT:
5391 case ISD::VP_FP_TO_UINT:
5393 case ISD::VP_SIGN_EXTEND:
5395 case ISD::VP_SINT_TO_FP:
5396 case ISD::VP_TRUNCATE:
5399 case ISD::VP_UINT_TO_FP:
5401 case ISD::VP_ZERO_EXTEND:
5403 Res = WidenVecRes_Convert(
N);
5408 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5414 case ISD::VP_LLRINT:
5417 Res = WidenVecRes_XROUND(
N);
5443 if (unrollExpandedOp())
5454 case ISD::VP_BITREVERSE:
5460 case ISD::VP_CTLZ_ZERO_POISON:
5466 case ISD::VP_CTTZ_ZERO_POISON:
5471 case ISD::VP_FFLOOR:
5473 case ISD::VP_FNEARBYINT:
5474 case ISD::VP_FROUND:
5475 case ISD::VP_FROUNDEVEN:
5476 case ISD::VP_FROUNDTOZERO:
5481 Res = WidenVecRes_Unary(
N);
5488 Res = WidenVecRes_Ternary(
N);
5494 if (!unrollExpandedOp())
5495 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5502 SetWidenedVector(
SDValue(
N, ResNo), Res);
5508 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5509 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5510 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5511 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5512 if (
N->getNumOperands() == 3)
5513 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5515 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5516 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5520 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5521 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5527 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5528 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5529 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5530 if (
N->getNumOperands() == 2)
5531 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5534 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5535 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5539 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5540 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5545 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5546 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5547 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5550 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5551 Mask = ModifyToType(Mask, WideMaskVT,
true);
5552 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5557 LLVMContext &Ctxt = *DAG.getContext();
5562 EVT OpVT =
LHS.getValueType();
5564 LHS = GetWidenedVector(
LHS);
5565 RHS = GetWidenedVector(
RHS);
5566 OpVT =
LHS.getValueType();
5569 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5572 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5578SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5581 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5582 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5583 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5585 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5594 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5597 if (ConcatEnd == 1) {
5598 VT = ConcatOps[0].getValueType();
5600 return ConcatOps[0];
5603 SDLoc dl(ConcatOps[0]);
5610 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5611 int Idx = ConcatEnd - 1;
5612 VT = ConcatOps[Idx--].getValueType();
5613 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5626 unsigned NumToInsert = ConcatEnd - Idx - 1;
5627 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5629 ConcatOps[Idx+1] = VecOp;
5630 ConcatEnd = Idx + 2;
5636 unsigned RealVals = ConcatEnd - Idx - 1;
5637 unsigned SubConcatEnd = 0;
5638 unsigned SubConcatIdx = Idx + 1;
5639 while (SubConcatEnd < RealVals)
5640 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5641 while (SubConcatEnd < OpsToConcat)
5642 SubConcatOps[SubConcatEnd++] = undefVec;
5644 NextVT, SubConcatOps);
5645 ConcatEnd = SubConcatIdx + 1;
5650 if (ConcatEnd == 1) {
5651 VT = ConcatOps[0].getValueType();
5653 return ConcatOps[0];
5658 if (
NumOps != ConcatEnd ) {
5660 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5661 ConcatOps[j] = UndefVal;
5669 unsigned Opcode =
N->getOpcode();
5671 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5675 const SDNodeFlags
Flags =
N->getFlags();
5676 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5677 NumElts = NumElts / 2;
5681 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5683 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5684 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5685 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5693 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5696 TLI.isTypeLegal(WideMaskVT)) {
5697 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5698 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5699 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5701 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5702 N->getValueType(0).getVectorElementCount());
5703 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5717 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5718 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5719 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5722 unsigned ConcatEnd = 0;
5730 while (CurNumElts != 0) {
5731 while (CurNumElts >= NumElts) {
5732 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5733 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5734 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5736 CurNumElts -= NumElts;
5739 NumElts = NumElts / 2;
5741 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5744 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5745 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5746 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5747 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5758 switch (
N->getOpcode()) {
5761 return WidenVecRes_STRICT_FSETCC(
N);
5768 return WidenVecRes_Convert_StrictFP(
N);
5775 unsigned Opcode =
N->getOpcode();
5777 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5781 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5782 NumElts = NumElts / 2;
5793 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5797 unsigned ConcatEnd = 0;
5804 for (
unsigned i = 1; i < NumOpers; ++i) {
5810 Oper = GetWidenedVector(Oper);
5816 DAG.getPOISON(WideOpVT), Oper,
5817 DAG.getVectorIdxConstant(0, dl));
5829 while (CurNumElts != 0) {
5830 while (CurNumElts >= NumElts) {
5833 for (
unsigned i = 0; i < NumOpers; ++i) {
5836 EVT OpVT =
Op.getValueType();
5841 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5847 EVT OperVT[] = {VT, MVT::Other};
5849 ConcatOps[ConcatEnd++] = Oper;
5852 CurNumElts -= NumElts;
5855 NumElts = NumElts / 2;
5857 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5860 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5863 for (
unsigned i = 0; i < NumOpers; ++i) {
5866 EVT OpVT =
Op.getValueType();
5874 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5876 ConcatOps[ConcatEnd++] = Oper;
5885 if (Chains.
size() == 1)
5886 NewChain = Chains[0];
5889 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5894SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5896 EVT ResVT =
N->getValueType(0);
5897 EVT OvVT =
N->getValueType(1);
5898 EVT WideResVT, WideOvVT;
5903 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5908 WideLHS = GetWidenedVector(
N->getOperand(0));
5909 WideRHS = GetWidenedVector(
N->getOperand(1));
5911 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5920 N->getOperand(0), Zero);
5922 N->getOperand(1), Zero);
5925 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5926 SDNode *WideNode = DAG.getNode(
5927 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5930 unsigned OtherNo = 1 - ResNo;
5931 EVT OtherVT =
N->getValueType(OtherNo);
5938 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5941 return SDValue(WideNode, ResNo);
5945 LLVMContext &Ctx = *DAG.getContext();
5949 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5954 unsigned Opcode =
N->getOpcode();
5955 const SDNodeFlags
Flags =
N->getFlags();
5961 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5963 InOp = ZExtPromotedInteger(InOp);
5974 InOp = GetWidenedVector(
N->getOperand(0));
5977 if (InVTEC == WidenEC) {
5978 if (
N->getNumOperands() == 1)
5979 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5980 if (
N->getNumOperands() == 3) {
5981 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5984 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5986 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
6012 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6016 if (TLI.isTypeLegal(InWidenVT)) {
6024 unsigned NumConcat =
6029 if (
N->getNumOperands() == 1)
6030 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
6031 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
6035 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6037 if (
N->getNumOperands() == 1)
6038 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
6039 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
6048 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6049 for (
unsigned i=0; i < MinElts; ++i) {
6050 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6051 if (
N->getNumOperands() == 1)
6054 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
6057 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6062 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6066 EVT SrcVT = Src.getValueType();
6070 Src = GetWidenedVector(Src);
6071 SrcVT = Src.getValueType();
6078 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6083 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6087 EVT SrcVT = Src.getValueType();
6091 Src = GetWidenedVector(Src);
6092 SrcVT = Src.getValueType();
6099 if (
N->getNumOperands() == 1)
6100 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6102 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6103 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6107 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6110SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6115 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6121 unsigned Opcode =
N->getOpcode();
6127 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6132 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6133 for (
unsigned i=0; i < MinElts; ++i) {
6134 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6135 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6139 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6141 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6144SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6145 unsigned Opcode =
N->getOpcode();
6149 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6158 InOp = GetWidenedVector(InOp);
6165 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6172 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6173 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6190 while (
Ops.size() != WidenNumElts)
6191 Ops.push_back(DAG.getPOISON(WidenSVT));
6193 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6199 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6200 return WidenVecRes_BinaryCanTrap(
N);
6203 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6210SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6212 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6215 SDValue Arg = GetWidenedVector(FpValue);
6216 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6221 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6222 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6224 EVT ExpVT =
RHS.getValueType();
6229 ExpOp = ModifyToType(
RHS, WideExpVT);
6232 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6237 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6238 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6239 if (
N->getNumOperands() == 1)
6240 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6242 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6243 N->getOperand(1),
N->getFlags());
6245 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6246 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6250 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6251 {InOp,
Mask,
N->getOperand(2)});
6255 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6260 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6261 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6262 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6265SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6267 EVT VT0 =
N->getValueType(0);
6268 EVT VT1 =
N->getValueType(1);
6272 "expected both results to be vectors of matching element count");
6274 LLVMContext &Ctx = *DAG.getContext();
6275 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6277 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6284 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6287 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6288 return SDValue(WidenNode, ResNo);
6291SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6292 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6293 return GetWidenedVector(WidenVec);
6297 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6298 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6301 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6302 AddrSpaceCastN->getSrcAddressSpace(),
6303 AddrSpaceCastN->getDestAddressSpace());
6309 EVT VT =
N->getValueType(0);
6310 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6313 switch (getTypeAction(InVT)) {
6327 SDValue NInOp = GetPromotedInteger(InOp);
6329 if (WidenVT.
bitsEq(NInVT)) {
6332 if (DAG.getDataLayout().isBigEndian()) {
6335 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6353 InOp = GetWidenedVector(InOp);
6355 if (WidenVT.
bitsEq(InVT))
6365 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6370 unsigned NewNumParts = WidenSize / InSize;
6383 EVT OrigInVT =
N->getOperand(0).getValueType();
6388 if (TLI.isTypeLegal(NewInVT)) {
6396 if (WidenSize % InSize == 0) {
6403 DAG.ExtractVectorElements(InOp,
Ops);
6404 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6416 return CreateStackStoreLoad(InOp, WidenVT);
6419SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6421 N->getOpcode(), SDLoc(
N),
6422 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6423 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6429 EVT VT =
N->getValueType(0);
6433 EVT EltVT =
N->getOperand(0).getValueType();
6436 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6440 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6441 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6443 return DAG.getBuildVector(WidenVT, dl, NewOps);
6447 EVT InVT =
N->getOperand(0).getValueType();
6448 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6450 unsigned NumOperands =
N->getNumOperands();
6452 bool InputWidened =
false;
6456 if (WidenNumElts % NumInElts == 0) {
6458 unsigned NumConcat = WidenNumElts / NumInElts;
6459 SDValue UndefVal = DAG.getPOISON(InVT);
6461 for (
unsigned i=0; i < NumOperands; ++i)
6462 Ops[i] =
N->getOperand(i);
6463 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6468 InputWidened =
true;
6469 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6472 for (i=1; i < NumOperands; ++i)
6473 if (!
N->getOperand(i).isUndef())
6476 if (i == NumOperands)
6479 return GetWidenedVector(
N->getOperand(0));
6481 if (NumOperands == 2) {
6483 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6488 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6489 for (
unsigned i = 0; i < NumInElts; ++i) {
6491 MaskOps[i + NumInElts] = i + WidenNumElts;
6493 return DAG.getVectorShuffle(WidenVT, dl,
6494 GetWidenedVector(
N->getOperand(0)),
6495 GetWidenedVector(
N->getOperand(1)),
6502 "Cannot use build vectors to widen CONCAT_VECTOR result");
6510 for (
unsigned i=0; i < NumOperands; ++i) {
6513 InOp = GetWidenedVector(InOp);
6514 for (
unsigned j = 0;
j < NumInElts; ++
j)
6515 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6517 SDValue UndefVal = DAG.getPOISON(EltVT);
6518 for (; Idx < WidenNumElts; ++Idx)
6519 Ops[Idx] = UndefVal;
6520 return DAG.getBuildVector(WidenVT, dl,
Ops);
6523SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6524 EVT VT =
N->getValueType(0);
6525 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6526 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6533SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6534 EVT VT =
N->getValueType(0);
6536 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6541 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6543 InOp = GetWidenedVector(InOp);
6549 if (IdxVal == 0 && InVT == WidenVT)
6556 assert(IdxVal % VTNumElts == 0 &&
6557 "Expected Idx to be a multiple of subvector minimum vector length");
6558 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6571 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6572 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6573 "down type's element count");
6580 for (;
I < VTNumElts / GCD; ++
I)
6582 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6583 for (;
I < WidenNumElts / GCD; ++
I)
6591 Align Alignment = DAG.getReducedAlign(InVT,
false);
6593 MachineFunction &MF = DAG.getMachineFunction();
6605 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6612 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6613 return DAG.getMaskedLoad(
6614 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6622 for (i = 0; i < VTNumElts; ++i)
6623 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6625 SDValue UndefVal = DAG.getPOISON(EltVT);
6626 for (; i < WidenNumElts; ++i)
6628 return DAG.getBuildVector(WidenVT, dl,
Ops);
6634 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6639SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6640 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6643 N->getOperand(1),
N->getOperand(2));
6652 "Load width must be less than or equal to first value type width");
6661 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6678 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6689 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6690 EVT LdVT =
LD->getMemoryVT();
6699 TypeSize WidthDiff = WidenWidth - LdWidth;
6702 std::optional<EVT> FirstVT =
6703 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6710 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6713 Chain, BasePtr,
LD->getMemOperand());
6717 FirstVTWidth, dl, DAG);
6735 if (!
LD->getMemoryVT().isByteSized()) {
6737 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6739 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6748 EVT VT =
LD->getValueType(0);
6749 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6750 EVT WideMaskVT = getSetCCResultType(WideVT);
6753 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6754 TLI.isTypeLegal(WideMaskVT)) {
6757 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6761 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6762 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6774 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6776 Result = GenWidenVectorLoads(LdChain, LD);
6783 if (LdChain.
size() == 1)
6784 NewChain = LdChain[0];
6790 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6801 SDValue NewLoad = DAG.getMaskedLoad(
6802 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6803 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6804 LD->getAddressingMode(),
LD->getExtensionType());
6814 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6816 SDValue EVL =
N->getVectorLength();
6823 "Unable to widen binary VP op");
6824 Mask = GetWidenedVector(Mask);
6825 assert(
Mask.getValueType().getVectorElementCount() ==
6826 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6827 .getVectorElementCount() &&
6828 "Unable to widen vector load");
6831 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6832 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6833 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6841 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6843 SDValue EVL =
N->getVectorLength();
6849 "Unable to widen binary VP op");
6850 Mask = GetWidenedVector(Mask);
6851 assert(
Mask.getValueType().getVectorElementCount() ==
6852 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6853 .getVectorElementCount() &&
6854 "Unable to widen vector load");
6856 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6857 Mask, EVL,
N->getMemOperand());
6870 "Unable to widen VP strided load");
6871 Mask = GetWidenedVector(Mask);
6873 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6874 assert(
Mask.getValueType().getVectorElementCount() ==
6876 "Data and mask vectors should have the same number of elements");
6878 SDValue Res = DAG.getStridedLoadVP(
6879 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6880 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6881 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6882 N->isExpandingLoad());
6890SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6895 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6897 Mask.getValueType().getVectorElementType(),
6900 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6901 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6902 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6904 WideMask, WidePassthru);
6908 EVT VT =
N->getValueType(0);
6909 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6911 EVT MaskVT =
Mask.getValueType();
6912 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6921 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6922 TLI.isTypeLegal(WideMaskVT) &&
6928 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6929 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6933 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6934 N->getMemoryVT(),
N->getMemOperand());
6938 if (!
N->getPassThru()->isUndef()) {
6942 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6943 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6944 DAG.getPOISON(WidenVT), EVL);
6955 Mask = ModifyToType(Mask, WideMaskVT,
true);
6957 SDValue Res = DAG.getMaskedLoad(
6958 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6959 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6960 ExtType,
N->isExpandingLoad());
6969 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6971 EVT MaskVT =
Mask.getValueType();
6972 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6981 Mask = ModifyToType(Mask, WideMaskVT,
true);
6986 Index.getValueType().getScalarType(),
6988 Index = ModifyToType(Index, WideIndexVT);
6994 N->getMemoryVT().getScalarType(), NumElts);
6995 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6996 WideMemVT, dl,
Ops,
N->getMemOperand(),
6997 N->getIndexType(),
N->getExtensionType());
7006 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7014 N->getMemoryVT().getScalarType(), WideEC);
7015 Mask = GetWidenedMask(Mask, WideEC);
7018 Mask,
N->getVectorLength()};
7019 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7020 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7029 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7030 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7058 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7059 return N->getOperand(OpNo).getValueType();
7067 N =
N.getOperand(0);
7069 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7070 if (!
N->getOperand(i)->isUndef())
7072 N =
N.getOperand(0);
7076 N =
N.getOperand(0);
7078 N =
N.getOperand(0);
7105 { MaskVT, MVT::Other },
Ops);
7106 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7114 LLVMContext &Ctx = *DAG.getContext();
7117 if (MaskScalarBits < ToMaskScalBits) {
7121 }
else if (MaskScalarBits > ToMaskScalBits) {
7127 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7129 "Mask should have the right element size by now.");
7132 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7134 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7137 EVT SubVT =
Mask->getValueType(0);
7143 assert((
Mask->getValueType(0) == ToMaskVT) &&
7144 "A mask of ToMaskVT should have been produced by now.");
7154 LLVMContext &Ctx = *DAG.getContext();
7165 EVT CondVT =
Cond->getValueType(0);
7169 EVT VSelVT =
N->getValueType(0);
7181 EVT FinalVT = VSelVT;
7192 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7193 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7200 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7208 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7211 EVT ToMaskVT = VSelVT;
7218 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7234 if (ScalarBits0 != ScalarBits1) {
7235 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7236 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7248 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7249 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7250 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7253 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7261 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7266 unsigned Opcode =
N->getOpcode();
7268 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7269 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7270 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7272 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7278 Cond1 = GetWidenedVector(Cond1);
7286 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7287 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7292 Cond1 = ModifyToType(Cond1, CondWidenVT);
7295 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7296 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7298 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7299 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7301 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7305 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7306 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7309 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7313 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7314 return DAG.getUNDEF(WidenVT);
7318 EVT VT =
N->getValueType(0);
7321 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7325 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7326 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7329 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7330 for (
unsigned i = 0; i != NumElts; ++i) {
7331 int Idx =
N->getMaskElt(i);
7332 if (Idx < (
int)NumElts)
7335 NewMask[i] = Idx - NumElts + WidenNumElts;
7337 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7341 EVT VT =
N->getValueType(0);
7345 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7346 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7352 unsigned IdxVal = WidenNumElts - VTNumElts;
7365 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7368 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7369 "down type's element count");
7372 for (; i < VTNumElts / GCD; ++i)
7374 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7375 for (; i < WidenNumElts / GCD; ++i)
7383 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7384 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7386 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7390SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7391 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7396 assert(
N->getValueType(0).isVector() &&
7397 N->getOperand(0).getValueType().isVector() &&
7398 "Operands must be vectors");
7399 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7412 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7413 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7420 InOp1 = GetWidenedVector(InOp1);
7421 InOp2 = GetWidenedVector(InOp2);
7424 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7435 "Input not widened to expected type!");
7437 if (
N->getOpcode() == ISD::VP_SETCC) {
7440 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7441 N->getOperand(2), Mask,
N->getOperand(4));
7443 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7448 assert(
N->getValueType(0).isVector() &&
7449 N->getOperand(1).getValueType().isVector() &&
7450 "Operands must be vectors");
7451 EVT VT =
N->getValueType(0);
7452 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7462 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7467 for (
unsigned i = 0; i != NumElts; ++i) {
7468 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7469 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7471 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7472 {Chain, LHSElem, RHSElem, CC});
7473 Chains[i] = Scalars[i].getValue(1);
7474 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7475 DAG.getBoolConstant(
true, dl, EltVT, VT),
7476 DAG.getBoolConstant(
false, dl, EltVT, VT));
7480 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7482 return DAG.getBuildVector(WidenVT, dl, Scalars);
7488bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7489 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7493 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7496 switch (
N->getOpcode()) {
7499 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7507 Res = WidenVecOp_FAKE_USE(
N);
7513 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7517 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7518 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7519 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7524 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7526 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7527 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7529 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7530 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7540 Res = WidenVecOp_UnrollVectorOp(
N);
7547 Res = WidenVecOp_EXTEND(
N);
7552 Res = WidenVecOp_CMP(
N);
7569 Res = WidenVecOp_Convert(
N);
7574 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7592 Res = WidenVecOp_VECREDUCE(
N);
7596 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7598 case ISD::VP_REDUCE_FADD:
7599 case ISD::VP_REDUCE_SEQ_FADD:
7600 case ISD::VP_REDUCE_FMUL:
7601 case ISD::VP_REDUCE_SEQ_FMUL:
7602 case ISD::VP_REDUCE_ADD:
7603 case ISD::VP_REDUCE_MUL:
7604 case ISD::VP_REDUCE_AND:
7605 case ISD::VP_REDUCE_OR:
7606 case ISD::VP_REDUCE_XOR:
7607 case ISD::VP_REDUCE_SMAX:
7608 case ISD::VP_REDUCE_SMIN:
7609 case ISD::VP_REDUCE_UMAX:
7610 case ISD::VP_REDUCE_UMIN:
7611 case ISD::VP_REDUCE_FMAX:
7612 case ISD::VP_REDUCE_FMIN:
7613 case ISD::VP_REDUCE_FMAXIMUM:
7614 case ISD::VP_REDUCE_FMINIMUM:
7615 Res = WidenVecOp_VP_REDUCE(
N);
7617 case ISD::VP_CTTZ_ELTS:
7618 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7619 Res = WidenVecOp_VP_CttzElements(
N);
7622 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7627 if (!Res.
getNode())
return false;
7635 if (
N->isStrictFPOpcode())
7637 "Invalid operand expansion");
7640 "Invalid operand expansion");
7642 ReplaceValueWith(
SDValue(
N, 0), Res);
7648 EVT VT =
N->getValueType(0);
7653 "Unexpected type action");
7654 InOp = GetWidenedVector(InOp);
7657 "Input wasn't widened!");
7665 EVT FixedEltVT = FixedVT.getVectorElementType();
7666 if (TLI.isTypeLegal(FixedVT) &&
7668 FixedEltVT == InEltVT) {
7670 "Not enough elements in the fixed type for the operand!");
7672 "We can't have the same type as we started with!");
7674 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7676 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7685 return WidenVecOp_Convert(
N);
7690 switch (
N->getOpcode()) {
7705 EVT OpVT =
N->getOperand(0).getValueType();
7706 EVT ResVT =
N->getValueType(0);
7713 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7714 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7720 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7721 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7723 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7730 return DAG.UnrollVectorOp(
N);
7735 EVT ResultVT =
N->getValueType(0);
7737 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7740 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7746 {WideArg,
Test},
N->getFlags());
7752 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7754 EVT OpVT =
N->getOperand(0).getValueType();
7757 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7762 EVT VT =
N->getValueType(0);
7768 "Unexpected type action");
7769 InOp = GetWidenedVector(InOp);
7771 unsigned Opcode =
N->getOpcode();
7777 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7779 if (
N->isStrictFPOpcode()) {
7781 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7784 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7785 {
N->getOperand(0), InOp });
7791 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7793 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7795 return DAG.getExtractSubvector(dl, VT, Res, 0);
7803 if (
N->isStrictFPOpcode()) {
7806 for (
unsigned i=0; i < NumElts; ++i) {
7807 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7808 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7812 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7814 for (
unsigned i = 0; i < NumElts; ++i) {
7815 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7817 Ops[i] = DAG.
getNode(Opcode, dl, EltVT, Elt,
N->getOperand(1));
7819 Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
7823 return DAG.getBuildVector(VT, dl,
Ops);
7827 EVT DstVT =
N->getValueType(0);
7828 SDValue Src = GetWidenedVector(
N->getOperand(0));
7829 EVT SrcVT = Src.getValueType();
7836 if (TLI.isTypeLegal(WideDstVT)) {
7838 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7841 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7845 return DAG.UnrollVectorOp(
N);
7849 EVT VT =
N->getValueType(0);
7850 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7858 if (!VT.
isVector() && VT != MVT::x86mmx &&
7862 if (TLI.isTypeLegal(NewVT)) {
7864 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7876 ElementCount NewNumElts =
7878 .divideCoefficientBy(EltSize);
7880 if (TLI.isTypeLegal(NewVT)) {
7882 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7887 return CreateStackStoreLoad(InOp, VT);
7895 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7896 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7901 EVT VT =
N->getValueType(0);
7903 EVT InVT =
N->getOperand(0).getValueType();
7908 unsigned NumOperands =
N->getNumOperands();
7909 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7911 for (i = 1; i < NumOperands; ++i)
7912 if (!
N->getOperand(i).isUndef())
7915 if (i == NumOperands)
7916 return GetWidenedVector(
N->getOperand(0));
7926 for (
unsigned i=0; i < NumOperands; ++i) {
7930 "Unexpected type action");
7931 InOp = GetWidenedVector(InOp);
7932 for (
unsigned j = 0;
j < NumInElts; ++
j)
7933 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7935 return DAG.getBuildVector(VT, dl,
Ops);
7938SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7939 EVT VT =
N->getValueType(0);
7944 SubVec = GetWidenedVector(SubVec);
7949 bool IndicesValid =
false;
7952 IndicesValid =
true;
7956 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7957 Attribute::VScaleRange);
7962 IndicesValid =
true;
7968 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7974 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7981 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7988 Align Alignment = DAG.getReducedAlign(VT,
false);
7990 MachineFunction &MF = DAG.getMachineFunction();
8003 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8011 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8012 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8017 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8022 unsigned Idx =
N->getConstantOperandVal(2);
8028 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8034SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8035 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8037 N->getValueType(0), InOp,
N->getOperand(1));
8040SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8041 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8043 N->getValueType(0), InOp,
N->getOperand(1));
8046SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8048 EVT ResVT =
N->getValueType(0);
8051 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8057 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8065 "Widened input size must be a multiple of result element size");
8068 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8070 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8071 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8079 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8080 return TLI.scalarizeVectorStore(ST, DAG);
8082 if (
ST->isTruncatingStore())
8083 return TLI.scalarizeVectorStore(ST, DAG);
8093 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8094 EVT WideMaskVT = getSetCCResultType(WideVT);
8096 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8097 TLI.isTypeLegal(WideMaskVT)) {
8100 StVal = GetWidenedVector(StVal);
8102 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8104 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8105 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8106 ST->getAddressingMode());
8110 if (GenWidenVectorStores(StChain, ST)) {
8111 if (StChain.
size() == 1)
8120 SDValue WideStVal = GetWidenedVector(StVal);
8124 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8125 ST->getOffset(), Mask,
ST->getMemoryVT(),
8126 ST->getMemOperand(),
ST->getAddressingMode(),
8127 ST->isTruncatingStore());
8134 EVT StVT =
ST->getMemoryVT();
8137 SDValue StVal = GetWidenedVector(
ST->getVal());
8142 TypeSize WidthDiff = WidenWidth - StWidth;
8148 std::optional<EVT> FirstVT =
8149 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8154 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8160 ST->getBasePtr(),
ST->getMemOperand());
8163SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8164 assert((OpNo == 1 || OpNo == 3) &&
8165 "Can widen only data or mask operand of vp_store");
8173 StVal = GetWidenedVector(StVal);
8179 "Unable to widen VP store");
8180 Mask = GetWidenedVector(Mask);
8182 Mask = GetWidenedVector(Mask);
8188 "Unable to widen VP store");
8189 StVal = GetWidenedVector(StVal);
8192 assert(
Mask.getValueType().getVectorElementCount() ==
8194 "Mask and data vectors should have the same number of elements");
8195 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8196 ST->getOffset(), Mask,
ST->getVectorLength(),
8197 ST->getMemoryVT(),
ST->getMemOperand(),
8198 ST->getAddressingMode(),
ST->isTruncatingStore(),
8199 ST->isCompressingStore());
8204 assert((OpNo == 1 || OpNo == 4) &&
8205 "Can widen only data or mask operand of vp_strided_store");
8214 "Unable to widen VP strided store");
8218 "Unable to widen VP strided store");
8220 StVal = GetWidenedVector(StVal);
8221 Mask = GetWidenedVector(Mask);
8224 Mask.getValueType().getVectorElementCount() &&
8225 "Data and mask vectors should have the same number of elements");
8227 return DAG.getStridedStoreVP(
8234SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8235 assert((OpNo == 1 || OpNo == 4) &&
8236 "Can widen only data or mask operand of mstore");
8239 EVT MaskVT =
Mask.getValueType();
8244 EVT WideVT, WideMaskVT;
8247 StVal = GetWidenedVector(StVal);
8254 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8261 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8263 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8264 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8273 Mask = ModifyToType(Mask, WideMaskVT,
true);
8276 Mask = ModifyToType(Mask, WideMaskVT,
true);
8278 StVal = ModifyToType(StVal, WideVT);
8281 assert(
Mask.getValueType().getVectorElementCount() ==
8283 "Mask and data vectors should have the same number of elements");
8290SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8291 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8293 SDValue DataOp = MG->getPassThru();
8295 SDValue Scale = MG->getScale();
8303 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8304 MG->getMemOperand(), MG->getIndexType(),
8305 MG->getExtensionType());
8311SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8320 DataOp = GetWidenedVector(DataOp);
8324 EVT IndexVT =
Index.getValueType();
8327 Index = ModifyToType(Index, WideIndexVT);
8330 EVT MaskVT =
Mask.getValueType();
8333 Mask = ModifyToType(Mask, WideMaskVT,
true);
8338 }
else if (OpNo == 4) {
8340 Index = GetWidenedVector(Index);
8346 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8351SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8360 DataOp = GetWidenedVector(DataOp);
8361 Index = GetWidenedVector(Index);
8363 Mask = GetWidenedMask(Mask, WideEC);
8366 }
else if (OpNo == 3) {
8368 Index = GetWidenedVector(Index);
8375 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8380 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8381 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8383 EVT VT =
N->getValueType(0);
8398 SVT, InOp0, InOp1,
N->getOperand(2));
8404 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8406 EVT OpVT =
N->getOperand(0).getValueType();
8409 return DAG.getNode(ExtendCode, dl, VT, CC);
8419 EVT VT =
N->getValueType(0);
8421 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8428 for (
unsigned i = 0; i != NumElts; ++i) {
8429 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8430 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8432 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8433 {Chain, LHSElem, RHSElem, CC});
8434 Chains[i] = Scalars[i].getValue(1);
8435 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8436 DAG.getBoolConstant(
true, dl, EltVT, VT),
8437 DAG.getBoolConstant(
false, dl, EltVT, VT));
8441 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8443 return DAG.getBuildVector(VT, dl, Scalars);
8467 SDValue Op = GetWidenedVector(
N->getOperand(0));
8468 EVT VT =
N->getValueType(0);
8469 EVT OrigVT =
N->getOperand(0).getValueType();
8470 EVT WideVT =
Op.getValueType();
8472 SDNodeFlags
Flags =
N->getFlags();
8474 unsigned Opc =
N->getOpcode();
8476 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8477 assert(NeutralElem &&
"Neutral element must exist");
8487 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8494 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8495 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8501 unsigned GCD = std::gcd(OrigElts, WideElts);
8504 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8505 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8506 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8507 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8510 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8511 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8513 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8522 EVT VT =
N->getValueType(0);
8524 EVT WideVT =
Op.getValueType();
8526 SDNodeFlags
Flags =
N->getFlags();
8528 unsigned Opc =
N->getOpcode();
8530 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8540 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8543 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8544 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8550 unsigned GCD = std::gcd(OrigElts, WideElts);
8553 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8554 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8555 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8556 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8559 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8560 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8562 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8566 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8569 SDValue Op = GetWidenedVector(
N->getOperand(1));
8571 Op.getValueType().getVectorElementCount());
8573 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8574 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8582 EVT VT =
N->getValueType(0);
8586 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8587 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8592 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8598 EVT SrcVT =
Source.getValueType();
8602 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8603 {Source, Mask, N->getOperand(2)},
N->getFlags());
8606SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8609 EVT OrigMaskVT =
Mask.getValueType();
8610 SDValue WideMask = GetWidenedVector(Mask);
8616 if (OrigElts != WideElts) {
8617 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8619 Mask, DAG.getVectorIdxConstant(0,
DL));
8640 unsigned WidenEx = 0) {
8645 unsigned AlignInBits =
Align*8;
8647 EVT RetVT = WidenEltVT;
8652 if (Width == WidenEltWidth)
8663 (WidenWidth % MemVTWidth) == 0 &&
8665 (MemVTWidth <= Width ||
8666 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8667 if (MemVTWidth == WidenWidth)
8686 (WidenWidth % MemVTWidth) == 0 &&
8688 (MemVTWidth <= Width ||
8689 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8698 return std::nullopt;
8709 unsigned Start,
unsigned End) {
8710 SDLoc dl(LdOps[Start]);
8711 EVT LdTy = LdOps[Start].getValueType();
8719 for (
unsigned i = Start + 1; i != End; ++i) {
8720 EVT NewLdTy = LdOps[i].getValueType();
8721 if (NewLdTy != LdTy) {
8740 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8741 EVT LdVT =
LD->getMemoryVT();
8751 AAMDNodes AAInfo =
LD->getAAInfo();
8755 TypeSize WidthDiff = WidenWidth - LdWidth;
8762 std::optional<EVT> FirstVT =
8763 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8770 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8775 std::optional<EVT> NewVT = FirstVT;
8776 TypeSize RemainingWidth = LdWidth;
8777 TypeSize NewVTWidth = FirstVTWidth;
8779 RemainingWidth -= NewVTWidth;
8786 NewVTWidth = NewVT->getSizeInBits();
8792 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8793 LD->getBaseAlign(), MMOFlags, AAInfo);
8805 uint64_t ScaledOffset = 0;
8806 MachinePointerInfo MPI =
LD->getPointerInfo();
8812 for (EVT MemVT : MemVTs) {
8813 Align NewAlign = ScaledOffset == 0
8814 ?
LD->getBaseAlign()
8817 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8825 unsigned End = LdOps.
size();
8836 EVT LdTy = LdOps[i].getValueType();
8839 for (--i; i >= 0; --i) {
8840 LdTy = LdOps[i].getValueType();
8847 ConcatOps[--Idx] = LdOps[i];
8848 for (--i; i >= 0; --i) {
8849 EVT NewLdTy = LdOps[i].getValueType();
8850 if (NewLdTy != LdTy) {
8860 for (;
j != End-Idx; ++
j)
8861 WidenOps[j] = ConcatOps[Idx+j];
8863 WidenOps[j] = DAG.getPOISON(LdTy);
8870 ConcatOps[--Idx] = LdOps[i];
8875 ArrayRef(&ConcatOps[Idx], End - Idx));
8881 SDValue UndefVal = DAG.getPOISON(LdTy);
8884 for (; i != End-Idx; ++i)
8885 WidenOps[i] = ConcatOps[Idx+i];
8887 WidenOps[i] = UndefVal;
8898 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8899 EVT LdVT =
LD->getMemoryVT();
8908 AAMDNodes AAInfo =
LD->getAAInfo();
8922 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8923 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8929 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8930 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8931 LD->getBaseAlign(), MMOFlags, AAInfo);
8936 SDValue UndefVal = DAG.getPOISON(EltVT);
8937 for (; i != WidenNumElts; ++i)
8940 return DAG.getBuildVector(WidenVT, dl,
Ops);
8951 AAMDNodes AAInfo =
ST->getAAInfo();
8952 SDValue ValOp = GetWidenedVector(
ST->getValue());
8955 EVT StVT =
ST->getMemoryVT();
8963 "Mismatch between store and value types");
8967 MachinePointerInfo MPI =
ST->getPointerInfo();
8968 uint64_t ScaledOffset = 0;
8977 std::optional<EVT> NewVT =
8982 TypeSize NewVTWidth = NewVT->getSizeInBits();
8985 StWidth -= NewVTWidth;
8986 MemVTs.
back().second++;
8990 for (
const auto &Pair : MemVTs) {
8991 EVT NewVT = Pair.first;
8992 unsigned Count = Pair.second;
8998 Align NewAlign = ScaledOffset == 0
8999 ?
ST->getBaseAlign()
9001 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9002 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9018 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9019 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9020 ST->getBaseAlign(), MMOFlags, AAInfo);
9037 bool FillWithZeroes) {
9042 "input and widen element type must match");
9044 "cannot modify scalable vectors in this way");
9057 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9059 for (
unsigned i = 1; i != NumConcat; ++i)
9066 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9069 "Scalable vectors should have been handled already.");
9077 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9079 for (Idx = 0; Idx < MinNumElts; ++Idx)
9080 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9082 SDValue UndefVal = DAG.getPOISON(EltVT);
9083 for (; Idx < WidenNumElts; ++Idx)
9084 Ops[Idx] = UndefVal;
9086 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9087 if (!FillWithZeroes)
9091 "We expect to never want to FillWithZeroes for non-integral types.");
9094 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9095 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9097 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9098 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.