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);
905 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
908 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
911 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
914 Res = ScalarizeVecOp_FP_EXTEND(
N);
931 Res = ScalarizeVecOp_VECREDUCE(
N);
935 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
939 Res = ScalarizeVecOp_CMP(
N);
942 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
946 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
952 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
957 if (!Res.
getNode())
return false;
965 "Invalid operand expansion");
967 ReplaceValueWith(
SDValue(
N, 0), Res);
974 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
976 N->getValueType(0), Elt);
981 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
982 "Fake Use: Unexpected vector type!");
983 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
984 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
990 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
991 "Unexpected vector type!");
992 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
994 N->getValueType(0).getScalarType(), Elt);
1002SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1003 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1004 "Unexpected vector type!");
1005 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1007 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1008 Elt,
N->getOperand(1));
1016SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1017 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1018 "Unexpected vector type!");
1019 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1021 {
N->getValueType(0).getScalarType(), MVT::Other },
1022 {
N->getOperand(0), Elt });
1032 ReplaceValueWith(
SDValue(
N, 0), Res);
1037SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1039 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1040 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1041 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1046SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1050 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1051 SDValue ContainingVec =
N->getOperand(0);
1059SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1060 EVT VT =
N->getValueType(0);
1061 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1073 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1074 EVT VT =
N->getValueType(0);
1076 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1084 assert(
N->getValueType(0).isVector() &&
1085 N->getOperand(0).getValueType().isVector() &&
1086 "Operand types must be vectors");
1087 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1089 EVT VT =
N->getValueType(0);
1090 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1091 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1093 EVT OpVT =
N->getOperand(0).getValueType();
1105 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1111SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1113 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1114 assert(
N->getValueType(0).isVector() &&
1115 N->getOperand(1).getValueType().isVector() &&
1116 "Operand types must be vectors");
1117 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1119 EVT VT =
N->getValueType(0);
1121 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1122 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1125 EVT OpVT =
N->getOperand(1).getValueType();
1129 {Ch, LHS, RHS, CC});
1138 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1143 ReplaceValueWith(
SDValue(
N, 0), Res);
1150 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1151 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1154 if (
N->isTruncatingStore())
1155 return DAG.getTruncStore(
1156 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1157 N->getBasePtr(),
N->getPointerInfo(),
1158 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1159 N->getMemOperand()->getFlags(),
N->getAAInfo());
1161 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1162 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1163 N->getMemOperand()->getFlags(),
N->getAAInfo());
1168SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1169 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1170 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1172 N->getValueType(0).getVectorElementType(), Elt,
1177SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1179 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1180 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1183 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1193 ReplaceValueWith(
SDValue(
N, 0), Res);
1200 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1202 N->getValueType(0).getVectorElementType(), Elt);
1208SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1209 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1212 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1213 {
N->getOperand(0), Elt});
1222 ReplaceValueWith(
SDValue(
N, 0), Res);
1227 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1234SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1240 SDValue Op = GetScalarizedVector(VecOp);
1241 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1242 AccOp,
Op,
N->getFlags());
1246 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1247 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1254SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1262 EVT VT =
N->getValueType(0);
1263 return DAG.getConstant(0, SDLoc(
N), VT);
1270 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1271 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1273 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1274 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1275 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1278SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1279 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1282 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1283 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1292 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1304void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1309 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1312 switch (
N->getOpcode()) {
1315 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1324 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1332 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1348 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1351 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1363 case ISD::VP_LOAD_FF:
1366 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1373 case ISD::VP_GATHER:
1377 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1381 SplitVecRes_SETCC(
N,
Lo,
Hi);
1384 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1391 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1394 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1397 SplitVecRes_VECTOR_INTERLEAVE(
N);
1400 SplitVecRes_VAARG(
N,
Lo,
Hi);
1406 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1413 case ISD::VP_BITREVERSE:
1421 case ISD::VP_CTLZ_ZERO_POISON:
1423 case ISD::VP_CTTZ_ZERO_POISON:
1438 case ISD::VP_FFLOOR:
1443 case ISD::VP_FNEARBYINT:
1448 case ISD::VP_FP_EXTEND:
1450 case ISD::VP_FP_ROUND:
1452 case ISD::VP_FP_TO_SINT:
1454 case ISD::VP_FP_TO_UINT:
1460 case ISD::VP_LLRINT:
1462 case ISD::VP_FROUND:
1464 case ISD::VP_FROUNDEVEN:
1473 case ISD::VP_FROUNDTOZERO:
1475 case ISD::VP_SINT_TO_FP:
1477 case ISD::VP_TRUNCATE:
1479 case ISD::VP_UINT_TO_FP:
1483 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1486 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1492 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1498 case ISD::VP_SIGN_EXTEND:
1499 case ISD::VP_ZERO_EXTEND:
1500 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1522 case ISD::VP_FMINNUM:
1525 case ISD::VP_FMAXNUM:
1527 case ISD::VP_FMINIMUM:
1529 case ISD::VP_FMAXIMUM:
1538 case ISD::OR:
case ISD::VP_OR:
1558 case ISD::VP_FCOPYSIGN:
1559 SplitVecRes_BinOp(
N,
Lo,
Hi);
1565 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1572 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1576 SplitVecRes_CMP(
N,
Lo,
Hi);
1579#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1580 case ISD::STRICT_##DAGN:
1581#include "llvm/IR/ConstrainedOps.def"
1582 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1587 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1596 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1606 SplitVecRes_FIX(
N,
Lo,
Hi);
1608 case ISD::EXPERIMENTAL_VP_SPLICE:
1609 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1611 case ISD::EXPERIMENTAL_VP_REVERSE:
1612 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1618 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1621 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1630void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1632 uint64_t *ScaledOffset) {
1637 SDValue BytesIncrement = DAG.getVScale(
1640 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1642 *ScaledOffset += IncrementSize;
1652std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1653 return SplitMask(Mask, SDLoc(Mask));
1656std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1659 EVT MaskVT =
Mask.getValueType();
1661 GetSplitVector(Mask, MaskLo, MaskHi);
1663 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1664 return std::make_pair(MaskLo, MaskHi);
1669 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1671 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1674 const SDNodeFlags
Flags =
N->getFlags();
1675 unsigned Opcode =
N->getOpcode();
1676 if (
N->getNumOperands() == 2) {
1677 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1678 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1682 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1683 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1686 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1689 std::tie(EVLLo, EVLHi) =
1690 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1693 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1695 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1701 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1703 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1704 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(2));
1707 const SDNodeFlags
Flags =
N->getFlags();
1708 unsigned Opcode =
N->getOpcode();
1709 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1711 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1718 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1720 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1722 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1725 const SDNodeFlags
Flags =
N->getFlags();
1726 unsigned Opcode =
N->getOpcode();
1727 if (
N->getNumOperands() == 3) {
1728 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1729 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1733 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1734 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1737 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1740 std::tie(EVLLo, EVLHi) =
1741 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1744 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1746 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1750 LLVMContext &Ctxt = *DAG.getContext();
1756 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1758 GetSplitVector(
LHS, LHSLo, LHSHi);
1759 GetSplitVector(
RHS, RHSLo, RHSHi);
1761 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1762 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1766 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1767 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1772 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1774 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1778 unsigned Opcode =
N->getOpcode();
1779 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1781 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1790 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1797 switch (getTypeAction(InVT)) {
1811 GetExpandedOp(InOp,
Lo,
Hi);
1812 if (DAG.getDataLayout().isBigEndian())
1822 GetSplitVector(InOp,
Lo,
Hi);
1831 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1840 if (DAG.getDataLayout().isBigEndian())
1843 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1845 if (DAG.getDataLayout().isBigEndian())
1851void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1857 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1860 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1865 unsigned LaneOffset =
1868 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1870 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1877 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1880 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1883 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1888 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1890 unsigned NumSubvectors =
N->getNumOperands() / 2;
1891 if (NumSubvectors == 1) {
1892 Lo =
N->getOperand(0);
1893 Hi =
N->getOperand(1);
1898 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1907void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1914 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1929 GetSplitVector(Vec,
Lo,
Hi);
1932 EVT LoVT =
Lo.getValueType();
1942 if (IdxVal + SubElems <= LoElems) {
1950 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1952 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1958 SDValue WideSubVec = GetWidenedVector(SubVec);
1960 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1968 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1970 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1971 auto &MF = DAG.getMachineFunction();
1975 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1980 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1981 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1985 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1990 MachinePointerInfo MPI =
Load->getPointerInfo();
1991 IncrementPointer(Load, LoVT, MPI, StackPtr);
1994 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
2003 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2008 EVT RHSVT =
RHS.getValueType();
2011 GetSplitVector(
RHS, RHSLo, RHSHi);
2013 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2028 SDValue FpValue =
N->getOperand(0);
2030 GetSplitVector(FpValue, ArgLo, ArgHi);
2032 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2034 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2043 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2047 std::tie(LoVT, HiVT) =
2051 DAG.getValueType(LoVT));
2053 DAG.getValueType(HiVT));
2058 unsigned Opcode =
N->getOpcode();
2065 GetSplitVector(N0, InLo, InHi);
2067 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2072 EVT OutLoVT, OutHiVT;
2073 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2075 assert((2 * OutNumElements) <= InNumElements &&
2076 "Illegal extend vector in reg split");
2085 SmallVector<int, 8> SplitHi(InNumElements, -1);
2086 for (
unsigned i = 0; i != OutNumElements; ++i)
2087 SplitHi[i] = i + OutNumElements;
2088 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2090 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2091 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2096 unsigned NumOps =
N->getNumOperands();
2100 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2110 for (
unsigned i = 1; i <
NumOps; ++i) {
2115 EVT InVT =
Op.getValueType();
2120 GetSplitVector(
Op, OpLo, OpHi);
2122 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2129 EVT LoValueVTs[] = {LoVT, MVT::Other};
2130 EVT HiValueVTs[] = {HiVT, MVT::Other};
2131 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2133 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2139 Lo.getValue(1),
Hi.getValue(1));
2143 ReplaceValueWith(
SDValue(
N, 1), Chain);
2146SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2148 EVT VT =
N->getValueType(0);
2159 else if (NE > ResNE)
2163 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2167 for (i = 0; i !=
NE; ++i) {
2168 Operands[0] = Chain;
2169 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2170 SDValue Operand =
N->getOperand(j);
2174 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2176 Operands[
j] = Operand;
2180 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2188 for (; i < ResNE; ++i)
2189 Scalars.
push_back(DAG.getPOISON(EltVT));
2193 ReplaceValueWith(
SDValue(
N, 1), Chain);
2197 return DAG.getBuildVector(VecVT, dl, Scalars);
2200void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2203 EVT ResVT =
N->getValueType(0);
2204 EVT OvVT =
N->getValueType(1);
2205 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2206 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2207 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2209 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2211 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2212 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2214 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2215 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2218 unsigned Opcode =
N->getOpcode();
2219 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2220 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2222 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2224 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2230 unsigned OtherNo = 1 - ResNo;
2231 EVT OtherVT =
N->getValueType(OtherNo);
2233 SetSplitVector(
SDValue(
N, OtherNo),
2239 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2243void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2249 GetSplitVector(Vec,
Lo,
Hi);
2252 unsigned IdxVal = CIdx->getZExtValue();
2253 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2254 if (IdxVal < LoNumElts) {
2256 Lo.getValueType(),
Lo, Elt, Idx);
2259 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2279 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2281 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2282 auto &MF = DAG.getMachineFunction();
2286 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2291 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2292 Store = DAG.getTruncStore(
2298 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2301 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2305 MachinePointerInfo MPI =
Load->getPointerInfo();
2306 IncrementPointer(Load, LoVT, MPI, StackPtr);
2308 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2311 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2312 if (LoVT !=
Lo.getValueType())
2314 if (HiVT !=
Hi.getValueType())
2322 assert(
N->getValueType(0).isScalableVector() &&
2323 "Only scalable vectors are supported for STEP_VECTOR");
2324 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2345 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2346 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2348 Hi = DAG.getPOISON(HiVT);
2358 "Extended load during type legalization!");
2360 EVT VT =
LD->getValueType(0);
2362 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2370 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2371 Ch, Ptr,
LD->getMemOperand());
2376 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2378 Lo = DAG.getBitcast(LoVT, ExtractLo);
2379 Hi = DAG.getBitcast(HiVT, ExtractHi);
2391 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2397 EVT MemoryVT =
LD->getMemoryVT();
2399 AAMDNodes AAInfo =
LD->getAAInfo();
2401 EVT LoMemVT, HiMemVT;
2402 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2406 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2407 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2408 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2413 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2416 MachinePointerInfo MPI;
2417 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2420 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2429 ReplaceValueWith(
SDValue(LD, 1), Ch);
2434 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2437 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2443 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2444 Align Alignment =
LD->getBaseAlign();
2447 EVT MemoryVT =
LD->getMemoryVT();
2449 EVT LoMemVT, HiMemVT;
2450 bool HiIsEmpty =
false;
2451 std::tie(LoMemVT, HiMemVT) =
2452 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2457 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2460 GetSplitVector(Mask, MaskLo, MaskHi);
2462 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2467 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2469 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2475 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2476 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2484 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2485 LD->isExpandingLoad());
2487 MachinePointerInfo MPI;
2489 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2491 MPI =
LD->getPointerInfo().getWithOffset(
2494 MMO = DAG.getMachineFunction().getMachineMemOperand(
2496 Alignment,
LD->getAAInfo(),
LD->getRanges());
2498 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2499 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2500 LD->isExpandingLoad());
2510 ReplaceValueWith(
SDValue(LD, 1), Ch);
2516 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2520 Align Alignment =
LD->getBaseAlign();
2527 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2530 GetSplitVector(Mask, MaskLo, MaskHi);
2532 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2536 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2538 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2543 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2546 Hi = DAG.getPOISON(HiVT);
2548 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2549 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2555 "Indexed VP strided load during type legalization!");
2557 "Unexpected indexed variable-length load offset");
2562 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2564 EVT LoMemVT, HiMemVT;
2565 bool HiIsEmpty =
false;
2566 std::tie(LoMemVT, HiMemVT) =
2567 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2572 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2575 GetSplitVector(Mask, LoMask, HiMask);
2577 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2581 std::tie(LoEVL, HiEVL) =
2585 Lo = DAG.getStridedLoadVP(
2612 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2619 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2630 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2638 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2643 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2653 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2656 GetSplitVector(Mask, MaskLo, MaskHi);
2658 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2662 EVT LoMemVT, HiMemVT;
2663 bool HiIsEmpty =
false;
2664 std::tie(LoMemVT, HiMemVT) =
2665 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2667 SDValue PassThruLo, PassThruHi;
2669 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2671 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2673 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2677 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2687 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2690 MachinePointerInfo MPI;
2697 MMO = DAG.getMachineFunction().getMachineMemOperand(
2701 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2713 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2721 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2729 }
Ops = [&]() -> Operands {
2731 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2734 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2737 EVT MemoryVT =
N->getMemoryVT();
2738 Align Alignment =
N->getBaseAlign();
2743 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2745 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2748 EVT LoMemVT, HiMemVT;
2750 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2753 if (getTypeAction(
Ops.Index.getValueType()) ==
2755 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2757 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2760 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2762 Alignment,
N->getAAInfo(),
N->getRanges());
2765 SDValue PassThru = MGT->getPassThru();
2766 SDValue PassThruLo, PassThruHi;
2769 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2771 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2776 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2777 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2778 OpsLo, MMO, IndexTy, ExtType);
2780 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2781 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2782 OpsHi, MMO, IndexTy, ExtType);
2786 std::tie(EVLLo, EVLHi) =
2787 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2789 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2790 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2791 MMO, VPGT->getIndexType());
2793 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2794 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2795 MMO, VPGT->getIndexType());
2805 ReplaceValueWith(
SDValue(
N, 1), Ch);
2819 EVT VecVT =
N->getValueType(0);
2821 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2822 bool HasCustomLowering =
false;
2829 HasCustomLowering =
true;
2835 SDValue Passthru =
N->getOperand(2);
2836 if (!HasCustomLowering) {
2837 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2838 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2845 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2846 std::tie(LoMask, HiMask) = SplitMask(Mask);
2848 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2853 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2854 MachineFunction &MF = DAG.getMachineFunction();
2866 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2868 SDValue Chain = DAG.getEntryNode();
2869 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2873 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2878 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2882 assert(
N->getValueType(0).isVector() &&
2883 N->getOperand(0).getValueType().isVector() &&
2884 "Operand types must be vectors");
2888 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2892 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2894 GetSplitVector(
N->getOperand(0), LL, LH);
2896 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2898 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2900 GetSplitVector(
N->getOperand(1), RL, RH);
2902 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2905 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2906 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2908 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2909 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2910 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2911 std::tie(EVLLo, EVLHi) =
2912 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2913 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2915 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2925 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2929 EVT InVT =
N->getOperand(0).getValueType();
2931 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2933 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2935 const SDNodeFlags
Flags =
N->getFlags();
2936 unsigned Opcode =
N->getOpcode();
2937 if (
N->getNumOperands() <= 2) {
2940 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2941 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2943 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2944 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2949 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2950 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2953 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2956 std::tie(EVLLo, EVLHi) =
2957 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2960 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2966 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2970 EVT InVT =
N->getOperand(0).getValueType();
2972 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2974 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2977 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2978 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2979 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2980 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2983void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2988 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2989 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2993 EVT InVT =
N->getOperand(0).getValueType();
2995 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2997 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2999 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3000 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3002 SDNode *HiNode =
Hi.getNode();
3003 SDNode *LoNode =
Lo.getNode();
3006 unsigned OtherNo = 1 - ResNo;
3007 EVT OtherVT =
N->getValueType(OtherNo);
3015 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3022 EVT SrcVT =
N->getOperand(0).getValueType();
3023 EVT DestVT =
N->getValueType(0);
3025 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3042 LLVMContext &Ctx = *DAG.getContext();
3046 EVT SplitLoVT, SplitHiVT;
3047 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3048 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3049 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3050 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3051 N->dump(&DAG);
dbgs() <<
"\n");
3052 if (!
N->isVPOpcode()) {
3055 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3057 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3059 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3060 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3066 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
3067 N->getOperand(1),
N->getOperand(2));
3069 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3072 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3075 std::tie(EVLLo, EVLHi) =
3076 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3078 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
3079 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
3084 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3092 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3093 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3099 return N.getResNo() == 0 &&
3103 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3105 ArrayRef<int>
Mask) {
3108 "Expected build vector node.");
3111 for (
unsigned I = 0;
I < NewElts; ++
I) {
3114 unsigned Idx =
Mask[
I];
3116 Ops[
I] = Input2.getOperand(Idx - NewElts);
3118 Ops[
I] = Input1.getOperand(Idx);
3123 return DAG.getBuildVector(NewVT,
DL,
Ops);
3129 SmallVector<int> OrigMask(
N->getMask());
3131 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3132 &
DL](SmallVectorImpl<int> &
Mask) {
3134 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3135 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3146 for (
auto &
P : ShufflesIdxs) {
3147 if (
P.second.size() < 2)
3151 for (
int &Idx : Mask) {
3154 unsigned SrcRegIdx = Idx / NewElts;
3155 if (Inputs[SrcRegIdx].
isUndef()) {
3163 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3168 Idx = MaskElt % NewElts +
3169 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3175 Inputs[
P.second[0]] =
P.first.first;
3176 Inputs[
P.second[1]] =
P.first.second;
3179 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3182 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3183 for (
int &Idx : Mask) {
3186 unsigned SrcRegIdx = Idx / NewElts;
3187 if (Inputs[SrcRegIdx].
isUndef()) {
3194 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3195 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3198 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3200 if (UsedSubVector.count() > 1) {
3202 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3203 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3205 if (Pairs.
empty() || Pairs.
back().size() == 2)
3207 if (UsedSubVector.test(2 *
I)) {
3208 Pairs.
back().emplace_back(
I, 0);
3210 assert(UsedSubVector.test(2 *
I + 1) &&
3211 "Expected to be used one of the subvectors.");
3212 Pairs.
back().emplace_back(
I, 1);
3215 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3217 for (
int &Idx : Mask) {
3220 unsigned SrcRegIdx = Idx / NewElts;
3222 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3223 return Idxs.front().first == SrcRegIdx ||
3224 Idxs.back().first == SrcRegIdx;
3226 if (It == Pairs.
end())
3228 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3229 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3232 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3233 Inputs[Idxs.front().first] = DAG.
getNode(
3235 Inputs[Idxs.front().first].getValueType(),
3236 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3237 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3246 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3250 if (Shuffle->getOperand(0).getValueType() != NewVT)
3253 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3254 !Shuffle->isSplat()) {
3256 }
else if (!Inputs[
I].hasOneUse() &&
3257 !Shuffle->getOperand(1).isUndef()) {
3259 for (
int &Idx : Mask) {
3262 unsigned SrcRegIdx = Idx / NewElts;
3265 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3270 int OpIdx = MaskElt / NewElts;
3284 if (Shuffle->getOperand(
OpIdx).isUndef())
3286 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3287 if (It == std::end(Inputs))
3289 int FoundOp = std::distance(std::begin(Inputs), It);
3292 for (
int &Idx : Mask) {
3295 unsigned SrcRegIdx = Idx / NewElts;
3298 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3303 int MaskIdx = MaskElt / NewElts;
3304 if (
OpIdx == MaskIdx)
3305 Idx = MaskElt % NewElts + FoundOp * NewElts;
3316 for (
int &Idx : Mask) {
3319 unsigned SrcRegIdx = Idx / NewElts;
3322 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3323 int OpIdx = MaskElt / NewElts;
3326 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3332 TryPeekThroughShufflesInputs(OrigMask);
3334 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3335 NewElts](SmallVectorImpl<int> &
Mask) {
3336 SetVector<SDValue> UniqueInputs;
3337 SetVector<SDValue> UniqueConstantInputs;
3338 for (
const auto &
I : Inputs) {
3340 UniqueConstantInputs.
insert(
I);
3341 else if (!
I.isUndef())
3346 if (UniqueInputs.
size() != std::size(Inputs)) {
3347 auto &&UniqueVec = UniqueInputs.
takeVector();
3348 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3349 unsigned ConstNum = UniqueConstantVec.size();
3350 for (
int &Idx : Mask) {
3353 unsigned SrcRegIdx = Idx / NewElts;
3354 if (Inputs[SrcRegIdx].
isUndef()) {
3358 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3359 if (It != UniqueConstantVec.end()) {
3360 Idx = (Idx % NewElts) +
3361 NewElts * std::distance(UniqueConstantVec.begin(), It);
3362 assert(Idx >= 0 &&
"Expected defined mask idx.");
3365 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3366 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3367 Idx = (Idx % NewElts) +
3368 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3369 assert(Idx >= 0 &&
"Expected defined mask idx.");
3371 copy(UniqueConstantVec, std::begin(Inputs));
3372 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3375 MakeUniqueInputs(OrigMask);
3377 copy(Inputs, std::begin(OrigInputs));
3383 unsigned FirstMaskIdx =
High * NewElts;
3386 assert(!Output &&
"Expected default initialized initial value.");
3387 TryPeekThroughShufflesInputs(Mask);
3388 MakeUniqueInputs(Mask);
3390 copy(Inputs, std::begin(TmpInputs));
3393 bool SecondIteration =
false;
3394 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3399 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3400 SecondIteration =
true;
3401 return SecondIteration;
3404 Mask, std::size(Inputs), std::size(Inputs),
3406 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3407 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3408 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3410 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3412 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3413 DAG.getPOISON(NewVT), Mask);
3414 Inputs[Idx] = Output;
3416 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3417 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3418 unsigned Idx2,
bool ) {
3419 if (AccumulateResults(Idx1)) {
3422 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3424 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3425 Inputs[Idx2], Mask);
3429 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3431 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3432 TmpInputs[Idx2], Mask);
3434 Inputs[Idx1] = Output;
3436 copy(OrigInputs, std::begin(Inputs));
3441 EVT OVT =
N->getValueType(0);
3448 const Align Alignment =
3449 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3451 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3452 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3457 ReplaceValueWith(
SDValue(
N, 1), Chain);
3462 EVT DstVTLo, DstVTHi;
3463 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3467 EVT SrcVT =
N->getOperand(0).getValueType();
3469 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3471 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3473 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3474 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3480 GetSplitVector(
N->getOperand(0), InLo, InHi);
3491 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3492 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3497 EVT VT =
N->getValueType(0);
3504 Align Alignment = DAG.getReducedAlign(VT,
false);
3509 EVT PtrVT =
StackPtr.getValueType();
3510 auto &MF = DAG.getMachineFunction();
3514 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3517 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3523 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3524 DAG.getConstant(1,
DL, PtrVT));
3526 DAG.getConstant(EltWidth,
DL, PtrVT));
3528 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3530 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3531 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3532 DAG.getPOISON(PtrVT), Stride, TrueMask,
3535 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3537 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3542 EVT VT =
N->getValueType(0);
3554 EVL1 = ZExtPromotedInteger(EVL1);
3556 Align Alignment = DAG.getReducedAlign(VT,
false);
3561 EVT PtrVT =
StackPtr.getValueType();
3562 auto &MF = DAG.getMachineFunction();
3566 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3569 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3573 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3574 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3576 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3578 DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr, PoisonPtr, TrueMask,
3582 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3587 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3588 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3590 uint64_t TrailingElts = -
Imm;
3592 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3601 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3605 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3607 DAG.getVectorIdxConstant(0,
DL));
3613void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3621 GetSplitVector(Acc, AccLo, AccHi);
3622 unsigned Opcode =
N->getOpcode();
3634 GetSplitVector(Input1, Input1Lo, Input1Hi);
3635 GetSplitVector(Input2, Input2Lo, Input2Hi);
3638 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3639 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3642void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3650 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3658void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3659 unsigned Factor =
N->getNumOperands();
3662 for (
unsigned i = 0; i != Factor; ++i) {
3664 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3666 Ops[i * 2 + 1] = OpHi;
3677 for (
unsigned i = 0; i != Factor; ++i)
3681void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3682 unsigned Factor =
N->getNumOperands();
3685 for (
unsigned i = 0; i != Factor; ++i) {
3687 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3689 Ops[i + Factor] = OpHi;
3700 for (
unsigned i = 0; i != Factor; ++i) {
3701 unsigned IdxLo = 2 * i;
3702 unsigned IdxHi = 2 * i + 1;
3703 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3704 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3716bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3721 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3724 switch (
N->getOpcode()) {
3727 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3737 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3744 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3746 case ISD::VP_TRUNCATE:
3748 Res = SplitVecOp_TruncateHelper(
N);
3751 case ISD::VP_FP_ROUND:
3754 Res = SplitVecOp_FP_ROUND(
N);
3763 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3770 case ISD::VP_SCATTER:
3774 case ISD::VP_GATHER:
3778 Res = SplitVecOp_VSELECT(
N, OpNo);
3781 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3787 case ISD::VP_SINT_TO_FP:
3788 case ISD::VP_UINT_TO_FP:
3789 if (
N->getValueType(0).bitsLT(
3790 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3791 Res = SplitVecOp_TruncateHelper(
N);
3793 Res = SplitVecOp_UnaryOp(
N);
3797 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3801 case ISD::VP_FP_TO_SINT:
3802 case ISD::VP_FP_TO_UINT:
3815 Res = SplitVecOp_UnaryOp(
N);
3818 Res = SplitVecOp_FPOpDifferentTypes(
N);
3823 Res = SplitVecOp_CMP(
N);
3827 Res = SplitVecOp_FAKE_USE(
N);
3832 Res = SplitVecOp_ExtVecInRegOp(
N);
3850 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3854 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3856 case ISD::VP_REDUCE_FADD:
3857 case ISD::VP_REDUCE_SEQ_FADD:
3858 case ISD::VP_REDUCE_FMUL:
3859 case ISD::VP_REDUCE_SEQ_FMUL:
3860 case ISD::VP_REDUCE_ADD:
3861 case ISD::VP_REDUCE_MUL:
3862 case ISD::VP_REDUCE_AND:
3863 case ISD::VP_REDUCE_OR:
3864 case ISD::VP_REDUCE_XOR:
3865 case ISD::VP_REDUCE_SMAX:
3866 case ISD::VP_REDUCE_SMIN:
3867 case ISD::VP_REDUCE_UMAX:
3868 case ISD::VP_REDUCE_UMIN:
3869 case ISD::VP_REDUCE_FMAX:
3870 case ISD::VP_REDUCE_FMIN:
3871 case ISD::VP_REDUCE_FMAXIMUM:
3872 case ISD::VP_REDUCE_FMINIMUM:
3873 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3877 Res = SplitVecOp_CttzElts(
N);
3879 case ISD::VP_CTTZ_ELTS:
3880 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3881 Res = SplitVecOp_VP_CttzElements(
N);
3884 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3890 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3895 if (!Res.
getNode())
return false;
3902 if (
N->isStrictFPOpcode())
3904 "Invalid operand expansion");
3907 "Invalid operand expansion");
3909 ReplaceValueWith(
SDValue(
N, 0), Res);
3913SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3917 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3919 EVT VT =
N->getValueType(0);
3932 getSetCCResultType(MVT::i1), MVT::i1);
3937 DAG.getElementCount(
DL, VT, SplitEC)),
3941SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3944 assert(OpNo == 0 &&
"Illegal operand must be mask");
3951 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3954 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3955 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3956 "Lo and Hi have differing types");
3959 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3960 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3962 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3963 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3964 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3965 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3975SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3978 assert(OpNo == 1 &&
"Illegal operand must be mask");
3983 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3985 EVT VecVT =
N->getValueType(0);
3989SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3990 EVT ResVT =
N->getValueType(0);
3996 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3997 GetSplitVector(VecOp,
Lo,
Hi);
3999 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4004 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4005 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4009 EVT ResVT =
N->getValueType(0);
4015 SDNodeFlags
Flags =
N->getFlags();
4018 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4019 GetSplitVector(VecOp,
Lo,
Hi);
4021 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4027 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4030SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4031 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4032 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4034 unsigned Opc =
N->getOpcode();
4035 EVT ResVT =
N->getValueType(0);
4041 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4042 GetSplitVector(VecOp,
Lo,
Hi);
4045 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4048 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4050 const SDNodeFlags
Flags =
N->getFlags();
4054 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4059 EVT ResVT =
N->getValueType(0);
4062 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4063 EVT InVT =
Lo.getValueType();
4068 if (
N->isStrictFPOpcode()) {
4069 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4070 {N->getOperand(0), Lo});
4071 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4072 {N->getOperand(0), Hi});
4081 ReplaceValueWith(
SDValue(
N, 1), Ch);
4082 }
else if (
N->getNumOperands() == 3) {
4083 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4084 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4085 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4086 std::tie(EVLLo, EVLHi) =
4087 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4088 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4089 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4091 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4092 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4101 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4111 EVT ResVT =
N->getValueType(0);
4113 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4117 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4123 Lo = BitConvertToInteger(
Lo);
4124 Hi = BitConvertToInteger(
Hi);
4126 if (DAG.getDataLayout().isBigEndian())
4134 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4136 EVT ResVT =
N->getValueType(0);
4144 GetSplitVector(SubVec,
Lo,
Hi);
4153 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4155 return SecondInsertion;
4158SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4165 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4167 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4169 ElementCount IdxVal =
4173 EVT SrcVT =
N->getOperand(0).getValueType();
4192 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4193 LoEltsMin - IdxValMin);
4194 DAG.ExtractVectorElements(
Hi, Elts, 0,
4197 return DAG.getBuildVector(SubVT, dl, Elts);
4201 ElementCount ExtractIdx = IdxVal - LoElts;
4203 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4206 EVT HiVT =
Hi.getValueType();
4208 "Only fixed-vector extracts are supported in this case");
4218 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4219 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4225 "Extracting scalable subvector from fixed-width unsupported");
4233 "subvector from a scalable predicate vector");
4239 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4241 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4242 auto &MF = DAG.getMachineFunction();
4246 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4250 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4253 SubVT, dl, Store, StackPtr,
4257SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4263 uint64_t IdxVal =
Index->getZExtValue();
4266 GetSplitVector(Vec,
Lo,
Hi);
4268 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4270 if (IdxVal < LoElts)
4271 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4274 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4279 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4291 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4297 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4299 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4300 auto &MF = DAG.getMachineFunction();
4303 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4307 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4311 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4313 return DAG.getExtLoad(
4324 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4332 SplitVecRes_Gather(
N,
Lo,
Hi);
4335 ReplaceValueWith(
SDValue(
N, 0), Res);
4340 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4344 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4346 SDValue EVL =
N->getVectorLength();
4348 Align Alignment =
N->getBaseAlign();
4354 GetSplitVector(
Data, DataLo, DataHi);
4356 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4361 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4364 GetSplitVector(Mask, MaskLo, MaskHi);
4366 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4369 EVT MemoryVT =
N->getMemoryVT();
4370 EVT LoMemVT, HiMemVT;
4371 bool HiIsEmpty =
false;
4372 std::tie(LoMemVT, HiMemVT) =
4373 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4377 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4380 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4385 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4386 N->getAddressingMode(),
N->isTruncatingStore(),
4387 N->isCompressingStore());
4393 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4394 N->isCompressingStore());
4396 MachinePointerInfo MPI;
4400 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4405 MMO = DAG.getMachineFunction().getMachineMemOperand(
4407 Alignment,
N->getAAInfo(),
N->getRanges());
4409 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4410 N->getAddressingMode(),
N->isTruncatingStore(),
4411 N->isCompressingStore());
4420 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4421 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4428 GetSplitVector(
Data, LoData, HiData);
4430 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4432 EVT LoMemVT, HiMemVT;
4433 bool HiIsEmpty =
false;
4434 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4440 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4441 else if (getTypeAction(
Mask.getValueType()) ==
4443 GetSplitVector(Mask, LoMask, HiMask);
4445 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4448 std::tie(LoEVL, HiEVL) =
4449 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4453 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4454 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4455 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4466 EVT PtrVT =
N->getBasePtr().getValueType();
4469 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4472 Align Alignment =
N->getBaseAlign();
4477 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4478 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4480 Alignment,
N->getAAInfo(),
N->getRanges());
4483 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4484 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4485 N->isCompressingStore());
4494 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4498 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4501 Align Alignment =
N->getBaseAlign();
4507 GetSplitVector(
Data, DataLo, DataHi);
4509 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4514 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4517 GetSplitVector(Mask, MaskLo, MaskHi);
4519 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4522 EVT MemoryVT =
N->getMemoryVT();
4523 EVT LoMemVT, HiMemVT;
4524 bool HiIsEmpty =
false;
4525 std::tie(LoMemVT, HiMemVT) =
4526 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4529 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4534 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4535 N->getAddressingMode(),
N->isTruncatingStore(),
4536 N->isCompressingStore());
4544 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4545 N->isCompressingStore());
4547 MachinePointerInfo MPI;
4551 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4556 MMO = DAG.getMachineFunction().getMachineMemOperand(
4558 Alignment,
N->getAAInfo(),
N->getRanges());
4560 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4561 N->getAddressingMode(),
N->isTruncatingStore(),
4562 N->isCompressingStore());
4575 EVT MemoryVT =
N->getMemoryVT();
4576 Align Alignment =
N->getBaseAlign();
4583 }
Ops = [&]() -> Operands {
4585 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4589 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4594 EVT LoMemVT, HiMemVT;
4595 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4600 GetSplitVector(
Ops.Data, DataLo, DataHi);
4602 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4607 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4609 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4613 if (getTypeAction(
Ops.Index.getValueType()) ==
4615 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4617 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4621 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4623 Alignment,
N->getAAInfo(),
N->getRanges());
4626 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4628 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4629 MSC->getIndexType(), MSC->isTruncatingStore());
4634 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4635 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4636 MMO, MSC->getIndexType(),
4637 MSC->isTruncatingStore());
4641 std::tie(EVLLo, EVLHi) =
4642 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4644 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4645 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4646 VPSC->getIndexType());
4651 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4652 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4653 VPSC->getIndexType());
4657 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4658 assert(OpNo == 1 &&
"Can only split the stored value");
4661 bool isTruncating =
N->isTruncatingStore();
4664 EVT MemoryVT =
N->getMemoryVT();
4665 Align Alignment =
N->getBaseAlign();
4667 AAMDNodes AAInfo =
N->getAAInfo();
4669 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4671 EVT LoMemVT, HiMemVT;
4672 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4676 return TLI.scalarizeVectorStore(
N, DAG);
4679 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4680 Alignment, MMOFlags, AAInfo);
4682 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4685 MachinePointerInfo MPI;
4686 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4689 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4690 HiMemVT, Alignment, MMOFlags, AAInfo);
4692 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4708 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4714 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4735 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4736 SDValue InVec =
N->getOperand(OpNo);
4738 EVT OutVT =
N->getValueType(0);
4746 EVT LoOutVT, HiOutVT;
4747 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4748 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4753 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4755 return SplitVecOp_UnaryOp(
N);
4764 return SplitVecOp_UnaryOp(
N);
4768 GetSplitVector(InVec, InLoVec, InHiVec);
4774 EVT HalfElementVT = IsFloat ?
4776 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4783 if (
N->isStrictFPOpcode()) {
4784 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4785 {N->getOperand(0), InLoVec});
4786 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4787 {N->getOperand(0), InHiVec});
4793 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4794 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4798 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4806 if (
N->isStrictFPOpcode()) {
4810 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4818 DAG.getTargetConstant(
4819 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4826 assert(
N->getValueType(0).isVector() &&
4827 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4828 "Operand types must be vectors");
4830 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4832 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4833 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4835 EVT VT =
N->getValueType(0);
4836 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4841 }
else if (isStrict) {
4842 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4843 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4844 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4845 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4848 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4850 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4851 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4852 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4853 std::tie(EVLLo, EVLHi) =
4854 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4855 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4856 N->getOperand(2), MaskLo, EVLLo);
4857 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4858 N->getOperand(2), MaskHi, EVLHi);
4866 EVT OpVT =
N->getOperand(0).getValueType();
4869 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4875 EVT ResVT =
N->getValueType(0);
4878 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4879 EVT InVT =
Lo.getValueType();
4884 if (
N->isStrictFPOpcode()) {
4885 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4886 {N->getOperand(0), Lo, N->getOperand(2)});
4887 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4888 {N->getOperand(0), Hi, N->getOperand(2)});
4892 Lo.getValue(1),
Hi.getValue(1));
4893 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4894 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4895 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4896 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4897 std::tie(EVLLo, EVLHi) =
4898 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4899 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4900 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4902 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4903 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
4914SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4917 EVT LHSLoVT, LHSHiVT;
4918 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4920 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4921 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4924 std::tie(LHSLo, LHSHi) =
4925 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4928 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4931 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4937 LLVMContext &Ctxt = *DAG.getContext();
4940 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4941 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4942 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4944 EVT ResVT =
N->getValueType(0);
4949 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4950 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4956 EVT ResVT =
N->getValueType(0);
4959 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4960 EVT InVT =
Lo.getValueType();
4966 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4967 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4974 EVT ResVT =
N->getValueType(0);
4978 GetSplitVector(VecOp,
Lo,
Hi);
4984 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
4986 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
4988 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
4989 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
4994 EVT ResVT =
N->getValueType(0);
4998 GetSplitVector(VecOp,
Lo,
Hi);
5000 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5001 auto [EVLLo, EVLHi] =
5003 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5009 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5011 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5012 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5015SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5026 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5027 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5028 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5029 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5030 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5031 OpsLo, MMO, IndexType);
5032 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5033 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5037SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5040 "Accumulator should already be a legal type, and shouldn't need "
5041 "further splitting");
5044 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5045 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5046 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5047 unsigned Opcode =
N->getOpcode();
5050 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5051 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5058void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5059 unsigned WidenResNo) {
5060 unsigned NumResults =
N->getNumValues();
5061 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5062 if (ResNo == WidenResNo)
5064 EVT ResVT =
N->getValueType(ResNo);
5070 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5071 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5076void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5077 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5080 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5085 auto unrollExpandedOp = [&]() {
5090 EVT VT =
N->getValueType(0);
5091 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5092 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5093 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5095 if (
N->getNumValues() > 1)
5096 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5102 switch (
N->getOpcode()) {
5105 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5113 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5117 Res = WidenVecRes_ADDRSPACECAST(
N);
5124 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5131 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5135 Res = WidenVecRes_ScalarOp(
N);
5140 case ISD::VP_SELECT:
5142 Res = WidenVecRes_Select(
N);
5146 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5148 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5155 case ISD::VP_LOAD_FF:
5158 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5162 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5170 case ISD::VP_GATHER:
5174 Res = WidenVecRes_VECTOR_REVERSE(
N);
5177 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5187 case ISD::OR:
case ISD::VP_OR:
5198 case ISD::VP_FMINNUM:
5201 case ISD::VP_FMAXNUM:
5203 case ISD::VP_FMINIMUM:
5205 case ISD::VP_FMAXIMUM:
5238 case ISD::VP_FCOPYSIGN:
5239 Res = WidenVecRes_Binary(
N);
5246 Res = WidenVecRes_MaskedBinary(
N);
5251 Res = WidenVecRes_CMP(
N);
5257 if (unrollExpandedOp())
5272 Res = WidenVecRes_BinaryCanTrap(
N);
5281 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5284#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5285 case ISD::STRICT_##DAGN:
5286#include "llvm/IR/ConstrainedOps.def"
5287 Res = WidenVecRes_StrictFP(
N);
5296 Res = WidenVecRes_OverflowOp(
N, ResNo);
5300 Res = WidenVecRes_FCOPYSIGN(
N);
5305 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5310 if (!unrollExpandedOp())
5311 Res = WidenVecRes_ExpOp(
N);
5317 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5322 case ISD::VP_FP_EXTEND:
5324 case ISD::VP_FP_ROUND:
5326 case ISD::VP_FP_TO_SINT:
5328 case ISD::VP_FP_TO_UINT:
5330 case ISD::VP_SIGN_EXTEND:
5332 case ISD::VP_SINT_TO_FP:
5333 case ISD::VP_TRUNCATE:
5336 case ISD::VP_UINT_TO_FP:
5338 case ISD::VP_ZERO_EXTEND:
5340 Res = WidenVecRes_Convert(
N);
5345 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5351 case ISD::VP_LLRINT:
5354 Res = WidenVecRes_XROUND(
N);
5380 if (unrollExpandedOp())
5391 case ISD::VP_BITREVERSE:
5397 case ISD::VP_CTLZ_ZERO_POISON:
5403 case ISD::VP_CTTZ_ZERO_POISON:
5408 case ISD::VP_FFLOOR:
5410 case ISD::VP_FNEARBYINT:
5411 case ISD::VP_FROUND:
5412 case ISD::VP_FROUNDEVEN:
5413 case ISD::VP_FROUNDTOZERO:
5418 Res = WidenVecRes_Unary(
N);
5425 Res = WidenVecRes_Ternary(
N);
5431 if (!unrollExpandedOp())
5432 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5439 SetWidenedVector(
SDValue(
N, ResNo), Res);
5445 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5446 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5447 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5448 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5449 if (
N->getNumOperands() == 3)
5450 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5452 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5453 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5457 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5458 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5464 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5465 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5466 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5467 if (
N->getNumOperands() == 2)
5468 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5471 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5472 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5476 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5477 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5482 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5483 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5484 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5487 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5488 Mask = ModifyToType(Mask, WideMaskVT,
true);
5489 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5494 LLVMContext &Ctxt = *DAG.getContext();
5499 EVT OpVT =
LHS.getValueType();
5501 LHS = GetWidenedVector(
LHS);
5502 RHS = GetWidenedVector(
RHS);
5503 OpVT =
LHS.getValueType();
5506 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5509 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5515SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5518 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5519 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5520 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5522 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5531 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5534 if (ConcatEnd == 1) {
5535 VT = ConcatOps[0].getValueType();
5537 return ConcatOps[0];
5540 SDLoc dl(ConcatOps[0]);
5547 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5548 int Idx = ConcatEnd - 1;
5549 VT = ConcatOps[Idx--].getValueType();
5550 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5563 unsigned NumToInsert = ConcatEnd - Idx - 1;
5564 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5566 ConcatOps[Idx+1] = VecOp;
5567 ConcatEnd = Idx + 2;
5573 unsigned RealVals = ConcatEnd - Idx - 1;
5574 unsigned SubConcatEnd = 0;
5575 unsigned SubConcatIdx = Idx + 1;
5576 while (SubConcatEnd < RealVals)
5577 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5578 while (SubConcatEnd < OpsToConcat)
5579 SubConcatOps[SubConcatEnd++] = undefVec;
5581 NextVT, SubConcatOps);
5582 ConcatEnd = SubConcatIdx + 1;
5587 if (ConcatEnd == 1) {
5588 VT = ConcatOps[0].getValueType();
5590 return ConcatOps[0];
5595 if (
NumOps != ConcatEnd ) {
5597 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5598 ConcatOps[j] = UndefVal;
5606 unsigned Opcode =
N->getOpcode();
5608 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5612 const SDNodeFlags
Flags =
N->getFlags();
5613 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5614 NumElts = NumElts / 2;
5618 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5620 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5621 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5622 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5630 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5633 TLI.isTypeLegal(WideMaskVT)) {
5634 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5635 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5636 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5638 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5639 N->getValueType(0).getVectorElementCount());
5640 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5654 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5655 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5656 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5659 unsigned ConcatEnd = 0;
5667 while (CurNumElts != 0) {
5668 while (CurNumElts >= NumElts) {
5669 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5670 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5671 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5673 CurNumElts -= NumElts;
5676 NumElts = NumElts / 2;
5678 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5681 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5682 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5683 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5684 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5695 switch (
N->getOpcode()) {
5698 return WidenVecRes_STRICT_FSETCC(
N);
5705 return WidenVecRes_Convert_StrictFP(
N);
5712 unsigned Opcode =
N->getOpcode();
5714 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5718 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5719 NumElts = NumElts / 2;
5730 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5734 unsigned ConcatEnd = 0;
5741 for (
unsigned i = 1; i < NumOpers; ++i) {
5747 Oper = GetWidenedVector(Oper);
5753 DAG.getPOISON(WideOpVT), Oper,
5754 DAG.getVectorIdxConstant(0, dl));
5766 while (CurNumElts != 0) {
5767 while (CurNumElts >= NumElts) {
5770 for (
unsigned i = 0; i < NumOpers; ++i) {
5773 EVT OpVT =
Op.getValueType();
5778 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5784 EVT OperVT[] = {VT, MVT::Other};
5786 ConcatOps[ConcatEnd++] = Oper;
5789 CurNumElts -= NumElts;
5792 NumElts = NumElts / 2;
5794 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5797 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5800 for (
unsigned i = 0; i < NumOpers; ++i) {
5803 EVT OpVT =
Op.getValueType();
5811 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5813 ConcatOps[ConcatEnd++] = Oper;
5822 if (Chains.
size() == 1)
5823 NewChain = Chains[0];
5826 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5831SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5833 EVT ResVT =
N->getValueType(0);
5834 EVT OvVT =
N->getValueType(1);
5835 EVT WideResVT, WideOvVT;
5840 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5845 WideLHS = GetWidenedVector(
N->getOperand(0));
5846 WideRHS = GetWidenedVector(
N->getOperand(1));
5848 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5857 N->getOperand(0), Zero);
5859 N->getOperand(1), Zero);
5862 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5863 SDNode *WideNode = DAG.getNode(
5864 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5867 unsigned OtherNo = 1 - ResNo;
5868 EVT OtherVT =
N->getValueType(OtherNo);
5875 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5878 return SDValue(WideNode, ResNo);
5882 LLVMContext &Ctx = *DAG.getContext();
5886 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5891 unsigned Opcode =
N->getOpcode();
5892 const SDNodeFlags
Flags =
N->getFlags();
5898 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5900 InOp = ZExtPromotedInteger(InOp);
5911 InOp = GetWidenedVector(
N->getOperand(0));
5914 if (InVTEC == WidenEC) {
5915 if (
N->getNumOperands() == 1)
5916 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5917 if (
N->getNumOperands() == 3) {
5918 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5921 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5923 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5949 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5953 if (TLI.isTypeLegal(InWidenVT)) {
5961 unsigned NumConcat =
5966 if (
N->getNumOperands() == 1)
5967 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5968 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5972 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5974 if (
N->getNumOperands() == 1)
5975 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5976 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5985 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5986 for (
unsigned i=0; i < MinElts; ++i) {
5987 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5988 if (
N->getNumOperands() == 1)
5991 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5994 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5999 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6003 EVT SrcVT = Src.getValueType();
6007 Src = GetWidenedVector(Src);
6008 SrcVT = Src.getValueType();
6015 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6020 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6024 EVT SrcVT = Src.getValueType();
6028 Src = GetWidenedVector(Src);
6029 SrcVT = Src.getValueType();
6036 if (
N->getNumOperands() == 1)
6037 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6039 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6040 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6044 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6047SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6052 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6058 unsigned Opcode =
N->getOpcode();
6064 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6069 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6070 for (
unsigned i=0; i < MinElts; ++i) {
6071 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6072 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6076 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6078 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6081SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6082 unsigned Opcode =
N->getOpcode();
6086 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6095 InOp = GetWidenedVector(InOp);
6102 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6109 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6110 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6127 while (
Ops.size() != WidenNumElts)
6128 Ops.push_back(DAG.getPOISON(WidenSVT));
6130 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6136 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6137 return WidenVecRes_BinaryCanTrap(
N);
6140 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6147SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6149 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6152 SDValue Arg = GetWidenedVector(FpValue);
6153 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6158 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6159 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6161 EVT ExpVT =
RHS.getValueType();
6166 ExpOp = ModifyToType(
RHS, WideExpVT);
6169 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6174 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6175 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6176 if (
N->getNumOperands() == 1)
6177 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6179 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6180 N->getOperand(1),
N->getFlags());
6182 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6183 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6187 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6188 {InOp,
Mask,
N->getOperand(2)});
6192 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6197 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6198 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6199 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6202SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6204 EVT VT0 =
N->getValueType(0);
6205 EVT VT1 =
N->getValueType(1);
6209 "expected both results to be vectors of matching element count");
6211 LLVMContext &Ctx = *DAG.getContext();
6212 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6214 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6221 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6224 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6225 return SDValue(WidenNode, ResNo);
6228SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6229 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6230 return GetWidenedVector(WidenVec);
6234 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6235 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6238 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6239 AddrSpaceCastN->getSrcAddressSpace(),
6240 AddrSpaceCastN->getDestAddressSpace());
6246 EVT VT =
N->getValueType(0);
6247 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6250 switch (getTypeAction(InVT)) {
6264 SDValue NInOp = GetPromotedInteger(InOp);
6266 if (WidenVT.
bitsEq(NInVT)) {
6269 if (DAG.getDataLayout().isBigEndian()) {
6272 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6290 InOp = GetWidenedVector(InOp);
6292 if (WidenVT.
bitsEq(InVT))
6302 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6307 unsigned NewNumParts = WidenSize / InSize;
6320 EVT OrigInVT =
N->getOperand(0).getValueType();
6325 if (TLI.isTypeLegal(NewInVT)) {
6333 if (WidenSize % InSize == 0) {
6340 DAG.ExtractVectorElements(InOp,
Ops);
6341 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6353 return CreateStackStoreLoad(InOp, WidenVT);
6356SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6358 N->getOpcode(), SDLoc(
N),
6359 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6360 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6366 EVT VT =
N->getValueType(0);
6370 EVT EltVT =
N->getOperand(0).getValueType();
6373 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6377 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6378 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6380 return DAG.getBuildVector(WidenVT, dl, NewOps);
6384 EVT InVT =
N->getOperand(0).getValueType();
6385 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6387 unsigned NumOperands =
N->getNumOperands();
6389 bool InputWidened =
false;
6393 if (WidenNumElts % NumInElts == 0) {
6395 unsigned NumConcat = WidenNumElts / NumInElts;
6396 SDValue UndefVal = DAG.getPOISON(InVT);
6398 for (
unsigned i=0; i < NumOperands; ++i)
6399 Ops[i] =
N->getOperand(i);
6400 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6405 InputWidened =
true;
6406 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6409 for (i=1; i < NumOperands; ++i)
6410 if (!
N->getOperand(i).isUndef())
6413 if (i == NumOperands)
6416 return GetWidenedVector(
N->getOperand(0));
6418 if (NumOperands == 2) {
6420 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6425 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6426 for (
unsigned i = 0; i < NumInElts; ++i) {
6428 MaskOps[i + NumInElts] = i + WidenNumElts;
6430 return DAG.getVectorShuffle(WidenVT, dl,
6431 GetWidenedVector(
N->getOperand(0)),
6432 GetWidenedVector(
N->getOperand(1)),
6439 "Cannot use build vectors to widen CONCAT_VECTOR result");
6447 for (
unsigned i=0; i < NumOperands; ++i) {
6450 InOp = GetWidenedVector(InOp);
6451 for (
unsigned j = 0;
j < NumInElts; ++
j)
6452 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6454 SDValue UndefVal = DAG.getPOISON(EltVT);
6455 for (; Idx < WidenNumElts; ++Idx)
6456 Ops[Idx] = UndefVal;
6457 return DAG.getBuildVector(WidenVT, dl,
Ops);
6460SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6461 EVT VT =
N->getValueType(0);
6462 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6463 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6470SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6471 EVT VT =
N->getValueType(0);
6473 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6478 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6480 InOp = GetWidenedVector(InOp);
6486 if (IdxVal == 0 && InVT == WidenVT)
6493 assert(IdxVal % VTNumElts == 0 &&
6494 "Expected Idx to be a multiple of subvector minimum vector length");
6495 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6508 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6509 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6510 "down type's element count");
6517 for (;
I < VTNumElts / GCD; ++
I)
6519 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6520 for (;
I < WidenNumElts / GCD; ++
I)
6528 Align Alignment = DAG.getReducedAlign(InVT,
false);
6530 MachineFunction &MF = DAG.getMachineFunction();
6542 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6549 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6550 return DAG.getMaskedLoad(
6551 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6559 for (i = 0; i < VTNumElts; ++i)
6560 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6562 SDValue UndefVal = DAG.getPOISON(EltVT);
6563 for (; i < WidenNumElts; ++i)
6565 return DAG.getBuildVector(WidenVT, dl,
Ops);
6571 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6576SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6577 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6580 N->getOperand(1),
N->getOperand(2));
6589 "Load width must be less than or equal to first value type width");
6598 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6609 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6610 EVT LdVT =
LD->getMemoryVT();
6614 "Must be scalable");
6616 "Expected equivalent element types");
6624 TypeSize WidthDiff = WidenWidth - LdWidth;
6627 std::optional<EVT> FirstVT =
6628 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6635 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6638 Chain, BasePtr,
LD->getMemOperand());
6642 FirstVTWidth, dl, DAG);
6660 if (!
LD->getMemoryVT().isByteSized()) {
6662 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6664 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6673 EVT VT =
LD->getValueType(0);
6674 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6675 EVT WideMaskVT = getSetCCResultType(WideVT);
6678 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6679 TLI.isTypeLegal(WideMaskVT)) {
6682 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6686 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6687 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6699 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6701 Result = GenWidenVectorLoads(LdChain, LD);
6708 if (LdChain.
size() == 1)
6709 NewChain = LdChain[0];
6715 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6726 SDValue NewLoad = DAG.getMaskedLoad(
6727 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6728 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6729 LD->getAddressingMode(),
LD->getExtensionType());
6739 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6741 SDValue EVL =
N->getVectorLength();
6748 "Unable to widen binary VP op");
6749 Mask = GetWidenedVector(Mask);
6750 assert(
Mask.getValueType().getVectorElementCount() ==
6751 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6752 .getVectorElementCount() &&
6753 "Unable to widen vector load");
6756 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6757 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6758 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6766 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6768 SDValue EVL =
N->getVectorLength();
6774 "Unable to widen binary VP op");
6775 Mask = GetWidenedVector(Mask);
6776 assert(
Mask.getValueType().getVectorElementCount() ==
6777 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6778 .getVectorElementCount() &&
6779 "Unable to widen vector load");
6781 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6782 Mask, EVL,
N->getMemOperand());
6795 "Unable to widen VP strided load");
6796 Mask = GetWidenedVector(Mask);
6798 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6799 assert(
Mask.getValueType().getVectorElementCount() ==
6801 "Data and mask vectors should have the same number of elements");
6803 SDValue Res = DAG.getStridedLoadVP(
6804 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6805 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6806 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6807 N->isExpandingLoad());
6815SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6820 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6822 Mask.getValueType().getVectorElementType(),
6825 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6826 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6827 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6829 WideMask, WidePassthru);
6833 EVT VT =
N->getValueType(0);
6834 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6836 EVT MaskVT =
Mask.getValueType();
6837 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6846 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6847 TLI.isTypeLegal(WideMaskVT) &&
6853 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6854 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6858 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6859 N->getMemoryVT(),
N->getMemOperand());
6863 if (!
N->getPassThru()->isUndef()) {
6867 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6868 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6869 DAG.getPOISON(WidenVT), EVL);
6880 Mask = ModifyToType(Mask, WideMaskVT,
true);
6882 SDValue Res = DAG.getMaskedLoad(
6883 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6884 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6885 ExtType,
N->isExpandingLoad());
6894 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6896 EVT MaskVT =
Mask.getValueType();
6897 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6906 Mask = ModifyToType(Mask, WideMaskVT,
true);
6911 Index.getValueType().getScalarType(),
6913 Index = ModifyToType(Index, WideIndexVT);
6919 N->getMemoryVT().getScalarType(), NumElts);
6920 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6921 WideMemVT, dl,
Ops,
N->getMemOperand(),
6922 N->getIndexType(),
N->getExtensionType());
6931 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6939 N->getMemoryVT().getScalarType(), WideEC);
6940 Mask = GetWidenedMask(Mask, WideEC);
6943 Mask,
N->getVectorLength()};
6944 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6945 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6954 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6955 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6983 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6984 return N->getOperand(OpNo).getValueType();
6992 N =
N.getOperand(0);
6994 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6995 if (!
N->getOperand(i)->isUndef())
6997 N =
N.getOperand(0);
7001 N =
N.getOperand(0);
7003 N =
N.getOperand(0);
7030 { MaskVT, MVT::Other },
Ops);
7031 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7039 LLVMContext &Ctx = *DAG.getContext();
7042 if (MaskScalarBits < ToMaskScalBits) {
7046 }
else if (MaskScalarBits > ToMaskScalBits) {
7052 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7054 "Mask should have the right element size by now.");
7057 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7059 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7062 EVT SubVT =
Mask->getValueType(0);
7068 assert((
Mask->getValueType(0) == ToMaskVT) &&
7069 "A mask of ToMaskVT should have been produced by now.");
7079 LLVMContext &Ctx = *DAG.getContext();
7090 EVT CondVT =
Cond->getValueType(0);
7094 EVT VSelVT =
N->getValueType(0);
7106 EVT FinalVT = VSelVT;
7117 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7118 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7125 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7133 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7136 EVT ToMaskVT = VSelVT;
7143 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7159 if (ScalarBits0 != ScalarBits1) {
7160 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7161 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7173 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7174 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7175 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7178 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7186 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7191 unsigned Opcode =
N->getOpcode();
7193 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7194 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7195 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7197 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7203 Cond1 = GetWidenedVector(Cond1);
7211 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7212 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7217 Cond1 = ModifyToType(Cond1, CondWidenVT);
7220 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7221 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7223 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7224 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7226 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7230 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7231 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7234 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7238 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7239 return DAG.getUNDEF(WidenVT);
7243 EVT VT =
N->getValueType(0);
7246 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7250 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7251 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7254 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7255 for (
unsigned i = 0; i != NumElts; ++i) {
7256 int Idx =
N->getMaskElt(i);
7257 if (Idx < (
int)NumElts)
7260 NewMask[i] = Idx - NumElts + WidenNumElts;
7262 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7266 EVT VT =
N->getValueType(0);
7270 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7271 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7277 unsigned IdxVal = WidenNumElts - VTNumElts;
7290 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7293 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7294 "down type's element count");
7297 for (; i < VTNumElts / GCD; ++i)
7299 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7300 for (; i < WidenNumElts / GCD; ++i)
7308 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7309 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7311 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7315SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7316 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7321 assert(
N->getValueType(0).isVector() &&
7322 N->getOperand(0).getValueType().isVector() &&
7323 "Operands must be vectors");
7324 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7337 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7338 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7345 InOp1 = GetWidenedVector(InOp1);
7346 InOp2 = GetWidenedVector(InOp2);
7349 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7360 "Input not widened to expected type!");
7362 if (
N->getOpcode() == ISD::VP_SETCC) {
7365 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7366 N->getOperand(2), Mask,
N->getOperand(4));
7368 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7373 assert(
N->getValueType(0).isVector() &&
7374 N->getOperand(1).getValueType().isVector() &&
7375 "Operands must be vectors");
7376 EVT VT =
N->getValueType(0);
7377 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7387 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7392 for (
unsigned i = 0; i != NumElts; ++i) {
7393 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7394 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7396 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7397 {Chain, LHSElem, RHSElem, CC});
7398 Chains[i] = Scalars[i].getValue(1);
7399 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7400 DAG.getBoolConstant(
true, dl, EltVT, VT),
7401 DAG.getBoolConstant(
false, dl, EltVT, VT));
7405 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7407 return DAG.getBuildVector(WidenVT, dl, Scalars);
7413bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7414 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7418 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7421 switch (
N->getOpcode()) {
7424 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7432 Res = WidenVecOp_FAKE_USE(
N);
7438 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7439 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7440 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7441 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7446 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7448 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7449 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7451 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7452 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7462 Res = WidenVecOp_UnrollVectorOp(
N);
7469 Res = WidenVecOp_EXTEND(
N);
7474 Res = WidenVecOp_CMP(
N);
7491 Res = WidenVecOp_Convert(
N);
7496 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7514 Res = WidenVecOp_VECREDUCE(
N);
7518 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7520 case ISD::VP_REDUCE_FADD:
7521 case ISD::VP_REDUCE_SEQ_FADD:
7522 case ISD::VP_REDUCE_FMUL:
7523 case ISD::VP_REDUCE_SEQ_FMUL:
7524 case ISD::VP_REDUCE_ADD:
7525 case ISD::VP_REDUCE_MUL:
7526 case ISD::VP_REDUCE_AND:
7527 case ISD::VP_REDUCE_OR:
7528 case ISD::VP_REDUCE_XOR:
7529 case ISD::VP_REDUCE_SMAX:
7530 case ISD::VP_REDUCE_SMIN:
7531 case ISD::VP_REDUCE_UMAX:
7532 case ISD::VP_REDUCE_UMIN:
7533 case ISD::VP_REDUCE_FMAX:
7534 case ISD::VP_REDUCE_FMIN:
7535 case ISD::VP_REDUCE_FMAXIMUM:
7536 case ISD::VP_REDUCE_FMINIMUM:
7537 Res = WidenVecOp_VP_REDUCE(
N);
7539 case ISD::VP_CTTZ_ELTS:
7540 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7541 Res = WidenVecOp_VP_CttzElements(
N);
7544 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7549 if (!Res.
getNode())
return false;
7557 if (
N->isStrictFPOpcode())
7559 "Invalid operand expansion");
7562 "Invalid operand expansion");
7564 ReplaceValueWith(
SDValue(
N, 0), Res);
7570 EVT VT =
N->getValueType(0);
7575 "Unexpected type action");
7576 InOp = GetWidenedVector(InOp);
7579 "Input wasn't widened!");
7587 EVT FixedEltVT = FixedVT.getVectorElementType();
7588 if (TLI.isTypeLegal(FixedVT) &&
7590 FixedEltVT == InEltVT) {
7592 "Not enough elements in the fixed type for the operand!");
7594 "We can't have the same type as we started with!");
7596 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7598 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7607 return WidenVecOp_Convert(
N);
7612 switch (
N->getOpcode()) {
7627 EVT OpVT =
N->getOperand(0).getValueType();
7628 EVT ResVT =
N->getValueType(0);
7635 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7636 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7642 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7643 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7645 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7652 return DAG.UnrollVectorOp(
N);
7657 EVT ResultVT =
N->getValueType(0);
7659 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7662 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7668 {WideArg,
Test},
N->getFlags());
7674 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7676 EVT OpVT =
N->getOperand(0).getValueType();
7679 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7684 EVT VT =
N->getValueType(0);
7690 "Unexpected type action");
7691 InOp = GetWidenedVector(InOp);
7693 unsigned Opcode =
N->getOpcode();
7699 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7701 if (
N->isStrictFPOpcode()) {
7703 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7706 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7707 {
N->getOperand(0), InOp });
7713 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7715 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7717 return DAG.getExtractSubvector(dl, VT, Res, 0);
7725 if (
N->isStrictFPOpcode()) {
7728 for (
unsigned i=0; i < NumElts; ++i) {
7729 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7730 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7734 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7736 for (
unsigned i = 0; i < NumElts; ++i) {
7737 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7739 Ops[i] = DAG.
getNode(Opcode, dl, EltVT, Elt,
N->getOperand(1));
7741 Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
7745 return DAG.getBuildVector(VT, dl,
Ops);
7749 EVT DstVT =
N->getValueType(0);
7750 SDValue Src = GetWidenedVector(
N->getOperand(0));
7751 EVT SrcVT = Src.getValueType();
7758 if (TLI.isTypeLegal(WideDstVT)) {
7760 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7763 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7767 return DAG.UnrollVectorOp(
N);
7771 EVT VT =
N->getValueType(0);
7772 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7780 if (!VT.
isVector() && VT != MVT::x86mmx &&
7784 if (TLI.isTypeLegal(NewVT)) {
7786 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7798 ElementCount NewNumElts =
7800 .divideCoefficientBy(EltSize);
7802 if (TLI.isTypeLegal(NewVT)) {
7804 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7809 return CreateStackStoreLoad(InOp, VT);
7817 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7818 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7823 EVT VT =
N->getValueType(0);
7825 EVT InVT =
N->getOperand(0).getValueType();
7830 unsigned NumOperands =
N->getNumOperands();
7831 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7833 for (i = 1; i < NumOperands; ++i)
7834 if (!
N->getOperand(i).isUndef())
7837 if (i == NumOperands)
7838 return GetWidenedVector(
N->getOperand(0));
7848 for (
unsigned i=0; i < NumOperands; ++i) {
7852 "Unexpected type action");
7853 InOp = GetWidenedVector(InOp);
7854 for (
unsigned j = 0;
j < NumInElts; ++
j)
7855 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7857 return DAG.getBuildVector(VT, dl,
Ops);
7860SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7861 EVT VT =
N->getValueType(0);
7866 SubVec = GetWidenedVector(SubVec);
7871 bool IndicesValid =
false;
7874 IndicesValid =
true;
7878 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7879 Attribute::VScaleRange);
7884 IndicesValid =
true;
7890 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7896 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7903 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7910 Align Alignment = DAG.getReducedAlign(VT,
false);
7912 MachineFunction &MF = DAG.getMachineFunction();
7925 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7933 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7934 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7939 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7944 unsigned Idx =
N->getConstantOperandVal(2);
7950 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7956SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7957 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7959 N->getValueType(0), InOp,
N->getOperand(1));
7962SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7963 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7965 N->getValueType(0), InOp,
N->getOperand(1));
7968SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7970 EVT ResVT =
N->getValueType(0);
7973 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
7979 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
7987 "Widened input size must be a multiple of result element size");
7990 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
7992 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
7993 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8001 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8002 return TLI.scalarizeVectorStore(ST, DAG);
8004 if (
ST->isTruncatingStore())
8005 return TLI.scalarizeVectorStore(ST, DAG);
8015 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8016 EVT WideMaskVT = getSetCCResultType(WideVT);
8018 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8019 TLI.isTypeLegal(WideMaskVT)) {
8022 StVal = GetWidenedVector(StVal);
8024 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8026 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8027 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8028 ST->getAddressingMode());
8032 if (GenWidenVectorStores(StChain, ST)) {
8033 if (StChain.
size() == 1)
8042 SDValue WideStVal = GetWidenedVector(StVal);
8046 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8047 ST->getOffset(), Mask,
ST->getMemoryVT(),
8048 ST->getMemOperand(),
ST->getAddressingMode(),
8049 ST->isTruncatingStore());
8055SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8056 assert((OpNo == 1 || OpNo == 3) &&
8057 "Can widen only data or mask operand of vp_store");
8065 StVal = GetWidenedVector(StVal);
8071 "Unable to widen VP store");
8072 Mask = GetWidenedVector(Mask);
8074 Mask = GetWidenedVector(Mask);
8080 "Unable to widen VP store");
8081 StVal = GetWidenedVector(StVal);
8084 assert(
Mask.getValueType().getVectorElementCount() ==
8086 "Mask and data vectors should have the same number of elements");
8087 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8088 ST->getOffset(), Mask,
ST->getVectorLength(),
8089 ST->getMemoryVT(),
ST->getMemOperand(),
8090 ST->getAddressingMode(),
ST->isTruncatingStore(),
8091 ST->isCompressingStore());
8096 assert((OpNo == 1 || OpNo == 4) &&
8097 "Can widen only data or mask operand of vp_strided_store");
8106 "Unable to widen VP strided store");
8110 "Unable to widen VP strided store");
8112 StVal = GetWidenedVector(StVal);
8113 Mask = GetWidenedVector(Mask);
8116 Mask.getValueType().getVectorElementCount() &&
8117 "Data and mask vectors should have the same number of elements");
8119 return DAG.getStridedStoreVP(
8126SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8127 assert((OpNo == 1 || OpNo == 4) &&
8128 "Can widen only data or mask operand of mstore");
8131 EVT MaskVT =
Mask.getValueType();
8136 EVT WideVT, WideMaskVT;
8139 StVal = GetWidenedVector(StVal);
8146 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8153 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8155 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8156 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8165 Mask = ModifyToType(Mask, WideMaskVT,
true);
8168 Mask = ModifyToType(Mask, WideMaskVT,
true);
8170 StVal = ModifyToType(StVal, WideVT);
8173 assert(
Mask.getValueType().getVectorElementCount() ==
8175 "Mask and data vectors should have the same number of elements");
8182SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8183 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8185 SDValue DataOp = MG->getPassThru();
8187 SDValue Scale = MG->getScale();
8195 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8196 MG->getMemOperand(), MG->getIndexType(),
8197 MG->getExtensionType());
8203SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8212 DataOp = GetWidenedVector(DataOp);
8216 EVT IndexVT =
Index.getValueType();
8219 Index = ModifyToType(Index, WideIndexVT);
8222 EVT MaskVT =
Mask.getValueType();
8225 Mask = ModifyToType(Mask, WideMaskVT,
true);
8230 }
else if (OpNo == 4) {
8232 Index = GetWidenedVector(Index);
8238 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8243SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8252 DataOp = GetWidenedVector(DataOp);
8253 Index = GetWidenedVector(Index);
8255 Mask = GetWidenedMask(Mask, WideEC);
8258 }
else if (OpNo == 3) {
8260 Index = GetWidenedVector(Index);
8267 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8272 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8273 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8275 EVT VT =
N->getValueType(0);
8290 SVT, InOp0, InOp1,
N->getOperand(2));
8296 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8298 EVT OpVT =
N->getOperand(0).getValueType();
8301 return DAG.getNode(ExtendCode, dl, VT, CC);
8311 EVT VT =
N->getValueType(0);
8313 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8320 for (
unsigned i = 0; i != NumElts; ++i) {
8321 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8322 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8324 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8325 {Chain, LHSElem, RHSElem, CC});
8326 Chains[i] = Scalars[i].getValue(1);
8327 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8328 DAG.getBoolConstant(
true, dl, EltVT, VT),
8329 DAG.getBoolConstant(
false, dl, EltVT, VT));
8333 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8335 return DAG.getBuildVector(VT, dl, Scalars);
8359 SDValue Op = GetWidenedVector(
N->getOperand(0));
8360 EVT VT =
N->getValueType(0);
8361 EVT OrigVT =
N->getOperand(0).getValueType();
8362 EVT WideVT =
Op.getValueType();
8364 SDNodeFlags
Flags =
N->getFlags();
8366 unsigned Opc =
N->getOpcode();
8368 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8369 assert(NeutralElem &&
"Neutral element must exist");
8379 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8386 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8387 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8393 unsigned GCD = std::gcd(OrigElts, WideElts);
8396 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8397 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8398 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8399 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8402 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8403 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8405 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8414 EVT VT =
N->getValueType(0);
8416 EVT WideVT =
Op.getValueType();
8418 SDNodeFlags
Flags =
N->getFlags();
8420 unsigned Opc =
N->getOpcode();
8422 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8432 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8435 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8436 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8442 unsigned GCD = std::gcd(OrigElts, WideElts);
8445 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8446 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8447 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8448 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8451 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8452 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8454 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8458 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8461 SDValue Op = GetWidenedVector(
N->getOperand(1));
8463 Op.getValueType().getVectorElementCount());
8465 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8466 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8474 EVT VT =
N->getValueType(0);
8478 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8479 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8484 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8490 EVT SrcVT =
Source.getValueType();
8494 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8495 {Source, Mask, N->getOperand(2)},
N->getFlags());
8498SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8501 EVT OrigMaskVT =
Mask.getValueType();
8502 SDValue WideMask = GetWidenedVector(Mask);
8508 if (OrigElts != WideElts) {
8509 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8511 Mask, DAG.getVectorIdxConstant(0,
DL));
8532 unsigned WidenEx = 0) {
8537 unsigned AlignInBits =
Align*8;
8539 EVT RetVT = WidenEltVT;
8544 if (Width == WidenEltWidth)
8555 (WidenWidth % MemVTWidth) == 0 &&
8557 (MemVTWidth <= Width ||
8558 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8559 if (MemVTWidth == WidenWidth)
8578 (WidenWidth % MemVTWidth) == 0 &&
8580 (MemVTWidth <= Width ||
8581 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8590 return std::nullopt;
8601 unsigned Start,
unsigned End) {
8602 SDLoc dl(LdOps[Start]);
8603 EVT LdTy = LdOps[Start].getValueType();
8611 for (
unsigned i = Start + 1; i != End; ++i) {
8612 EVT NewLdTy = LdOps[i].getValueType();
8613 if (NewLdTy != LdTy) {
8632 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8633 EVT LdVT =
LD->getMemoryVT();
8643 AAMDNodes AAInfo =
LD->getAAInfo();
8647 TypeSize WidthDiff = WidenWidth - LdWidth;
8654 std::optional<EVT> FirstVT =
8655 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8662 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8667 std::optional<EVT> NewVT = FirstVT;
8668 TypeSize RemainingWidth = LdWidth;
8669 TypeSize NewVTWidth = FirstVTWidth;
8671 RemainingWidth -= NewVTWidth;
8678 NewVTWidth = NewVT->getSizeInBits();
8684 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8685 LD->getBaseAlign(), MMOFlags, AAInfo);
8697 uint64_t ScaledOffset = 0;
8698 MachinePointerInfo MPI =
LD->getPointerInfo();
8704 for (EVT MemVT : MemVTs) {
8705 Align NewAlign = ScaledOffset == 0
8706 ?
LD->getBaseAlign()
8709 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8717 unsigned End = LdOps.
size();
8728 EVT LdTy = LdOps[i].getValueType();
8731 for (--i; i >= 0; --i) {
8732 LdTy = LdOps[i].getValueType();
8739 ConcatOps[--Idx] = LdOps[i];
8740 for (--i; i >= 0; --i) {
8741 EVT NewLdTy = LdOps[i].getValueType();
8742 if (NewLdTy != LdTy) {
8752 for (;
j != End-Idx; ++
j)
8753 WidenOps[j] = ConcatOps[Idx+j];
8755 WidenOps[j] = DAG.getPOISON(LdTy);
8762 ConcatOps[--Idx] = LdOps[i];
8767 ArrayRef(&ConcatOps[Idx], End - Idx));
8773 SDValue UndefVal = DAG.getPOISON(LdTy);
8776 for (; i != End-Idx; ++i)
8777 WidenOps[i] = ConcatOps[Idx+i];
8779 WidenOps[i] = UndefVal;
8790 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8791 EVT LdVT =
LD->getMemoryVT();
8800 AAMDNodes AAInfo =
LD->getAAInfo();
8814 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8815 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8821 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8822 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8823 LD->getBaseAlign(), MMOFlags, AAInfo);
8828 SDValue UndefVal = DAG.getPOISON(EltVT);
8829 for (; i != WidenNumElts; ++i)
8832 return DAG.getBuildVector(WidenVT, dl,
Ops);
8843 AAMDNodes AAInfo =
ST->getAAInfo();
8844 SDValue ValOp = GetWidenedVector(
ST->getValue());
8847 EVT StVT =
ST->getMemoryVT();
8855 "Mismatch between store and value types");
8859 MachinePointerInfo MPI =
ST->getPointerInfo();
8860 uint64_t ScaledOffset = 0;
8869 std::optional<EVT> NewVT =
8874 TypeSize NewVTWidth = NewVT->getSizeInBits();
8877 StWidth -= NewVTWidth;
8878 MemVTs.
back().second++;
8882 for (
const auto &Pair : MemVTs) {
8883 EVT NewVT = Pair.first;
8884 unsigned Count = Pair.second;
8890 Align NewAlign = ScaledOffset == 0
8891 ?
ST->getBaseAlign()
8893 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8894 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8910 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8911 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8912 ST->getBaseAlign(), MMOFlags, AAInfo);
8929 bool FillWithZeroes) {
8934 "input and widen element type must match");
8936 "cannot modify scalable vectors in this way");
8949 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
8951 for (
unsigned i = 1; i != NumConcat; ++i)
8958 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8961 "Scalable vectors should have been handled already.");
8969 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8971 for (Idx = 0; Idx < MinNumElts; ++Idx)
8972 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8974 SDValue UndefVal = DAG.getPOISON(EltVT);
8975 for (; Idx < WidenNumElts; ++Idx)
8976 Ops[Idx] = UndefVal;
8978 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8979 if (!FillWithZeroes)
8983 "We expect to never want to FillWithZeroes for non-integral types.");
8986 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8987 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8989 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8990 DAG.getBuildVector(NVT, dl, MaskOps));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V, bool LookThroughCmp=false)
Returns the "element type" of the given value/instruction V.
This file implements the SmallBitVector class.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ 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.