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);
61 case ISD::BITCAST: R = ScalarizeVecRes_BITCAST(
N);
break;
69 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
78 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
80 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
86 R = ScalarizeVecRes_VecInregOp(
N);
111 case ISD::FNEARBYINT:
114 case ISD::ARITH_FENCE:
122 case ISD::FROUNDEVEN:
137 R = ScalarizeVecRes_UnaryOp(
N);
139 case ISD::ADDRSPACECAST:
140 R = ScalarizeVecRes_ADDRSPACECAST(
N);
146 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
160 case ISD::FMINNUM_IEEE:
161 case ISD::FMAXNUM_IEEE:
164 case ISD::FMINIMUMNUM:
165 case ISD::FMAXIMUMNUM:
200 R = ScalarizeVecRes_BinOp(
N);
205 R = ScalarizeVecRes_CMP(
N);
211 R = ScalarizeVecRes_TernaryOp(
N);
214#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
215 case ISD::STRICT_##DAGN:
216#include "llvm/IR/ConstrainedOps.def"
217 R = ScalarizeVecRes_StrictFPOp(
N);
222 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
231 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
241 R = ScalarizeVecRes_FIX(
N);
247 SetScalarizedVector(
SDValue(
N, ResNo), R);
251 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
252 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
253 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
262 if (getTypeAction(
LHS.getValueType()) ==
264 LHS = GetScalarizedVector(
LHS);
265 RHS = GetScalarizedVector(
RHS);
267 EVT VT =
LHS.getValueType().getVectorElementType();
268 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
269 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
272 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
273 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
277 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
278 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
279 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
280 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
285 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
286 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
293DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
295 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
296 "Unexpected vector type!");
297 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
299 EVT VT0 =
N->getValueType(0);
300 EVT VT1 =
N->getValueType(1);
304 DAG.getNode(
N->getOpcode(), dl,
305 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
309 unsigned OtherNo = 1 - ResNo;
310 EVT OtherVT =
N->getValueType(OtherNo);
312 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
316 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
319 return SDValue(ScalarNode, ResNo);
324 unsigned NumOpers =
N->getNumOperands();
326 EVT ValueVTs[] = {VT, MVT::Other};
335 for (
unsigned i = 1; i < NumOpers; ++i) {
341 Oper = GetScalarizedVector(Oper);
350 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
351 Opers,
N->getFlags());
362 EVT ResVT =
N->getValueType(0);
363 EVT OvVT =
N->getValueType(1);
367 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
368 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
371 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
372 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
373 ScalarLHS = ElemsLHS[0];
374 ScalarRHS = ElemsRHS[0];
377 SDVTList ScalarVTs = DAG.getVTList(
379 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
380 {ScalarLHS, ScalarRHS},
N->getFlags())
384 unsigned OtherNo = 1 - ResNo;
385 EVT OtherVT =
N->getValueType(OtherNo);
387 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
391 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
394 return SDValue(ScalarNode, ResNo);
399 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
400 return GetScalarizedVector(
Op);
403SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
411 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
422 Op = GetScalarizedVector(
Op);
423 EVT NewVT =
N->getValueType(0).getVectorElementType();
424 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
428SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
438SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
440 N->getValueType(0).getVectorElementType(),
441 N->getOperand(0),
N->getOperand(1));
447 EVT OpVT =
Op.getValueType();
451 Op = GetScalarizedVector(
Op);
454 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
457 N->getValueType(0).getVectorElementType(),
Op,
461SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
462 SDValue Op = GetScalarizedVector(
N->getOperand(0));
463 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
467SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
472 if (
Op.getValueType() != EltVT)
479 assert(
N->isUnindexed() &&
"Indexed vector load?");
483 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
484 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
485 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
486 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
498 EVT OpVT =
Op.getValueType();
508 Op = GetScalarizedVector(
Op);
511 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
513 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
519 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
520 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
521 LHS, DAG.getValueType(ExtVT));
528 EVT OpVT =
Op.getValueType();
533 Op = GetScalarizedVector(
Op);
535 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
538 switch (
N->getOpcode()) {
550SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
553 EVT OpVT =
Op.getValueType();
563 Op = GetScalarizedVector(
Op);
566 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
569 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
570 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
571 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
574SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
586 EVT OpVT =
Cond.getValueType();
595 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
598 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
600 TLI.getBooleanContents(
false,
false);
607 if (TLI.getBooleanContents(
false,
false) !=
608 TLI.getBooleanContents(
false,
true)) {
612 EVT OpVT =
Cond->getOperand(0).getValueType();
614 VecBool = TLI.getBooleanContents(OpVT);
619 EVT CondVT =
Cond.getValueType();
620 if (ScalarBool != VecBool) {
621 switch (ScalarBool) {
629 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
636 Cond, DAG.getValueType(MVT::i1));
642 auto BoolVT = getSetCCResultType(CondVT);
643 if (BoolVT.bitsLT(CondVT))
646 return DAG.getSelect(SDLoc(
N),
648 GetScalarizedVector(
N->getOperand(2)));
652 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
653 return DAG.getSelect(SDLoc(
N),
654 LHS.getValueType(),
N->getOperand(0),
LHS,
655 GetScalarizedVector(
N->getOperand(2)));
659 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
661 N->getOperand(0),
N->getOperand(1),
662 LHS, GetScalarizedVector(
N->getOperand(3)),
667 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
670SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
674 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
676 return GetScalarizedVector(
N->getOperand(
Op));
679SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
681 EVT SrcVT = Src.getValueType();
686 Src = GetScalarizedVector(Src);
690 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
692 EVT DstVT =
N->getValueType(0).getVectorElementType();
693 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
697 assert(
N->getValueType(0).isVector() &&
698 N->getOperand(0).getValueType().isVector() &&
699 "Operand types must be vectors");
702 EVT OpVT =
LHS.getValueType();
703 EVT NVT =
N->getValueType(0).getVectorElementType();
708 LHS = GetScalarizedVector(
LHS);
709 RHS = GetScalarizedVector(
RHS);
712 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
713 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
723 return DAG.getNode(ExtendCode,
DL, NVT, Res);
734 Arg = GetScalarizedVector(Arg);
737 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
746 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
753bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
758 switch (
N->getOpcode()) {
761 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
768 Res = ScalarizeVecOp_BITCAST(
N);
771 Res = ScalarizeVecOp_FAKE_USE(
N);
785 Res = ScalarizeVecOp_UnaryOp(
N);
789 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
795 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
798 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
801 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
804 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
807 Res = ScalarizeVecOp_VSELECT(
N);
810 Res = ScalarizeVecOp_VSETCC(
N);
814 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
820 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
823 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
826 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
829 Res = ScalarizeVecOp_FP_EXTEND(
N);
831 case ISD::VECREDUCE_FADD:
832 case ISD::VECREDUCE_FMUL:
833 case ISD::VECREDUCE_ADD:
834 case ISD::VECREDUCE_MUL:
835 case ISD::VECREDUCE_AND:
836 case ISD::VECREDUCE_OR:
837 case ISD::VECREDUCE_XOR:
838 case ISD::VECREDUCE_SMAX:
839 case ISD::VECREDUCE_SMIN:
840 case ISD::VECREDUCE_UMAX:
841 case ISD::VECREDUCE_UMIN:
842 case ISD::VECREDUCE_FMAX:
843 case ISD::VECREDUCE_FMIN:
844 case ISD::VECREDUCE_FMAXIMUM:
845 case ISD::VECREDUCE_FMINIMUM:
846 Res = ScalarizeVecOp_VECREDUCE(
N);
848 case ISD::VECREDUCE_SEQ_FADD:
849 case ISD::VECREDUCE_SEQ_FMUL:
850 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
854 Res = ScalarizeVecOp_CMP(
N);
859 if (!Res.
getNode())
return false;
867 "Invalid operand expansion");
869 ReplaceValueWith(
SDValue(
N, 0), Res);
876 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
877 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
878 N->getValueType(0), Elt);
883 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
884 "Fake Use: Unexpected vector type!");
885 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
886 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
892 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
893 "Unexpected vector type!");
894 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
896 N->getValueType(0).getScalarType(), Elt);
904SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
905 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
906 "Unexpected vector type!");
907 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
909 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
910 Elt,
N->getOperand(1));
918SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
919 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
920 "Unexpected vector type!");
921 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
923 {
N->getValueType(0).getScalarType(), MVT::Other },
924 {
N->getOperand(0), Elt });
934 ReplaceValueWith(
SDValue(
N, 0), Res);
939SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
941 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
942 Ops[i] = GetScalarizedVector(
N->getOperand(i));
943 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
948SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
952 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
953 SDValue ContainingVec =
N->getOperand(0);
961SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
962 EVT VT =
N->getValueType(0);
963 SDValue Res = GetScalarizedVector(
N->getOperand(0));
966 ? DAG.getNode(ISD::FP_EXTEND, SDLoc(
N), VT, Res)
975 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
976 EVT VT =
N->getValueType(0);
978 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
986 assert(
N->getValueType(0).isVector() &&
987 N->getOperand(0).getValueType().isVector() &&
988 "Operand types must be vectors");
989 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
991 EVT VT =
N->getValueType(0);
992 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
993 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
995 EVT OpVT =
N->getOperand(0).getValueType();
1007 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1013SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1015 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1016 assert(
N->getValueType(0).isVector() &&
1017 N->getOperand(1).getValueType().isVector() &&
1018 "Operand types must be vectors");
1019 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1021 EVT VT =
N->getValueType(0);
1023 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1024 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1027 EVT OpVT =
N->getOperand(1).getValueType();
1031 {Ch, LHS, RHS, CC});
1040 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1045 ReplaceValueWith(
SDValue(
N, 0), Res);
1052 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1053 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1056 if (
N->isTruncatingStore())
1057 return DAG.getTruncStore(
1058 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1059 N->getBasePtr(),
N->getPointerInfo(),
1060 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1061 N->getMemOperand()->getFlags(),
N->getAAInfo());
1063 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1064 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1065 N->getMemOperand()->getFlags(),
N->getAAInfo());
1070SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1071 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1072 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1074 N->getValueType(0).getVectorElementType(), Elt,
1079SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1081 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1082 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1084 {
N->getValueType(0).getVectorElementType(),
1095 ReplaceValueWith(
SDValue(
N, 0), Res);
1102 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1104 N->getValueType(0).getVectorElementType(), Elt);
1110SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1111 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1114 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1115 {
N->getOperand(0), Elt});
1124 ReplaceValueWith(
SDValue(
N, 0), Res);
1129 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1136SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1142 SDValue Op = GetScalarizedVector(VecOp);
1143 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1144 AccOp,
Op,
N->getFlags());
1148 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1149 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1164void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1169 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1172 switch (
N->getOpcode()) {
1175 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1184 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1191 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1195 case ISD::BITCAST: SplitVecRes_BITCAST(
N,
Lo,
Hi);
break;
1205 case ISD::EXPERIMENTAL_VP_SPLAT: SplitVecRes_VP_SPLAT(
N,
Lo,
Hi);
break;
1208 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1211 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1220 case ISD::VP_LOAD_FF:
1223 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1230 case ISD::VP_GATHER:
1234 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1238 SplitVecRes_SETCC(
N,
Lo,
Hi);
1241 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1247 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1250 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1253 SplitVecRes_VECTOR_INTERLEAVE(
N);
1256 SplitVecRes_VAARG(
N,
Lo,
Hi);
1262 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1268 case ISD::VP_BITREVERSE:
1276 case ISD::VP_CTLZ_ZERO_UNDEF:
1278 case ISD::VP_CTTZ_ZERO_UNDEF:
1281 case ISD::FABS:
case ISD::VP_FABS:
1293 case ISD::VP_FFLOOR:
1297 case ISD::FNEARBYINT:
1298 case ISD::VP_FNEARBYINT:
1299 case ISD::FNEG:
case ISD::VP_FNEG:
1301 case ISD::ARITH_FENCE:
1302 case ISD::FP_EXTEND:
1303 case ISD::VP_FP_EXTEND:
1305 case ISD::VP_FP_ROUND:
1307 case ISD::VP_FP_TO_SINT:
1309 case ISD::VP_FP_TO_UINT:
1315 case ISD::VP_LLRINT:
1317 case ISD::VP_FROUND:
1318 case ISD::FROUNDEVEN:
1319 case ISD::VP_FROUNDEVEN:
1324 case ISD::FSQRT:
case ISD::VP_SQRT:
1328 case ISD::VP_FROUNDTOZERO:
1330 case ISD::VP_SINT_TO_FP:
1332 case ISD::VP_TRUNCATE:
1334 case ISD::VP_UINT_TO_FP:
1337 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1339 case ISD::ADDRSPACECAST:
1340 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1345 case ISD::FSINCOSPI:
1346 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1352 case ISD::VP_SIGN_EXTEND:
1353 case ISD::VP_ZERO_EXTEND:
1354 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1372 case ISD::FMINNUM_IEEE:
1373 case ISD::VP_FMINNUM:
1375 case ISD::FMAXNUM_IEEE:
1376 case ISD::VP_FMAXNUM:
1378 case ISD::VP_FMINIMUM:
1380 case ISD::VP_FMAXIMUM:
1381 case ISD::FMINIMUMNUM:
1382 case ISD::FMAXIMUMNUM:
1389 case ISD::OR:
case ISD::VP_OR:
1409 case ISD::VP_FCOPYSIGN:
1410 SplitVecRes_BinOp(
N,
Lo,
Hi);
1417 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1421 SplitVecRes_CMP(
N,
Lo,
Hi);
1424#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1425 case ISD::STRICT_##DAGN:
1426#include "llvm/IR/ConstrainedOps.def"
1427 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1432 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1441 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1451 SplitVecRes_FIX(
N,
Lo,
Hi);
1453 case ISD::EXPERIMENTAL_VP_SPLICE:
1454 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1456 case ISD::EXPERIMENTAL_VP_REVERSE:
1457 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1459 case ISD::PARTIAL_REDUCE_UMLA:
1460 case ISD::PARTIAL_REDUCE_SMLA:
1461 case ISD::PARTIAL_REDUCE_SUMLA:
1462 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1464 case ISD::GET_ACTIVE_LANE_MASK:
1465 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1474void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1476 uint64_t *ScaledOffset) {
1481 SDValue BytesIncrement = DAG.getVScale(
1482 DL,
Ptr.getValueType(),
1483 APInt(
Ptr.getValueSizeInBits().getFixedValue(), IncrementSize));
1484 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1486 *ScaledOffset += IncrementSize;
1496std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1497 return SplitMask(Mask, SDLoc(Mask));
1500std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1503 EVT MaskVT =
Mask.getValueType();
1505 GetSplitVector(Mask, MaskLo, MaskHi);
1507 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1508 return std::make_pair(MaskLo, MaskHi);
1513 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1515 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1518 const SDNodeFlags
Flags =
N->getFlags();
1519 unsigned Opcode =
N->getOpcode();
1520 if (
N->getNumOperands() == 2) {
1521 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1522 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1526 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1527 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1530 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1533 std::tie(EVLLo, EVLHi) =
1534 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1537 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1539 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1545 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1547 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1549 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1552 const SDNodeFlags
Flags =
N->getFlags();
1553 unsigned Opcode =
N->getOpcode();
1554 if (
N->getNumOperands() == 3) {
1555 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1556 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1560 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1561 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1564 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1567 std::tie(EVLLo, EVLHi) =
1568 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1571 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1573 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1577 LLVMContext &Ctxt = *DAG.getContext();
1583 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1585 GetSplitVector(
LHS, LHSLo, LHSHi);
1586 GetSplitVector(
RHS, RHSLo, RHSHi);
1588 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1589 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1593 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1594 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1599 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1601 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1605 unsigned Opcode =
N->getOpcode();
1606 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1608 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1617 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1624 switch (getTypeAction(InVT)) {
1639 GetExpandedOp(InOp,
Lo,
Hi);
1640 if (DAG.getDataLayout().isBigEndian())
1642 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1643 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1650 GetSplitVector(InOp,
Lo,
Hi);
1651 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1652 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1659 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1660 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, InLo);
1661 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, InHi);
1668 if (DAG.getDataLayout().isBigEndian())
1671 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1673 if (DAG.getDataLayout().isBigEndian())
1675 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
1676 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
1679void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1683 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1686 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
N->getOperand(2));
1691 ? DAG.getVScale(
DL, MVT::i64, APInt(64,
Offset))
1692 : DAG.getConstant(
Offset,
DL, MVT::i64);
1695 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
N->getOperand(2));
1702 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1705 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1708 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1713 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1715 unsigned NumSubvectors =
N->getNumOperands() / 2;
1716 if (NumSubvectors == 1) {
1717 Lo =
N->getOperand(0);
1718 Hi =
N->getOperand(1);
1723 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1732void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1739 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1754 GetSplitVector(Vec,
Lo,
Hi);
1757 EVT LoVT =
Lo.getValueType();
1767 if (IdxVal + SubElems <= LoElems) {
1775 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1777 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1783 SDValue WideSubVec = GetWidenedVector(SubVec);
1785 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1793 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1795 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1796 auto &MF = DAG.getMachineFunction();
1800 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1805 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1806 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1810 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1815 MachinePointerInfo MPI =
Load->getPointerInfo();
1816 IncrementPointer(Load, LoVT, MPI, StackPtr);
1819 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1828 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1833 EVT RHSVT =
RHS.getValueType();
1836 GetSplitVector(
RHS, RHSLo, RHSHi);
1838 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1853 SDValue FpValue =
N->getOperand(0);
1855 GetSplitVector(FpValue, ArgLo, ArgHi);
1857 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1859 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1868 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1872 std::tie(LoVT, HiVT) =
1876 DAG.getValueType(LoVT));
1878 DAG.getValueType(HiVT));
1883 unsigned Opcode =
N->getOpcode();
1890 GetSplitVector(N0, InLo, InHi);
1892 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1897 EVT OutLoVT, OutHiVT;
1898 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1900 assert((2 * OutNumElements) <= InNumElements &&
1901 "Illegal extend vector in reg split");
1910 SmallVector<int, 8> SplitHi(InNumElements, -1);
1911 for (
unsigned i = 0; i != OutNumElements; ++i)
1912 SplitHi[i] = i + OutNumElements;
1913 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1915 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1916 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1921 unsigned NumOps =
N->getNumOperands();
1925 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1935 for (
unsigned i = 1; i <
NumOps; ++i) {
1940 EVT InVT =
Op.getValueType();
1945 GetSplitVector(
Op, OpLo, OpHi);
1947 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
1954 EVT LoValueVTs[] = {LoVT, MVT::Other};
1955 EVT HiValueVTs[] = {HiVT, MVT::Other};
1956 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1958 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
1964 Lo.getValue(1),
Hi.getValue(1));
1968 ReplaceValueWith(
SDValue(
N, 1), Chain);
1971SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
1973 EVT VT =
N->getValueType(0);
1984 else if (NE > ResNE)
1988 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
1992 for (i = 0; i !=
NE; ++i) {
1994 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
1995 SDValue Operand =
N->getOperand(j);
1999 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2005 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2013 for (; i < ResNE; ++i)
2018 ReplaceValueWith(
SDValue(
N, 1), Chain);
2022 return DAG.getBuildVector(VecVT, dl, Scalars);
2025void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2028 EVT ResVT =
N->getValueType(0);
2029 EVT OvVT =
N->getValueType(1);
2030 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2031 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2032 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2034 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2036 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2037 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2039 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2040 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2043 unsigned Opcode =
N->getOpcode();
2044 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2045 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2047 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2049 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2055 unsigned OtherNo = 1 - ResNo;
2056 EVT OtherVT =
N->getValueType(OtherNo);
2058 SetSplitVector(
SDValue(
N, OtherNo),
2064 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2068void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2074 GetSplitVector(Vec,
Lo,
Hi);
2077 unsigned IdxVal = CIdx->getZExtValue();
2078 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2079 if (IdxVal < LoNumElts) {
2081 Lo.getValueType(),
Lo, Elt, Idx);
2084 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2104 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2106 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2107 auto &MF = DAG.getMachineFunction();
2111 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2116 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2117 Store = DAG.getTruncStore(
2123 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2126 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2130 MachinePointerInfo MPI =
Load->getPointerInfo();
2131 IncrementPointer(Load, LoVT, MPI, StackPtr);
2133 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2136 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2137 if (LoVT !=
Lo.getValueType())
2139 if (HiVT !=
Hi.getValueType())
2147 assert(
N->getValueType(0).isScalableVector() &&
2148 "Only scalable vectors are supported for STEP_VECTOR");
2149 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2170 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2171 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2173 Hi = DAG.getUNDEF(HiVT);
2183 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2184 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
2185 auto [EVLLo, EVLHi] = DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2186 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0), MaskLo, EVLLo);
2187 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
N->getOperand(0), MaskHi, EVLHi);
2195 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2201 EVT MemoryVT =
LD->getMemoryVT();
2203 AAMDNodes AAInfo =
LD->getAAInfo();
2205 EVT LoMemVT, HiMemVT;
2206 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2210 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2211 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2212 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2217 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2220 MachinePointerInfo MPI;
2221 IncrementPointer(LD, LoMemVT, MPI,
Ptr);
2224 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2233 ReplaceValueWith(
SDValue(LD, 1), Ch);
2238 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2241 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2247 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2248 Align Alignment =
LD->getBaseAlign();
2251 EVT MemoryVT =
LD->getMemoryVT();
2253 EVT LoMemVT, HiMemVT;
2254 bool HiIsEmpty =
false;
2255 std::tie(LoMemVT, HiMemVT) =
2256 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2261 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2264 GetSplitVector(Mask, MaskLo, MaskHi);
2266 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2271 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2273 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2279 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch,
Ptr,
Offset,
2280 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2288 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo, dl, LoMemVT, DAG,
2289 LD->isExpandingLoad());
2291 MachinePointerInfo MPI;
2293 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2295 MPI =
LD->getPointerInfo().getWithOffset(
2298 MMO = DAG.getMachineFunction().getMachineMemOperand(
2300 Alignment,
LD->getAAInfo(),
LD->getRanges());
2302 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch,
Ptr,
2303 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2304 LD->isExpandingLoad());
2314 ReplaceValueWith(
SDValue(LD, 1), Ch);
2320 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2324 Align Alignment =
LD->getBaseAlign();
2331 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2334 GetSplitVector(Mask, MaskLo, MaskHi);
2336 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2340 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2342 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2347 Lo = DAG.getLoadFFVP(LoVT, dl, Ch,
Ptr, MaskLo, EVLLo, MMO);
2350 Hi = DAG.getUNDEF(HiVT);
2352 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2353 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2359 "Indexed VP strided load during type legalization!");
2361 "Unexpected indexed variable-length load offset");
2366 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2368 EVT LoMemVT, HiMemVT;
2369 bool HiIsEmpty =
false;
2370 std::tie(LoMemVT, HiMemVT) =
2371 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2376 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2379 GetSplitVector(Mask, LoMask, HiMask);
2381 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2385 std::tie(LoEVL, HiEVL) =
2389 Lo = DAG.getStridedLoadVP(
2416 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2423 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2434 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2442 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2447 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2456 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2459 GetSplitVector(Mask, MaskLo, MaskHi);
2461 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2465 EVT LoMemVT, HiMemVT;
2466 bool HiIsEmpty =
false;
2467 std::tie(LoMemVT, HiMemVT) =
2468 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2470 SDValue PassThruLo, PassThruHi;
2472 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2474 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2476 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2481 Lo = DAG.getMaskedLoad(LoVT, dl, Ch,
Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2491 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo, dl, LoMemVT, DAG,
2494 MachinePointerInfo MPI;
2501 MMO = DAG.getMachineFunction().getMachineMemOperand(
2505 Hi = DAG.getMaskedLoad(HiVT, dl, Ch,
Ptr,
Offset, MaskHi, PassThruHi,
2517 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2525 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2535 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2538 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2541 EVT MemoryVT =
N->getMemoryVT();
2542 Align Alignment =
N->getBaseAlign();
2547 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2549 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2552 EVT LoMemVT, HiMemVT;
2554 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2557 if (getTypeAction(
Ops.Index.getValueType()) ==
2559 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2561 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2564 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2566 Alignment,
N->getAAInfo(),
N->getRanges());
2569 SDValue PassThru = MGT->getPassThru();
2570 SDValue PassThruLo, PassThruHi;
2573 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2575 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2580 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo,
Ptr, IndexLo,
Ops.Scale};
2581 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2582 OpsLo, MMO, IndexTy, ExtType);
2584 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi,
Ptr, IndexHi,
Ops.Scale};
2585 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2586 OpsHi, MMO, IndexTy, ExtType);
2590 std::tie(EVLLo, EVLHi) =
2591 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2593 SDValue OpsLo[] = {Ch,
Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2594 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2595 MMO, VPGT->getIndexType());
2597 SDValue OpsHi[] = {Ch,
Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2598 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2599 MMO, VPGT->getIndexType());
2609 ReplaceValueWith(
SDValue(
N, 1), Ch);
2623 EVT VecVT =
N->getValueType(0);
2625 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2626 bool HasCustomLowering =
false;
2633 HasCustomLowering =
true;
2639 SDValue Passthru =
N->getOperand(2);
2640 if (!HasCustomLowering) {
2641 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2642 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2649 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2650 std::tie(LoMask, HiMask) = SplitMask(Mask);
2652 SDValue UndefPassthru = DAG.getUNDEF(LoVT);
2657 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2658 MachineFunction &MF = DAG.getMachineFunction();
2665 SDValue Offset = DAG.getNode(ISD::VECREDUCE_ADD,
DL, MVT::i32, WideMask);
2666 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2668 SDValue Chain = DAG.getEntryNode();
2669 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2673 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2678 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2682 assert(
N->getValueType(0).isVector() &&
2683 N->getOperand(0).getValueType().isVector() &&
2684 "Operand types must be vectors");
2688 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2692 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2694 GetSplitVector(
N->getOperand(0), LL, LH);
2696 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2698 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2700 GetSplitVector(
N->getOperand(1), RL, RH);
2702 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2705 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2706 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2708 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2709 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2710 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2711 std::tie(EVLLo, EVLHi) =
2712 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2713 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2715 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2725 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2729 EVT InVT =
N->getOperand(0).getValueType();
2731 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2733 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2735 const SDNodeFlags
Flags =
N->getFlags();
2736 unsigned Opcode =
N->getOpcode();
2737 if (
N->getNumOperands() <= 2) {
2739 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2740 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2742 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2743 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2748 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2749 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2752 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2755 std::tie(EVLLo, EVLHi) =
2756 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2759 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2765 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2769 EVT InVT =
N->getOperand(0).getValueType();
2771 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2773 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2776 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2777 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2778 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2779 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2782void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2787 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2788 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2792 EVT InVT =
N->getOperand(0).getValueType();
2794 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2796 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2798 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2799 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2801 SDNode *HiNode =
Hi.getNode();
2802 SDNode *LoNode =
Lo.getNode();
2805 unsigned OtherNo = 1 - ResNo;
2806 EVT OtherVT =
N->getValueType(OtherNo);
2814 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2821 EVT SrcVT =
N->getOperand(0).getValueType();
2822 EVT DestVT =
N->getValueType(0);
2824 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2841 LLVMContext &Ctx = *DAG.getContext();
2845 EVT SplitLoVT, SplitHiVT;
2846 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2847 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2848 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2849 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2850 N->dump(&DAG);
dbgs() <<
"\n");
2851 if (!
N->isVPOpcode()) {
2854 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2856 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2858 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2859 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2865 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2866 N->getOperand(1),
N->getOperand(2));
2868 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2871 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2874 std::tie(EVLLo, EVLHi) =
2875 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2877 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2878 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2883 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2891 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2892 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2898 return N.getResNo() == 0 &&
2902 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2904 ArrayRef<int>
Mask) {
2907 "Expected build vector node.");
2910 for (
unsigned I = 0;
I < NewElts; ++
I) {
2913 unsigned Idx =
Mask[
I];
2915 Ops[
I] = Input2.getOperand(Idx - NewElts);
2917 Ops[
I] = Input1.getOperand(Idx);
2922 return DAG.getBuildVector(NewVT,
DL,
Ops);
2928 SmallVector<int> OrigMask(
N->getMask());
2930 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2931 &
DL](SmallVectorImpl<int> &
Mask) {
2933 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2934 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2945 for (
auto &
P : ShufflesIdxs) {
2946 if (
P.second.size() < 2)
2950 for (
int &Idx : Mask) {
2953 unsigned SrcRegIdx = Idx / NewElts;
2954 if (Inputs[SrcRegIdx].
isUndef()) {
2962 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2967 Idx = MaskElt % NewElts +
2968 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
2974 Inputs[
P.second[0]] =
P.first.first;
2975 Inputs[
P.second[1]] =
P.first.second;
2978 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
2981 SmallBitVector UsedSubVector(2 * std::size(Inputs));
2982 for (
int &Idx : Mask) {
2985 unsigned SrcRegIdx = Idx / NewElts;
2986 if (Inputs[SrcRegIdx].
isUndef()) {
2993 Inputs[SrcRegIdx].getNumOperands() == 2 &&
2994 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
2997 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
2999 if (UsedSubVector.count() > 1) {
3001 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3002 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3004 if (Pairs.
empty() || Pairs.
back().size() == 2)
3006 if (UsedSubVector.test(2 *
I)) {
3007 Pairs.
back().emplace_back(
I, 0);
3009 assert(UsedSubVector.test(2 *
I + 1) &&
3010 "Expected to be used one of the subvectors.");
3011 Pairs.
back().emplace_back(
I, 1);
3014 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3016 for (
int &Idx : Mask) {
3019 unsigned SrcRegIdx = Idx / NewElts;
3021 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3022 return Idxs.front().first == SrcRegIdx ||
3023 Idxs.back().first == SrcRegIdx;
3025 if (It == Pairs.
end())
3027 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3028 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3031 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3032 Inputs[Idxs.front().first] = DAG.
getNode(
3034 Inputs[Idxs.front().first].getValueType(),
3035 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3036 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3045 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3049 if (Shuffle->getOperand(0).getValueType() != NewVT)
3052 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3053 !Shuffle->isSplat()) {
3055 }
else if (!Inputs[
I].hasOneUse() &&
3056 !Shuffle->getOperand(1).isUndef()) {
3058 for (
int &Idx : Mask) {
3061 unsigned SrcRegIdx = Idx / NewElts;
3064 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3069 int OpIdx = MaskElt / NewElts;
3083 if (Shuffle->getOperand(
OpIdx).isUndef())
3085 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3086 if (It == std::end(Inputs))
3088 int FoundOp = std::distance(std::begin(Inputs), It);
3091 for (
int &Idx : Mask) {
3094 unsigned SrcRegIdx = Idx / NewElts;
3097 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3102 int MaskIdx = MaskElt / NewElts;
3103 if (
OpIdx == MaskIdx)
3104 Idx = MaskElt % NewElts + FoundOp * NewElts;
3115 for (
int &Idx : Mask) {
3118 unsigned SrcRegIdx = Idx / NewElts;
3121 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3122 int OpIdx = MaskElt / NewElts;
3125 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3131 TryPeekThroughShufflesInputs(OrigMask);
3133 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3134 NewElts](SmallVectorImpl<int> &
Mask) {
3135 SetVector<SDValue> UniqueInputs;
3136 SetVector<SDValue> UniqueConstantInputs;
3137 for (
const auto &
I : Inputs) {
3139 UniqueConstantInputs.
insert(
I);
3140 else if (!
I.isUndef())
3145 if (UniqueInputs.
size() != std::size(Inputs)) {
3146 auto &&UniqueVec = UniqueInputs.
takeVector();
3147 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3148 unsigned ConstNum = UniqueConstantVec.size();
3149 for (
int &Idx : Mask) {
3152 unsigned SrcRegIdx = Idx / NewElts;
3153 if (Inputs[SrcRegIdx].
isUndef()) {
3157 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3158 if (It != UniqueConstantVec.end()) {
3159 Idx = (Idx % NewElts) +
3160 NewElts * std::distance(UniqueConstantVec.begin(), It);
3161 assert(Idx >= 0 &&
"Expected defined mask idx.");
3164 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3165 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3166 Idx = (Idx % NewElts) +
3167 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3168 assert(Idx >= 0 &&
"Expected defined mask idx.");
3170 copy(UniqueConstantVec, std::begin(Inputs));
3171 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3174 MakeUniqueInputs(OrigMask);
3176 copy(Inputs, std::begin(OrigInputs));
3182 unsigned FirstMaskIdx =
High * NewElts;
3185 assert(!Output &&
"Expected default initialized initial value.");
3186 TryPeekThroughShufflesInputs(Mask);
3187 MakeUniqueInputs(Mask);
3189 copy(Inputs, std::begin(TmpInputs));
3192 bool SecondIteration =
false;
3193 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3198 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3199 SecondIteration =
true;
3200 return SecondIteration;
3203 Mask, std::size(Inputs), std::size(Inputs),
3205 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3206 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3207 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3209 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3211 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3212 DAG.getUNDEF(NewVT), Mask);
3213 Inputs[Idx] = Output;
3215 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3216 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3217 unsigned Idx2,
bool ) {
3218 if (AccumulateResults(Idx1)) {
3221 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3223 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3224 Inputs[Idx2], Mask);
3228 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3230 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3231 TmpInputs[Idx2], Mask);
3233 Inputs[Idx1] = Output;
3235 copy(OrigInputs, std::begin(Inputs));
3240 EVT OVT =
N->getValueType(0);
3247 const Align Alignment =
3248 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3250 Lo = DAG.getVAArg(NVT, dl, Chain,
Ptr, SV, Alignment.
value());
3251 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1),
Ptr, SV, Alignment.
value());
3256 ReplaceValueWith(
SDValue(
N, 1), Chain);
3261 EVT DstVTLo, DstVTHi;
3262 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3266 EVT SrcVT =
N->getOperand(0).getValueType();
3268 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3270 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3272 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3273 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3279 GetSplitVector(
N->getOperand(0), InLo, InHi);
3290 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3291 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3296 EVT VT =
N->getValueType(0);
3303 Align Alignment = DAG.getReducedAlign(VT,
false);
3308 EVT PtrVT =
StackPtr.getValueType();
3309 auto &MF = DAG.getMachineFunction();
3313 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3316 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3322 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3323 DAG.getConstant(1,
DL, PtrVT));
3325 DAG.getConstant(EltWidth,
DL, PtrVT));
3327 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3329 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3330 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3331 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3334 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3336 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3341 EVT VT =
N->getValueType(0);
3353 EVL1 = ZExtPromotedInteger(EVL1);
3355 Align Alignment = DAG.getReducedAlign(VT,
false);
3360 EVT PtrVT =
StackPtr.getValueType();
3361 auto &MF = DAG.getMachineFunction();
3365 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3368 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3372 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3374 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3375 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3376 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3380 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3385 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3386 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3388 uint64_t TrailingElts = -
Imm;
3390 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3399 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3403 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3405 DAG.getVectorIdxConstant(0,
DL));
3411void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3419 std::tie(AccLo, AccHi) = DAG.SplitVector(Acc,
DL);
3420 unsigned Opcode =
N->getOpcode();
3432 std::tie(Input1Lo, Input1Hi) = DAG.SplitVector(Input1,
DL);
3433 std::tie(Input2Lo, Input2Hi) = DAG.SplitVector(Input2,
DL);
3436 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3437 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3440void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3448 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3450 Lo = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, LoVT, Op0, Op1);
3453 Hi = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK,
DL, HiVT, HiStartVal, Op1);
3456void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3457 unsigned Factor =
N->getNumOperands();
3460 for (
unsigned i = 0; i != Factor; ++i) {
3462 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3464 Ops[i * 2 + 1] = OpHi;
3475 for (
unsigned i = 0; i != Factor; ++i)
3479void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3480 unsigned Factor =
N->getNumOperands();
3483 for (
unsigned i = 0; i != Factor; ++i) {
3485 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3487 Ops[i + Factor] = OpHi;
3498 for (
unsigned i = 0; i != Factor; ++i) {
3499 unsigned IdxLo = 2 * i;
3500 unsigned IdxHi = 2 * i + 1;
3501 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3502 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3514bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3519 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3522 switch (
N->getOpcode()) {
3525 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3535 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3536 case ISD::BITCAST: Res = SplitVecOp_BITCAST(
N);
break;
3541 case ISD::VP_TRUNCATE:
3543 Res = SplitVecOp_TruncateHelper(
N);
3546 case ISD::VP_FP_ROUND:
3555 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3562 case ISD::VP_SCATTER:
3566 case ISD::VP_GATHER:
3570 Res = SplitVecOp_VSELECT(
N, OpNo);
3573 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3579 case ISD::VP_SINT_TO_FP:
3580 case ISD::VP_UINT_TO_FP:
3581 if (
N->getValueType(0).bitsLT(
3582 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3583 Res = SplitVecOp_TruncateHelper(
N);
3585 Res = SplitVecOp_UnaryOp(
N);
3589 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3593 case ISD::VP_FP_TO_SINT:
3594 case ISD::VP_FP_TO_UINT:
3598 case ISD::FP_EXTEND:
3607 Res = SplitVecOp_UnaryOp(
N);
3610 Res = SplitVecOp_FPOpDifferentTypes(
N);
3615 Res = SplitVecOp_CMP(
N);
3619 Res = SplitVecOp_FAKE_USE(
N);
3624 Res = SplitVecOp_ExtVecInRegOp(
N);
3627 case ISD::VECREDUCE_FADD:
3628 case ISD::VECREDUCE_FMUL:
3629 case ISD::VECREDUCE_ADD:
3630 case ISD::VECREDUCE_MUL:
3631 case ISD::VECREDUCE_AND:
3632 case ISD::VECREDUCE_OR:
3633 case ISD::VECREDUCE_XOR:
3634 case ISD::VECREDUCE_SMAX:
3635 case ISD::VECREDUCE_SMIN:
3636 case ISD::VECREDUCE_UMAX:
3637 case ISD::VECREDUCE_UMIN:
3638 case ISD::VECREDUCE_FMAX:
3639 case ISD::VECREDUCE_FMIN:
3640 case ISD::VECREDUCE_FMAXIMUM:
3641 case ISD::VECREDUCE_FMINIMUM:
3642 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3644 case ISD::VECREDUCE_SEQ_FADD:
3645 case ISD::VECREDUCE_SEQ_FMUL:
3646 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3648 case ISD::VP_REDUCE_FADD:
3649 case ISD::VP_REDUCE_SEQ_FADD:
3650 case ISD::VP_REDUCE_FMUL:
3651 case ISD::VP_REDUCE_SEQ_FMUL:
3652 case ISD::VP_REDUCE_ADD:
3653 case ISD::VP_REDUCE_MUL:
3654 case ISD::VP_REDUCE_AND:
3655 case ISD::VP_REDUCE_OR:
3656 case ISD::VP_REDUCE_XOR:
3657 case ISD::VP_REDUCE_SMAX:
3658 case ISD::VP_REDUCE_SMIN:
3659 case ISD::VP_REDUCE_UMAX:
3660 case ISD::VP_REDUCE_UMIN:
3661 case ISD::VP_REDUCE_FMAX:
3662 case ISD::VP_REDUCE_FMIN:
3663 case ISD::VP_REDUCE_FMAXIMUM:
3664 case ISD::VP_REDUCE_FMINIMUM:
3665 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3667 case ISD::VP_CTTZ_ELTS:
3668 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3669 Res = SplitVecOp_VP_CttzElements(
N);
3671 case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
3672 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3674 case ISD::PARTIAL_REDUCE_UMLA:
3675 case ISD::PARTIAL_REDUCE_SMLA:
3676 case ISD::PARTIAL_REDUCE_SUMLA:
3677 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3682 if (!Res.
getNode())
return false;
3689 if (
N->isStrictFPOpcode())
3691 "Invalid operand expansion");
3694 "Invalid operand expansion");
3696 ReplaceValueWith(
SDValue(
N, 0), Res);
3700SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3703 assert(OpNo == 0 &&
"Illegal operand must be mask");
3710 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3713 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3714 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3715 "Lo and Hi have differing types");
3718 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3719 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3721 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3722 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3723 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3724 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3734SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3737 assert(OpNo == 1 &&
"Illegal operand must be mask");
3742 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3744 EVT VecVT =
N->getValueType(0);
3748SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3749 EVT ResVT =
N->getValueType(0);
3755 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3756 GetSplitVector(VecOp,
Lo,
Hi);
3758 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3763 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3764 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3768 EVT ResVT =
N->getValueType(0);
3774 SDNodeFlags
Flags =
N->getFlags();
3777 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3778 GetSplitVector(VecOp,
Lo,
Hi);
3780 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3786 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3789SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3790 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3791 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3793 unsigned Opc =
N->getOpcode();
3794 EVT ResVT =
N->getValueType(0);
3800 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3801 GetSplitVector(VecOp,
Lo,
Hi);
3804 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3807 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3809 const SDNodeFlags
Flags =
N->getFlags();
3813 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3818 EVT ResVT =
N->getValueType(0);
3821 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3822 EVT InVT =
Lo.getValueType();
3827 if (
N->isStrictFPOpcode()) {
3828 Lo = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3829 { N->getOperand(0), Lo });
3830 Hi = DAG.getNode(
N->getOpcode(), dl, { OutVT, MVT::Other },
3831 { N->getOperand(0), Hi });
3840 ReplaceValueWith(
SDValue(
N, 1), Ch);
3841 }
else if (
N->getNumOperands() == 3) {
3842 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3843 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3844 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3845 std::tie(EVLLo, EVLHi) =
3846 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3847 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3848 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3850 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3851 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3860 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3862 DAG.
getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
Lo);
3863 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other, Chain,
Hi);
3870 EVT ResVT =
N->getValueType(0);
3872 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3876 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3877 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT,
Lo);
3878 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT,
Hi);
3882 Lo = BitConvertToInteger(
Lo);
3883 Hi = BitConvertToInteger(
Hi);
3885 if (DAG.getDataLayout().isBigEndian())
3888 return DAG.getNode(ISD::BITCAST, dl, ResVT, JoinIntegers(
Lo,
Hi));
3893 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3895 EVT ResVT =
N->getValueType(0);
3903 GetSplitVector(SubVec,
Lo,
Hi);
3912 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3914 return SecondInsertion;
3917SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3924 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3926 uint64_t LoEltsMin =
Lo.getValueType().getVectorMinNumElements();
3931 if (IdxVal < LoEltsMin) {
3933 if (IdxVal + NumResultElts <= LoEltsMin)
3942 DAG.ExtractVectorElements(
Lo, Elts, IdxVal,
3943 LoEltsMin - IdxVal);
3944 DAG.ExtractVectorElements(
Hi, Elts, 0,
3947 return DAG.getBuildVector(SubVT, dl, Elts);
3950 EVT SrcVT =
N->getOperand(0).getValueType();
3952 uint64_t ExtractIdx = IdxVal - LoEltsMin;
3953 if (ExtractIdx % NumResultElts == 0)
3954 return DAG.getExtractSubvector(dl, SubVT,
Hi, ExtractIdx);
3959 EVT HiVT =
Hi.getValueType();
3961 for (
int I = 0;
I !=
static_cast<int>(NumResultElts); ++
I)
3962 Mask[
I] = ExtractIdx +
I;
3965 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
3966 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
3972 "Extracting scalable subvector from fixed-width unsupported");
3980 "subvector from a scalable predicate vector");
3986 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
3988 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
3989 auto &MF = DAG.getMachineFunction();
3993 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
3997 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4000 SubVT, dl, Store, StackPtr,
4004SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4010 uint64_t IdxVal =
Index->getZExtValue();
4013 GetSplitVector(Vec,
Lo,
Hi);
4015 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4017 if (IdxVal < LoElts)
4018 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4021 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4026 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4038 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4044 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4046 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4047 auto &MF = DAG.getMachineFunction();
4050 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4054 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4058 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4060 return DAG.getExtLoad(
4071 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4079 SplitVecRes_Gather(
N,
Lo,
Hi);
4082 ReplaceValueWith(
SDValue(
N, 0), Res);
4087 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4091 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4093 SDValue EVL =
N->getVectorLength();
4095 Align Alignment =
N->getBaseAlign();
4101 GetSplitVector(
Data, DataLo, DataHi);
4103 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4108 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4111 GetSplitVector(Mask, MaskLo, MaskHi);
4113 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4116 EVT MemoryVT =
N->getMemoryVT();
4117 EVT LoMemVT, HiMemVT;
4118 bool HiIsEmpty =
false;
4119 std::tie(LoMemVT, HiMemVT) =
4120 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4124 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4127 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4132 Lo = DAG.getStoreVP(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4133 N->getAddressingMode(),
N->isTruncatingStore(),
4134 N->isCompressingStore());
4140 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo,
DL, LoMemVT, DAG,
4141 N->isCompressingStore());
4143 MachinePointerInfo MPI;
4147 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4152 MMO = DAG.getMachineFunction().getMachineMemOperand(
4154 Alignment,
N->getAAInfo(),
N->getRanges());
4156 Hi = DAG.getStoreVP(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4157 N->getAddressingMode(),
N->isTruncatingStore(),
4158 N->isCompressingStore());
4167 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4168 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4175 GetSplitVector(
Data, LoData, HiData);
4177 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4179 EVT LoMemVT, HiMemVT;
4180 bool HiIsEmpty =
false;
4181 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4187 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4188 else if (getTypeAction(
Mask.getValueType()) ==
4190 GetSplitVector(Mask, LoMask, HiMask);
4192 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4195 std::tie(LoEVL, HiEVL) =
4196 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4200 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4201 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4202 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4213 EVT PtrVT =
N->getBasePtr().getValueType();
4216 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4219 Align Alignment =
N->getBaseAlign();
4224 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4225 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4227 Alignment,
N->getAAInfo(),
N->getRanges());
4230 N->getChain(),
DL, HiData,
Ptr,
N->getOffset(),
N->getStride(), HiMask,
4231 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4232 N->isCompressingStore());
4241 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4245 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4248 Align Alignment =
N->getBaseAlign();
4254 GetSplitVector(
Data, DataLo, DataHi);
4256 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4261 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4264 GetSplitVector(Mask, MaskLo, MaskHi);
4266 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4269 EVT MemoryVT =
N->getMemoryVT();
4270 EVT LoMemVT, HiMemVT;
4271 bool HiIsEmpty =
false;
4272 std::tie(LoMemVT, HiMemVT) =
4273 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4276 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4281 Lo = DAG.getMaskedStore(Ch,
DL, DataLo,
Ptr,
Offset, MaskLo, LoMemVT, MMO,
4282 N->getAddressingMode(),
N->isTruncatingStore(),
4283 N->isCompressingStore());
4291 Ptr = TLI.IncrementMemoryAddress(
Ptr, MaskLo,
DL, LoMemVT, DAG,
4292 N->isCompressingStore());
4294 MachinePointerInfo MPI;
4298 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4303 MMO = DAG.getMachineFunction().getMachineMemOperand(
4305 Alignment,
N->getAAInfo(),
N->getRanges());
4307 Hi = DAG.getMaskedStore(Ch,
DL, DataHi,
Ptr,
Offset, MaskHi, HiMemVT, MMO,
4308 N->getAddressingMode(),
N->isTruncatingStore(),
4309 N->isCompressingStore());
4322 EVT MemoryVT =
N->getMemoryVT();
4323 Align Alignment =
N->getBaseAlign();
4332 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4336 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4341 EVT LoMemVT, HiMemVT;
4342 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4347 GetSplitVector(
Ops.Data, DataLo, DataHi);
4349 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4354 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4356 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4360 if (getTypeAction(
Ops.Index.getValueType()) ==
4362 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4364 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4368 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4370 Alignment,
N->getAAInfo(),
N->getRanges());
4373 SDValue OpsLo[] = {Ch, DataLo, MaskLo,
Ptr, IndexLo,
Ops.Scale};
4375 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4376 MSC->getIndexType(), MSC->isTruncatingStore());
4382 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4383 MMO, MSC->getIndexType(),
4384 MSC->isTruncatingStore());
4388 std::tie(EVLLo, EVLHi) =
4389 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4391 SDValue OpsLo[] = {Ch, DataLo,
Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4392 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4393 VPSC->getIndexType());
4398 SDValue OpsHi[] = {
Lo, DataHi,
Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4399 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4400 VPSC->getIndexType());
4404 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4405 assert(OpNo == 1 &&
"Can only split the stored value");
4408 bool isTruncating =
N->isTruncatingStore();
4411 EVT MemoryVT =
N->getMemoryVT();
4412 Align Alignment =
N->getBaseAlign();
4414 AAMDNodes AAInfo =
N->getAAInfo();
4416 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4418 EVT LoMemVT, HiMemVT;
4419 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4423 return TLI.scalarizeVectorStore(
N, DAG);
4426 Lo = DAG.getTruncStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), LoMemVT,
4427 Alignment, MMOFlags, AAInfo);
4429 Lo = DAG.getStore(Ch,
DL,
Lo,
Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4432 MachinePointerInfo MPI;
4433 IncrementPointer(
N, LoMemVT, MPI,
Ptr);
4436 Hi = DAG.getTruncStore(Ch,
DL,
Hi,
Ptr, MPI,
4437 HiMemVT, Alignment, MMOFlags, AAInfo);
4439 Hi = DAG.getStore(Ch,
DL,
Hi,
Ptr, MPI, Alignment, MMOFlags, AAInfo);
4455 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4461 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4482 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4483 SDValue InVec =
N->getOperand(OpNo);
4485 EVT OutVT =
N->getValueType(0);
4493 EVT LoOutVT, HiOutVT;
4494 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4495 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4500 if (isTypeLegal(LoOutVT) ||
4501 InElementSize <= OutElementSize * 2)
4502 return SplitVecOp_UnaryOp(
N);
4511 return SplitVecOp_UnaryOp(
N);
4515 GetSplitVector(InVec, InLoVec, InHiVec);
4521 EVT HalfElementVT = IsFloat ?
4523 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4530 if (
N->isStrictFPOpcode()) {
4531 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4532 {N->getOperand(0), InLoVec});
4533 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4534 {N->getOperand(0), InHiVec});
4540 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4541 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4545 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4553 if (
N->isStrictFPOpcode()) {
4557 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4565 DAG.getTargetConstant(
4566 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4573 assert(
N->getValueType(0).isVector() &&
4574 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4575 "Operand types must be vectors");
4577 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4579 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4580 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4582 EVT VT =
N->getValueType(0);
4588 }
else if (isStrict) {
4589 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4590 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4591 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4592 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4595 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4597 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4598 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4599 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4600 std::tie(EVLLo, EVLHi) =
4601 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4602 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4603 N->getOperand(2), MaskLo, EVLLo);
4604 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4605 N->getOperand(2), MaskHi, EVLHi);
4614 EVT ResVT =
N->getValueType(0);
4617 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4618 EVT InVT =
Lo.getValueType();
4623 if (
N->isStrictFPOpcode()) {
4624 Lo = DAG.getNode(
N->getOpcode(),
DL, { OutVT, MVT::Other },
4625 { N->getOperand(0), Lo, N->getOperand(2) });
4626 Hi = DAG.getNode(
N->getOpcode(),
DL, { OutVT, MVT::Other },
4627 { N->getOperand(0), Hi, N->getOperand(2) });
4631 Lo.getValue(1),
Hi.getValue(1));
4632 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4633 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4634 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4635 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4636 std::tie(EVLLo, EVLHi) =
4637 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4638 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4639 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4653SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4656 EVT LHSLoVT, LHSHiVT;
4657 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4659 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4660 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4663 std::tie(LHSLo, LHSHi) =
4664 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4667 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4670 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4676 LLVMContext &Ctxt = *DAG.getContext();
4679 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4680 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4681 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4683 EVT ResVT =
N->getValueType(0);
4688 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4689 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4695 EVT ResVT =
N->getValueType(0);
4698 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4699 EVT InVT =
Lo.getValueType();
4705 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4706 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4713 EVT ResVT =
N->getValueType(0);
4717 GetSplitVector(VecOp,
Lo,
Hi);
4719 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4720 auto [EVLLo, EVLHi] =
4722 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4728 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4730 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4731 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4734SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4745 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4746 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4747 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4749 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4750 OpsLo, MMO, IndexType);
4751 SDValue OpsHi[] = {
Lo, Inc, MaskHi,
Ptr, IndexHi, Scale, IntID};
4752 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4756SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4759 "Accumulator should already be a legal type, and shouldn't need "
4760 "further splitting");
4763 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4764 std::tie(Input1Lo, Input1Hi) = DAG.SplitVector(
N->getOperand(1),
DL);
4765 std::tie(Input2Lo, Input2Hi) = DAG.SplitVector(
N->getOperand(2),
DL);
4766 unsigned Opcode =
N->getOpcode();
4769 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4770 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4777void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4778 unsigned WidenResNo) {
4779 unsigned NumResults =
N->getNumValues();
4780 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4781 if (ResNo == WidenResNo)
4783 EVT ResVT =
N->getValueType(ResNo);
4789 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4790 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4795void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4796 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4799 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4804 auto unrollExpandedOp = [&]() {
4809 EVT VT =
N->getValueType(0);
4810 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4811 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4814 if (
N->getNumValues() > 1)
4815 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4821 switch (
N->getOpcode()) {
4824 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4832 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4835 case ISD::ADDRSPACECAST:
4836 Res = WidenVecRes_ADDRSPACECAST(
N);
4839 case ISD::BITCAST: Res = WidenVecRes_BITCAST(
N);
break;
4843 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4847 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4851 case ISD::EXPERIMENTAL_VP_SPLAT:
4852 Res = WidenVecRes_ScalarOp(
N);
4857 case ISD::VP_SELECT:
4859 Res = WidenVecRes_Select(
N);
4863 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4865 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4872 case ISD::VP_LOAD_FF:
4875 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4879 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4887 case ISD::VP_GATHER:
4891 Res = WidenVecRes_VECTOR_REVERSE(
N);
4893 case ISD::GET_ACTIVE_LANE_MASK:
4894 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4904 case ISD::OR:
case ISD::VP_OR:
4911 case ISD::FMINNUM_IEEE:
4912 case ISD::VP_FMINNUM:
4914 case ISD::FMAXNUM_IEEE:
4915 case ISD::VP_FMAXNUM:
4917 case ISD::VP_FMINIMUM:
4919 case ISD::VP_FMAXIMUM:
4920 case ISD::FMINIMUMNUM:
4921 case ISD::FMAXIMUMNUM:
4952 case ISD::VP_FCOPYSIGN:
4953 Res = WidenVecRes_Binary(
N);
4958 Res = WidenVecRes_CMP(
N);
4964 if (unrollExpandedOp())
4979 Res = WidenVecRes_BinaryCanTrap(
N);
4988 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
4991#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
4992 case ISD::STRICT_##DAGN:
4993#include "llvm/IR/ConstrainedOps.def"
4994 Res = WidenVecRes_StrictFP(
N);
5003 Res = WidenVecRes_OverflowOp(
N, ResNo);
5007 Res = WidenVecRes_FCOPYSIGN(
N);
5012 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5017 if (!unrollExpandedOp())
5018 Res = WidenVecRes_ExpOp(
N);
5024 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5028 case ISD::FP_EXTEND:
5029 case ISD::VP_FP_EXTEND:
5031 case ISD::VP_FP_ROUND:
5033 case ISD::VP_FP_TO_SINT:
5035 case ISD::VP_FP_TO_UINT:
5037 case ISD::VP_SIGN_EXTEND:
5039 case ISD::VP_SINT_TO_FP:
5040 case ISD::VP_TRUNCATE:
5043 case ISD::VP_UINT_TO_FP:
5045 case ISD::VP_ZERO_EXTEND:
5046 Res = WidenVecRes_Convert(
N);
5051 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5057 case ISD::VP_LLRINT:
5060 Res = WidenVecRes_XROUND(
N);
5076 case ISD::FNEARBYINT:
5079 case ISD::FROUNDEVEN:
5086 if (unrollExpandedOp())
5096 case ISD::VP_BITREVERSE:
5102 case ISD::VP_CTLZ_ZERO_UNDEF:
5108 case ISD::VP_CTTZ_ZERO_UNDEF:
5109 case ISD::FNEG:
case ISD::VP_FNEG:
5110 case ISD::FABS:
case ISD::VP_FABS:
5113 case ISD::VP_FFLOOR:
5115 case ISD::VP_FNEARBYINT:
5116 case ISD::VP_FROUND:
5117 case ISD::VP_FROUNDEVEN:
5118 case ISD::VP_FROUNDTOZERO:
5120 case ISD::ARITH_FENCE:
5123 Res = WidenVecRes_Unary(
N);
5130 Res = WidenVecRes_Ternary(
N);
5135 case ISD::FSINCOSPI: {
5136 if (!unrollExpandedOp())
5137 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5144 SetWidenedVector(
SDValue(
N, ResNo), Res);
5150 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5151 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5152 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5153 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5154 if (
N->getNumOperands() == 3)
5155 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5157 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5158 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5162 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5163 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5169 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5170 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5171 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5172 if (
N->getNumOperands() == 2)
5173 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5176 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5177 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5181 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5182 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5186 LLVMContext &Ctxt = *DAG.getContext();
5191 EVT OpVT =
LHS.getValueType();
5193 LHS = GetWidenedVector(
LHS);
5194 RHS = GetWidenedVector(
RHS);
5195 OpVT =
LHS.getValueType();
5198 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5201 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5207SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5210 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5211 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5212 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5214 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5223 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5226 if (ConcatEnd == 1) {
5227 VT = ConcatOps[0].getValueType();
5229 return ConcatOps[0];
5232 SDLoc dl(ConcatOps[0]);
5239 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5240 int Idx = ConcatEnd - 1;
5241 VT = ConcatOps[Idx--].getValueType();
5242 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5255 unsigned NumToInsert = ConcatEnd - Idx - 1;
5256 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5258 ConcatOps[Idx+1] = VecOp;
5259 ConcatEnd = Idx + 2;
5265 unsigned RealVals = ConcatEnd - Idx - 1;
5266 unsigned SubConcatEnd = 0;
5267 unsigned SubConcatIdx = Idx + 1;
5268 while (SubConcatEnd < RealVals)
5269 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5270 while (SubConcatEnd < OpsToConcat)
5271 SubConcatOps[SubConcatEnd++] = undefVec;
5273 NextVT, SubConcatOps);
5274 ConcatEnd = SubConcatIdx + 1;
5279 if (ConcatEnd == 1) {
5280 VT = ConcatOps[0].getValueType();
5282 return ConcatOps[0];
5287 if (
NumOps != ConcatEnd ) {
5289 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5290 ConcatOps[j] = UndefVal;
5298 unsigned Opcode =
N->getOpcode();
5300 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5304 const SDNodeFlags
Flags =
N->getFlags();
5305 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5306 NumElts = NumElts / 2;
5310 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5312 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5313 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5314 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5322 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5325 TLI.isTypeLegal(WideMaskVT)) {
5326 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5327 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5328 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5330 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5331 N->getValueType(0).getVectorElementCount());
5332 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5346 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5347 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5348 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5351 unsigned ConcatEnd = 0;
5359 while (CurNumElts != 0) {
5360 while (CurNumElts >= NumElts) {
5361 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5362 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5363 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5365 CurNumElts -= NumElts;
5368 NumElts = NumElts / 2;
5370 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5373 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5374 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5375 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5376 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5387 switch (
N->getOpcode()) {
5390 return WidenVecRes_STRICT_FSETCC(
N);
5397 return WidenVecRes_Convert_StrictFP(
N);
5404 unsigned Opcode =
N->getOpcode();
5406 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5410 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5411 NumElts = NumElts / 2;
5422 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5426 unsigned ConcatEnd = 0;
5433 for (
unsigned i = 1; i < NumOpers; ++i) {
5439 Oper = GetWidenedVector(Oper);
5445 DAG.getUNDEF(WideOpVT), Oper,
5446 DAG.getVectorIdxConstant(0, dl));
5458 while (CurNumElts != 0) {
5459 while (CurNumElts >= NumElts) {
5462 for (
unsigned i = 0; i < NumOpers; ++i) {
5465 EVT OpVT =
Op.getValueType();
5470 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5476 EVT OperVT[] = {VT, MVT::Other};
5478 ConcatOps[ConcatEnd++] = Oper;
5481 CurNumElts -= NumElts;
5484 NumElts = NumElts / 2;
5486 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5489 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5492 for (
unsigned i = 0; i < NumOpers; ++i) {
5495 EVT OpVT =
Op.getValueType();
5503 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5505 ConcatOps[ConcatEnd++] = Oper;
5514 if (Chains.
size() == 1)
5515 NewChain = Chains[0];
5518 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5523SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5525 EVT ResVT =
N->getValueType(0);
5526 EVT OvVT =
N->getValueType(1);
5527 EVT WideResVT, WideOvVT;
5532 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5537 WideLHS = GetWidenedVector(
N->getOperand(0));
5538 WideRHS = GetWidenedVector(
N->getOperand(1));
5540 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5548 N->getOperand(0), Zero);
5551 N->getOperand(1), Zero);
5554 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5555 SDNode *WideNode = DAG.getNode(
5556 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5559 unsigned OtherNo = 1 - ResNo;
5560 EVT OtherVT =
N->getValueType(OtherNo);
5567 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5570 return SDValue(WideNode, ResNo);
5574 LLVMContext &Ctx = *DAG.getContext();
5578 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5583 unsigned Opcode =
N->getOpcode();
5584 const SDNodeFlags
Flags =
N->getFlags();
5590 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5592 InOp = ZExtPromotedInteger(InOp);
5603 InOp = GetWidenedVector(
N->getOperand(0));
5606 if (InVTEC == WidenEC) {
5607 if (
N->getNumOperands() == 1)
5608 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5609 if (
N->getNumOperands() == 3) {
5610 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5613 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5615 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5630 if (TLI.isTypeLegal(InWidenVT)) {
5638 unsigned NumConcat =
5643 if (
N->getNumOperands() == 1)
5644 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5645 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5649 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5651 if (
N->getNumOperands() == 1)
5652 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5653 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5662 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5663 for (
unsigned i=0; i < MinElts; ++i) {
5664 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5665 if (
N->getNumOperands() == 1)
5668 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5671 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5676 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5680 EVT SrcVT = Src.getValueType();
5684 Src = GetWidenedVector(Src);
5685 SrcVT = Src.getValueType();
5692 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5697 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5701 EVT SrcVT = Src.getValueType();
5705 Src = GetWidenedVector(Src);
5706 SrcVT = Src.getValueType();
5713 if (
N->getNumOperands() == 1)
5714 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5716 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5717 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5721 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5724SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5729 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5735 unsigned Opcode =
N->getOpcode();
5741 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5746 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5747 for (
unsigned i=0; i < MinElts; ++i) {
5748 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5749 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5753 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5755 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5758SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5759 unsigned Opcode =
N->getOpcode();
5763 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5772 InOp = GetWidenedVector(InOp);
5779 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5786 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5787 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5804 while (
Ops.size() != WidenNumElts)
5805 Ops.push_back(DAG.getUNDEF(WidenSVT));
5807 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5813 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5814 return WidenVecRes_BinaryCanTrap(
N);
5817 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5824SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5826 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5829 SDValue Arg = GetWidenedVector(FpValue);
5830 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5835 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5836 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5838 EVT ExpVT =
RHS.getValueType();
5843 ExpOp = ModifyToType(
RHS, WideExpVT);
5846 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5851 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5852 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5853 if (
N->getNumOperands() == 1)
5854 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5856 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5857 N->getOperand(1),
N->getFlags());
5859 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5860 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5864 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5865 {InOp,
Mask,
N->getOperand(2)});
5869 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5872 .getVectorElementType(),
5874 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5875 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5876 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5879SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5881 EVT VT0 =
N->getValueType(0);
5882 EVT VT1 =
N->getValueType(1);
5886 "expected both results to be vectors of matching element count");
5888 LLVMContext &Ctx = *DAG.getContext();
5889 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5891 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5898 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5901 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5902 return SDValue(WidenNode, ResNo);
5905SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5906 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5907 return GetWidenedVector(WidenVec);
5911 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5912 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5915 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5916 AddrSpaceCastN->getSrcAddressSpace(),
5917 AddrSpaceCastN->getDestAddressSpace());
5923 EVT VT =
N->getValueType(0);
5924 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5927 switch (getTypeAction(InVT)) {
5941 SDValue NInOp = GetPromotedInteger(InOp);
5943 if (WidenVT.
bitsEq(NInVT)) {
5946 if (DAG.getDataLayout().isBigEndian()) {
5948 EVT ShiftAmtTy = TLI.getShiftAmountTy(NInVT, DAG.getDataLayout());
5951 DAG.getConstant(ShiftAmt, dl, ShiftAmtTy));
5953 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NInOp);
5970 InOp = GetWidenedVector(InOp);
5972 if (WidenVT.
bitsEq(InVT))
5974 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp);
5982 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
5987 unsigned NewNumParts = WidenSize / InSize;
6000 EVT OrigInVT =
N->getOperand(0).getValueType();
6005 if (TLI.isTypeLegal(NewInVT)) {
6013 if (WidenSize % InSize == 0) {
6020 DAG.ExtractVectorElements(InOp,
Ops);
6021 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6029 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec);
6033 return CreateStackStoreLoad(InOp, WidenVT);
6036SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6038 N->getOpcode(), SDLoc(
N),
6039 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6040 N->getOperand(0),
N->getOperand(1),
N->getOperand(2));
6046 EVT VT =
N->getValueType(0);
6050 EVT EltVT =
N->getOperand(0).getValueType();
6053 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6057 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6058 NewOps.append(WidenNumElts - NumElts, DAG.getUNDEF(EltVT));
6060 return DAG.getBuildVector(WidenVT, dl, NewOps);
6064 EVT InVT =
N->getOperand(0).getValueType();
6065 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6067 unsigned NumOperands =
N->getNumOperands();
6069 bool InputWidened =
false;
6073 if (WidenNumElts % NumInElts == 0) {
6075 unsigned NumConcat = WidenNumElts / NumInElts;
6076 SDValue UndefVal = DAG.getUNDEF(InVT);
6078 for (
unsigned i=0; i < NumOperands; ++i)
6079 Ops[i] =
N->getOperand(i);
6080 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6085 InputWidened =
true;
6086 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6089 for (i=1; i < NumOperands; ++i)
6090 if (!
N->getOperand(i).isUndef())
6093 if (i == NumOperands)
6096 return GetWidenedVector(
N->getOperand(0));
6098 if (NumOperands == 2) {
6100 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6105 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6106 for (
unsigned i = 0; i < NumInElts; ++i) {
6108 MaskOps[i + NumInElts] = i + WidenNumElts;
6110 return DAG.getVectorShuffle(WidenVT, dl,
6111 GetWidenedVector(
N->getOperand(0)),
6112 GetWidenedVector(
N->getOperand(1)),
6119 "Cannot use build vectors to widen CONCAT_VECTOR result");
6127 for (
unsigned i=0; i < NumOperands; ++i) {
6130 InOp = GetWidenedVector(InOp);
6131 for (
unsigned j = 0;
j < NumInElts; ++
j)
6132 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6134 SDValue UndefVal = DAG.getUNDEF(EltVT);
6135 for (; Idx < WidenNumElts; ++Idx)
6136 Ops[Idx] = UndefVal;
6137 return DAG.getBuildVector(WidenVT, dl,
Ops);
6140SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6141 EVT VT =
N->getValueType(0);
6142 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6143 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6150SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6151 EVT VT =
N->getValueType(0);
6153 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6158 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6160 InOp = GetWidenedVector(InOp);
6166 if (IdxVal == 0 && InVT == WidenVT)
6173 assert(IdxVal % VTNumElts == 0 &&
6174 "Expected Idx to be a multiple of subvector minimum vector length");
6175 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6188 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6189 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6190 "down type's element count");
6197 for (;
I < VTNumElts / GCD; ++
I)
6199 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6200 for (;
I < WidenNumElts / GCD; ++
I)
6207 "EXTRACT_SUBVECTOR for scalable vectors");
6214 for (i = 0; i < VTNumElts; ++i)
6215 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6217 SDValue UndefVal = DAG.getUNDEF(EltVT);
6218 for (; i < WidenNumElts; ++i)
6220 return DAG.getBuildVector(WidenVT, dl,
Ops);
6226 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6231SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6232 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6235 N->getOperand(1),
N->getOperand(2));
6248 if (!
LD->getMemoryVT().isByteSized()) {
6250 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6252 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6261 EVT LdVT =
LD->getMemoryVT();
6262 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), LdVT);
6266 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6267 TLI.isTypeLegal(WideMaskVT)) {
6270 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6274 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6275 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6287 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6289 Result = GenWidenVectorLoads(LdChain, LD);
6296 if (LdChain.
size() == 1)
6297 NewChain = LdChain[0];
6303 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6312 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6314 SDValue EVL =
N->getVectorLength();
6321 "Unable to widen binary VP op");
6322 Mask = GetWidenedVector(Mask);
6323 assert(
Mask.getValueType().getVectorElementCount() ==
6324 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6325 .getVectorElementCount() &&
6326 "Unable to widen vector load");
6329 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6330 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6331 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6339 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6341 SDValue EVL =
N->getVectorLength();
6347 "Unable to widen binary VP op");
6348 Mask = GetWidenedVector(Mask);
6349 assert(
Mask.getValueType().getVectorElementCount() ==
6350 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6351 .getVectorElementCount() &&
6352 "Unable to widen vector load");
6354 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6355 Mask, EVL,
N->getMemOperand());
6368 "Unable to widen VP strided load");
6369 Mask = GetWidenedVector(Mask);
6371 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6372 assert(
Mask.getValueType().getVectorElementCount() ==
6374 "Data and mask vectors should have the same number of elements");
6376 SDValue Res = DAG.getStridedLoadVP(
6377 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6378 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6379 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6380 N->isExpandingLoad());
6388SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6393 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6395 Mask.getValueType().getVectorElementType(),
6398 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6399 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6400 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6402 WideMask, WidePassthru);
6406 EVT VT =
N->getValueType(0);
6407 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6409 EVT MaskVT =
Mask.getValueType();
6410 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6419 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6420 TLI.isTypeLegal(WideMaskVT) &&
6426 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6427 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6431 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6432 N->getMemoryVT(),
N->getMemOperand());
6436 if (!
N->getPassThru()->isUndef()) {
6439 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6450 Mask = ModifyToType(Mask, WideMaskVT,
true);
6452 SDValue Res = DAG.getMaskedLoad(
6453 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6454 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6455 ExtType,
N->isExpandingLoad());
6464 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6466 EVT MaskVT =
Mask.getValueType();
6467 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6476 Mask = ModifyToType(Mask, WideMaskVT,
true);
6481 Index.getValueType().getScalarType(),
6483 Index = ModifyToType(Index, WideIndexVT);
6489 N->getMemoryVT().getScalarType(), NumElts);
6490 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6491 WideMemVT, dl,
Ops,
N->getMemOperand(),
6492 N->getIndexType(),
N->getExtensionType());
6501 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6509 N->getMemoryVT().getScalarType(), WideEC);
6510 Mask = GetWidenedMask(Mask, WideEC);
6513 Mask,
N->getVectorLength()};
6514 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6515 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6524 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6525 if (
N->isVPOpcode())
6526 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0),
6527 N->getOperand(1),
N->getOperand(2));
6528 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6556 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6557 return N->getOperand(OpNo).getValueType();
6565 N =
N.getOperand(0);
6567 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6568 if (!
N->getOperand(i)->isUndef())
6570 N =
N.getOperand(0);
6574 N =
N.getOperand(0);
6576 N =
N.getOperand(0);
6603 { MaskVT, MVT::Other },
Ops);
6604 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6611 LLVMContext &Ctx = *DAG.getContext();
6614 if (MaskScalarBits < ToMaskScalBits) {
6618 }
else if (MaskScalarBits > ToMaskScalBits) {
6624 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6626 "Mask should have the right element size by now.");
6629 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6631 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6634 EVT SubVT =
Mask->getValueType(0);
6640 assert((
Mask->getValueType(0) == ToMaskVT) &&
6641 "A mask of ToMaskVT should have been produced by now.");
6651 LLVMContext &Ctx = *DAG.getContext();
6662 EVT CondVT =
Cond->getValueType(0);
6666 EVT VSelVT =
N->getValueType(0);
6678 EVT FinalVT = VSelVT;
6689 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6690 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6697 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6705 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6708 EVT ToMaskVT = VSelVT;
6715 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6731 if (ScalarBits0 != ScalarBits1) {
6732 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6733 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6745 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6746 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6747 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6750 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6758 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6763 unsigned Opcode =
N->getOpcode();
6765 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6766 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6767 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6769 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6775 Cond1 = GetWidenedVector(Cond1);
6783 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6784 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6789 Cond1 = ModifyToType(Cond1, CondWidenVT);
6792 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6793 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6795 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6796 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6798 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6802 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6803 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6806 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6810 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6811 return DAG.getUNDEF(WidenVT);
6815 EVT VT =
N->getValueType(0);
6818 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6822 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6823 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6826 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6827 for (
unsigned i = 0; i != NumElts; ++i) {
6828 int Idx =
N->getMaskElt(i);
6829 if (Idx < (
int)NumElts)
6832 NewMask[i] = Idx - NumElts + WidenNumElts;
6834 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6838 EVT VT =
N->getValueType(0);
6842 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6843 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6849 unsigned IdxVal = WidenNumElts - VTNumElts;
6862 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6865 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6866 "down type's element count");
6869 for (; i < VTNumElts / GCD; ++i)
6871 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6872 for (; i < WidenNumElts / GCD; ++i)
6880 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6881 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6883 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6887SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6888 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6889 return DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, SDLoc(
N), NVT,
N->ops());
6893 assert(
N->getValueType(0).isVector() &&
6894 N->getOperand(0).getValueType().isVector() &&
6895 "Operands must be vectors");
6896 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6909 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
6910 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
6917 InOp1 = GetWidenedVector(InOp1);
6918 InOp2 = GetWidenedVector(InOp2);
6921 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
6932 "Input not widened to expected type!");
6934 if (
N->getOpcode() == ISD::VP_SETCC) {
6937 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6938 N->getOperand(2), Mask,
N->getOperand(4));
6940 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6945 assert(
N->getValueType(0).isVector() &&
6946 N->getOperand(1).getValueType().isVector() &&
6947 "Operands must be vectors");
6948 EVT VT =
N->getValueType(0);
6949 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6959 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
6964 for (
unsigned i = 0; i != NumElts; ++i) {
6965 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
6966 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
6968 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
6969 {Chain, LHSElem, RHSElem, CC});
6970 Chains[i] = Scalars[i].getValue(1);
6971 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
6972 DAG.getBoolConstant(
true, dl, EltVT, VT),
6973 DAG.getBoolConstant(
false, dl, EltVT, VT));
6977 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6979 return DAG.getBuildVector(WidenVT, dl, Scalars);
6985bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
6986 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
6990 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
6993 switch (
N->getOpcode()) {
6996 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7002 case ISD::BITCAST: Res = WidenVecOp_BITCAST(
N);
break;
7004 Res = WidenVecOp_FAKE_USE(
N);
7010 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7011 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7012 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7013 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7018 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7020 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7021 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7022 case ISD::MSCATTER: Res = WidenVecOp_MSCATTER(
N, OpNo);
break;
7023 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7024 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7034 Res = WidenVecOp_UnrollVectorOp(
N);
7041 Res = WidenVecOp_EXTEND(
N);
7046 Res = WidenVecOp_CMP(
N);
7049 case ISD::FP_EXTEND:
7062 Res = WidenVecOp_Convert(
N);
7067 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7070 case ISD::EXPERIMENTAL_VP_SPLAT:
7071 Res = WidenVecOp_VP_SPLAT(
N, OpNo);
7074 case ISD::VECREDUCE_FADD:
7075 case ISD::VECREDUCE_FMUL:
7076 case ISD::VECREDUCE_ADD:
7077 case ISD::VECREDUCE_MUL:
7078 case ISD::VECREDUCE_AND:
7079 case ISD::VECREDUCE_OR:
7080 case ISD::VECREDUCE_XOR:
7081 case ISD::VECREDUCE_SMAX:
7082 case ISD::VECREDUCE_SMIN:
7083 case ISD::VECREDUCE_UMAX:
7084 case ISD::VECREDUCE_UMIN:
7085 case ISD::VECREDUCE_FMAX:
7086 case ISD::VECREDUCE_FMIN:
7087 case ISD::VECREDUCE_FMAXIMUM:
7088 case ISD::VECREDUCE_FMINIMUM:
7089 Res = WidenVecOp_VECREDUCE(
N);
7091 case ISD::VECREDUCE_SEQ_FADD:
7092 case ISD::VECREDUCE_SEQ_FMUL:
7093 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7095 case ISD::VP_REDUCE_FADD:
7096 case ISD::VP_REDUCE_SEQ_FADD:
7097 case ISD::VP_REDUCE_FMUL:
7098 case ISD::VP_REDUCE_SEQ_FMUL:
7099 case ISD::VP_REDUCE_ADD:
7100 case ISD::VP_REDUCE_MUL:
7101 case ISD::VP_REDUCE_AND:
7102 case ISD::VP_REDUCE_OR:
7103 case ISD::VP_REDUCE_XOR:
7104 case ISD::VP_REDUCE_SMAX:
7105 case ISD::VP_REDUCE_SMIN:
7106 case ISD::VP_REDUCE_UMAX:
7107 case ISD::VP_REDUCE_UMIN:
7108 case ISD::VP_REDUCE_FMAX:
7109 case ISD::VP_REDUCE_FMIN:
7110 case ISD::VP_REDUCE_FMAXIMUM:
7111 case ISD::VP_REDUCE_FMINIMUM:
7112 Res = WidenVecOp_VP_REDUCE(
N);
7114 case ISD::VP_CTTZ_ELTS:
7115 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7116 Res = WidenVecOp_VP_CttzElements(
N);
7121 if (!Res.
getNode())
return false;
7129 if (
N->isStrictFPOpcode())
7131 "Invalid operand expansion");
7134 "Invalid operand expansion");
7136 ReplaceValueWith(
SDValue(
N, 0), Res);
7142 EVT VT =
N->getValueType(0);
7147 "Unexpected type action");
7148 InOp = GetWidenedVector(InOp);
7151 "Input wasn't widened!");
7159 EVT FixedEltVT = FixedVT.getVectorElementType();
7160 if (TLI.isTypeLegal(FixedVT) &&
7162 FixedEltVT == InEltVT) {
7164 "Not enough elements in the fixed type for the operand!");
7166 "We can't have the same type as we started with!");
7168 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7170 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7179 return WidenVecOp_Convert(
N);
7184 switch (
N->getOpcode()) {
7199 EVT OpVT =
N->getOperand(0).getValueType();
7200 EVT ResVT =
N->getValueType(0);
7207 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7208 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7214 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7215 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7217 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7224 return DAG.UnrollVectorOp(
N);
7229 EVT ResultVT =
N->getValueType(0);
7231 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7234 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7240 {WideArg,
Test},
N->getFlags());
7246 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7248 EVT OpVT =
N->getOperand(0).getValueType();
7251 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7256 EVT VT =
N->getValueType(0);
7262 "Unexpected type action");
7263 InOp = GetWidenedVector(InOp);
7265 unsigned Opcode =
N->getOpcode();
7271 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7273 if (
N->isStrictFPOpcode()) {
7275 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7278 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7279 {
N->getOperand(0), InOp });
7285 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7287 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7289 return DAG.getExtractSubvector(dl, VT, Res, 0);
7297 if (
N->isStrictFPOpcode()) {
7300 for (
unsigned i=0; i < NumElts; ++i) {
7301 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7302 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7306 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7308 for (
unsigned i = 0; i < NumElts; ++i)
7309 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7310 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7313 return DAG.getBuildVector(VT, dl,
Ops);
7317 EVT DstVT =
N->getValueType(0);
7318 SDValue Src = GetWidenedVector(
N->getOperand(0));
7319 EVT SrcVT = Src.getValueType();
7326 if (TLI.isTypeLegal(WideDstVT)) {
7328 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7331 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7335 return DAG.UnrollVectorOp(
N);
7339 EVT VT =
N->getValueType(0);
7340 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7348 if (!VT.
isVector() && VT != MVT::x86mmx &&
7352 if (TLI.isTypeLegal(NewVT)) {
7353 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
7354 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7366 ElementCount NewNumElts =
7368 .divideCoefficientBy(EltSize);
7370 if (TLI.isTypeLegal(NewVT)) {
7372 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7377 return CreateStackStoreLoad(InOp, VT);
7385 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7386 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7391 EVT VT =
N->getValueType(0);
7393 EVT InVT =
N->getOperand(0).getValueType();
7398 unsigned NumOperands =
N->getNumOperands();
7399 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7401 for (i = 1; i < NumOperands; ++i)
7402 if (!
N->getOperand(i).isUndef())
7405 if (i == NumOperands)
7406 return GetWidenedVector(
N->getOperand(0));
7416 for (
unsigned i=0; i < NumOperands; ++i) {
7420 "Unexpected type action");
7421 InOp = GetWidenedVector(InOp);
7422 for (
unsigned j = 0;
j < NumInElts; ++
j)
7423 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7425 return DAG.getBuildVector(VT, dl,
Ops);
7428SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7429 EVT VT =
N->getValueType(0);
7435 SubVec = GetWidenedVector(SubVec);
7441 bool IndicesValid =
false;
7444 IndicesValid =
true;
7448 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7449 Attribute::VScaleRange);
7454 IndicesValid =
true;
7462 if (IndicesValid && InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7468 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7472 unsigned Idx =
N->getConstantOperandVal(2);
7478 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7484SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7485 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7487 N->getValueType(0), InOp,
N->getOperand(1));
7490SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7491 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7493 N->getValueType(0), InOp,
N->getOperand(1));
7496SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7497 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7498 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7506 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7507 return TLI.scalarizeVectorStore(ST, DAG);
7509 if (
ST->isTruncatingStore())
7510 return TLI.scalarizeVectorStore(ST, DAG);
7520 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7524 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7525 TLI.isTypeLegal(WideMaskVT)) {
7528 StVal = GetWidenedVector(StVal);
7530 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7532 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7533 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7534 ST->getAddressingMode());
7538 if (GenWidenVectorStores(StChain, ST)) {
7539 if (StChain.
size() == 1)
7548SDValue DAGTypeLegalizer::WidenVecOp_VP_SPLAT(
SDNode *
N,
unsigned OpNo) {
7549 assert(OpNo == 1 &&
"Can widen only mask operand of vp_splat");
7550 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
7551 N->getOperand(0), GetWidenedVector(
N->getOperand(1)),
7555SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7556 assert((OpNo == 1 || OpNo == 3) &&
7557 "Can widen only data or mask operand of vp_store");
7565 StVal = GetWidenedVector(StVal);
7571 "Unable to widen VP store");
7572 Mask = GetWidenedVector(Mask);
7574 Mask = GetWidenedVector(Mask);
7580 "Unable to widen VP store");
7581 StVal = GetWidenedVector(StVal);
7584 assert(
Mask.getValueType().getVectorElementCount() ==
7586 "Mask and data vectors should have the same number of elements");
7587 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7588 ST->getOffset(), Mask,
ST->getVectorLength(),
7589 ST->getMemoryVT(),
ST->getMemOperand(),
7590 ST->getAddressingMode(),
ST->isTruncatingStore(),
7591 ST->isCompressingStore());
7596 assert((OpNo == 1 || OpNo == 4) &&
7597 "Can widen only data or mask operand of vp_strided_store");
7606 "Unable to widen VP strided store");
7610 "Unable to widen VP strided store");
7612 StVal = GetWidenedVector(StVal);
7613 Mask = GetWidenedVector(Mask);
7616 Mask.getValueType().getVectorElementCount() &&
7617 "Data and mask vectors should have the same number of elements");
7619 return DAG.getStridedStoreVP(
7626SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7627 assert((OpNo == 1 || OpNo == 4) &&
7628 "Can widen only data or mask operand of mstore");
7631 EVT MaskVT =
Mask.getValueType();
7636 EVT WideVT, WideMaskVT;
7639 StVal = GetWidenedVector(StVal);
7646 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7653 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7654 TLI.isTypeLegal(WideMaskVT)) {
7655 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7656 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7665 Mask = ModifyToType(Mask, WideMaskVT,
true);
7668 Mask = ModifyToType(Mask, WideMaskVT,
true);
7670 StVal = ModifyToType(StVal, WideVT);
7673 assert(
Mask.getValueType().getVectorElementCount() ==
7675 "Mask and data vectors should have the same number of elements");
7682SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7683 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7685 SDValue DataOp = MG->getPassThru();
7687 SDValue Scale = MG->getScale();
7695 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7696 MG->getMemOperand(), MG->getIndexType(),
7697 MG->getExtensionType());
7703SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7712 DataOp = GetWidenedVector(DataOp);
7716 EVT IndexVT =
Index.getValueType();
7719 Index = ModifyToType(Index, WideIndexVT);
7722 EVT MaskVT =
Mask.getValueType();
7725 Mask = ModifyToType(Mask, WideMaskVT,
true);
7730 }
else if (OpNo == 4) {
7732 Index = GetWidenedVector(Index);
7738 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7743SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7752 DataOp = GetWidenedVector(DataOp);
7753 Index = GetWidenedVector(Index);
7755 Mask = GetWidenedMask(Mask, WideEC);
7758 }
else if (OpNo == 3) {
7760 Index = GetWidenedVector(Index);
7767 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7772 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7773 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7775 EVT VT =
N->getValueType(0);
7790 SVT, InOp0, InOp1,
N->getOperand(2));
7796 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7798 EVT OpVT =
N->getOperand(0).getValueType();
7801 return DAG.getNode(ExtendCode, dl, VT, CC);
7811 EVT VT =
N->getValueType(0);
7813 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7820 for (
unsigned i = 0; i != NumElts; ++i) {
7821 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7822 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7824 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7825 {Chain, LHSElem, RHSElem, CC});
7826 Chains[i] = Scalars[i].getValue(1);
7827 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7828 DAG.getBoolConstant(
true, dl, EltVT, VT),
7829 DAG.getBoolConstant(
false, dl, EltVT, VT));
7833 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7835 return DAG.getBuildVector(VT, dl, Scalars);
7842 case ISD::VECREDUCE_ADD:
7843 case ISD::VECREDUCE_MUL:
7844 case ISD::VECREDUCE_AND:
7845 case ISD::VECREDUCE_OR:
7846 case ISD::VECREDUCE_XOR:
7848 case ISD::VECREDUCE_SMAX:
7849 case ISD::VECREDUCE_SMIN:
7851 case ISD::VECREDUCE_UMAX:
7852 case ISD::VECREDUCE_UMIN:
7859 SDValue Op = GetWidenedVector(
N->getOperand(0));
7860 EVT VT =
N->getValueType(0);
7861 EVT OrigVT =
N->getOperand(0).getValueType();
7862 EVT WideVT =
Op.getValueType();
7864 SDNodeFlags
Flags =
N->getFlags();
7866 unsigned Opc =
N->getOpcode();
7868 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7869 assert(NeutralElem &&
"Neutral element must exist");
7879 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7886 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7887 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7893 unsigned GCD = std::gcd(OrigElts, WideElts);
7896 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
7897 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
7898 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
7899 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7902 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
7903 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
7905 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7914 EVT VT =
N->getValueType(0);
7916 EVT WideVT =
Op.getValueType();
7918 SDNodeFlags
Flags =
N->getFlags();
7920 unsigned Opc =
N->getOpcode();
7922 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7932 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7935 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7936 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7942 unsigned GCD = std::gcd(OrigElts, WideElts);
7945 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
7946 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
7947 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
7948 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
7951 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
7952 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
7954 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
7958 assert(
N->isVPOpcode() &&
"Expected VP opcode");
7961 SDValue Op = GetWidenedVector(
N->getOperand(1));
7963 Op.getValueType().getVectorElementCount());
7965 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
7966 {N->getOperand(0), Op, Mask, N->getOperand(3)},
7974 EVT VT =
N->getValueType(0);
7978 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
7979 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
7984 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
7990 EVT SrcVT =
Source.getValueType();
7994 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
7995 {Source, Mask, N->getOperand(2)},
N->getFlags());
8012 unsigned WidenEx = 0) {
8017 unsigned AlignInBits =
Align*8;
8019 EVT RetVT = WidenEltVT;
8024 if (Width == WidenEltWidth)
8035 (WidenWidth % MemVTWidth) == 0 &&
8037 (MemVTWidth <= Width ||
8038 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8039 if (MemVTWidth == WidenWidth)
8058 (WidenWidth % MemVTWidth) == 0 &&
8060 (MemVTWidth <= Width ||
8061 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8070 return std::nullopt;
8081 unsigned Start,
unsigned End) {
8082 SDLoc dl(LdOps[Start]);
8083 EVT LdTy = LdOps[Start].getValueType();
8091 for (
unsigned i = Start + 1; i != End; ++i) {
8092 EVT NewLdTy = LdOps[i].getValueType();
8093 if (NewLdTy != LdTy) {
8096 VecOp = DAG.
getNode(ISD::BITCAST, dl, NewVecVT, VecOp);
8103 return DAG.
getNode(ISD::BITCAST, dl, VecTy, VecOp);
8112 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8113 EVT LdVT =
LD->getMemoryVT();
8123 AAMDNodes AAInfo =
LD->getAAInfo();
8127 TypeSize WidthDiff = WidenWidth - LdWidth;
8134 std::optional<EVT> FirstVT =
8135 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8142 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8147 std::optional<EVT> NewVT = FirstVT;
8148 TypeSize RemainingWidth = LdWidth;
8149 TypeSize NewVTWidth = FirstVTWidth;
8151 RemainingWidth -= NewVTWidth;
8158 NewVTWidth = NewVT->getSizeInBits();
8164 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8165 LD->getBaseAlign(), MMOFlags, AAInfo);
8169 if (MemVTs.
empty()) {
8171 if (!FirstVT->isVector()) {
8176 return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
8178 if (FirstVT == WidenVT)
8183 unsigned NumConcat =
8186 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8187 ConcatOps[0] = LdOp;
8188 for (
unsigned i = 1; i != NumConcat; ++i)
8189 ConcatOps[i] = UndefVal;
8197 uint64_t ScaledOffset = 0;
8198 MachinePointerInfo MPI =
LD->getPointerInfo();
8204 for (EVT MemVT : MemVTs) {
8205 Align NewAlign = ScaledOffset == 0
8206 ?
LD->getBaseAlign()
8209 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8217 unsigned End = LdOps.
size();
8228 EVT LdTy = LdOps[i].getValueType();
8231 for (--i; i >= 0; --i) {
8232 LdTy = LdOps[i].getValueType();
8239 ConcatOps[--Idx] = LdOps[i];
8240 for (--i; i >= 0; --i) {
8241 EVT NewLdTy = LdOps[i].getValueType();
8242 if (NewLdTy != LdTy) {
8252 for (;
j != End-Idx; ++
j)
8253 WidenOps[j] = ConcatOps[Idx+j];
8255 WidenOps[j] = DAG.getUNDEF(LdTy);
8262 ConcatOps[--Idx] = LdOps[i];
8267 ArrayRef(&ConcatOps[Idx], End - Idx));
8273 SDValue UndefVal = DAG.getUNDEF(LdTy);
8276 for (; i != End-Idx; ++i)
8277 WidenOps[i] = ConcatOps[Idx+i];
8279 WidenOps[i] = UndefVal;
8290 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8291 EVT LdVT =
LD->getMemoryVT();
8300 AAMDNodes AAInfo =
LD->getAAInfo();
8304 "not yet supported");
8315 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8316 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8322 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8323 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8324 LD->getBaseAlign(), MMOFlags, AAInfo);
8329 SDValue UndefVal = DAG.getUNDEF(EltVT);
8330 for (; i != WidenNumElts; ++i)
8333 return DAG.getBuildVector(WidenVT, dl,
Ops);
8344 AAMDNodes AAInfo =
ST->getAAInfo();
8345 SDValue ValOp = GetWidenedVector(
ST->getValue());
8348 EVT StVT =
ST->getMemoryVT();
8356 "Mismatch between store and value types");
8360 MachinePointerInfo MPI =
ST->getPointerInfo();
8361 uint64_t ScaledOffset = 0;
8370 std::optional<EVT> NewVT =
8375 TypeSize NewVTWidth = NewVT->getSizeInBits();
8378 StWidth -= NewVTWidth;
8379 MemVTs.
back().second++;
8383 for (
const auto &Pair : MemVTs) {
8384 EVT NewVT = Pair.first;
8385 unsigned Count = Pair.second;
8391 Align NewAlign = ScaledOffset == 0
8392 ?
ST->getBaseAlign()
8394 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8395 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8411 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8412 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8413 ST->getBaseAlign(), MMOFlags, AAInfo);
8430 bool FillWithZeroes) {
8435 "input and widen element type must match");
8437 "cannot modify scalable vectors in this way");
8449 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8452 for (
unsigned i = 1; i != NumConcat; ++i)
8459 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8462 "Scalable vectors should have been handled already.");
8470 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8472 for (Idx = 0; Idx < MinNumElts; ++Idx)
8473 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8475 SDValue UndefVal = DAG.getUNDEF(EltVT);
8476 for (; Idx < WidenNumElts; ++Idx)
8477 Ops[Idx] = UndefVal;
8479 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8480 if (!FillWithZeroes)
8484 "We expect to never want to FillWithZeroes for non-integral types.");
8487 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8488 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8490 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8491 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")
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 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 std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align=0, unsigned WidenEx=0)
mir Rename Register Operands
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)
Returns the type of the given value/instruction V.
This file implements the SmallBitVector class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
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)
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()
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
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 a 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.
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.
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 getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
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.
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.
@ LOOP_DEPENDENCE_RAW_MASK
@ 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.
@ 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.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ 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 ...
@ FADD
Simple binary floating point operators.
@ 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.
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ 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...
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ 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).
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ 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.
@ 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) ...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ 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.
@ 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...
@ 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.
@ 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.
@ 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],...
@ 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.
@ VECTOR_SPLICE
VECTOR_SPLICE(VEC1, VEC2, IMM) - Returns a subvector of the same type as VEC1/VEC2 from CONCAT_VECTOR...
@ 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 ...
@ 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.
@ 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 ...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
Set rounding mode.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
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.
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.
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
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.
EVT changeElementType(EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
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.
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 isScalableVT() const
Return true if the type is a scalable type.
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 changeVectorElementType(EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
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.