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);
69 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
81 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
83 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
89 R = ScalarizeVecRes_VecInregOp(
N);
140 R = ScalarizeVecRes_UnaryOp(
N);
143 R = ScalarizeVecRes_ADDRSPACECAST(
N);
149 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
203 R = ScalarizeVecRes_BinOp(
N);
208 R = ScalarizeVecRes_CMP(
N);
214 R = ScalarizeVecRes_TernaryOp(
N);
217#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
218 case ISD::STRICT_##DAGN:
219#include "llvm/IR/ConstrainedOps.def"
220 R = ScalarizeVecRes_StrictFPOp(
N);
225 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
234 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
244 R = ScalarizeVecRes_FIX(
N);
250 SetScalarizedVector(
SDValue(
N, ResNo), R);
254 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
255 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
256 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
265 if (getTypeAction(
LHS.getValueType()) ==
267 LHS = GetScalarizedVector(
LHS);
268 RHS = GetScalarizedVector(
RHS);
270 EVT VT =
LHS.getValueType().getVectorElementType();
271 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
272 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
275 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
276 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
280 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
281 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
282 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
283 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
288 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
289 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
296DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
298 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
299 "Unexpected vector type!");
300 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
302 EVT VT0 =
N->getValueType(0);
303 EVT VT1 =
N->getValueType(1);
307 DAG.getNode(
N->getOpcode(), dl,
308 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
312 unsigned OtherNo = 1 - ResNo;
313 EVT OtherVT =
N->getValueType(OtherNo);
315 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
319 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
322 return SDValue(ScalarNode, ResNo);
327 unsigned NumOpers =
N->getNumOperands();
329 EVT ValueVTs[] = {VT, MVT::Other};
338 for (
unsigned i = 1; i < NumOpers; ++i) {
344 Oper = GetScalarizedVector(Oper);
353 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
354 Opers,
N->getFlags());
365 EVT ResVT =
N->getValueType(0);
366 EVT OvVT =
N->getValueType(1);
370 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
371 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
374 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
375 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
376 ScalarLHS = ElemsLHS[0];
377 ScalarRHS = ElemsRHS[0];
380 SDVTList ScalarVTs = DAG.getVTList(
382 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
383 {ScalarLHS, ScalarRHS},
N->getFlags())
387 unsigned OtherNo = 1 - ResNo;
388 EVT OtherVT =
N->getValueType(OtherNo);
390 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
394 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
397 return SDValue(ScalarNode, ResNo);
402 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
403 return GetScalarizedVector(
Op);
406SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
408 SDValue SourceValue =
N->getOperand(0);
409 SDValue SinkValue =
N->getOperand(1);
410 SDValue EltSizeInBytes =
N->getOperand(2);
411 SDValue LaneOffset =
N->getOperand(3);
419 if (IsReadAfterWrite)
427 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
432 return DAG.getNode(
ISD::OR,
DL, CmpVT, Cmp,
439 Op = GetScalarizedVector(
Op);
440 EVT NewVT =
N->getValueType(0).getVectorElementType();
445SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
455SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
457 N->getValueType(0).getVectorElementType(),
458 N->getOperand(0),
N->getOperand(1));
464 EVT OpVT =
Op.getValueType();
468 Op = GetScalarizedVector(
Op);
471 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
474 N->getValueType(0).getVectorElementType(),
Op,
478SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
479 SDValue Op = GetScalarizedVector(
N->getOperand(0));
480 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
484SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
489 if (
Op.getValueType() != EltVT)
497 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
498 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
508 assert(
N->isUnindexed() &&
"Indexed vector load?");
512 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
513 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
514 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
515 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
527 EVT OpVT =
Op.getValueType();
537 Op = GetScalarizedVector(
Op);
540 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
542 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
548 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
549 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
550 LHS, DAG.getValueType(ExtVT));
557 EVT OpVT =
Op.getValueType();
562 Op = GetScalarizedVector(
Op);
564 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
567 switch (
N->getOpcode()) {
579SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
582 EVT OpVT =
Op.getValueType();
592 Op = GetScalarizedVector(
Op);
595 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
598 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
599 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
600 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
603SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
615 EVT OpVT =
Cond.getValueType();
624 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
627 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
629 TLI.getBooleanContents(
false,
false);
636 if (TLI.getBooleanContents(
false,
false) !=
637 TLI.getBooleanContents(
false,
true)) {
641 EVT OpVT =
Cond->getOperand(0).getValueType();
643 VecBool = TLI.getBooleanContents(OpVT);
648 EVT CondVT =
Cond.getValueType();
649 if (ScalarBool != VecBool) {
650 switch (ScalarBool) {
658 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
665 Cond, DAG.getValueType(MVT::i1));
671 auto BoolVT = getSetCCResultType(CondVT);
672 if (BoolVT.bitsLT(CondVT))
675 return DAG.getSelect(SDLoc(
N),
677 GetScalarizedVector(
N->getOperand(2)));
681 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
682 return DAG.getSelect(SDLoc(
N),
683 LHS.getValueType(),
N->getOperand(0),
LHS,
684 GetScalarizedVector(
N->getOperand(2)));
688 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
690 N->getOperand(0),
N->getOperand(1),
691 LHS, GetScalarizedVector(
N->getOperand(3)),
696 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
699SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
703 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
705 return GetScalarizedVector(
N->getOperand(
Op));
708SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
710 EVT SrcVT = Src.getValueType();
715 Src = GetScalarizedVector(Src);
719 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
721 EVT DstVT =
N->getValueType(0).getVectorElementType();
722 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
726 assert(
N->getValueType(0).isVector() &&
727 N->getOperand(0).getValueType().isVector() &&
728 "Operand types must be vectors");
731 EVT OpVT =
LHS.getValueType();
732 EVT NVT =
N->getValueType(0).getVectorElementType();
737 LHS = GetScalarizedVector(
LHS);
738 RHS = GetScalarizedVector(
RHS);
741 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
742 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
752 return DAG.getNode(ExtendCode,
DL, NVT, Res);
763 Arg = GetScalarizedVector(Arg);
766 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
775 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
782bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
787 switch (
N->getOpcode()) {
790 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
797 Res = ScalarizeVecOp_BITCAST(
N);
800 Res = ScalarizeVecOp_FAKE_USE(
N);
814 Res = ScalarizeVecOp_UnaryOp(
N);
818 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
824 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
827 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
830 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
833 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
836 Res = ScalarizeVecOp_VSELECT(
N);
839 Res = ScalarizeVecOp_VSETCC(
N);
843 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
849 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
852 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
855 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
858 Res = ScalarizeVecOp_FP_EXTEND(
N);
875 Res = ScalarizeVecOp_VECREDUCE(
N);
879 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
883 Res = ScalarizeVecOp_CMP(
N);
888 if (!Res.
getNode())
return false;
896 "Invalid operand expansion");
898 ReplaceValueWith(
SDValue(
N, 0), Res);
905 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
907 N->getValueType(0), Elt);
912 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
913 "Fake Use: Unexpected vector type!");
914 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
915 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
921 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
922 "Unexpected vector type!");
923 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
925 N->getValueType(0).getScalarType(), Elt);
933SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
934 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
935 "Unexpected vector type!");
936 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
938 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
939 Elt,
N->getOperand(1));
947SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
948 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
949 "Unexpected vector type!");
950 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
952 {
N->getValueType(0).getScalarType(), MVT::Other },
953 {
N->getOperand(0), Elt });
963 ReplaceValueWith(
SDValue(
N, 0), Res);
968SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
970 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
971 Ops[i] = GetScalarizedVector(
N->getOperand(i));
972 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
977SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
981 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
982 SDValue ContainingVec =
N->getOperand(0);
990SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
991 EVT VT =
N->getValueType(0);
992 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1004 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1005 EVT VT =
N->getValueType(0);
1007 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1015 assert(
N->getValueType(0).isVector() &&
1016 N->getOperand(0).getValueType().isVector() &&
1017 "Operand types must be vectors");
1018 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1020 EVT VT =
N->getValueType(0);
1021 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1022 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1024 EVT OpVT =
N->getOperand(0).getValueType();
1036 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1042SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1044 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1045 assert(
N->getValueType(0).isVector() &&
1046 N->getOperand(1).getValueType().isVector() &&
1047 "Operand types must be vectors");
1048 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1050 EVT VT =
N->getValueType(0);
1052 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1053 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1056 EVT OpVT =
N->getOperand(1).getValueType();
1060 {Ch, LHS, RHS, CC});
1069 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1074 ReplaceValueWith(
SDValue(
N, 0), Res);
1081 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1082 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1085 if (
N->isTruncatingStore())
1086 return DAG.getTruncStore(
1087 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1088 N->getBasePtr(),
N->getPointerInfo(),
1089 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1090 N->getMemOperand()->getFlags(),
N->getAAInfo());
1092 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1093 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1094 N->getMemOperand()->getFlags(),
N->getAAInfo());
1099SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1100 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1101 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1103 N->getValueType(0).getVectorElementType(), Elt,
1108SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1110 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1111 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1114 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1124 ReplaceValueWith(
SDValue(
N, 0), Res);
1131 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1133 N->getValueType(0).getVectorElementType(), Elt);
1139SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1140 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1143 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1144 {
N->getOperand(0), Elt});
1153 ReplaceValueWith(
SDValue(
N, 0), Res);
1158 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1165SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1171 SDValue Op = GetScalarizedVector(VecOp);
1172 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1173 AccOp,
Op,
N->getFlags());
1177 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1178 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1193void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1198 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1201 switch (
N->getOpcode()) {
1204 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1213 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1220 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1236 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1239 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1248 case ISD::VP_LOAD_FF:
1251 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1258 case ISD::VP_GATHER:
1262 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1266 SplitVecRes_SETCC(
N,
Lo,
Hi);
1269 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1275 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1278 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1281 SplitVecRes_VECTOR_INTERLEAVE(
N);
1284 SplitVecRes_VAARG(
N,
Lo,
Hi);
1290 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1296 case ISD::VP_BITREVERSE:
1304 case ISD::VP_CTLZ_ZERO_UNDEF:
1306 case ISD::VP_CTTZ_ZERO_UNDEF:
1321 case ISD::VP_FFLOOR:
1326 case ISD::VP_FNEARBYINT:
1331 case ISD::VP_FP_EXTEND:
1333 case ISD::VP_FP_ROUND:
1335 case ISD::VP_FP_TO_SINT:
1337 case ISD::VP_FP_TO_UINT:
1343 case ISD::VP_LLRINT:
1345 case ISD::VP_FROUND:
1347 case ISD::VP_FROUNDEVEN:
1356 case ISD::VP_FROUNDTOZERO:
1358 case ISD::VP_SINT_TO_FP:
1360 case ISD::VP_TRUNCATE:
1362 case ISD::VP_UINT_TO_FP:
1365 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1368 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1374 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1380 case ISD::VP_SIGN_EXTEND:
1381 case ISD::VP_ZERO_EXTEND:
1382 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1401 case ISD::VP_FMINNUM:
1404 case ISD::VP_FMAXNUM:
1406 case ISD::VP_FMINIMUM:
1408 case ISD::VP_FMAXIMUM:
1417 case ISD::OR:
case ISD::VP_OR:
1437 case ISD::VP_FCOPYSIGN:
1438 SplitVecRes_BinOp(
N,
Lo,
Hi);
1445 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1449 SplitVecRes_CMP(
N,
Lo,
Hi);
1452#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1453 case ISD::STRICT_##DAGN:
1454#include "llvm/IR/ConstrainedOps.def"
1455 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1460 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1469 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1479 SplitVecRes_FIX(
N,
Lo,
Hi);
1481 case ISD::EXPERIMENTAL_VP_SPLICE:
1482 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1484 case ISD::EXPERIMENTAL_VP_REVERSE:
1485 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1491 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1494 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1503void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1505 uint64_t *ScaledOffset) {
1510 SDValue BytesIncrement = DAG.getVScale(
1513 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1515 *ScaledOffset += IncrementSize;
1525std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1526 return SplitMask(Mask, SDLoc(Mask));
1529std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1532 EVT MaskVT =
Mask.getValueType();
1534 GetSplitVector(Mask, MaskLo, MaskHi);
1536 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1537 return std::make_pair(MaskLo, MaskHi);
1542 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1544 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1547 const SDNodeFlags
Flags =
N->getFlags();
1548 unsigned Opcode =
N->getOpcode();
1549 if (
N->getNumOperands() == 2) {
1550 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1551 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1555 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1556 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1559 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1562 std::tie(EVLLo, EVLHi) =
1563 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1566 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1568 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1574 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1576 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1578 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1581 const SDNodeFlags
Flags =
N->getFlags();
1582 unsigned Opcode =
N->getOpcode();
1583 if (
N->getNumOperands() == 3) {
1584 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1585 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1589 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1590 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1593 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1596 std::tie(EVLLo, EVLHi) =
1597 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1600 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1602 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1606 LLVMContext &Ctxt = *DAG.getContext();
1612 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1614 GetSplitVector(
LHS, LHSLo, LHSHi);
1615 GetSplitVector(
RHS, RHSLo, RHSHi);
1617 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1618 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1622 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1623 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1628 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1630 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1634 unsigned Opcode =
N->getOpcode();
1635 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1637 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1646 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1653 switch (getTypeAction(InVT)) {
1668 GetExpandedOp(InOp,
Lo,
Hi);
1669 if (DAG.getDataLayout().isBigEndian())
1679 GetSplitVector(InOp,
Lo,
Hi);
1688 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1697 if (DAG.getDataLayout().isBigEndian())
1700 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1702 if (DAG.getDataLayout().isBigEndian())
1708void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1714 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1717 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1722 unsigned LaneOffset =
1725 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1727 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1734 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1737 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1740 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1745 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1747 unsigned NumSubvectors =
N->getNumOperands() / 2;
1748 if (NumSubvectors == 1) {
1749 Lo =
N->getOperand(0);
1750 Hi =
N->getOperand(1);
1755 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1764void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1771 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1786 GetSplitVector(Vec,
Lo,
Hi);
1789 EVT LoVT =
Lo.getValueType();
1799 if (IdxVal + SubElems <= LoElems) {
1807 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1809 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1815 SDValue WideSubVec = GetWidenedVector(SubVec);
1817 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1825 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1827 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1828 auto &MF = DAG.getMachineFunction();
1832 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1837 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1838 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1842 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1847 MachinePointerInfo MPI =
Load->getPointerInfo();
1848 IncrementPointer(Load, LoVT, MPI, StackPtr);
1851 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1860 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1865 EVT RHSVT =
RHS.getValueType();
1868 GetSplitVector(
RHS, RHSLo, RHSHi);
1870 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
1885 SDValue FpValue =
N->getOperand(0);
1887 GetSplitVector(FpValue, ArgLo, ArgHi);
1889 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1891 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1900 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1904 std::tie(LoVT, HiVT) =
1908 DAG.getValueType(LoVT));
1910 DAG.getValueType(HiVT));
1915 unsigned Opcode =
N->getOpcode();
1922 GetSplitVector(N0, InLo, InHi);
1924 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
1929 EVT OutLoVT, OutHiVT;
1930 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1932 assert((2 * OutNumElements) <= InNumElements &&
1933 "Illegal extend vector in reg split");
1942 SmallVector<int, 8> SplitHi(InNumElements, -1);
1943 for (
unsigned i = 0; i != OutNumElements; ++i)
1944 SplitHi[i] = i + OutNumElements;
1945 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1947 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
1948 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1953 unsigned NumOps =
N->getNumOperands();
1957 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1967 for (
unsigned i = 1; i <
NumOps; ++i) {
1972 EVT InVT =
Op.getValueType();
1977 GetSplitVector(
Op, OpLo, OpHi);
1979 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
1986 EVT LoValueVTs[] = {LoVT, MVT::Other};
1987 EVT HiValueVTs[] = {HiVT, MVT::Other};
1988 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1990 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
1996 Lo.getValue(1),
Hi.getValue(1));
2000 ReplaceValueWith(
SDValue(
N, 1), Chain);
2003SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2005 EVT VT =
N->getValueType(0);
2016 else if (NE > ResNE)
2020 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2024 for (i = 0; i !=
NE; ++i) {
2025 Operands[0] = Chain;
2026 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2027 SDValue Operand =
N->getOperand(j);
2031 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2033 Operands[
j] = Operand;
2037 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2045 for (; i < ResNE; ++i)
2050 ReplaceValueWith(
SDValue(
N, 1), Chain);
2054 return DAG.getBuildVector(VecVT, dl, Scalars);
2057void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2060 EVT ResVT =
N->getValueType(0);
2061 EVT OvVT =
N->getValueType(1);
2062 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2063 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2064 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2066 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2068 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2069 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2071 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2072 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2075 unsigned Opcode =
N->getOpcode();
2076 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2077 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2079 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2081 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2087 unsigned OtherNo = 1 - ResNo;
2088 EVT OtherVT =
N->getValueType(OtherNo);
2090 SetSplitVector(
SDValue(
N, OtherNo),
2096 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2100void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2106 GetSplitVector(Vec,
Lo,
Hi);
2109 unsigned IdxVal = CIdx->getZExtValue();
2110 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2111 if (IdxVal < LoNumElts) {
2113 Lo.getValueType(),
Lo, Elt, Idx);
2116 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2136 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2138 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2139 auto &MF = DAG.getMachineFunction();
2143 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2148 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2149 Store = DAG.getTruncStore(
2155 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2158 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2162 MachinePointerInfo MPI =
Load->getPointerInfo();
2163 IncrementPointer(Load, LoVT, MPI, StackPtr);
2165 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2168 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2169 if (LoVT !=
Lo.getValueType())
2171 if (HiVT !=
Hi.getValueType())
2179 assert(
N->getValueType(0).isScalableVector() &&
2180 "Only scalable vectors are supported for STEP_VECTOR");
2181 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2202 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2203 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2205 Hi = DAG.getPOISON(HiVT);
2217 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2223 EVT MemoryVT =
LD->getMemoryVT();
2225 AAMDNodes AAInfo =
LD->getAAInfo();
2227 EVT LoMemVT, HiMemVT;
2228 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2232 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2233 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2234 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2239 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2242 MachinePointerInfo MPI;
2243 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2246 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2255 ReplaceValueWith(
SDValue(LD, 1), Ch);
2260 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2263 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2269 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2270 Align Alignment =
LD->getBaseAlign();
2273 EVT MemoryVT =
LD->getMemoryVT();
2275 EVT LoMemVT, HiMemVT;
2276 bool HiIsEmpty =
false;
2277 std::tie(LoMemVT, HiMemVT) =
2278 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2283 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2286 GetSplitVector(Mask, MaskLo, MaskHi);
2288 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2293 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2295 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2301 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2302 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2310 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2311 LD->isExpandingLoad());
2313 MachinePointerInfo MPI;
2315 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2317 MPI =
LD->getPointerInfo().getWithOffset(
2320 MMO = DAG.getMachineFunction().getMachineMemOperand(
2322 Alignment,
LD->getAAInfo(),
LD->getRanges());
2324 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2325 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2326 LD->isExpandingLoad());
2336 ReplaceValueWith(
SDValue(LD, 1), Ch);
2342 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2346 Align Alignment =
LD->getBaseAlign();
2353 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2356 GetSplitVector(Mask, MaskLo, MaskHi);
2358 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2362 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2364 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2369 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2372 Hi = DAG.getPOISON(HiVT);
2374 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2375 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2381 "Indexed VP strided load during type legalization!");
2383 "Unexpected indexed variable-length load offset");
2388 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2390 EVT LoMemVT, HiMemVT;
2391 bool HiIsEmpty =
false;
2392 std::tie(LoMemVT, HiMemVT) =
2393 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2398 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2401 GetSplitVector(Mask, LoMask, HiMask);
2403 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2407 std::tie(LoEVL, HiEVL) =
2411 Lo = DAG.getStridedLoadVP(
2438 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2445 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2456 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2464 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2469 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2479 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2482 GetSplitVector(Mask, MaskLo, MaskHi);
2484 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2488 EVT LoMemVT, HiMemVT;
2489 bool HiIsEmpty =
false;
2490 std::tie(LoMemVT, HiMemVT) =
2491 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2493 SDValue PassThruLo, PassThruHi;
2495 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2497 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2499 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2503 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2513 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2516 MachinePointerInfo MPI;
2523 MMO = DAG.getMachineFunction().getMachineMemOperand(
2527 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2539 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2547 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2555 }
Ops = [&]() -> Operands {
2557 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2560 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2563 EVT MemoryVT =
N->getMemoryVT();
2564 Align Alignment =
N->getBaseAlign();
2569 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2571 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2574 EVT LoMemVT, HiMemVT;
2576 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2579 if (getTypeAction(
Ops.Index.getValueType()) ==
2581 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2583 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2586 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2588 Alignment,
N->getAAInfo(),
N->getRanges());
2591 SDValue PassThru = MGT->getPassThru();
2592 SDValue PassThruLo, PassThruHi;
2595 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2597 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2602 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2603 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2604 OpsLo, MMO, IndexTy, ExtType);
2606 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2607 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2608 OpsHi, MMO, IndexTy, ExtType);
2612 std::tie(EVLLo, EVLHi) =
2613 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2615 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2616 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2617 MMO, VPGT->getIndexType());
2619 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2620 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2621 MMO, VPGT->getIndexType());
2631 ReplaceValueWith(
SDValue(
N, 1), Ch);
2645 EVT VecVT =
N->getValueType(0);
2647 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2648 bool HasCustomLowering =
false;
2655 HasCustomLowering =
true;
2661 SDValue Passthru =
N->getOperand(2);
2662 if (!HasCustomLowering) {
2663 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2664 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2671 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2672 std::tie(LoMask, HiMask) = SplitMask(Mask);
2674 SDValue UndefPassthru = DAG.getUNDEF(LoVT);
2679 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2680 MachineFunction &MF = DAG.getMachineFunction();
2692 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2694 SDValue Chain = DAG.getEntryNode();
2695 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2699 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2704 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2708 assert(
N->getValueType(0).isVector() &&
2709 N->getOperand(0).getValueType().isVector() &&
2710 "Operand types must be vectors");
2714 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2718 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2720 GetSplitVector(
N->getOperand(0), LL, LH);
2722 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2724 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2726 GetSplitVector(
N->getOperand(1), RL, RH);
2728 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2731 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2732 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2734 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2735 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2736 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2737 std::tie(EVLLo, EVLHi) =
2738 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2739 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2741 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2751 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2755 EVT InVT =
N->getOperand(0).getValueType();
2757 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2759 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2761 const SDNodeFlags
Flags =
N->getFlags();
2762 unsigned Opcode =
N->getOpcode();
2763 if (
N->getNumOperands() <= 2) {
2765 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2766 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2768 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2769 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2774 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2775 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2778 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2781 std::tie(EVLLo, EVLHi) =
2782 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2785 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2791 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2795 EVT InVT =
N->getOperand(0).getValueType();
2797 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2799 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2802 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2803 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2804 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2805 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2808void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2813 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2814 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2818 EVT InVT =
N->getOperand(0).getValueType();
2820 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2822 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2824 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2825 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2827 SDNode *HiNode =
Hi.getNode();
2828 SDNode *LoNode =
Lo.getNode();
2831 unsigned OtherNo = 1 - ResNo;
2832 EVT OtherVT =
N->getValueType(OtherNo);
2840 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2847 EVT SrcVT =
N->getOperand(0).getValueType();
2848 EVT DestVT =
N->getValueType(0);
2850 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2867 LLVMContext &Ctx = *DAG.getContext();
2871 EVT SplitLoVT, SplitHiVT;
2872 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2873 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2874 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2875 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2876 N->dump(&DAG);
dbgs() <<
"\n");
2877 if (!
N->isVPOpcode()) {
2880 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2882 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2884 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2885 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2891 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2892 N->getOperand(1),
N->getOperand(2));
2894 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2897 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2900 std::tie(EVLLo, EVLHi) =
2901 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2903 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2904 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2909 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2917 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2918 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2924 return N.getResNo() == 0 &&
2928 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2930 ArrayRef<int>
Mask) {
2933 "Expected build vector node.");
2936 for (
unsigned I = 0;
I < NewElts; ++
I) {
2939 unsigned Idx =
Mask[
I];
2941 Ops[
I] = Input2.getOperand(Idx - NewElts);
2943 Ops[
I] = Input1.getOperand(Idx);
2948 return DAG.getBuildVector(NewVT,
DL,
Ops);
2954 SmallVector<int> OrigMask(
N->getMask());
2956 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2957 &
DL](SmallVectorImpl<int> &
Mask) {
2959 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2960 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2971 for (
auto &
P : ShufflesIdxs) {
2972 if (
P.second.size() < 2)
2976 for (
int &Idx : Mask) {
2979 unsigned SrcRegIdx = Idx / NewElts;
2980 if (Inputs[SrcRegIdx].
isUndef()) {
2988 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2993 Idx = MaskElt % NewElts +
2994 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3000 Inputs[
P.second[0]] =
P.first.first;
3001 Inputs[
P.second[1]] =
P.first.second;
3004 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3007 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3008 for (
int &Idx : Mask) {
3011 unsigned SrcRegIdx = Idx / NewElts;
3012 if (Inputs[SrcRegIdx].
isUndef()) {
3019 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3020 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3023 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3025 if (UsedSubVector.count() > 1) {
3027 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3028 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3030 if (Pairs.
empty() || Pairs.
back().size() == 2)
3032 if (UsedSubVector.test(2 *
I)) {
3033 Pairs.
back().emplace_back(
I, 0);
3035 assert(UsedSubVector.test(2 *
I + 1) &&
3036 "Expected to be used one of the subvectors.");
3037 Pairs.
back().emplace_back(
I, 1);
3040 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3042 for (
int &Idx : Mask) {
3045 unsigned SrcRegIdx = Idx / NewElts;
3047 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3048 return Idxs.front().first == SrcRegIdx ||
3049 Idxs.back().first == SrcRegIdx;
3051 if (It == Pairs.
end())
3053 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3054 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3057 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3058 Inputs[Idxs.front().first] = DAG.
getNode(
3060 Inputs[Idxs.front().first].getValueType(),
3061 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3062 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3071 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3075 if (Shuffle->getOperand(0).getValueType() != NewVT)
3078 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3079 !Shuffle->isSplat()) {
3081 }
else if (!Inputs[
I].hasOneUse() &&
3082 !Shuffle->getOperand(1).isUndef()) {
3084 for (
int &Idx : Mask) {
3087 unsigned SrcRegIdx = Idx / NewElts;
3090 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3095 int OpIdx = MaskElt / NewElts;
3109 if (Shuffle->getOperand(
OpIdx).isUndef())
3111 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3112 if (It == std::end(Inputs))
3114 int FoundOp = std::distance(std::begin(Inputs), It);
3117 for (
int &Idx : Mask) {
3120 unsigned SrcRegIdx = Idx / NewElts;
3123 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3128 int MaskIdx = MaskElt / NewElts;
3129 if (
OpIdx == MaskIdx)
3130 Idx = MaskElt % NewElts + FoundOp * NewElts;
3141 for (
int &Idx : Mask) {
3144 unsigned SrcRegIdx = Idx / NewElts;
3147 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3148 int OpIdx = MaskElt / NewElts;
3151 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3157 TryPeekThroughShufflesInputs(OrigMask);
3159 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3160 NewElts](SmallVectorImpl<int> &
Mask) {
3161 SetVector<SDValue> UniqueInputs;
3162 SetVector<SDValue> UniqueConstantInputs;
3163 for (
const auto &
I : Inputs) {
3165 UniqueConstantInputs.
insert(
I);
3166 else if (!
I.isUndef())
3171 if (UniqueInputs.
size() != std::size(Inputs)) {
3172 auto &&UniqueVec = UniqueInputs.
takeVector();
3173 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3174 unsigned ConstNum = UniqueConstantVec.size();
3175 for (
int &Idx : Mask) {
3178 unsigned SrcRegIdx = Idx / NewElts;
3179 if (Inputs[SrcRegIdx].
isUndef()) {
3183 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3184 if (It != UniqueConstantVec.end()) {
3185 Idx = (Idx % NewElts) +
3186 NewElts * std::distance(UniqueConstantVec.begin(), It);
3187 assert(Idx >= 0 &&
"Expected defined mask idx.");
3190 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3191 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3192 Idx = (Idx % NewElts) +
3193 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3194 assert(Idx >= 0 &&
"Expected defined mask idx.");
3196 copy(UniqueConstantVec, std::begin(Inputs));
3197 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3200 MakeUniqueInputs(OrigMask);
3202 copy(Inputs, std::begin(OrigInputs));
3208 unsigned FirstMaskIdx =
High * NewElts;
3211 assert(!Output &&
"Expected default initialized initial value.");
3212 TryPeekThroughShufflesInputs(Mask);
3213 MakeUniqueInputs(Mask);
3215 copy(Inputs, std::begin(TmpInputs));
3218 bool SecondIteration =
false;
3219 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3224 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3225 SecondIteration =
true;
3226 return SecondIteration;
3229 Mask, std::size(Inputs), std::size(Inputs),
3231 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3232 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3233 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3235 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3237 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3238 DAG.getUNDEF(NewVT), Mask);
3239 Inputs[Idx] = Output;
3241 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3242 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3243 unsigned Idx2,
bool ) {
3244 if (AccumulateResults(Idx1)) {
3247 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3249 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3250 Inputs[Idx2], Mask);
3254 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3256 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3257 TmpInputs[Idx2], Mask);
3259 Inputs[Idx1] = Output;
3261 copy(OrigInputs, std::begin(Inputs));
3266 EVT OVT =
N->getValueType(0);
3273 const Align Alignment =
3274 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3276 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3277 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3282 ReplaceValueWith(
SDValue(
N, 1), Chain);
3287 EVT DstVTLo, DstVTHi;
3288 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3292 EVT SrcVT =
N->getOperand(0).getValueType();
3294 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3296 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3298 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3299 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3305 GetSplitVector(
N->getOperand(0), InLo, InHi);
3316 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3317 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3322 EVT VT =
N->getValueType(0);
3329 Align Alignment = DAG.getReducedAlign(VT,
false);
3334 EVT PtrVT =
StackPtr.getValueType();
3335 auto &MF = DAG.getMachineFunction();
3339 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3342 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3348 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3349 DAG.getConstant(1,
DL, PtrVT));
3351 DAG.getConstant(EltWidth,
DL, PtrVT));
3353 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3355 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3356 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3357 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3360 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3362 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3367 EVT VT =
N->getValueType(0);
3379 EVL1 = ZExtPromotedInteger(EVL1);
3381 Align Alignment = DAG.getReducedAlign(VT,
false);
3386 EVT PtrVT =
StackPtr.getValueType();
3387 auto &MF = DAG.getMachineFunction();
3391 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3394 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3398 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3400 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3401 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3402 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3406 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3411 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3412 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3414 uint64_t TrailingElts = -
Imm;
3416 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3425 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3429 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3431 DAG.getVectorIdxConstant(0,
DL));
3437void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3445 GetSplitVector(Acc, AccLo, AccHi);
3446 unsigned Opcode =
N->getOpcode();
3458 GetSplitVector(Input1, Input1Lo, Input1Hi);
3459 GetSplitVector(Input2, Input2Lo, Input2Hi);
3462 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3463 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3466void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3474 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3482void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3483 unsigned Factor =
N->getNumOperands();
3486 for (
unsigned i = 0; i != Factor; ++i) {
3488 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3490 Ops[i * 2 + 1] = OpHi;
3501 for (
unsigned i = 0; i != Factor; ++i)
3505void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3506 unsigned Factor =
N->getNumOperands();
3509 for (
unsigned i = 0; i != Factor; ++i) {
3511 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3513 Ops[i + Factor] = OpHi;
3524 for (
unsigned i = 0; i != Factor; ++i) {
3525 unsigned IdxLo = 2 * i;
3526 unsigned IdxHi = 2 * i + 1;
3527 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3528 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3540bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3545 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3548 switch (
N->getOpcode()) {
3551 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3561 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3567 case ISD::VP_TRUNCATE:
3569 Res = SplitVecOp_TruncateHelper(
N);
3572 case ISD::VP_FP_ROUND:
3581 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3588 case ISD::VP_SCATTER:
3592 case ISD::VP_GATHER:
3596 Res = SplitVecOp_VSELECT(
N, OpNo);
3599 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3605 case ISD::VP_SINT_TO_FP:
3606 case ISD::VP_UINT_TO_FP:
3607 if (
N->getValueType(0).bitsLT(
3608 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3609 Res = SplitVecOp_TruncateHelper(
N);
3611 Res = SplitVecOp_UnaryOp(
N);
3615 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3619 case ISD::VP_FP_TO_SINT:
3620 case ISD::VP_FP_TO_UINT:
3633 Res = SplitVecOp_UnaryOp(
N);
3636 Res = SplitVecOp_FPOpDifferentTypes(
N);
3641 Res = SplitVecOp_CMP(
N);
3645 Res = SplitVecOp_FAKE_USE(
N);
3650 Res = SplitVecOp_ExtVecInRegOp(
N);
3668 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3672 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3674 case ISD::VP_REDUCE_FADD:
3675 case ISD::VP_REDUCE_SEQ_FADD:
3676 case ISD::VP_REDUCE_FMUL:
3677 case ISD::VP_REDUCE_SEQ_FMUL:
3678 case ISD::VP_REDUCE_ADD:
3679 case ISD::VP_REDUCE_MUL:
3680 case ISD::VP_REDUCE_AND:
3681 case ISD::VP_REDUCE_OR:
3682 case ISD::VP_REDUCE_XOR:
3683 case ISD::VP_REDUCE_SMAX:
3684 case ISD::VP_REDUCE_SMIN:
3685 case ISD::VP_REDUCE_UMAX:
3686 case ISD::VP_REDUCE_UMIN:
3687 case ISD::VP_REDUCE_FMAX:
3688 case ISD::VP_REDUCE_FMIN:
3689 case ISD::VP_REDUCE_FMAXIMUM:
3690 case ISD::VP_REDUCE_FMINIMUM:
3691 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3693 case ISD::VP_CTTZ_ELTS:
3694 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3695 Res = SplitVecOp_VP_CttzElements(
N);
3698 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3704 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3709 if (!Res.
getNode())
return false;
3716 if (
N->isStrictFPOpcode())
3718 "Invalid operand expansion");
3721 "Invalid operand expansion");
3723 ReplaceValueWith(
SDValue(
N, 0), Res);
3727SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3730 assert(OpNo == 0 &&
"Illegal operand must be mask");
3737 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3740 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3741 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3742 "Lo and Hi have differing types");
3745 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3746 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3748 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3749 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3750 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3751 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3761SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3764 assert(OpNo == 1 &&
"Illegal operand must be mask");
3769 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3771 EVT VecVT =
N->getValueType(0);
3775SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3776 EVT ResVT =
N->getValueType(0);
3782 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3783 GetSplitVector(VecOp,
Lo,
Hi);
3785 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3790 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3791 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3795 EVT ResVT =
N->getValueType(0);
3801 SDNodeFlags
Flags =
N->getFlags();
3804 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3805 GetSplitVector(VecOp,
Lo,
Hi);
3807 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3813 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3816SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3817 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3818 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3820 unsigned Opc =
N->getOpcode();
3821 EVT ResVT =
N->getValueType(0);
3827 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3828 GetSplitVector(VecOp,
Lo,
Hi);
3831 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3834 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3836 const SDNodeFlags
Flags =
N->getFlags();
3840 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3845 EVT ResVT =
N->getValueType(0);
3848 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3849 EVT InVT =
Lo.getValueType();
3854 if (
N->isStrictFPOpcode()) {
3855 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3856 {N->getOperand(0), Lo});
3857 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3858 {N->getOperand(0), Hi});
3867 ReplaceValueWith(
SDValue(
N, 1), Ch);
3868 }
else if (
N->getNumOperands() == 3) {
3869 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3870 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3871 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3872 std::tie(EVLLo, EVLHi) =
3873 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3874 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3875 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3877 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3878 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3887 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3897 EVT ResVT =
N->getValueType(0);
3899 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3903 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3909 Lo = BitConvertToInteger(
Lo);
3910 Hi = BitConvertToInteger(
Hi);
3912 if (DAG.getDataLayout().isBigEndian())
3920 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3922 EVT ResVT =
N->getValueType(0);
3930 GetSplitVector(SubVec,
Lo,
Hi);
3939 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3941 return SecondInsertion;
3944SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3951 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3953 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
3955 ElementCount IdxVal =
3959 EVT SrcVT =
N->getOperand(0).getValueType();
3978 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
3979 LoEltsMin - IdxValMin);
3980 DAG.ExtractVectorElements(
Hi, Elts, 0,
3983 return DAG.getBuildVector(SubVT, dl, Elts);
3987 ElementCount ExtractIdx = IdxVal - LoElts;
3989 return DAG.getExtractSubvector(dl, SubVT,
Hi,
3992 EVT HiVT =
Hi.getValueType();
3994 "Only fixed-vector extracts are supported in this case");
4004 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4005 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4011 "Extracting scalable subvector from fixed-width unsupported");
4019 "subvector from a scalable predicate vector");
4025 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4027 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4028 auto &MF = DAG.getMachineFunction();
4032 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4036 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4039 SubVT, dl, Store, StackPtr,
4043SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4049 uint64_t IdxVal =
Index->getZExtValue();
4052 GetSplitVector(Vec,
Lo,
Hi);
4054 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4056 if (IdxVal < LoElts)
4057 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4060 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4065 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4077 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4083 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4085 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4086 auto &MF = DAG.getMachineFunction();
4089 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4093 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4097 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4099 return DAG.getExtLoad(
4110 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4118 SplitVecRes_Gather(
N,
Lo,
Hi);
4121 ReplaceValueWith(
SDValue(
N, 0), Res);
4126 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4130 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4132 SDValue EVL =
N->getVectorLength();
4134 Align Alignment =
N->getBaseAlign();
4140 GetSplitVector(
Data, DataLo, DataHi);
4142 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4147 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4150 GetSplitVector(Mask, MaskLo, MaskHi);
4152 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4155 EVT MemoryVT =
N->getMemoryVT();
4156 EVT LoMemVT, HiMemVT;
4157 bool HiIsEmpty =
false;
4158 std::tie(LoMemVT, HiMemVT) =
4159 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4163 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4166 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4171 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4172 N->getAddressingMode(),
N->isTruncatingStore(),
4173 N->isCompressingStore());
4179 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4180 N->isCompressingStore());
4182 MachinePointerInfo MPI;
4186 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4191 MMO = DAG.getMachineFunction().getMachineMemOperand(
4193 Alignment,
N->getAAInfo(),
N->getRanges());
4195 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4196 N->getAddressingMode(),
N->isTruncatingStore(),
4197 N->isCompressingStore());
4206 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4207 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4214 GetSplitVector(
Data, LoData, HiData);
4216 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4218 EVT LoMemVT, HiMemVT;
4219 bool HiIsEmpty =
false;
4220 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4226 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4227 else if (getTypeAction(
Mask.getValueType()) ==
4229 GetSplitVector(Mask, LoMask, HiMask);
4231 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4234 std::tie(LoEVL, HiEVL) =
4235 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4239 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4240 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4241 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4252 EVT PtrVT =
N->getBasePtr().getValueType();
4255 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4258 Align Alignment =
N->getBaseAlign();
4263 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4264 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4266 Alignment,
N->getAAInfo(),
N->getRanges());
4269 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4270 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4271 N->isCompressingStore());
4280 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4284 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4287 Align Alignment =
N->getBaseAlign();
4293 GetSplitVector(
Data, DataLo, DataHi);
4295 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4300 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4303 GetSplitVector(Mask, MaskLo, MaskHi);
4305 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4308 EVT MemoryVT =
N->getMemoryVT();
4309 EVT LoMemVT, HiMemVT;
4310 bool HiIsEmpty =
false;
4311 std::tie(LoMemVT, HiMemVT) =
4312 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4315 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4320 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4321 N->getAddressingMode(),
N->isTruncatingStore(),
4322 N->isCompressingStore());
4330 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4331 N->isCompressingStore());
4333 MachinePointerInfo MPI;
4337 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4342 MMO = DAG.getMachineFunction().getMachineMemOperand(
4344 Alignment,
N->getAAInfo(),
N->getRanges());
4346 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4347 N->getAddressingMode(),
N->isTruncatingStore(),
4348 N->isCompressingStore());
4361 EVT MemoryVT =
N->getMemoryVT();
4362 Align Alignment =
N->getBaseAlign();
4369 }
Ops = [&]() -> Operands {
4371 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4375 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4380 EVT LoMemVT, HiMemVT;
4381 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4386 GetSplitVector(
Ops.Data, DataLo, DataHi);
4388 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4393 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4395 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4399 if (getTypeAction(
Ops.Index.getValueType()) ==
4401 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4403 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4407 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4409 Alignment,
N->getAAInfo(),
N->getRanges());
4412 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4414 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4415 MSC->getIndexType(), MSC->isTruncatingStore());
4420 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4421 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4422 MMO, MSC->getIndexType(),
4423 MSC->isTruncatingStore());
4427 std::tie(EVLLo, EVLHi) =
4428 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4430 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4431 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4432 VPSC->getIndexType());
4437 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4438 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4439 VPSC->getIndexType());
4443 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4444 assert(OpNo == 1 &&
"Can only split the stored value");
4447 bool isTruncating =
N->isTruncatingStore();
4450 EVT MemoryVT =
N->getMemoryVT();
4451 Align Alignment =
N->getBaseAlign();
4453 AAMDNodes AAInfo =
N->getAAInfo();
4455 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4457 EVT LoMemVT, HiMemVT;
4458 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4462 return TLI.scalarizeVectorStore(
N, DAG);
4465 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4466 Alignment, MMOFlags, AAInfo);
4468 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4471 MachinePointerInfo MPI;
4472 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4475 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4476 HiMemVT, Alignment, MMOFlags, AAInfo);
4478 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4494 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4500 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4521 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4522 SDValue InVec =
N->getOperand(OpNo);
4524 EVT OutVT =
N->getValueType(0);
4532 EVT LoOutVT, HiOutVT;
4533 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4534 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4539 if (isTypeLegal(LoOutVT) ||
4540 InElementSize <= OutElementSize * 2)
4541 return SplitVecOp_UnaryOp(
N);
4550 return SplitVecOp_UnaryOp(
N);
4554 GetSplitVector(InVec, InLoVec, InHiVec);
4560 EVT HalfElementVT = IsFloat ?
4562 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4569 if (
N->isStrictFPOpcode()) {
4570 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4571 {N->getOperand(0), InLoVec});
4572 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4573 {N->getOperand(0), InHiVec});
4579 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4580 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4584 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4592 if (
N->isStrictFPOpcode()) {
4596 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4604 DAG.getTargetConstant(
4605 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4612 assert(
N->getValueType(0).isVector() &&
4613 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4614 "Operand types must be vectors");
4616 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4618 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4619 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4621 EVT VT =
N->getValueType(0);
4627 }
else if (isStrict) {
4628 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4629 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4630 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4631 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4634 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4636 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4637 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4638 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4639 std::tie(EVLLo, EVLHi) =
4640 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4641 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4642 N->getOperand(2), MaskLo, EVLLo);
4643 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4644 N->getOperand(2), MaskHi, EVLHi);
4653 EVT ResVT =
N->getValueType(0);
4656 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4657 EVT InVT =
Lo.getValueType();
4662 if (
N->isStrictFPOpcode()) {
4663 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4664 {N->getOperand(0), Lo, N->getOperand(2)});
4665 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4666 {N->getOperand(0), Hi, N->getOperand(2)});
4670 Lo.getValue(1),
Hi.getValue(1));
4671 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4672 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4673 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4674 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4675 std::tie(EVLLo, EVLHi) =
4676 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4677 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4678 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4692SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4695 EVT LHSLoVT, LHSHiVT;
4696 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4698 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4699 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4702 std::tie(LHSLo, LHSHi) =
4703 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4706 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4709 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4715 LLVMContext &Ctxt = *DAG.getContext();
4718 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4719 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4720 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4722 EVT ResVT =
N->getValueType(0);
4727 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4728 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4734 EVT ResVT =
N->getValueType(0);
4737 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4738 EVT InVT =
Lo.getValueType();
4744 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4745 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4752 EVT ResVT =
N->getValueType(0);
4756 GetSplitVector(VecOp,
Lo,
Hi);
4758 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4759 auto [EVLLo, EVLHi] =
4761 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4767 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4769 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4770 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4773SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4784 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4785 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4786 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4787 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4788 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4789 OpsLo, MMO, IndexType);
4790 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4791 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4795SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4798 "Accumulator should already be a legal type, and shouldn't need "
4799 "further splitting");
4802 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4803 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4804 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4805 unsigned Opcode =
N->getOpcode();
4808 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4809 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4816void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4817 unsigned WidenResNo) {
4818 unsigned NumResults =
N->getNumValues();
4819 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4820 if (ResNo == WidenResNo)
4822 EVT ResVT =
N->getValueType(ResNo);
4828 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4829 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4834void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4835 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4838 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4843 auto unrollExpandedOp = [&]() {
4848 EVT VT =
N->getValueType(0);
4849 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4850 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4851 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
4853 if (
N->getNumValues() > 1)
4854 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4860 switch (
N->getOpcode()) {
4863 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4871 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4875 Res = WidenVecRes_ADDRSPACECAST(
N);
4882 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4886 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4890 Res = WidenVecRes_ScalarOp(
N);
4895 case ISD::VP_SELECT:
4897 Res = WidenVecRes_Select(
N);
4901 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4903 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4910 case ISD::VP_LOAD_FF:
4913 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4917 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4925 case ISD::VP_GATHER:
4929 Res = WidenVecRes_VECTOR_REVERSE(
N);
4932 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4942 case ISD::OR:
case ISD::VP_OR:
4950 case ISD::VP_FMINNUM:
4953 case ISD::VP_FMAXNUM:
4955 case ISD::VP_FMINIMUM:
4957 case ISD::VP_FMAXIMUM:
4990 case ISD::VP_FCOPYSIGN:
4991 Res = WidenVecRes_Binary(
N);
4996 Res = WidenVecRes_CMP(
N);
5002 if (unrollExpandedOp())
5017 Res = WidenVecRes_BinaryCanTrap(
N);
5026 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5029#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5030 case ISD::STRICT_##DAGN:
5031#include "llvm/IR/ConstrainedOps.def"
5032 Res = WidenVecRes_StrictFP(
N);
5041 Res = WidenVecRes_OverflowOp(
N, ResNo);
5045 Res = WidenVecRes_FCOPYSIGN(
N);
5050 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5055 if (!unrollExpandedOp())
5056 Res = WidenVecRes_ExpOp(
N);
5062 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5067 case ISD::VP_FP_EXTEND:
5069 case ISD::VP_FP_ROUND:
5071 case ISD::VP_FP_TO_SINT:
5073 case ISD::VP_FP_TO_UINT:
5075 case ISD::VP_SIGN_EXTEND:
5077 case ISD::VP_SINT_TO_FP:
5078 case ISD::VP_TRUNCATE:
5081 case ISD::VP_UINT_TO_FP:
5083 case ISD::VP_ZERO_EXTEND:
5084 Res = WidenVecRes_Convert(
N);
5089 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5095 case ISD::VP_LLRINT:
5098 Res = WidenVecRes_XROUND(
N);
5124 if (unrollExpandedOp())
5134 case ISD::VP_BITREVERSE:
5140 case ISD::VP_CTLZ_ZERO_UNDEF:
5146 case ISD::VP_CTTZ_ZERO_UNDEF:
5151 case ISD::VP_FFLOOR:
5153 case ISD::VP_FNEARBYINT:
5154 case ISD::VP_FROUND:
5155 case ISD::VP_FROUNDEVEN:
5156 case ISD::VP_FROUNDTOZERO:
5161 Res = WidenVecRes_Unary(
N);
5168 Res = WidenVecRes_Ternary(
N);
5174 if (!unrollExpandedOp())
5175 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5182 SetWidenedVector(
SDValue(
N, ResNo), Res);
5188 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5189 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5190 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5191 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5192 if (
N->getNumOperands() == 3)
5193 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5195 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5196 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5200 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5201 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5207 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5208 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5209 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5210 if (
N->getNumOperands() == 2)
5211 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5214 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5215 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5219 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5220 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5224 LLVMContext &Ctxt = *DAG.getContext();
5229 EVT OpVT =
LHS.getValueType();
5231 LHS = GetWidenedVector(
LHS);
5232 RHS = GetWidenedVector(
RHS);
5233 OpVT =
LHS.getValueType();
5236 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5239 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5245SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5248 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5249 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5250 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5252 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5261 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5264 if (ConcatEnd == 1) {
5265 VT = ConcatOps[0].getValueType();
5267 return ConcatOps[0];
5270 SDLoc dl(ConcatOps[0]);
5277 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5278 int Idx = ConcatEnd - 1;
5279 VT = ConcatOps[Idx--].getValueType();
5280 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5293 unsigned NumToInsert = ConcatEnd - Idx - 1;
5294 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5296 ConcatOps[Idx+1] = VecOp;
5297 ConcatEnd = Idx + 2;
5303 unsigned RealVals = ConcatEnd - Idx - 1;
5304 unsigned SubConcatEnd = 0;
5305 unsigned SubConcatIdx = Idx + 1;
5306 while (SubConcatEnd < RealVals)
5307 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5308 while (SubConcatEnd < OpsToConcat)
5309 SubConcatOps[SubConcatEnd++] = undefVec;
5311 NextVT, SubConcatOps);
5312 ConcatEnd = SubConcatIdx + 1;
5317 if (ConcatEnd == 1) {
5318 VT = ConcatOps[0].getValueType();
5320 return ConcatOps[0];
5325 if (
NumOps != ConcatEnd ) {
5327 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5328 ConcatOps[j] = UndefVal;
5336 unsigned Opcode =
N->getOpcode();
5338 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5342 const SDNodeFlags
Flags =
N->getFlags();
5343 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5344 NumElts = NumElts / 2;
5348 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5350 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5351 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5352 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5360 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5363 TLI.isTypeLegal(WideMaskVT)) {
5364 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5365 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5366 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5368 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5369 N->getValueType(0).getVectorElementCount());
5370 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5384 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5385 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5386 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5389 unsigned ConcatEnd = 0;
5397 while (CurNumElts != 0) {
5398 while (CurNumElts >= NumElts) {
5399 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5400 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5401 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5403 CurNumElts -= NumElts;
5406 NumElts = NumElts / 2;
5408 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5411 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5412 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5413 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5414 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5425 switch (
N->getOpcode()) {
5428 return WidenVecRes_STRICT_FSETCC(
N);
5435 return WidenVecRes_Convert_StrictFP(
N);
5442 unsigned Opcode =
N->getOpcode();
5444 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5448 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5449 NumElts = NumElts / 2;
5460 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5464 unsigned ConcatEnd = 0;
5471 for (
unsigned i = 1; i < NumOpers; ++i) {
5477 Oper = GetWidenedVector(Oper);
5483 DAG.getUNDEF(WideOpVT), Oper,
5484 DAG.getVectorIdxConstant(0, dl));
5496 while (CurNumElts != 0) {
5497 while (CurNumElts >= NumElts) {
5500 for (
unsigned i = 0; i < NumOpers; ++i) {
5503 EVT OpVT =
Op.getValueType();
5508 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5514 EVT OperVT[] = {VT, MVT::Other};
5516 ConcatOps[ConcatEnd++] = Oper;
5519 CurNumElts -= NumElts;
5522 NumElts = NumElts / 2;
5524 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5527 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5530 for (
unsigned i = 0; i < NumOpers; ++i) {
5533 EVT OpVT =
Op.getValueType();
5541 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5543 ConcatOps[ConcatEnd++] = Oper;
5552 if (Chains.
size() == 1)
5553 NewChain = Chains[0];
5556 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5561SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5563 EVT ResVT =
N->getValueType(0);
5564 EVT OvVT =
N->getValueType(1);
5565 EVT WideResVT, WideOvVT;
5570 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5575 WideLHS = GetWidenedVector(
N->getOperand(0));
5576 WideRHS = GetWidenedVector(
N->getOperand(1));
5578 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5586 N->getOperand(0), Zero);
5589 N->getOperand(1), Zero);
5592 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5593 SDNode *WideNode = DAG.getNode(
5594 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5597 unsigned OtherNo = 1 - ResNo;
5598 EVT OtherVT =
N->getValueType(OtherNo);
5605 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5608 return SDValue(WideNode, ResNo);
5612 LLVMContext &Ctx = *DAG.getContext();
5616 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5621 unsigned Opcode =
N->getOpcode();
5622 const SDNodeFlags
Flags =
N->getFlags();
5628 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5630 InOp = ZExtPromotedInteger(InOp);
5641 InOp = GetWidenedVector(
N->getOperand(0));
5644 if (InVTEC == WidenEC) {
5645 if (
N->getNumOperands() == 1)
5646 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5647 if (
N->getNumOperands() == 3) {
5648 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5651 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5653 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5668 if (TLI.isTypeLegal(InWidenVT)) {
5676 unsigned NumConcat =
5681 if (
N->getNumOperands() == 1)
5682 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5683 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5687 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5689 if (
N->getNumOperands() == 1)
5690 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5691 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5700 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5701 for (
unsigned i=0; i < MinElts; ++i) {
5702 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5703 if (
N->getNumOperands() == 1)
5706 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5709 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5714 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5718 EVT SrcVT = Src.getValueType();
5722 Src = GetWidenedVector(Src);
5723 SrcVT = Src.getValueType();
5730 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5735 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5739 EVT SrcVT = Src.getValueType();
5743 Src = GetWidenedVector(Src);
5744 SrcVT = Src.getValueType();
5751 if (
N->getNumOperands() == 1)
5752 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5754 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5755 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5759 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5762SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5767 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5773 unsigned Opcode =
N->getOpcode();
5779 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5784 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5785 for (
unsigned i=0; i < MinElts; ++i) {
5786 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5787 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5791 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5793 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5796SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5797 unsigned Opcode =
N->getOpcode();
5801 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5810 InOp = GetWidenedVector(InOp);
5817 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5824 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5825 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5842 while (
Ops.size() != WidenNumElts)
5843 Ops.push_back(DAG.getPOISON(WidenSVT));
5845 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5851 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5852 return WidenVecRes_BinaryCanTrap(
N);
5855 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5862SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5864 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5867 SDValue Arg = GetWidenedVector(FpValue);
5868 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5873 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5874 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5876 EVT ExpVT =
RHS.getValueType();
5881 ExpOp = ModifyToType(
RHS, WideExpVT);
5884 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5889 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5890 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5891 if (
N->getNumOperands() == 1)
5892 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5894 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5895 N->getOperand(1),
N->getFlags());
5897 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5898 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5902 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5903 {InOp,
Mask,
N->getOperand(2)});
5907 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5910 .getVectorElementType(),
5912 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5913 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5914 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5917SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5919 EVT VT0 =
N->getValueType(0);
5920 EVT VT1 =
N->getValueType(1);
5924 "expected both results to be vectors of matching element count");
5926 LLVMContext &Ctx = *DAG.getContext();
5927 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5929 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5936 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5939 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5940 return SDValue(WidenNode, ResNo);
5943SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5944 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5945 return GetWidenedVector(WidenVec);
5949 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5950 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5953 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5954 AddrSpaceCastN->getSrcAddressSpace(),
5955 AddrSpaceCastN->getDestAddressSpace());
5961 EVT VT =
N->getValueType(0);
5962 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5965 switch (getTypeAction(InVT)) {
5979 SDValue NInOp = GetPromotedInteger(InOp);
5981 if (WidenVT.
bitsEq(NInVT)) {
5984 if (DAG.getDataLayout().isBigEndian()) {
5987 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6006 InOp = GetWidenedVector(InOp);
6008 if (WidenVT.
bitsEq(InVT))
6018 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6023 unsigned NewNumParts = WidenSize / InSize;
6036 EVT OrigInVT =
N->getOperand(0).getValueType();
6041 if (TLI.isTypeLegal(NewInVT)) {
6049 if (WidenSize % InSize == 0) {
6056 DAG.ExtractVectorElements(InOp,
Ops);
6057 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6069 return CreateStackStoreLoad(InOp, WidenVT);
6072SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6074 N->getOpcode(), SDLoc(
N),
6075 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6076 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6082 EVT VT =
N->getValueType(0);
6086 EVT EltVT =
N->getOperand(0).getValueType();
6089 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6093 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6094 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6096 return DAG.getBuildVector(WidenVT, dl, NewOps);
6100 EVT InVT =
N->getOperand(0).getValueType();
6101 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6103 unsigned NumOperands =
N->getNumOperands();
6105 bool InputWidened =
false;
6109 if (WidenNumElts % NumInElts == 0) {
6111 unsigned NumConcat = WidenNumElts / NumInElts;
6112 SDValue UndefVal = DAG.getPOISON(InVT);
6114 for (
unsigned i=0; i < NumOperands; ++i)
6115 Ops[i] =
N->getOperand(i);
6116 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6121 InputWidened =
true;
6122 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6125 for (i=1; i < NumOperands; ++i)
6126 if (!
N->getOperand(i).isUndef())
6129 if (i == NumOperands)
6132 return GetWidenedVector(
N->getOperand(0));
6134 if (NumOperands == 2) {
6136 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6141 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6142 for (
unsigned i = 0; i < NumInElts; ++i) {
6144 MaskOps[i + NumInElts] = i + WidenNumElts;
6146 return DAG.getVectorShuffle(WidenVT, dl,
6147 GetWidenedVector(
N->getOperand(0)),
6148 GetWidenedVector(
N->getOperand(1)),
6155 "Cannot use build vectors to widen CONCAT_VECTOR result");
6163 for (
unsigned i=0; i < NumOperands; ++i) {
6166 InOp = GetWidenedVector(InOp);
6167 for (
unsigned j = 0;
j < NumInElts; ++
j)
6168 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6170 SDValue UndefVal = DAG.getPOISON(EltVT);
6171 for (; Idx < WidenNumElts; ++Idx)
6172 Ops[Idx] = UndefVal;
6173 return DAG.getBuildVector(WidenVT, dl,
Ops);
6176SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6177 EVT VT =
N->getValueType(0);
6178 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6179 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6186SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6187 EVT VT =
N->getValueType(0);
6189 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6194 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6196 InOp = GetWidenedVector(InOp);
6202 if (IdxVal == 0 && InVT == WidenVT)
6209 assert(IdxVal % VTNumElts == 0 &&
6210 "Expected Idx to be a multiple of subvector minimum vector length");
6211 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6224 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6225 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6226 "down type's element count");
6233 for (;
I < VTNumElts / GCD; ++
I)
6235 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6236 for (;
I < WidenNumElts / GCD; ++
I)
6244 Align Alignment = DAG.getReducedAlign(InVT,
false);
6246 MachineFunction &MF = DAG.getMachineFunction();
6258 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6265 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6266 return DAG.getMaskedLoad(
6267 WidenVT, dl, Ch, StackPtr, DAG.getUNDEF(
StackPtr.getValueType()), Mask,
6275 for (i = 0; i < VTNumElts; ++i)
6276 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6278 SDValue UndefVal = DAG.getPOISON(EltVT);
6279 for (; i < WidenNumElts; ++i)
6281 return DAG.getBuildVector(WidenVT, dl,
Ops);
6287 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6292SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6293 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6296 N->getOperand(1),
N->getOperand(2));
6309 if (!
LD->getMemoryVT().isByteSized()) {
6311 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6313 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6322 EVT VT =
LD->getValueType(0);
6323 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6324 EVT WideMaskVT = getSetCCResultType(WideVT);
6327 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6328 TLI.isTypeLegal(WideMaskVT)) {
6331 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6335 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6336 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6348 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6350 Result = GenWidenVectorLoads(LdChain, LD);
6357 if (LdChain.
size() == 1)
6358 NewChain = LdChain[0];
6364 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6375 SDValue NewLoad = DAG.getMaskedLoad(
6376 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6377 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6378 LD->getAddressingMode(),
LD->getExtensionType());
6388 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6390 SDValue EVL =
N->getVectorLength();
6397 "Unable to widen binary VP op");
6398 Mask = GetWidenedVector(Mask);
6399 assert(
Mask.getValueType().getVectorElementCount() ==
6400 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6401 .getVectorElementCount() &&
6402 "Unable to widen vector load");
6405 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6406 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6407 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6415 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6417 SDValue EVL =
N->getVectorLength();
6423 "Unable to widen binary VP op");
6424 Mask = GetWidenedVector(Mask);
6425 assert(
Mask.getValueType().getVectorElementCount() ==
6426 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6427 .getVectorElementCount() &&
6428 "Unable to widen vector load");
6430 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6431 Mask, EVL,
N->getMemOperand());
6444 "Unable to widen VP strided load");
6445 Mask = GetWidenedVector(Mask);
6447 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6448 assert(
Mask.getValueType().getVectorElementCount() ==
6450 "Data and mask vectors should have the same number of elements");
6452 SDValue Res = DAG.getStridedLoadVP(
6453 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6454 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6455 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6456 N->isExpandingLoad());
6464SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6469 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6471 Mask.getValueType().getVectorElementType(),
6474 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6475 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6476 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6478 WideMask, WidePassthru);
6482 EVT VT =
N->getValueType(0);
6483 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6485 EVT MaskVT =
Mask.getValueType();
6486 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6495 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6496 TLI.isTypeLegal(WideMaskVT) &&
6502 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6503 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6507 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6508 N->getMemoryVT(),
N->getMemOperand());
6512 if (!
N->getPassThru()->isUndef()) {
6515 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6526 Mask = ModifyToType(Mask, WideMaskVT,
true);
6528 SDValue Res = DAG.getMaskedLoad(
6529 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6530 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6531 ExtType,
N->isExpandingLoad());
6540 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6542 EVT MaskVT =
Mask.getValueType();
6543 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6552 Mask = ModifyToType(Mask, WideMaskVT,
true);
6557 Index.getValueType().getScalarType(),
6559 Index = ModifyToType(Index, WideIndexVT);
6565 N->getMemoryVT().getScalarType(), NumElts);
6566 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6567 WideMemVT, dl,
Ops,
N->getMemOperand(),
6568 N->getIndexType(),
N->getExtensionType());
6577 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6585 N->getMemoryVT().getScalarType(), WideEC);
6586 Mask = GetWidenedMask(Mask, WideEC);
6589 Mask,
N->getVectorLength()};
6590 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6591 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6600 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6601 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6629 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6630 return N->getOperand(OpNo).getValueType();
6638 N =
N.getOperand(0);
6640 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6641 if (!
N->getOperand(i)->isUndef())
6643 N =
N.getOperand(0);
6647 N =
N.getOperand(0);
6649 N =
N.getOperand(0);
6676 { MaskVT, MVT::Other },
Ops);
6677 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6684 LLVMContext &Ctx = *DAG.getContext();
6687 if (MaskScalarBits < ToMaskScalBits) {
6691 }
else if (MaskScalarBits > ToMaskScalBits) {
6697 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6699 "Mask should have the right element size by now.");
6702 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6704 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6707 EVT SubVT =
Mask->getValueType(0);
6713 assert((
Mask->getValueType(0) == ToMaskVT) &&
6714 "A mask of ToMaskVT should have been produced by now.");
6724 LLVMContext &Ctx = *DAG.getContext();
6735 EVT CondVT =
Cond->getValueType(0);
6739 EVT VSelVT =
N->getValueType(0);
6751 EVT FinalVT = VSelVT;
6762 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6763 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6770 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6778 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6781 EVT ToMaskVT = VSelVT;
6788 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6804 if (ScalarBits0 != ScalarBits1) {
6805 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6806 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6818 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6819 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6820 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6823 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6831 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6836 unsigned Opcode =
N->getOpcode();
6838 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6839 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6840 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6842 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6848 Cond1 = GetWidenedVector(Cond1);
6856 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6857 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6862 Cond1 = ModifyToType(Cond1, CondWidenVT);
6865 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6866 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6868 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6869 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6871 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6875 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6876 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6879 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6883 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6884 return DAG.getUNDEF(WidenVT);
6888 EVT VT =
N->getValueType(0);
6891 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6895 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6896 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6899 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6900 for (
unsigned i = 0; i != NumElts; ++i) {
6901 int Idx =
N->getMaskElt(i);
6902 if (Idx < (
int)NumElts)
6905 NewMask[i] = Idx - NumElts + WidenNumElts;
6907 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6911 EVT VT =
N->getValueType(0);
6915 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6916 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6922 unsigned IdxVal = WidenNumElts - VTNumElts;
6935 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6938 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6939 "down type's element count");
6942 for (; i < VTNumElts / GCD; ++i)
6944 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6945 for (; i < WidenNumElts / GCD; ++i)
6953 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6954 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6956 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6960SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6961 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6966 assert(
N->getValueType(0).isVector() &&
6967 N->getOperand(0).getValueType().isVector() &&
6968 "Operands must be vectors");
6969 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6982 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
6983 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
6990 InOp1 = GetWidenedVector(InOp1);
6991 InOp2 = GetWidenedVector(InOp2);
6994 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7005 "Input not widened to expected type!");
7007 if (
N->getOpcode() == ISD::VP_SETCC) {
7010 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7011 N->getOperand(2), Mask,
N->getOperand(4));
7013 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7018 assert(
N->getValueType(0).isVector() &&
7019 N->getOperand(1).getValueType().isVector() &&
7020 "Operands must be vectors");
7021 EVT VT =
N->getValueType(0);
7022 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7032 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7037 for (
unsigned i = 0; i != NumElts; ++i) {
7038 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7039 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7041 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7042 {Chain, LHSElem, RHSElem, CC});
7043 Chains[i] = Scalars[i].getValue(1);
7044 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7045 DAG.getBoolConstant(
true, dl, EltVT, VT),
7046 DAG.getBoolConstant(
false, dl, EltVT, VT));
7050 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7052 return DAG.getBuildVector(WidenVT, dl, Scalars);
7058bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7059 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7063 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7066 switch (
N->getOpcode()) {
7069 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7077 Res = WidenVecOp_FAKE_USE(
N);
7083 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7084 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7085 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7086 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7091 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7093 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7094 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7096 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7097 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7107 Res = WidenVecOp_UnrollVectorOp(
N);
7114 Res = WidenVecOp_EXTEND(
N);
7119 Res = WidenVecOp_CMP(
N);
7135 Res = WidenVecOp_Convert(
N);
7140 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7158 Res = WidenVecOp_VECREDUCE(
N);
7162 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7164 case ISD::VP_REDUCE_FADD:
7165 case ISD::VP_REDUCE_SEQ_FADD:
7166 case ISD::VP_REDUCE_FMUL:
7167 case ISD::VP_REDUCE_SEQ_FMUL:
7168 case ISD::VP_REDUCE_ADD:
7169 case ISD::VP_REDUCE_MUL:
7170 case ISD::VP_REDUCE_AND:
7171 case ISD::VP_REDUCE_OR:
7172 case ISD::VP_REDUCE_XOR:
7173 case ISD::VP_REDUCE_SMAX:
7174 case ISD::VP_REDUCE_SMIN:
7175 case ISD::VP_REDUCE_UMAX:
7176 case ISD::VP_REDUCE_UMIN:
7177 case ISD::VP_REDUCE_FMAX:
7178 case ISD::VP_REDUCE_FMIN:
7179 case ISD::VP_REDUCE_FMAXIMUM:
7180 case ISD::VP_REDUCE_FMINIMUM:
7181 Res = WidenVecOp_VP_REDUCE(
N);
7183 case ISD::VP_CTTZ_ELTS:
7184 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7185 Res = WidenVecOp_VP_CttzElements(
N);
7190 if (!Res.
getNode())
return false;
7198 if (
N->isStrictFPOpcode())
7200 "Invalid operand expansion");
7203 "Invalid operand expansion");
7205 ReplaceValueWith(
SDValue(
N, 0), Res);
7211 EVT VT =
N->getValueType(0);
7216 "Unexpected type action");
7217 InOp = GetWidenedVector(InOp);
7220 "Input wasn't widened!");
7228 EVT FixedEltVT = FixedVT.getVectorElementType();
7229 if (TLI.isTypeLegal(FixedVT) &&
7231 FixedEltVT == InEltVT) {
7233 "Not enough elements in the fixed type for the operand!");
7235 "We can't have the same type as we started with!");
7237 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7239 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7248 return WidenVecOp_Convert(
N);
7253 switch (
N->getOpcode()) {
7268 EVT OpVT =
N->getOperand(0).getValueType();
7269 EVT ResVT =
N->getValueType(0);
7276 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7277 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7283 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7284 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7286 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7293 return DAG.UnrollVectorOp(
N);
7298 EVT ResultVT =
N->getValueType(0);
7300 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7303 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7309 {WideArg,
Test},
N->getFlags());
7315 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7317 EVT OpVT =
N->getOperand(0).getValueType();
7320 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7325 EVT VT =
N->getValueType(0);
7331 "Unexpected type action");
7332 InOp = GetWidenedVector(InOp);
7334 unsigned Opcode =
N->getOpcode();
7340 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7342 if (
N->isStrictFPOpcode()) {
7344 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7347 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7348 {
N->getOperand(0), InOp });
7354 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7356 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7358 return DAG.getExtractSubvector(dl, VT, Res, 0);
7366 if (
N->isStrictFPOpcode()) {
7369 for (
unsigned i=0; i < NumElts; ++i) {
7370 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7371 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7375 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7377 for (
unsigned i = 0; i < NumElts; ++i)
7378 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7379 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7382 return DAG.getBuildVector(VT, dl,
Ops);
7386 EVT DstVT =
N->getValueType(0);
7387 SDValue Src = GetWidenedVector(
N->getOperand(0));
7388 EVT SrcVT = Src.getValueType();
7395 if (TLI.isTypeLegal(WideDstVT)) {
7397 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7400 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7404 return DAG.UnrollVectorOp(
N);
7408 EVT VT =
N->getValueType(0);
7409 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7417 if (!VT.
isVector() && VT != MVT::x86mmx &&
7421 if (TLI.isTypeLegal(NewVT)) {
7423 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7435 ElementCount NewNumElts =
7437 .divideCoefficientBy(EltSize);
7439 if (TLI.isTypeLegal(NewVT)) {
7441 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7446 return CreateStackStoreLoad(InOp, VT);
7454 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7455 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7460 EVT VT =
N->getValueType(0);
7462 EVT InVT =
N->getOperand(0).getValueType();
7467 unsigned NumOperands =
N->getNumOperands();
7468 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7470 for (i = 1; i < NumOperands; ++i)
7471 if (!
N->getOperand(i).isUndef())
7474 if (i == NumOperands)
7475 return GetWidenedVector(
N->getOperand(0));
7485 for (
unsigned i=0; i < NumOperands; ++i) {
7489 "Unexpected type action");
7490 InOp = GetWidenedVector(InOp);
7491 for (
unsigned j = 0;
j < NumInElts; ++
j)
7492 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7494 return DAG.getBuildVector(VT, dl,
Ops);
7497SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7498 EVT VT =
N->getValueType(0);
7503 SubVec = GetWidenedVector(SubVec);
7508 bool IndicesValid =
false;
7511 IndicesValid =
true;
7515 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7516 Attribute::VScaleRange);
7521 IndicesValid =
true;
7527 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7533 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7540 Align Alignment = DAG.getReducedAlign(VT,
false);
7542 MachineFunction &MF = DAG.getMachineFunction();
7555 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7563 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7564 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7569 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7574 unsigned Idx =
N->getConstantOperandVal(2);
7580 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7586SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7587 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7589 N->getValueType(0), InOp,
N->getOperand(1));
7592SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7593 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7595 N->getValueType(0), InOp,
N->getOperand(1));
7598SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7599 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7600 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7608 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7609 return TLI.scalarizeVectorStore(ST, DAG);
7611 if (
ST->isTruncatingStore())
7612 return TLI.scalarizeVectorStore(ST, DAG);
7622 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7623 EVT WideMaskVT = getSetCCResultType(WideVT);
7625 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7626 TLI.isTypeLegal(WideMaskVT)) {
7629 StVal = GetWidenedVector(StVal);
7631 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7633 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7634 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7635 ST->getAddressingMode());
7639 if (GenWidenVectorStores(StChain, ST)) {
7640 if (StChain.
size() == 1)
7649 SDValue WideStVal = GetWidenedVector(StVal);
7653 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7654 ST->getOffset(), Mask,
ST->getMemoryVT(),
7655 ST->getMemOperand(),
ST->getAddressingMode(),
7656 ST->isTruncatingStore());
7662SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7663 assert((OpNo == 1 || OpNo == 3) &&
7664 "Can widen only data or mask operand of vp_store");
7672 StVal = GetWidenedVector(StVal);
7678 "Unable to widen VP store");
7679 Mask = GetWidenedVector(Mask);
7681 Mask = GetWidenedVector(Mask);
7687 "Unable to widen VP store");
7688 StVal = GetWidenedVector(StVal);
7691 assert(
Mask.getValueType().getVectorElementCount() ==
7693 "Mask and data vectors should have the same number of elements");
7694 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7695 ST->getOffset(), Mask,
ST->getVectorLength(),
7696 ST->getMemoryVT(),
ST->getMemOperand(),
7697 ST->getAddressingMode(),
ST->isTruncatingStore(),
7698 ST->isCompressingStore());
7703 assert((OpNo == 1 || OpNo == 4) &&
7704 "Can widen only data or mask operand of vp_strided_store");
7713 "Unable to widen VP strided store");
7717 "Unable to widen VP strided store");
7719 StVal = GetWidenedVector(StVal);
7720 Mask = GetWidenedVector(Mask);
7723 Mask.getValueType().getVectorElementCount() &&
7724 "Data and mask vectors should have the same number of elements");
7726 return DAG.getStridedStoreVP(
7733SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7734 assert((OpNo == 1 || OpNo == 4) &&
7735 "Can widen only data or mask operand of mstore");
7738 EVT MaskVT =
Mask.getValueType();
7743 EVT WideVT, WideMaskVT;
7746 StVal = GetWidenedVector(StVal);
7753 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7760 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7761 TLI.isTypeLegal(WideMaskVT)) {
7762 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7763 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7772 Mask = ModifyToType(Mask, WideMaskVT,
true);
7775 Mask = ModifyToType(Mask, WideMaskVT,
true);
7777 StVal = ModifyToType(StVal, WideVT);
7780 assert(
Mask.getValueType().getVectorElementCount() ==
7782 "Mask and data vectors should have the same number of elements");
7789SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7790 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7792 SDValue DataOp = MG->getPassThru();
7794 SDValue Scale = MG->getScale();
7802 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7803 MG->getMemOperand(), MG->getIndexType(),
7804 MG->getExtensionType());
7810SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7819 DataOp = GetWidenedVector(DataOp);
7823 EVT IndexVT =
Index.getValueType();
7826 Index = ModifyToType(Index, WideIndexVT);
7829 EVT MaskVT =
Mask.getValueType();
7832 Mask = ModifyToType(Mask, WideMaskVT,
true);
7837 }
else if (OpNo == 4) {
7839 Index = GetWidenedVector(Index);
7845 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7850SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7859 DataOp = GetWidenedVector(DataOp);
7860 Index = GetWidenedVector(Index);
7862 Mask = GetWidenedMask(Mask, WideEC);
7865 }
else if (OpNo == 3) {
7867 Index = GetWidenedVector(Index);
7874 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7879 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7880 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7882 EVT VT =
N->getValueType(0);
7897 SVT, InOp0, InOp1,
N->getOperand(2));
7903 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7905 EVT OpVT =
N->getOperand(0).getValueType();
7908 return DAG.getNode(ExtendCode, dl, VT, CC);
7918 EVT VT =
N->getValueType(0);
7920 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7927 for (
unsigned i = 0; i != NumElts; ++i) {
7928 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7929 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7931 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7932 {Chain, LHSElem, RHSElem, CC});
7933 Chains[i] = Scalars[i].getValue(1);
7934 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7935 DAG.getBoolConstant(
true, dl, EltVT, VT),
7936 DAG.getBoolConstant(
false, dl, EltVT, VT));
7940 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7942 return DAG.getBuildVector(VT, dl, Scalars);
7966 SDValue Op = GetWidenedVector(
N->getOperand(0));
7967 EVT VT =
N->getValueType(0);
7968 EVT OrigVT =
N->getOperand(0).getValueType();
7969 EVT WideVT =
Op.getValueType();
7971 SDNodeFlags
Flags =
N->getFlags();
7973 unsigned Opc =
N->getOpcode();
7975 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7976 assert(NeutralElem &&
"Neutral element must exist");
7986 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7993 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7994 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8000 unsigned GCD = std::gcd(OrigElts, WideElts);
8003 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8004 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8005 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8006 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8009 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8010 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8012 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8021 EVT VT =
N->getValueType(0);
8023 EVT WideVT =
Op.getValueType();
8025 SDNodeFlags
Flags =
N->getFlags();
8027 unsigned Opc =
N->getOpcode();
8029 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8039 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8042 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8043 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8049 unsigned GCD = std::gcd(OrigElts, WideElts);
8052 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8053 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8054 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8055 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8058 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8059 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8061 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8065 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8068 SDValue Op = GetWidenedVector(
N->getOperand(1));
8070 Op.getValueType().getVectorElementCount());
8072 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8073 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8081 EVT VT =
N->getValueType(0);
8085 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8086 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8091 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8097 EVT SrcVT =
Source.getValueType();
8101 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8102 {Source, Mask, N->getOperand(2)},
N->getFlags());
8119 unsigned WidenEx = 0) {
8124 unsigned AlignInBits =
Align*8;
8126 EVT RetVT = WidenEltVT;
8131 if (Width == WidenEltWidth)
8142 (WidenWidth % MemVTWidth) == 0 &&
8144 (MemVTWidth <= Width ||
8145 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8146 if (MemVTWidth == WidenWidth)
8165 (WidenWidth % MemVTWidth) == 0 &&
8167 (MemVTWidth <= Width ||
8168 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8177 return std::nullopt;
8188 unsigned Start,
unsigned End) {
8189 SDLoc dl(LdOps[Start]);
8190 EVT LdTy = LdOps[Start].getValueType();
8198 for (
unsigned i = Start + 1; i != End; ++i) {
8199 EVT NewLdTy = LdOps[i].getValueType();
8200 if (NewLdTy != LdTy) {
8219 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8220 EVT LdVT =
LD->getMemoryVT();
8230 AAMDNodes AAInfo =
LD->getAAInfo();
8234 TypeSize WidthDiff = WidenWidth - LdWidth;
8241 std::optional<EVT> FirstVT =
8242 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8249 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8254 std::optional<EVT> NewVT = FirstVT;
8255 TypeSize RemainingWidth = LdWidth;
8256 TypeSize NewVTWidth = FirstVTWidth;
8258 RemainingWidth -= NewVTWidth;
8265 NewVTWidth = NewVT->getSizeInBits();
8271 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8272 LD->getBaseAlign(), MMOFlags, AAInfo);
8276 if (MemVTs.
empty()) {
8278 if (!FirstVT->isVector()) {
8285 if (FirstVT == WidenVT)
8290 unsigned NumConcat =
8293 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8294 ConcatOps[0] = LdOp;
8295 for (
unsigned i = 1; i != NumConcat; ++i)
8296 ConcatOps[i] = UndefVal;
8304 uint64_t ScaledOffset = 0;
8305 MachinePointerInfo MPI =
LD->getPointerInfo();
8311 for (EVT MemVT : MemVTs) {
8312 Align NewAlign = ScaledOffset == 0
8313 ?
LD->getBaseAlign()
8316 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8324 unsigned End = LdOps.
size();
8335 EVT LdTy = LdOps[i].getValueType();
8338 for (--i; i >= 0; --i) {
8339 LdTy = LdOps[i].getValueType();
8346 ConcatOps[--Idx] = LdOps[i];
8347 for (--i; i >= 0; --i) {
8348 EVT NewLdTy = LdOps[i].getValueType();
8349 if (NewLdTy != LdTy) {
8359 for (;
j != End-Idx; ++
j)
8360 WidenOps[j] = ConcatOps[Idx+j];
8362 WidenOps[j] = DAG.getUNDEF(LdTy);
8369 ConcatOps[--Idx] = LdOps[i];
8374 ArrayRef(&ConcatOps[Idx], End - Idx));
8380 SDValue UndefVal = DAG.getUNDEF(LdTy);
8383 for (; i != End-Idx; ++i)
8384 WidenOps[i] = ConcatOps[Idx+i];
8386 WidenOps[i] = UndefVal;
8397 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8398 EVT LdVT =
LD->getMemoryVT();
8407 AAMDNodes AAInfo =
LD->getAAInfo();
8421 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8422 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8428 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8429 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8430 LD->getBaseAlign(), MMOFlags, AAInfo);
8435 SDValue UndefVal = DAG.getUNDEF(EltVT);
8436 for (; i != WidenNumElts; ++i)
8439 return DAG.getBuildVector(WidenVT, dl,
Ops);
8450 AAMDNodes AAInfo =
ST->getAAInfo();
8451 SDValue ValOp = GetWidenedVector(
ST->getValue());
8454 EVT StVT =
ST->getMemoryVT();
8462 "Mismatch between store and value types");
8466 MachinePointerInfo MPI =
ST->getPointerInfo();
8467 uint64_t ScaledOffset = 0;
8476 std::optional<EVT> NewVT =
8481 TypeSize NewVTWidth = NewVT->getSizeInBits();
8484 StWidth -= NewVTWidth;
8485 MemVTs.
back().second++;
8489 for (
const auto &Pair : MemVTs) {
8490 EVT NewVT = Pair.first;
8491 unsigned Count = Pair.second;
8497 Align NewAlign = ScaledOffset == 0
8498 ?
ST->getBaseAlign()
8500 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8501 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8517 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8518 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8519 ST->getBaseAlign(), MMOFlags, AAInfo);
8536 bool FillWithZeroes) {
8541 "input and widen element type must match");
8543 "cannot modify scalable vectors in this way");
8555 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8558 for (
unsigned i = 1; i != NumConcat; ++i)
8565 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8568 "Scalable vectors should have been handled already.");
8576 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8578 for (Idx = 0; Idx < MinNumElts; ++Idx)
8579 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8581 SDValue UndefVal = DAG.getUNDEF(EltVT);
8582 for (; Idx < WidenNumElts; ++Idx)
8583 Ops[Idx] = UndefVal;
8585 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8586 if (!FillWithZeroes)
8590 "We expect to never want to FillWithZeroes for non-integral types.");
8593 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8594 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8596 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8597 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)
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.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return 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.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue 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.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ 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...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ 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...
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
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 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.