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()) {
5949 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
5951 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NInOp);
5968 InOp = GetWidenedVector(InOp);
5970 if (WidenVT.
bitsEq(InVT))
5972 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp);
5980 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
5985 unsigned NewNumParts = WidenSize / InSize;
5998 EVT OrigInVT =
N->getOperand(0).getValueType();
6003 if (TLI.isTypeLegal(NewInVT)) {
6011 if (WidenSize % InSize == 0) {
6018 DAG.ExtractVectorElements(InOp,
Ops);
6019 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6027 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec);
6031 return CreateStackStoreLoad(InOp, WidenVT);
6034SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6036 N->getOpcode(), SDLoc(
N),
6037 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6038 N->getOperand(0),
N->getOperand(1),
N->getOperand(2));
6044 EVT VT =
N->getValueType(0);
6048 EVT EltVT =
N->getOperand(0).getValueType();
6051 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6055 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6056 NewOps.append(WidenNumElts - NumElts, DAG.getUNDEF(EltVT));
6058 return DAG.getBuildVector(WidenVT, dl, NewOps);
6062 EVT InVT =
N->getOperand(0).getValueType();
6063 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6065 unsigned NumOperands =
N->getNumOperands();
6067 bool InputWidened =
false;
6071 if (WidenNumElts % NumInElts == 0) {
6073 unsigned NumConcat = WidenNumElts / NumInElts;
6074 SDValue UndefVal = DAG.getUNDEF(InVT);
6076 for (
unsigned i=0; i < NumOperands; ++i)
6077 Ops[i] =
N->getOperand(i);
6078 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6083 InputWidened =
true;
6084 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6087 for (i=1; i < NumOperands; ++i)
6088 if (!
N->getOperand(i).isUndef())
6091 if (i == NumOperands)
6094 return GetWidenedVector(
N->getOperand(0));
6096 if (NumOperands == 2) {
6098 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6103 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6104 for (
unsigned i = 0; i < NumInElts; ++i) {
6106 MaskOps[i + NumInElts] = i + WidenNumElts;
6108 return DAG.getVectorShuffle(WidenVT, dl,
6109 GetWidenedVector(
N->getOperand(0)),
6110 GetWidenedVector(
N->getOperand(1)),
6117 "Cannot use build vectors to widen CONCAT_VECTOR result");
6125 for (
unsigned i=0; i < NumOperands; ++i) {
6128 InOp = GetWidenedVector(InOp);
6129 for (
unsigned j = 0;
j < NumInElts; ++
j)
6130 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6132 SDValue UndefVal = DAG.getUNDEF(EltVT);
6133 for (; Idx < WidenNumElts; ++Idx)
6134 Ops[Idx] = UndefVal;
6135 return DAG.getBuildVector(WidenVT, dl,
Ops);
6138SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6139 EVT VT =
N->getValueType(0);
6140 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6141 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6148SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6149 EVT VT =
N->getValueType(0);
6151 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6156 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6158 InOp = GetWidenedVector(InOp);
6164 if (IdxVal == 0 && InVT == WidenVT)
6171 assert(IdxVal % VTNumElts == 0 &&
6172 "Expected Idx to be a multiple of subvector minimum vector length");
6173 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6186 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6187 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6188 "down type's element count");
6195 for (;
I < VTNumElts / GCD; ++
I)
6197 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6198 for (;
I < WidenNumElts / GCD; ++
I)
6205 "EXTRACT_SUBVECTOR for scalable vectors");
6212 for (i = 0; i < VTNumElts; ++i)
6213 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6215 SDValue UndefVal = DAG.getUNDEF(EltVT);
6216 for (; i < WidenNumElts; ++i)
6218 return DAG.getBuildVector(WidenVT, dl,
Ops);
6224 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6229SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6230 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6233 N->getOperand(1),
N->getOperand(2));
6246 if (!
LD->getMemoryVT().isByteSized()) {
6248 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6250 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6259 EVT LdVT =
LD->getMemoryVT();
6260 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), LdVT);
6264 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6265 TLI.isTypeLegal(WideMaskVT)) {
6268 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6272 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6273 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6285 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6287 Result = GenWidenVectorLoads(LdChain, LD);
6294 if (LdChain.
size() == 1)
6295 NewChain = LdChain[0];
6301 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6310 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6312 SDValue EVL =
N->getVectorLength();
6319 "Unable to widen binary VP op");
6320 Mask = GetWidenedVector(Mask);
6321 assert(
Mask.getValueType().getVectorElementCount() ==
6322 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6323 .getVectorElementCount() &&
6324 "Unable to widen vector load");
6327 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6328 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6329 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6337 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6339 SDValue EVL =
N->getVectorLength();
6345 "Unable to widen binary VP op");
6346 Mask = GetWidenedVector(Mask);
6347 assert(
Mask.getValueType().getVectorElementCount() ==
6348 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6349 .getVectorElementCount() &&
6350 "Unable to widen vector load");
6352 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6353 Mask, EVL,
N->getMemOperand());
6366 "Unable to widen VP strided load");
6367 Mask = GetWidenedVector(Mask);
6369 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6370 assert(
Mask.getValueType().getVectorElementCount() ==
6372 "Data and mask vectors should have the same number of elements");
6374 SDValue Res = DAG.getStridedLoadVP(
6375 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6376 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6377 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6378 N->isExpandingLoad());
6386SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6391 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6393 Mask.getValueType().getVectorElementType(),
6396 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6397 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6398 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6400 WideMask, WidePassthru);
6404 EVT VT =
N->getValueType(0);
6405 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6407 EVT MaskVT =
Mask.getValueType();
6408 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6417 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6418 TLI.isTypeLegal(WideMaskVT) &&
6424 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6425 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6429 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6430 N->getMemoryVT(),
N->getMemOperand());
6434 if (!
N->getPassThru()->isUndef()) {
6437 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6448 Mask = ModifyToType(Mask, WideMaskVT,
true);
6450 SDValue Res = DAG.getMaskedLoad(
6451 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6452 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6453 ExtType,
N->isExpandingLoad());
6462 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6464 EVT MaskVT =
Mask.getValueType();
6465 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6474 Mask = ModifyToType(Mask, WideMaskVT,
true);
6479 Index.getValueType().getScalarType(),
6481 Index = ModifyToType(Index, WideIndexVT);
6487 N->getMemoryVT().getScalarType(), NumElts);
6488 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6489 WideMemVT, dl,
Ops,
N->getMemOperand(),
6490 N->getIndexType(),
N->getExtensionType());
6499 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6507 N->getMemoryVT().getScalarType(), WideEC);
6508 Mask = GetWidenedMask(Mask, WideEC);
6511 Mask,
N->getVectorLength()};
6512 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6513 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6522 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6523 if (
N->isVPOpcode())
6524 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0),
6525 N->getOperand(1),
N->getOperand(2));
6526 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6554 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6555 return N->getOperand(OpNo).getValueType();
6563 N =
N.getOperand(0);
6565 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6566 if (!
N->getOperand(i)->isUndef())
6568 N =
N.getOperand(0);
6572 N =
N.getOperand(0);
6574 N =
N.getOperand(0);
6601 { MaskVT, MVT::Other },
Ops);
6602 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6609 LLVMContext &Ctx = *DAG.getContext();
6612 if (MaskScalarBits < ToMaskScalBits) {
6616 }
else if (MaskScalarBits > ToMaskScalBits) {
6622 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6624 "Mask should have the right element size by now.");
6627 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6629 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6632 EVT SubVT =
Mask->getValueType(0);
6638 assert((
Mask->getValueType(0) == ToMaskVT) &&
6639 "A mask of ToMaskVT should have been produced by now.");
6649 LLVMContext &Ctx = *DAG.getContext();
6660 EVT CondVT =
Cond->getValueType(0);
6664 EVT VSelVT =
N->getValueType(0);
6676 EVT FinalVT = VSelVT;
6687 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6688 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6695 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6703 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6706 EVT ToMaskVT = VSelVT;
6713 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6729 if (ScalarBits0 != ScalarBits1) {
6730 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6731 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6743 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6744 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6745 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6748 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6756 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6761 unsigned Opcode =
N->getOpcode();
6763 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6764 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6765 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6767 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6773 Cond1 = GetWidenedVector(Cond1);
6781 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6782 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6787 Cond1 = ModifyToType(Cond1, CondWidenVT);
6790 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6791 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6793 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6794 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6796 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6800 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6801 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6804 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6808 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6809 return DAG.getUNDEF(WidenVT);
6813 EVT VT =
N->getValueType(0);
6816 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6820 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6821 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6824 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6825 for (
unsigned i = 0; i != NumElts; ++i) {
6826 int Idx =
N->getMaskElt(i);
6827 if (Idx < (
int)NumElts)
6830 NewMask[i] = Idx - NumElts + WidenNumElts;
6832 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6836 EVT VT =
N->getValueType(0);
6840 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6841 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6847 unsigned IdxVal = WidenNumElts - VTNumElts;
6860 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6863 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6864 "down type's element count");
6867 for (; i < VTNumElts / GCD; ++i)
6869 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6870 for (; i < WidenNumElts / GCD; ++i)
6878 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6879 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6881 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6885SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6886 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6887 return DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, SDLoc(
N), NVT,
N->ops());
6891 assert(
N->getValueType(0).isVector() &&
6892 N->getOperand(0).getValueType().isVector() &&
6893 "Operands must be vectors");
6894 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6907 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
6908 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
6915 InOp1 = GetWidenedVector(InOp1);
6916 InOp2 = GetWidenedVector(InOp2);
6919 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
6930 "Input not widened to expected type!");
6932 if (
N->getOpcode() == ISD::VP_SETCC) {
6935 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6936 N->getOperand(2), Mask,
N->getOperand(4));
6938 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
6943 assert(
N->getValueType(0).isVector() &&
6944 N->getOperand(1).getValueType().isVector() &&
6945 "Operands must be vectors");
6946 EVT VT =
N->getValueType(0);
6947 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6957 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
6962 for (
unsigned i = 0; i != NumElts; ++i) {
6963 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
6964 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
6966 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
6967 {Chain, LHSElem, RHSElem, CC});
6968 Chains[i] = Scalars[i].getValue(1);
6969 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
6970 DAG.getBoolConstant(
true, dl, EltVT, VT),
6971 DAG.getBoolConstant(
false, dl, EltVT, VT));
6975 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6977 return DAG.getBuildVector(WidenVT, dl, Scalars);
6983bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
6984 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
6988 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
6991 switch (
N->getOpcode()) {
6994 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7000 case ISD::BITCAST: Res = WidenVecOp_BITCAST(
N);
break;
7002 Res = WidenVecOp_FAKE_USE(
N);
7008 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7009 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7010 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7011 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7016 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7018 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7019 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7020 case ISD::MSCATTER: Res = WidenVecOp_MSCATTER(
N, OpNo);
break;
7021 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7022 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7032 Res = WidenVecOp_UnrollVectorOp(
N);
7039 Res = WidenVecOp_EXTEND(
N);
7044 Res = WidenVecOp_CMP(
N);
7047 case ISD::FP_EXTEND:
7060 Res = WidenVecOp_Convert(
N);
7065 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7068 case ISD::EXPERIMENTAL_VP_SPLAT:
7069 Res = WidenVecOp_VP_SPLAT(
N, OpNo);
7072 case ISD::VECREDUCE_FADD:
7073 case ISD::VECREDUCE_FMUL:
7074 case ISD::VECREDUCE_ADD:
7075 case ISD::VECREDUCE_MUL:
7076 case ISD::VECREDUCE_AND:
7077 case ISD::VECREDUCE_OR:
7078 case ISD::VECREDUCE_XOR:
7079 case ISD::VECREDUCE_SMAX:
7080 case ISD::VECREDUCE_SMIN:
7081 case ISD::VECREDUCE_UMAX:
7082 case ISD::VECREDUCE_UMIN:
7083 case ISD::VECREDUCE_FMAX:
7084 case ISD::VECREDUCE_FMIN:
7085 case ISD::VECREDUCE_FMAXIMUM:
7086 case ISD::VECREDUCE_FMINIMUM:
7087 Res = WidenVecOp_VECREDUCE(
N);
7089 case ISD::VECREDUCE_SEQ_FADD:
7090 case ISD::VECREDUCE_SEQ_FMUL:
7091 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7093 case ISD::VP_REDUCE_FADD:
7094 case ISD::VP_REDUCE_SEQ_FADD:
7095 case ISD::VP_REDUCE_FMUL:
7096 case ISD::VP_REDUCE_SEQ_FMUL:
7097 case ISD::VP_REDUCE_ADD:
7098 case ISD::VP_REDUCE_MUL:
7099 case ISD::VP_REDUCE_AND:
7100 case ISD::VP_REDUCE_OR:
7101 case ISD::VP_REDUCE_XOR:
7102 case ISD::VP_REDUCE_SMAX:
7103 case ISD::VP_REDUCE_SMIN:
7104 case ISD::VP_REDUCE_UMAX:
7105 case ISD::VP_REDUCE_UMIN:
7106 case ISD::VP_REDUCE_FMAX:
7107 case ISD::VP_REDUCE_FMIN:
7108 case ISD::VP_REDUCE_FMAXIMUM:
7109 case ISD::VP_REDUCE_FMINIMUM:
7110 Res = WidenVecOp_VP_REDUCE(
N);
7112 case ISD::VP_CTTZ_ELTS:
7113 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7114 Res = WidenVecOp_VP_CttzElements(
N);
7119 if (!Res.
getNode())
return false;
7127 if (
N->isStrictFPOpcode())
7129 "Invalid operand expansion");
7132 "Invalid operand expansion");
7134 ReplaceValueWith(
SDValue(
N, 0), Res);
7140 EVT VT =
N->getValueType(0);
7145 "Unexpected type action");
7146 InOp = GetWidenedVector(InOp);
7149 "Input wasn't widened!");
7157 EVT FixedEltVT = FixedVT.getVectorElementType();
7158 if (TLI.isTypeLegal(FixedVT) &&
7160 FixedEltVT == InEltVT) {
7162 "Not enough elements in the fixed type for the operand!");
7164 "We can't have the same type as we started with!");
7166 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7168 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7177 return WidenVecOp_Convert(
N);
7182 switch (
N->getOpcode()) {
7197 EVT OpVT =
N->getOperand(0).getValueType();
7198 EVT ResVT =
N->getValueType(0);
7205 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7206 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7212 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7213 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7215 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7222 return DAG.UnrollVectorOp(
N);
7227 EVT ResultVT =
N->getValueType(0);
7229 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7232 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7238 {WideArg,
Test},
N->getFlags());
7244 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7246 EVT OpVT =
N->getOperand(0).getValueType();
7249 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7254 EVT VT =
N->getValueType(0);
7260 "Unexpected type action");
7261 InOp = GetWidenedVector(InOp);
7263 unsigned Opcode =
N->getOpcode();
7269 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7271 if (
N->isStrictFPOpcode()) {
7273 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7276 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7277 {
N->getOperand(0), InOp });
7283 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7285 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7287 return DAG.getExtractSubvector(dl, VT, Res, 0);
7295 if (
N->isStrictFPOpcode()) {
7298 for (
unsigned i=0; i < NumElts; ++i) {
7299 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7300 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7304 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7306 for (
unsigned i = 0; i < NumElts; ++i)
7307 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7308 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7311 return DAG.getBuildVector(VT, dl,
Ops);
7315 EVT DstVT =
N->getValueType(0);
7316 SDValue Src = GetWidenedVector(
N->getOperand(0));
7317 EVT SrcVT = Src.getValueType();
7324 if (TLI.isTypeLegal(WideDstVT)) {
7326 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7329 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7333 return DAG.UnrollVectorOp(
N);
7337 EVT VT =
N->getValueType(0);
7338 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7346 if (!VT.
isVector() && VT != MVT::x86mmx &&
7350 if (TLI.isTypeLegal(NewVT)) {
7351 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
7352 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7364 ElementCount NewNumElts =
7366 .divideCoefficientBy(EltSize);
7368 if (TLI.isTypeLegal(NewVT)) {
7370 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7375 return CreateStackStoreLoad(InOp, VT);
7383 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7384 return DAG.getNode(ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7389 EVT VT =
N->getValueType(0);
7391 EVT InVT =
N->getOperand(0).getValueType();
7396 unsigned NumOperands =
N->getNumOperands();
7397 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7399 for (i = 1; i < NumOperands; ++i)
7400 if (!
N->getOperand(i).isUndef())
7403 if (i == NumOperands)
7404 return GetWidenedVector(
N->getOperand(0));
7414 for (
unsigned i=0; i < NumOperands; ++i) {
7418 "Unexpected type action");
7419 InOp = GetWidenedVector(InOp);
7420 for (
unsigned j = 0;
j < NumInElts; ++
j)
7421 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7423 return DAG.getBuildVector(VT, dl,
Ops);
7426SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7427 EVT VT =
N->getValueType(0);
7433 SubVec = GetWidenedVector(SubVec);
7439 bool IndicesValid =
false;
7442 IndicesValid =
true;
7446 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7447 Attribute::VScaleRange);
7452 IndicesValid =
true;
7460 if (IndicesValid && InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7466 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7470 unsigned Idx =
N->getConstantOperandVal(2);
7476 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7482SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7483 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7485 N->getValueType(0), InOp,
N->getOperand(1));
7488SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7489 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7491 N->getValueType(0), InOp,
N->getOperand(1));
7494SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7495 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7496 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7504 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7505 return TLI.scalarizeVectorStore(ST, DAG);
7507 if (
ST->isTruncatingStore())
7508 return TLI.scalarizeVectorStore(ST, DAG);
7518 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7522 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7523 TLI.isTypeLegal(WideMaskVT)) {
7526 StVal = GetWidenedVector(StVal);
7528 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7530 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7531 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7532 ST->getAddressingMode());
7536 if (GenWidenVectorStores(StChain, ST)) {
7537 if (StChain.
size() == 1)
7546SDValue DAGTypeLegalizer::WidenVecOp_VP_SPLAT(
SDNode *
N,
unsigned OpNo) {
7547 assert(OpNo == 1 &&
"Can widen only mask operand of vp_splat");
7548 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
7549 N->getOperand(0), GetWidenedVector(
N->getOperand(1)),
7553SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7554 assert((OpNo == 1 || OpNo == 3) &&
7555 "Can widen only data or mask operand of vp_store");
7563 StVal = GetWidenedVector(StVal);
7569 "Unable to widen VP store");
7570 Mask = GetWidenedVector(Mask);
7572 Mask = GetWidenedVector(Mask);
7578 "Unable to widen VP store");
7579 StVal = GetWidenedVector(StVal);
7582 assert(
Mask.getValueType().getVectorElementCount() ==
7584 "Mask and data vectors should have the same number of elements");
7585 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7586 ST->getOffset(), Mask,
ST->getVectorLength(),
7587 ST->getMemoryVT(),
ST->getMemOperand(),
7588 ST->getAddressingMode(),
ST->isTruncatingStore(),
7589 ST->isCompressingStore());
7594 assert((OpNo == 1 || OpNo == 4) &&
7595 "Can widen only data or mask operand of vp_strided_store");
7604 "Unable to widen VP strided store");
7608 "Unable to widen VP strided store");
7610 StVal = GetWidenedVector(StVal);
7611 Mask = GetWidenedVector(Mask);
7614 Mask.getValueType().getVectorElementCount() &&
7615 "Data and mask vectors should have the same number of elements");
7617 return DAG.getStridedStoreVP(
7624SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7625 assert((OpNo == 1 || OpNo == 4) &&
7626 "Can widen only data or mask operand of mstore");
7629 EVT MaskVT =
Mask.getValueType();
7634 EVT WideVT, WideMaskVT;
7637 StVal = GetWidenedVector(StVal);
7644 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7651 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7652 TLI.isTypeLegal(WideMaskVT)) {
7653 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7654 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7663 Mask = ModifyToType(Mask, WideMaskVT,
true);
7666 Mask = ModifyToType(Mask, WideMaskVT,
true);
7668 StVal = ModifyToType(StVal, WideVT);
7671 assert(
Mask.getValueType().getVectorElementCount() ==
7673 "Mask and data vectors should have the same number of elements");
7680SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7681 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7683 SDValue DataOp = MG->getPassThru();
7685 SDValue Scale = MG->getScale();
7693 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7694 MG->getMemOperand(), MG->getIndexType(),
7695 MG->getExtensionType());
7701SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7710 DataOp = GetWidenedVector(DataOp);
7714 EVT IndexVT =
Index.getValueType();
7717 Index = ModifyToType(Index, WideIndexVT);
7720 EVT MaskVT =
Mask.getValueType();
7723 Mask = ModifyToType(Mask, WideMaskVT,
true);
7728 }
else if (OpNo == 4) {
7730 Index = GetWidenedVector(Index);
7736 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7741SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7750 DataOp = GetWidenedVector(DataOp);
7751 Index = GetWidenedVector(Index);
7753 Mask = GetWidenedMask(Mask, WideEC);
7756 }
else if (OpNo == 3) {
7758 Index = GetWidenedVector(Index);
7765 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7770 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7771 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7773 EVT VT =
N->getValueType(0);
7788 SVT, InOp0, InOp1,
N->getOperand(2));
7794 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7796 EVT OpVT =
N->getOperand(0).getValueType();
7799 return DAG.getNode(ExtendCode, dl, VT, CC);
7809 EVT VT =
N->getValueType(0);
7811 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7818 for (
unsigned i = 0; i != NumElts; ++i) {
7819 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7820 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7822 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7823 {Chain, LHSElem, RHSElem, CC});
7824 Chains[i] = Scalars[i].getValue(1);
7825 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7826 DAG.getBoolConstant(
true, dl, EltVT, VT),
7827 DAG.getBoolConstant(
false, dl, EltVT, VT));
7831 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7833 return DAG.getBuildVector(VT, dl, Scalars);
7840 case ISD::VECREDUCE_ADD:
7841 case ISD::VECREDUCE_MUL:
7842 case ISD::VECREDUCE_AND:
7843 case ISD::VECREDUCE_OR:
7844 case ISD::VECREDUCE_XOR:
7846 case ISD::VECREDUCE_SMAX:
7847 case ISD::VECREDUCE_SMIN:
7849 case ISD::VECREDUCE_UMAX:
7850 case ISD::VECREDUCE_UMIN:
7857 SDValue Op = GetWidenedVector(
N->getOperand(0));
7858 EVT VT =
N->getValueType(0);
7859 EVT OrigVT =
N->getOperand(0).getValueType();
7860 EVT WideVT =
Op.getValueType();
7862 SDNodeFlags
Flags =
N->getFlags();
7864 unsigned Opc =
N->getOpcode();
7866 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7867 assert(NeutralElem &&
"Neutral element must exist");
7877 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7884 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7885 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7891 unsigned GCD = std::gcd(OrigElts, WideElts);
7894 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
7895 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
7896 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
7897 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7900 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
7901 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
7903 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
7912 EVT VT =
N->getValueType(0);
7914 EVT WideVT =
Op.getValueType();
7916 SDNodeFlags
Flags =
N->getFlags();
7918 unsigned Opc =
N->getOpcode();
7920 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7930 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7933 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7934 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7940 unsigned GCD = std::gcd(OrigElts, WideElts);
7943 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
7944 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
7945 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
7946 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
7949 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
7950 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
7952 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
7956 assert(
N->isVPOpcode() &&
"Expected VP opcode");
7959 SDValue Op = GetWidenedVector(
N->getOperand(1));
7961 Op.getValueType().getVectorElementCount());
7963 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
7964 {N->getOperand(0), Op, Mask, N->getOperand(3)},
7972 EVT VT =
N->getValueType(0);
7976 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
7977 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
7982 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
7988 EVT SrcVT =
Source.getValueType();
7992 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
7993 {Source, Mask, N->getOperand(2)},
N->getFlags());
8010 unsigned WidenEx = 0) {
8015 unsigned AlignInBits =
Align*8;
8017 EVT RetVT = WidenEltVT;
8022 if (Width == WidenEltWidth)
8033 (WidenWidth % MemVTWidth) == 0 &&
8035 (MemVTWidth <= Width ||
8036 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8037 if (MemVTWidth == WidenWidth)
8056 (WidenWidth % MemVTWidth) == 0 &&
8058 (MemVTWidth <= Width ||
8059 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8068 return std::nullopt;
8079 unsigned Start,
unsigned End) {
8080 SDLoc dl(LdOps[Start]);
8081 EVT LdTy = LdOps[Start].getValueType();
8089 for (
unsigned i = Start + 1; i != End; ++i) {
8090 EVT NewLdTy = LdOps[i].getValueType();
8091 if (NewLdTy != LdTy) {
8094 VecOp = DAG.
getNode(ISD::BITCAST, dl, NewVecVT, VecOp);
8101 return DAG.
getNode(ISD::BITCAST, dl, VecTy, VecOp);
8110 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8111 EVT LdVT =
LD->getMemoryVT();
8121 AAMDNodes AAInfo =
LD->getAAInfo();
8125 TypeSize WidthDiff = WidenWidth - LdWidth;
8132 std::optional<EVT> FirstVT =
8133 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8140 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8145 std::optional<EVT> NewVT = FirstVT;
8146 TypeSize RemainingWidth = LdWidth;
8147 TypeSize NewVTWidth = FirstVTWidth;
8149 RemainingWidth -= NewVTWidth;
8156 NewVTWidth = NewVT->getSizeInBits();
8162 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8163 LD->getBaseAlign(), MMOFlags, AAInfo);
8167 if (MemVTs.
empty()) {
8169 if (!FirstVT->isVector()) {
8174 return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
8176 if (FirstVT == WidenVT)
8181 unsigned NumConcat =
8184 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8185 ConcatOps[0] = LdOp;
8186 for (
unsigned i = 1; i != NumConcat; ++i)
8187 ConcatOps[i] = UndefVal;
8195 uint64_t ScaledOffset = 0;
8196 MachinePointerInfo MPI =
LD->getPointerInfo();
8202 for (EVT MemVT : MemVTs) {
8203 Align NewAlign = ScaledOffset == 0
8204 ?
LD->getBaseAlign()
8207 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8215 unsigned End = LdOps.
size();
8226 EVT LdTy = LdOps[i].getValueType();
8229 for (--i; i >= 0; --i) {
8230 LdTy = LdOps[i].getValueType();
8237 ConcatOps[--Idx] = LdOps[i];
8238 for (--i; i >= 0; --i) {
8239 EVT NewLdTy = LdOps[i].getValueType();
8240 if (NewLdTy != LdTy) {
8250 for (;
j != End-Idx; ++
j)
8251 WidenOps[j] = ConcatOps[Idx+j];
8253 WidenOps[j] = DAG.getUNDEF(LdTy);
8260 ConcatOps[--Idx] = LdOps[i];
8265 ArrayRef(&ConcatOps[Idx], End - Idx));
8271 SDValue UndefVal = DAG.getUNDEF(LdTy);
8274 for (; i != End-Idx; ++i)
8275 WidenOps[i] = ConcatOps[Idx+i];
8277 WidenOps[i] = UndefVal;
8288 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8289 EVT LdVT =
LD->getMemoryVT();
8298 AAMDNodes AAInfo =
LD->getAAInfo();
8302 "not yet supported");
8313 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8314 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8320 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8321 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8322 LD->getBaseAlign(), MMOFlags, AAInfo);
8327 SDValue UndefVal = DAG.getUNDEF(EltVT);
8328 for (; i != WidenNumElts; ++i)
8331 return DAG.getBuildVector(WidenVT, dl,
Ops);
8342 AAMDNodes AAInfo =
ST->getAAInfo();
8343 SDValue ValOp = GetWidenedVector(
ST->getValue());
8346 EVT StVT =
ST->getMemoryVT();
8354 "Mismatch between store and value types");
8358 MachinePointerInfo MPI =
ST->getPointerInfo();
8359 uint64_t ScaledOffset = 0;
8368 std::optional<EVT> NewVT =
8373 TypeSize NewVTWidth = NewVT->getSizeInBits();
8376 StWidth -= NewVTWidth;
8377 MemVTs.
back().second++;
8381 for (
const auto &Pair : MemVTs) {
8382 EVT NewVT = Pair.first;
8383 unsigned Count = Pair.second;
8389 Align NewAlign = ScaledOffset == 0
8390 ?
ST->getBaseAlign()
8392 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8393 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8409 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8410 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8411 ST->getBaseAlign(), MMOFlags, AAInfo);
8428 bool FillWithZeroes) {
8433 "input and widen element type must match");
8435 "cannot modify scalable vectors in this way");
8447 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8450 for (
unsigned i = 1; i != NumConcat; ++i)
8457 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8460 "Scalable vectors should have been handled already.");
8468 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8470 for (Idx = 0; Idx < MinNumElts; ++Idx)
8471 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8473 SDValue UndefVal = DAG.getUNDEF(EltVT);
8474 for (; Idx < WidenNumElts; ++Idx)
8475 Ops[Idx] = UndefVal;
8477 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8478 if (!FillWithZeroes)
8482 "We expect to never want to FillWithZeroes for non-integral types.");
8485 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8486 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8488 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8489 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.