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();
2688 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2690 SDValue Chain = DAG.getEntryNode();
2691 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2695 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2700 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2704 assert(
N->getValueType(0).isVector() &&
2705 N->getOperand(0).getValueType().isVector() &&
2706 "Operand types must be vectors");
2710 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2714 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2716 GetSplitVector(
N->getOperand(0), LL, LH);
2718 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2720 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2722 GetSplitVector(
N->getOperand(1), RL, RH);
2724 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2727 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2728 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2730 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2731 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2732 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2733 std::tie(EVLLo, EVLHi) =
2734 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2735 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2737 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2747 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2751 EVT InVT =
N->getOperand(0).getValueType();
2753 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2755 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2757 const SDNodeFlags
Flags =
N->getFlags();
2758 unsigned Opcode =
N->getOpcode();
2759 if (
N->getNumOperands() <= 2) {
2761 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2762 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2764 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2765 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2770 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2771 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2774 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2777 std::tie(EVLLo, EVLHi) =
2778 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2781 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2787 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2791 EVT InVT =
N->getOperand(0).getValueType();
2793 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2795 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2798 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2799 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2800 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2801 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2804void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2809 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2810 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2814 EVT InVT =
N->getOperand(0).getValueType();
2816 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2818 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2820 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2821 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2823 SDNode *HiNode =
Hi.getNode();
2824 SDNode *LoNode =
Lo.getNode();
2827 unsigned OtherNo = 1 - ResNo;
2828 EVT OtherVT =
N->getValueType(OtherNo);
2836 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2843 EVT SrcVT =
N->getOperand(0).getValueType();
2844 EVT DestVT =
N->getValueType(0);
2846 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2863 LLVMContext &Ctx = *DAG.getContext();
2867 EVT SplitLoVT, SplitHiVT;
2868 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2869 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2870 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2871 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
2872 N->dump(&DAG);
dbgs() <<
"\n");
2873 if (!
N->isVPOpcode()) {
2876 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
2878 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2880 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
2881 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
2887 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
2888 N->getOperand(1),
N->getOperand(2));
2890 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
2893 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2896 std::tie(EVLLo, EVLHi) =
2897 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2899 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2900 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2905 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
2913 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
2914 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
2920 return N.getResNo() == 0 &&
2924 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
2926 ArrayRef<int>
Mask) {
2929 "Expected build vector node.");
2932 for (
unsigned I = 0;
I < NewElts; ++
I) {
2935 unsigned Idx =
Mask[
I];
2937 Ops[
I] = Input2.getOperand(Idx - NewElts);
2939 Ops[
I] = Input1.getOperand(Idx);
2944 return DAG.getBuildVector(NewVT,
DL,
Ops);
2950 SmallVector<int> OrigMask(
N->getMask());
2952 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
2953 &
DL](SmallVectorImpl<int> &
Mask) {
2955 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2956 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2967 for (
auto &
P : ShufflesIdxs) {
2968 if (
P.second.size() < 2)
2972 for (
int &Idx : Mask) {
2975 unsigned SrcRegIdx = Idx / NewElts;
2976 if (Inputs[SrcRegIdx].
isUndef()) {
2984 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2989 Idx = MaskElt % NewElts +
2990 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
2996 Inputs[
P.second[0]] =
P.first.first;
2997 Inputs[
P.second[1]] =
P.first.second;
3000 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3003 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3004 for (
int &Idx : Mask) {
3007 unsigned SrcRegIdx = Idx / NewElts;
3008 if (Inputs[SrcRegIdx].
isUndef()) {
3015 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3016 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3019 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3021 if (UsedSubVector.count() > 1) {
3023 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3024 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3026 if (Pairs.
empty() || Pairs.
back().size() == 2)
3028 if (UsedSubVector.test(2 *
I)) {
3029 Pairs.
back().emplace_back(
I, 0);
3031 assert(UsedSubVector.test(2 *
I + 1) &&
3032 "Expected to be used one of the subvectors.");
3033 Pairs.
back().emplace_back(
I, 1);
3036 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3038 for (
int &Idx : Mask) {
3041 unsigned SrcRegIdx = Idx / NewElts;
3043 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3044 return Idxs.front().first == SrcRegIdx ||
3045 Idxs.back().first == SrcRegIdx;
3047 if (It == Pairs.
end())
3049 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3050 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3053 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3054 Inputs[Idxs.front().first] = DAG.
getNode(
3056 Inputs[Idxs.front().first].getValueType(),
3057 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3058 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3067 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3071 if (Shuffle->getOperand(0).getValueType() != NewVT)
3074 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3075 !Shuffle->isSplat()) {
3077 }
else if (!Inputs[
I].hasOneUse() &&
3078 !Shuffle->getOperand(1).isUndef()) {
3080 for (
int &Idx : Mask) {
3083 unsigned SrcRegIdx = Idx / NewElts;
3086 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3091 int OpIdx = MaskElt / NewElts;
3105 if (Shuffle->getOperand(
OpIdx).isUndef())
3107 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3108 if (It == std::end(Inputs))
3110 int FoundOp = std::distance(std::begin(Inputs), It);
3113 for (
int &Idx : Mask) {
3116 unsigned SrcRegIdx = Idx / NewElts;
3119 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3124 int MaskIdx = MaskElt / NewElts;
3125 if (
OpIdx == MaskIdx)
3126 Idx = MaskElt % NewElts + FoundOp * NewElts;
3137 for (
int &Idx : Mask) {
3140 unsigned SrcRegIdx = Idx / NewElts;
3143 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3144 int OpIdx = MaskElt / NewElts;
3147 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3153 TryPeekThroughShufflesInputs(OrigMask);
3155 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3156 NewElts](SmallVectorImpl<int> &
Mask) {
3157 SetVector<SDValue> UniqueInputs;
3158 SetVector<SDValue> UniqueConstantInputs;
3159 for (
const auto &
I : Inputs) {
3161 UniqueConstantInputs.
insert(
I);
3162 else if (!
I.isUndef())
3167 if (UniqueInputs.
size() != std::size(Inputs)) {
3168 auto &&UniqueVec = UniqueInputs.
takeVector();
3169 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3170 unsigned ConstNum = UniqueConstantVec.size();
3171 for (
int &Idx : Mask) {
3174 unsigned SrcRegIdx = Idx / NewElts;
3175 if (Inputs[SrcRegIdx].
isUndef()) {
3179 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3180 if (It != UniqueConstantVec.end()) {
3181 Idx = (Idx % NewElts) +
3182 NewElts * std::distance(UniqueConstantVec.begin(), It);
3183 assert(Idx >= 0 &&
"Expected defined mask idx.");
3186 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3187 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3188 Idx = (Idx % NewElts) +
3189 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3190 assert(Idx >= 0 &&
"Expected defined mask idx.");
3192 copy(UniqueConstantVec, std::begin(Inputs));
3193 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3196 MakeUniqueInputs(OrigMask);
3198 copy(Inputs, std::begin(OrigInputs));
3204 unsigned FirstMaskIdx =
High * NewElts;
3207 assert(!Output &&
"Expected default initialized initial value.");
3208 TryPeekThroughShufflesInputs(Mask);
3209 MakeUniqueInputs(Mask);
3211 copy(Inputs, std::begin(TmpInputs));
3214 bool SecondIteration =
false;
3215 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3220 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3221 SecondIteration =
true;
3222 return SecondIteration;
3225 Mask, std::size(Inputs), std::size(Inputs),
3227 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
3228 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3229 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3231 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3233 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3234 DAG.getUNDEF(NewVT), Mask);
3235 Inputs[Idx] = Output;
3237 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3238 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3239 unsigned Idx2,
bool ) {
3240 if (AccumulateResults(Idx1)) {
3243 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3245 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3246 Inputs[Idx2], Mask);
3250 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3252 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3253 TmpInputs[Idx2], Mask);
3255 Inputs[Idx1] = Output;
3257 copy(OrigInputs, std::begin(Inputs));
3262 EVT OVT =
N->getValueType(0);
3269 const Align Alignment =
3270 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3272 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3273 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3278 ReplaceValueWith(
SDValue(
N, 1), Chain);
3283 EVT DstVTLo, DstVTHi;
3284 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3288 EVT SrcVT =
N->getOperand(0).getValueType();
3290 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3292 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3294 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3295 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3301 GetSplitVector(
N->getOperand(0), InLo, InHi);
3312 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3313 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3318 EVT VT =
N->getValueType(0);
3325 Align Alignment = DAG.getReducedAlign(VT,
false);
3330 EVT PtrVT =
StackPtr.getValueType();
3331 auto &MF = DAG.getMachineFunction();
3335 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3338 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3344 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3345 DAG.getConstant(1,
DL, PtrVT));
3347 DAG.getConstant(EltWidth,
DL, PtrVT));
3349 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3351 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3352 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3353 DAG.getUNDEF(PtrVT), Stride, TrueMask,
3356 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3358 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3363 EVT VT =
N->getValueType(0);
3375 EVL1 = ZExtPromotedInteger(EVL1);
3377 Align Alignment = DAG.getReducedAlign(VT,
false);
3382 EVT PtrVT =
StackPtr.getValueType();
3383 auto &MF = DAG.getMachineFunction();
3387 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3390 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3394 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3396 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3397 SDValue StoreV1 = DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr,
3398 DAG.getUNDEF(PtrVT), TrueMask, EVL1,
3402 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, DAG.getUNDEF(PtrVT), TrueMask,
3407 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3408 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3410 uint64_t TrailingElts = -
Imm;
3412 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3421 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3425 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3427 DAG.getVectorIdxConstant(0,
DL));
3433void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3441 GetSplitVector(Acc, AccLo, AccHi);
3442 unsigned Opcode =
N->getOpcode();
3454 GetSplitVector(Input1, Input1Lo, Input1Hi);
3455 GetSplitVector(Input2, Input2Lo, Input2Hi);
3458 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3459 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3462void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3470 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3478void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3479 unsigned Factor =
N->getNumOperands();
3482 for (
unsigned i = 0; i != Factor; ++i) {
3484 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3486 Ops[i * 2 + 1] = OpHi;
3497 for (
unsigned i = 0; i != Factor; ++i)
3501void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3502 unsigned Factor =
N->getNumOperands();
3505 for (
unsigned i = 0; i != Factor; ++i) {
3507 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3509 Ops[i + Factor] = OpHi;
3520 for (
unsigned i = 0; i != Factor; ++i) {
3521 unsigned IdxLo = 2 * i;
3522 unsigned IdxHi = 2 * i + 1;
3523 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3524 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3536bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3541 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3544 switch (
N->getOpcode()) {
3547 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3557 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3563 case ISD::VP_TRUNCATE:
3565 Res = SplitVecOp_TruncateHelper(
N);
3568 case ISD::VP_FP_ROUND:
3577 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3584 case ISD::VP_SCATTER:
3588 case ISD::VP_GATHER:
3592 Res = SplitVecOp_VSELECT(
N, OpNo);
3595 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3601 case ISD::VP_SINT_TO_FP:
3602 case ISD::VP_UINT_TO_FP:
3603 if (
N->getValueType(0).bitsLT(
3604 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3605 Res = SplitVecOp_TruncateHelper(
N);
3607 Res = SplitVecOp_UnaryOp(
N);
3611 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3615 case ISD::VP_FP_TO_SINT:
3616 case ISD::VP_FP_TO_UINT:
3629 Res = SplitVecOp_UnaryOp(
N);
3632 Res = SplitVecOp_FPOpDifferentTypes(
N);
3637 Res = SplitVecOp_CMP(
N);
3641 Res = SplitVecOp_FAKE_USE(
N);
3646 Res = SplitVecOp_ExtVecInRegOp(
N);
3664 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3668 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3670 case ISD::VP_REDUCE_FADD:
3671 case ISD::VP_REDUCE_SEQ_FADD:
3672 case ISD::VP_REDUCE_FMUL:
3673 case ISD::VP_REDUCE_SEQ_FMUL:
3674 case ISD::VP_REDUCE_ADD:
3675 case ISD::VP_REDUCE_MUL:
3676 case ISD::VP_REDUCE_AND:
3677 case ISD::VP_REDUCE_OR:
3678 case ISD::VP_REDUCE_XOR:
3679 case ISD::VP_REDUCE_SMAX:
3680 case ISD::VP_REDUCE_SMIN:
3681 case ISD::VP_REDUCE_UMAX:
3682 case ISD::VP_REDUCE_UMIN:
3683 case ISD::VP_REDUCE_FMAX:
3684 case ISD::VP_REDUCE_FMIN:
3685 case ISD::VP_REDUCE_FMAXIMUM:
3686 case ISD::VP_REDUCE_FMINIMUM:
3687 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3689 case ISD::VP_CTTZ_ELTS:
3690 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3691 Res = SplitVecOp_VP_CttzElements(
N);
3694 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3700 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3705 if (!Res.
getNode())
return false;
3712 if (
N->isStrictFPOpcode())
3714 "Invalid operand expansion");
3717 "Invalid operand expansion");
3719 ReplaceValueWith(
SDValue(
N, 0), Res);
3723SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3726 assert(OpNo == 0 &&
"Illegal operand must be mask");
3733 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3736 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3737 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3738 "Lo and Hi have differing types");
3741 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3742 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3744 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3745 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3746 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3747 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3757SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3760 assert(OpNo == 1 &&
"Illegal operand must be mask");
3765 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3767 EVT VecVT =
N->getValueType(0);
3771SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3772 EVT ResVT =
N->getValueType(0);
3778 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3779 GetSplitVector(VecOp,
Lo,
Hi);
3781 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3786 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3787 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3791 EVT ResVT =
N->getValueType(0);
3797 SDNodeFlags
Flags =
N->getFlags();
3800 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3801 GetSplitVector(VecOp,
Lo,
Hi);
3803 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3809 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3812SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3813 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3814 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3816 unsigned Opc =
N->getOpcode();
3817 EVT ResVT =
N->getValueType(0);
3823 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3824 GetSplitVector(VecOp,
Lo,
Hi);
3827 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
3830 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
3832 const SDNodeFlags
Flags =
N->getFlags();
3836 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
3841 EVT ResVT =
N->getValueType(0);
3844 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
3845 EVT InVT =
Lo.getValueType();
3850 if (
N->isStrictFPOpcode()) {
3851 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3852 {N->getOperand(0), Lo});
3853 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
3854 {N->getOperand(0), Hi});
3863 ReplaceValueWith(
SDValue(
N, 1), Ch);
3864 }
else if (
N->getNumOperands() == 3) {
3865 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3866 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3867 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3868 std::tie(EVLLo, EVLHi) =
3869 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3870 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
3871 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
3873 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
3874 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
3883 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
3893 EVT ResVT =
N->getValueType(0);
3895 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3899 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
3905 Lo = BitConvertToInteger(
Lo);
3906 Hi = BitConvertToInteger(
Hi);
3908 if (DAG.getDataLayout().isBigEndian())
3916 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
3918 EVT ResVT =
N->getValueType(0);
3926 GetSplitVector(SubVec,
Lo,
Hi);
3935 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3937 return SecondInsertion;
3940SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
3947 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3949 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
3951 ElementCount IdxVal =
3955 EVT SrcVT =
N->getOperand(0).getValueType();
3974 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
3975 LoEltsMin - IdxValMin);
3976 DAG.ExtractVectorElements(
Hi, Elts, 0,
3979 return DAG.getBuildVector(SubVT, dl, Elts);
3983 ElementCount ExtractIdx = IdxVal - LoElts;
3985 return DAG.getExtractSubvector(dl, SubVT,
Hi,
3988 EVT HiVT =
Hi.getValueType();
3990 "Only fixed-vector extracts are supported in this case");
4000 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4001 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4007 "Extracting scalable subvector from fixed-width unsupported");
4015 "subvector from a scalable predicate vector");
4021 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4023 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4024 auto &MF = DAG.getMachineFunction();
4028 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4032 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4035 SubVT, dl, Store, StackPtr,
4039SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4045 uint64_t IdxVal =
Index->getZExtValue();
4048 GetSplitVector(Vec,
Lo,
Hi);
4050 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4052 if (IdxVal < LoElts)
4053 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4056 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4061 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4073 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4079 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4081 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4082 auto &MF = DAG.getMachineFunction();
4085 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4089 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4093 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4095 return DAG.getExtLoad(
4106 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4114 SplitVecRes_Gather(
N,
Lo,
Hi);
4117 ReplaceValueWith(
SDValue(
N, 0), Res);
4122 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4126 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4128 SDValue EVL =
N->getVectorLength();
4130 Align Alignment =
N->getBaseAlign();
4136 GetSplitVector(
Data, DataLo, DataHi);
4138 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4143 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4146 GetSplitVector(Mask, MaskLo, MaskHi);
4148 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4151 EVT MemoryVT =
N->getMemoryVT();
4152 EVT LoMemVT, HiMemVT;
4153 bool HiIsEmpty =
false;
4154 std::tie(LoMemVT, HiMemVT) =
4155 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4159 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4162 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4167 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4168 N->getAddressingMode(),
N->isTruncatingStore(),
4169 N->isCompressingStore());
4175 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4176 N->isCompressingStore());
4178 MachinePointerInfo MPI;
4182 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4187 MMO = DAG.getMachineFunction().getMachineMemOperand(
4189 Alignment,
N->getAAInfo(),
N->getRanges());
4191 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4192 N->getAddressingMode(),
N->isTruncatingStore(),
4193 N->isCompressingStore());
4202 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4203 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4210 GetSplitVector(
Data, LoData, HiData);
4212 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4214 EVT LoMemVT, HiMemVT;
4215 bool HiIsEmpty =
false;
4216 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4222 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4223 else if (getTypeAction(
Mask.getValueType()) ==
4225 GetSplitVector(Mask, LoMask, HiMask);
4227 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4230 std::tie(LoEVL, HiEVL) =
4231 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4235 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4236 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4237 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4248 EVT PtrVT =
N->getBasePtr().getValueType();
4251 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4254 Align Alignment =
N->getBaseAlign();
4259 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4260 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4262 Alignment,
N->getAAInfo(),
N->getRanges());
4265 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4266 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4267 N->isCompressingStore());
4276 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4280 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4283 Align Alignment =
N->getBaseAlign();
4289 GetSplitVector(
Data, DataLo, DataHi);
4291 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4296 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4299 GetSplitVector(Mask, MaskLo, MaskHi);
4301 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4304 EVT MemoryVT =
N->getMemoryVT();
4305 EVT LoMemVT, HiMemVT;
4306 bool HiIsEmpty =
false;
4307 std::tie(LoMemVT, HiMemVT) =
4308 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4311 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4316 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4317 N->getAddressingMode(),
N->isTruncatingStore(),
4318 N->isCompressingStore());
4326 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4327 N->isCompressingStore());
4329 MachinePointerInfo MPI;
4333 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4338 MMO = DAG.getMachineFunction().getMachineMemOperand(
4340 Alignment,
N->getAAInfo(),
N->getRanges());
4342 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4343 N->getAddressingMode(),
N->isTruncatingStore(),
4344 N->isCompressingStore());
4357 EVT MemoryVT =
N->getMemoryVT();
4358 Align Alignment =
N->getBaseAlign();
4365 }
Ops = [&]() -> Operands {
4367 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4371 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4376 EVT LoMemVT, HiMemVT;
4377 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4382 GetSplitVector(
Ops.Data, DataLo, DataHi);
4384 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4389 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4391 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4395 if (getTypeAction(
Ops.Index.getValueType()) ==
4397 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4399 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4403 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4405 Alignment,
N->getAAInfo(),
N->getRanges());
4408 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4410 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4411 MSC->getIndexType(), MSC->isTruncatingStore());
4416 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4417 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4418 MMO, MSC->getIndexType(),
4419 MSC->isTruncatingStore());
4423 std::tie(EVLLo, EVLHi) =
4424 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4426 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4427 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4428 VPSC->getIndexType());
4433 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4434 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4435 VPSC->getIndexType());
4439 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4440 assert(OpNo == 1 &&
"Can only split the stored value");
4443 bool isTruncating =
N->isTruncatingStore();
4446 EVT MemoryVT =
N->getMemoryVT();
4447 Align Alignment =
N->getBaseAlign();
4449 AAMDNodes AAInfo =
N->getAAInfo();
4451 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4453 EVT LoMemVT, HiMemVT;
4454 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4458 return TLI.scalarizeVectorStore(
N, DAG);
4461 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4462 Alignment, MMOFlags, AAInfo);
4464 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4467 MachinePointerInfo MPI;
4468 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4471 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4472 HiMemVT, Alignment, MMOFlags, AAInfo);
4474 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4490 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4496 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4517 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4518 SDValue InVec =
N->getOperand(OpNo);
4520 EVT OutVT =
N->getValueType(0);
4528 EVT LoOutVT, HiOutVT;
4529 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4530 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4535 if (isTypeLegal(LoOutVT) ||
4536 InElementSize <= OutElementSize * 2)
4537 return SplitVecOp_UnaryOp(
N);
4546 return SplitVecOp_UnaryOp(
N);
4550 GetSplitVector(InVec, InLoVec, InHiVec);
4556 EVT HalfElementVT = IsFloat ?
4558 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4565 if (
N->isStrictFPOpcode()) {
4566 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4567 {N->getOperand(0), InLoVec});
4568 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4569 {N->getOperand(0), InHiVec});
4575 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4576 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4580 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4588 if (
N->isStrictFPOpcode()) {
4592 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4600 DAG.getTargetConstant(
4601 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4608 assert(
N->getValueType(0).isVector() &&
4609 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4610 "Operand types must be vectors");
4612 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4614 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4615 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4617 EVT VT =
N->getValueType(0);
4623 }
else if (isStrict) {
4624 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4625 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4626 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4627 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4630 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4632 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4633 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4634 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4635 std::tie(EVLLo, EVLHi) =
4636 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4637 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4638 N->getOperand(2), MaskLo, EVLLo);
4639 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4640 N->getOperand(2), MaskHi, EVLHi);
4649 EVT ResVT =
N->getValueType(0);
4652 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4653 EVT InVT =
Lo.getValueType();
4658 if (
N->isStrictFPOpcode()) {
4659 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4660 {N->getOperand(0), Lo, N->getOperand(2)});
4661 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4662 {N->getOperand(0), Hi, N->getOperand(2)});
4666 Lo.getValue(1),
Hi.getValue(1));
4667 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4668 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4669 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4670 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4671 std::tie(EVLLo, EVLHi) =
4672 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4673 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4674 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4688SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4691 EVT LHSLoVT, LHSHiVT;
4692 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4694 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4695 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4698 std::tie(LHSLo, LHSHi) =
4699 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4702 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4705 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4711 LLVMContext &Ctxt = *DAG.getContext();
4714 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4715 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4716 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4718 EVT ResVT =
N->getValueType(0);
4723 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4724 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4730 EVT ResVT =
N->getValueType(0);
4733 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4734 EVT InVT =
Lo.getValueType();
4740 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4741 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4748 EVT ResVT =
N->getValueType(0);
4752 GetSplitVector(VecOp,
Lo,
Hi);
4754 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4755 auto [EVLLo, EVLHi] =
4757 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4763 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4765 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4766 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4769SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4780 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4781 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4782 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4783 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4784 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4785 OpsLo, MMO, IndexType);
4786 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4787 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4791SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4794 "Accumulator should already be a legal type, and shouldn't need "
4795 "further splitting");
4798 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
4799 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
4800 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
4801 unsigned Opcode =
N->getOpcode();
4804 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
4805 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
4812void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
4813 unsigned WidenResNo) {
4814 unsigned NumResults =
N->getNumValues();
4815 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
4816 if (ResNo == WidenResNo)
4818 EVT ResVT =
N->getValueType(ResNo);
4824 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
4825 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
4830void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
4831 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
4834 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
4839 auto unrollExpandedOp = [&]() {
4844 EVT VT =
N->getValueType(0);
4845 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4846 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
4849 if (
N->getNumValues() > 1)
4850 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
4856 switch (
N->getOpcode()) {
4859 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
4867 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
4871 Res = WidenVecRes_ADDRSPACECAST(
N);
4878 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
4882 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
4886 Res = WidenVecRes_ScalarOp(
N);
4891 case ISD::VP_SELECT:
4893 Res = WidenVecRes_Select(
N);
4897 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
4899 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
4906 case ISD::VP_LOAD_FF:
4909 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
4913 Res = WidenVecRes_VECTOR_COMPRESS(
N);
4921 case ISD::VP_GATHER:
4925 Res = WidenVecRes_VECTOR_REVERSE(
N);
4928 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
4938 case ISD::OR:
case ISD::VP_OR:
4946 case ISD::VP_FMINNUM:
4949 case ISD::VP_FMAXNUM:
4951 case ISD::VP_FMINIMUM:
4953 case ISD::VP_FMAXIMUM:
4986 case ISD::VP_FCOPYSIGN:
4987 Res = WidenVecRes_Binary(
N);
4992 Res = WidenVecRes_CMP(
N);
4998 if (unrollExpandedOp())
5013 Res = WidenVecRes_BinaryCanTrap(
N);
5022 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5025#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5026 case ISD::STRICT_##DAGN:
5027#include "llvm/IR/ConstrainedOps.def"
5028 Res = WidenVecRes_StrictFP(
N);
5037 Res = WidenVecRes_OverflowOp(
N, ResNo);
5041 Res = WidenVecRes_FCOPYSIGN(
N);
5046 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5051 if (!unrollExpandedOp())
5052 Res = WidenVecRes_ExpOp(
N);
5058 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5063 case ISD::VP_FP_EXTEND:
5065 case ISD::VP_FP_ROUND:
5067 case ISD::VP_FP_TO_SINT:
5069 case ISD::VP_FP_TO_UINT:
5071 case ISD::VP_SIGN_EXTEND:
5073 case ISD::VP_SINT_TO_FP:
5074 case ISD::VP_TRUNCATE:
5077 case ISD::VP_UINT_TO_FP:
5079 case ISD::VP_ZERO_EXTEND:
5080 Res = WidenVecRes_Convert(
N);
5085 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5091 case ISD::VP_LLRINT:
5094 Res = WidenVecRes_XROUND(
N);
5120 if (unrollExpandedOp())
5130 case ISD::VP_BITREVERSE:
5136 case ISD::VP_CTLZ_ZERO_UNDEF:
5142 case ISD::VP_CTTZ_ZERO_UNDEF:
5147 case ISD::VP_FFLOOR:
5149 case ISD::VP_FNEARBYINT:
5150 case ISD::VP_FROUND:
5151 case ISD::VP_FROUNDEVEN:
5152 case ISD::VP_FROUNDTOZERO:
5157 Res = WidenVecRes_Unary(
N);
5164 Res = WidenVecRes_Ternary(
N);
5170 if (!unrollExpandedOp())
5171 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5178 SetWidenedVector(
SDValue(
N, ResNo), Res);
5184 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5185 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5186 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5187 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5188 if (
N->getNumOperands() == 3)
5189 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5191 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5192 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5196 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5197 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5203 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5204 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5205 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5206 if (
N->getNumOperands() == 2)
5207 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5210 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5211 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5215 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5216 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5220 LLVMContext &Ctxt = *DAG.getContext();
5225 EVT OpVT =
LHS.getValueType();
5227 LHS = GetWidenedVector(
LHS);
5228 RHS = GetWidenedVector(
RHS);
5229 OpVT =
LHS.getValueType();
5232 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5235 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5241SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5244 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5245 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5246 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5248 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5257 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5260 if (ConcatEnd == 1) {
5261 VT = ConcatOps[0].getValueType();
5263 return ConcatOps[0];
5266 SDLoc dl(ConcatOps[0]);
5273 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5274 int Idx = ConcatEnd - 1;
5275 VT = ConcatOps[Idx--].getValueType();
5276 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5289 unsigned NumToInsert = ConcatEnd - Idx - 1;
5290 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5292 ConcatOps[Idx+1] = VecOp;
5293 ConcatEnd = Idx + 2;
5299 unsigned RealVals = ConcatEnd - Idx - 1;
5300 unsigned SubConcatEnd = 0;
5301 unsigned SubConcatIdx = Idx + 1;
5302 while (SubConcatEnd < RealVals)
5303 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5304 while (SubConcatEnd < OpsToConcat)
5305 SubConcatOps[SubConcatEnd++] = undefVec;
5307 NextVT, SubConcatOps);
5308 ConcatEnd = SubConcatIdx + 1;
5313 if (ConcatEnd == 1) {
5314 VT = ConcatOps[0].getValueType();
5316 return ConcatOps[0];
5321 if (
NumOps != ConcatEnd ) {
5323 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5324 ConcatOps[j] = UndefVal;
5332 unsigned Opcode =
N->getOpcode();
5334 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5338 const SDNodeFlags
Flags =
N->getFlags();
5339 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5340 NumElts = NumElts / 2;
5344 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5346 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5347 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5348 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5356 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5359 TLI.isTypeLegal(WideMaskVT)) {
5360 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5361 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5362 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5364 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5365 N->getValueType(0).getVectorElementCount());
5366 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5380 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5381 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5382 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5385 unsigned ConcatEnd = 0;
5393 while (CurNumElts != 0) {
5394 while (CurNumElts >= NumElts) {
5395 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5396 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5397 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5399 CurNumElts -= NumElts;
5402 NumElts = NumElts / 2;
5404 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5407 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5408 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5409 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5410 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5421 switch (
N->getOpcode()) {
5424 return WidenVecRes_STRICT_FSETCC(
N);
5431 return WidenVecRes_Convert_StrictFP(
N);
5438 unsigned Opcode =
N->getOpcode();
5440 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5444 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5445 NumElts = NumElts / 2;
5456 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5460 unsigned ConcatEnd = 0;
5467 for (
unsigned i = 1; i < NumOpers; ++i) {
5473 Oper = GetWidenedVector(Oper);
5479 DAG.getUNDEF(WideOpVT), Oper,
5480 DAG.getVectorIdxConstant(0, dl));
5492 while (CurNumElts != 0) {
5493 while (CurNumElts >= NumElts) {
5496 for (
unsigned i = 0; i < NumOpers; ++i) {
5499 EVT OpVT =
Op.getValueType();
5504 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5510 EVT OperVT[] = {VT, MVT::Other};
5512 ConcatOps[ConcatEnd++] = Oper;
5515 CurNumElts -= NumElts;
5518 NumElts = NumElts / 2;
5520 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5523 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5526 for (
unsigned i = 0; i < NumOpers; ++i) {
5529 EVT OpVT =
Op.getValueType();
5537 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5539 ConcatOps[ConcatEnd++] = Oper;
5548 if (Chains.
size() == 1)
5549 NewChain = Chains[0];
5552 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5557SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5559 EVT ResVT =
N->getValueType(0);
5560 EVT OvVT =
N->getValueType(1);
5561 EVT WideResVT, WideOvVT;
5566 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5571 WideLHS = GetWidenedVector(
N->getOperand(0));
5572 WideRHS = GetWidenedVector(
N->getOperand(1));
5574 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5582 N->getOperand(0), Zero);
5585 N->getOperand(1), Zero);
5588 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5589 SDNode *WideNode = DAG.getNode(
5590 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5593 unsigned OtherNo = 1 - ResNo;
5594 EVT OtherVT =
N->getValueType(OtherNo);
5601 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5604 return SDValue(WideNode, ResNo);
5608 LLVMContext &Ctx = *DAG.getContext();
5612 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5617 unsigned Opcode =
N->getOpcode();
5618 const SDNodeFlags
Flags =
N->getFlags();
5624 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5626 InOp = ZExtPromotedInteger(InOp);
5637 InOp = GetWidenedVector(
N->getOperand(0));
5640 if (InVTEC == WidenEC) {
5641 if (
N->getNumOperands() == 1)
5642 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5643 if (
N->getNumOperands() == 3) {
5644 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5647 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5649 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5664 if (TLI.isTypeLegal(InWidenVT)) {
5672 unsigned NumConcat =
5677 if (
N->getNumOperands() == 1)
5678 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5679 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5683 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5685 if (
N->getNumOperands() == 1)
5686 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5687 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5696 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5697 for (
unsigned i=0; i < MinElts; ++i) {
5698 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5699 if (
N->getNumOperands() == 1)
5702 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5705 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5710 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5714 EVT SrcVT = Src.getValueType();
5718 Src = GetWidenedVector(Src);
5719 SrcVT = Src.getValueType();
5726 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5731 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5735 EVT SrcVT = Src.getValueType();
5739 Src = GetWidenedVector(Src);
5740 SrcVT = Src.getValueType();
5747 if (
N->getNumOperands() == 1)
5748 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5750 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5751 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5755 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
5758SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
5763 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5769 unsigned Opcode =
N->getOpcode();
5775 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
5780 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5781 for (
unsigned i=0; i < MinElts; ++i) {
5782 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5783 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
5787 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5789 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5792SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
5793 unsigned Opcode =
N->getOpcode();
5797 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5806 InOp = GetWidenedVector(InOp);
5813 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
5820 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
5821 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
5838 while (
Ops.size() != WidenNumElts)
5839 Ops.push_back(DAG.getPOISON(WidenSVT));
5841 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5847 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
5848 return WidenVecRes_BinaryCanTrap(
N);
5851 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5858SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
5860 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5863 SDValue Arg = GetWidenedVector(FpValue);
5864 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
5869 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5870 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5872 EVT ExpVT =
RHS.getValueType();
5877 ExpOp = ModifyToType(
RHS, WideExpVT);
5880 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
5885 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5886 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5887 if (
N->getNumOperands() == 1)
5888 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
5890 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
5891 N->getOperand(1),
N->getFlags());
5893 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5894 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5898 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
5899 {InOp,
Mask,
N->getOperand(2)});
5903 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5906 .getVectorElementType(),
5908 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
5909 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
5910 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
5913SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
5915 EVT VT0 =
N->getValueType(0);
5916 EVT VT1 =
N->getValueType(1);
5920 "expected both results to be vectors of matching element count");
5922 LLVMContext &Ctx = *DAG.getContext();
5923 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5925 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
5932 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
5935 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
5936 return SDValue(WidenNode, ResNo);
5939SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
5940 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
5941 return GetWidenedVector(WidenVec);
5945 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5946 SDValue InOp = GetWidenedVector(
N->getOperand(0));
5949 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
5950 AddrSpaceCastN->getSrcAddressSpace(),
5951 AddrSpaceCastN->getDestAddressSpace());
5957 EVT VT =
N->getValueType(0);
5958 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5961 switch (getTypeAction(InVT)) {
5975 SDValue NInOp = GetPromotedInteger(InOp);
5977 if (WidenVT.
bitsEq(NInVT)) {
5980 if (DAG.getDataLayout().isBigEndian()) {
5983 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6002 InOp = GetWidenedVector(InOp);
6004 if (WidenVT.
bitsEq(InVT))
6014 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6019 unsigned NewNumParts = WidenSize / InSize;
6032 EVT OrigInVT =
N->getOperand(0).getValueType();
6037 if (TLI.isTypeLegal(NewInVT)) {
6045 if (WidenSize % InSize == 0) {
6052 DAG.ExtractVectorElements(InOp,
Ops);
6053 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6065 return CreateStackStoreLoad(InOp, WidenVT);
6068SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6070 N->getOpcode(), SDLoc(
N),
6071 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6072 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6078 EVT VT =
N->getValueType(0);
6082 EVT EltVT =
N->getOperand(0).getValueType();
6085 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6089 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6090 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6092 return DAG.getBuildVector(WidenVT, dl, NewOps);
6096 EVT InVT =
N->getOperand(0).getValueType();
6097 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6099 unsigned NumOperands =
N->getNumOperands();
6101 bool InputWidened =
false;
6105 if (WidenNumElts % NumInElts == 0) {
6107 unsigned NumConcat = WidenNumElts / NumInElts;
6108 SDValue UndefVal = DAG.getPOISON(InVT);
6110 for (
unsigned i=0; i < NumOperands; ++i)
6111 Ops[i] =
N->getOperand(i);
6112 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6117 InputWidened =
true;
6118 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6121 for (i=1; i < NumOperands; ++i)
6122 if (!
N->getOperand(i).isUndef())
6125 if (i == NumOperands)
6128 return GetWidenedVector(
N->getOperand(0));
6130 if (NumOperands == 2) {
6132 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6137 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6138 for (
unsigned i = 0; i < NumInElts; ++i) {
6140 MaskOps[i + NumInElts] = i + WidenNumElts;
6142 return DAG.getVectorShuffle(WidenVT, dl,
6143 GetWidenedVector(
N->getOperand(0)),
6144 GetWidenedVector(
N->getOperand(1)),
6151 "Cannot use build vectors to widen CONCAT_VECTOR result");
6159 for (
unsigned i=0; i < NumOperands; ++i) {
6162 InOp = GetWidenedVector(InOp);
6163 for (
unsigned j = 0;
j < NumInElts; ++
j)
6164 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6166 SDValue UndefVal = DAG.getPOISON(EltVT);
6167 for (; Idx < WidenNumElts; ++Idx)
6168 Ops[Idx] = UndefVal;
6169 return DAG.getBuildVector(WidenVT, dl,
Ops);
6172SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6173 EVT VT =
N->getValueType(0);
6174 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6175 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6182SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6183 EVT VT =
N->getValueType(0);
6185 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6190 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6192 InOp = GetWidenedVector(InOp);
6198 if (IdxVal == 0 && InVT == WidenVT)
6205 assert(IdxVal % VTNumElts == 0 &&
6206 "Expected Idx to be a multiple of subvector minimum vector length");
6207 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6220 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6221 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6222 "down type's element count");
6229 for (;
I < VTNumElts / GCD; ++
I)
6231 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6232 for (;
I < WidenNumElts / GCD; ++
I)
6240 Align Alignment = DAG.getReducedAlign(InVT,
false);
6242 MachineFunction &MF = DAG.getMachineFunction();
6254 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6261 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6262 return DAG.getMaskedLoad(
6263 WidenVT, dl, Ch, StackPtr, DAG.getUNDEF(
StackPtr.getValueType()), Mask,
6271 for (i = 0; i < VTNumElts; ++i)
6272 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6274 SDValue UndefVal = DAG.getPOISON(EltVT);
6275 for (; i < WidenNumElts; ++i)
6277 return DAG.getBuildVector(WidenVT, dl,
Ops);
6283 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6288SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6289 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6292 N->getOperand(1),
N->getOperand(2));
6305 if (!
LD->getMemoryVT().isByteSized()) {
6307 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6309 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6318 EVT VT =
LD->getValueType(0);
6319 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6320 EVT WideMaskVT = getSetCCResultType(WideVT);
6323 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6324 TLI.isTypeLegal(WideMaskVT)) {
6327 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6331 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6332 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6344 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6346 Result = GenWidenVectorLoads(LdChain, LD);
6353 if (LdChain.
size() == 1)
6354 NewChain = LdChain[0];
6360 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6371 SDValue NewLoad = DAG.getMaskedLoad(
6372 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6373 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6374 LD->getAddressingMode(),
LD->getExtensionType());
6384 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6386 SDValue EVL =
N->getVectorLength();
6393 "Unable to widen binary VP op");
6394 Mask = GetWidenedVector(Mask);
6395 assert(
Mask.getValueType().getVectorElementCount() ==
6396 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6397 .getVectorElementCount() &&
6398 "Unable to widen vector load");
6401 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6402 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6403 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6411 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6413 SDValue EVL =
N->getVectorLength();
6419 "Unable to widen binary VP op");
6420 Mask = GetWidenedVector(Mask);
6421 assert(
Mask.getValueType().getVectorElementCount() ==
6422 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6423 .getVectorElementCount() &&
6424 "Unable to widen vector load");
6426 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6427 Mask, EVL,
N->getMemOperand());
6440 "Unable to widen VP strided load");
6441 Mask = GetWidenedVector(Mask);
6443 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6444 assert(
Mask.getValueType().getVectorElementCount() ==
6446 "Data and mask vectors should have the same number of elements");
6448 SDValue Res = DAG.getStridedLoadVP(
6449 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6450 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6451 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6452 N->isExpandingLoad());
6460SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6465 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6467 Mask.getValueType().getVectorElementType(),
6470 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6471 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6472 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6474 WideMask, WidePassthru);
6478 EVT VT =
N->getValueType(0);
6479 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6481 EVT MaskVT =
Mask.getValueType();
6482 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6491 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6492 TLI.isTypeLegal(WideMaskVT) &&
6498 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
6499 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6503 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6504 N->getMemoryVT(),
N->getMemOperand());
6508 if (!
N->getPassThru()->isUndef()) {
6511 DAG.
getNode(ISD::VP_SELECT, dl, WidenVT, Mask, NewVal, PassThru, EVL);
6522 Mask = ModifyToType(Mask, WideMaskVT,
true);
6524 SDValue Res = DAG.getMaskedLoad(
6525 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6526 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6527 ExtType,
N->isExpandingLoad());
6536 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6538 EVT MaskVT =
Mask.getValueType();
6539 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6548 Mask = ModifyToType(Mask, WideMaskVT,
true);
6553 Index.getValueType().getScalarType(),
6555 Index = ModifyToType(Index, WideIndexVT);
6561 N->getMemoryVT().getScalarType(), NumElts);
6562 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6563 WideMemVT, dl,
Ops,
N->getMemOperand(),
6564 N->getIndexType(),
N->getExtensionType());
6573 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6581 N->getMemoryVT().getScalarType(), WideEC);
6582 Mask = GetWidenedMask(Mask, WideEC);
6585 Mask,
N->getVectorLength()};
6586 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6587 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6596 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6597 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6625 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6626 return N->getOperand(OpNo).getValueType();
6634 N =
N.getOperand(0);
6636 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6637 if (!
N->getOperand(i)->isUndef())
6639 N =
N.getOperand(0);
6643 N =
N.getOperand(0);
6645 N =
N.getOperand(0);
6672 { MaskVT, MVT::Other },
Ops);
6673 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6680 LLVMContext &Ctx = *DAG.getContext();
6683 if (MaskScalarBits < ToMaskScalBits) {
6687 }
else if (MaskScalarBits > ToMaskScalBits) {
6693 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
6695 "Mask should have the right element size by now.");
6698 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
6700 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
6703 EVT SubVT =
Mask->getValueType(0);
6709 assert((
Mask->getValueType(0) == ToMaskVT) &&
6710 "A mask of ToMaskVT should have been produced by now.");
6720 LLVMContext &Ctx = *DAG.getContext();
6731 EVT CondVT =
Cond->getValueType(0);
6735 EVT VSelVT =
N->getValueType(0);
6747 EVT FinalVT = VSelVT;
6758 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
6759 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
6766 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
6774 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
6777 EVT ToMaskVT = VSelVT;
6784 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6800 if (ScalarBits0 != ScalarBits1) {
6801 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
6802 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
6814 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
6815 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
6816 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
6819 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
6827 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6832 unsigned Opcode =
N->getOpcode();
6834 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
6835 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6836 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6838 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
6844 Cond1 = GetWidenedVector(Cond1);
6852 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
6853 SDValue Res = ModifyToType(SplitSelect, WidenVT);
6858 Cond1 = ModifyToType(Cond1, CondWidenVT);
6861 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
6862 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
6864 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
6865 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
6867 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
6871 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
6872 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
6875 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
6879 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6880 return DAG.getUNDEF(WidenVT);
6884 EVT VT =
N->getValueType(0);
6887 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6891 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6892 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
6895 SmallVector<int, 16> NewMask(WidenNumElts, -1);
6896 for (
unsigned i = 0; i != NumElts; ++i) {
6897 int Idx =
N->getMaskElt(i);
6898 if (Idx < (
int)NumElts)
6901 NewMask[i] = Idx - NumElts + WidenNumElts;
6903 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
6907 EVT VT =
N->getValueType(0);
6911 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6912 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
6918 unsigned IdxVal = WidenNumElts - VTNumElts;
6931 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6934 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6935 "down type's element count");
6938 for (; i < VTNumElts / GCD; ++i)
6940 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
6941 for (; i < WidenNumElts / GCD; ++i)
6949 SmallVector<int, 16>
Mask(WidenNumElts, -1);
6950 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
6952 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
6956SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
6957 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6962 assert(
N->getValueType(0).isVector() &&
6963 N->getOperand(0).getValueType().isVector() &&
6964 "Operands must be vectors");
6965 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6978 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
6979 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
6986 InOp1 = GetWidenedVector(InOp1);
6987 InOp2 = GetWidenedVector(InOp2);
6990 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7001 "Input not widened to expected type!");
7003 if (
N->getOpcode() == ISD::VP_SETCC) {
7006 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7007 N->getOperand(2), Mask,
N->getOperand(4));
7009 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7014 assert(
N->getValueType(0).isVector() &&
7015 N->getOperand(1).getValueType().isVector() &&
7016 "Operands must be vectors");
7017 EVT VT =
N->getValueType(0);
7018 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7028 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7033 for (
unsigned i = 0; i != NumElts; ++i) {
7034 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7035 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7037 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7038 {Chain, LHSElem, RHSElem, CC});
7039 Chains[i] = Scalars[i].getValue(1);
7040 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7041 DAG.getBoolConstant(
true, dl, EltVT, VT),
7042 DAG.getBoolConstant(
false, dl, EltVT, VT));
7046 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7048 return DAG.getBuildVector(WidenVT, dl, Scalars);
7054bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7055 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7059 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7062 switch (
N->getOpcode()) {
7065 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7073 Res = WidenVecOp_FAKE_USE(
N);
7079 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7080 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7081 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7082 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7087 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7089 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7090 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7092 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7093 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7103 Res = WidenVecOp_UnrollVectorOp(
N);
7110 Res = WidenVecOp_EXTEND(
N);
7115 Res = WidenVecOp_CMP(
N);
7131 Res = WidenVecOp_Convert(
N);
7136 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7154 Res = WidenVecOp_VECREDUCE(
N);
7158 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7160 case ISD::VP_REDUCE_FADD:
7161 case ISD::VP_REDUCE_SEQ_FADD:
7162 case ISD::VP_REDUCE_FMUL:
7163 case ISD::VP_REDUCE_SEQ_FMUL:
7164 case ISD::VP_REDUCE_ADD:
7165 case ISD::VP_REDUCE_MUL:
7166 case ISD::VP_REDUCE_AND:
7167 case ISD::VP_REDUCE_OR:
7168 case ISD::VP_REDUCE_XOR:
7169 case ISD::VP_REDUCE_SMAX:
7170 case ISD::VP_REDUCE_SMIN:
7171 case ISD::VP_REDUCE_UMAX:
7172 case ISD::VP_REDUCE_UMIN:
7173 case ISD::VP_REDUCE_FMAX:
7174 case ISD::VP_REDUCE_FMIN:
7175 case ISD::VP_REDUCE_FMAXIMUM:
7176 case ISD::VP_REDUCE_FMINIMUM:
7177 Res = WidenVecOp_VP_REDUCE(
N);
7179 case ISD::VP_CTTZ_ELTS:
7180 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7181 Res = WidenVecOp_VP_CttzElements(
N);
7186 if (!Res.
getNode())
return false;
7194 if (
N->isStrictFPOpcode())
7196 "Invalid operand expansion");
7199 "Invalid operand expansion");
7201 ReplaceValueWith(
SDValue(
N, 0), Res);
7207 EVT VT =
N->getValueType(0);
7212 "Unexpected type action");
7213 InOp = GetWidenedVector(InOp);
7216 "Input wasn't widened!");
7224 EVT FixedEltVT = FixedVT.getVectorElementType();
7225 if (TLI.isTypeLegal(FixedVT) &&
7227 FixedEltVT == InEltVT) {
7229 "Not enough elements in the fixed type for the operand!");
7231 "We can't have the same type as we started with!");
7233 InOp = DAG.getInsertSubvector(
DL, DAG.getUNDEF(FixedVT), InOp, 0);
7235 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7244 return WidenVecOp_Convert(
N);
7249 switch (
N->getOpcode()) {
7264 EVT OpVT =
N->getOperand(0).getValueType();
7265 EVT ResVT =
N->getValueType(0);
7272 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7273 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7279 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7280 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7282 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7289 return DAG.UnrollVectorOp(
N);
7294 EVT ResultVT =
N->getValueType(0);
7296 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7299 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7305 {WideArg,
Test},
N->getFlags());
7311 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7313 EVT OpVT =
N->getOperand(0).getValueType();
7316 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7321 EVT VT =
N->getValueType(0);
7327 "Unexpected type action");
7328 InOp = GetWidenedVector(InOp);
7330 unsigned Opcode =
N->getOpcode();
7336 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7338 if (
N->isStrictFPOpcode()) {
7340 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7343 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7344 {
N->getOperand(0), InOp });
7350 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7352 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7354 return DAG.getExtractSubvector(dl, VT, Res, 0);
7362 if (
N->isStrictFPOpcode()) {
7365 for (
unsigned i=0; i < NumElts; ++i) {
7366 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7367 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7371 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7373 for (
unsigned i = 0; i < NumElts; ++i)
7374 Ops[i] = DAG.getNode(Opcode, dl, EltVT,
7375 DAG.getExtractVectorElt(dl, InEltVT, InOp, i));
7378 return DAG.getBuildVector(VT, dl,
Ops);
7382 EVT DstVT =
N->getValueType(0);
7383 SDValue Src = GetWidenedVector(
N->getOperand(0));
7384 EVT SrcVT = Src.getValueType();
7391 if (TLI.isTypeLegal(WideDstVT)) {
7393 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7396 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7400 return DAG.UnrollVectorOp(
N);
7404 EVT VT =
N->getValueType(0);
7405 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7413 if (!VT.
isVector() && VT != MVT::x86mmx &&
7417 if (TLI.isTypeLegal(NewVT)) {
7419 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7431 ElementCount NewNumElts =
7433 .divideCoefficientBy(EltSize);
7435 if (TLI.isTypeLegal(NewVT)) {
7437 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7442 return CreateStackStoreLoad(InOp, VT);
7450 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7451 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7456 EVT VT =
N->getValueType(0);
7458 EVT InVT =
N->getOperand(0).getValueType();
7463 unsigned NumOperands =
N->getNumOperands();
7464 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7466 for (i = 1; i < NumOperands; ++i)
7467 if (!
N->getOperand(i).isUndef())
7470 if (i == NumOperands)
7471 return GetWidenedVector(
N->getOperand(0));
7481 for (
unsigned i=0; i < NumOperands; ++i) {
7485 "Unexpected type action");
7486 InOp = GetWidenedVector(InOp);
7487 for (
unsigned j = 0;
j < NumInElts; ++
j)
7488 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7490 return DAG.getBuildVector(VT, dl,
Ops);
7493SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7494 EVT VT =
N->getValueType(0);
7499 SubVec = GetWidenedVector(SubVec);
7504 bool IndicesValid =
false;
7507 IndicesValid =
true;
7511 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7512 Attribute::VScaleRange);
7517 IndicesValid =
true;
7523 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7529 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7536 Align Alignment = DAG.getReducedAlign(VT,
false);
7538 MachineFunction &MF = DAG.getMachineFunction();
7551 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7559 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7560 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7565 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7570 unsigned Idx =
N->getConstantOperandVal(2);
7576 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7582SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7583 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7585 N->getValueType(0), InOp,
N->getOperand(1));
7588SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7589 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7591 N->getValueType(0), InOp,
N->getOperand(1));
7594SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7595 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7596 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0), InOp);
7604 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7605 return TLI.scalarizeVectorStore(ST, DAG);
7607 if (
ST->isTruncatingStore())
7608 return TLI.scalarizeVectorStore(ST, DAG);
7618 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7619 EVT WideMaskVT = getSetCCResultType(WideVT);
7621 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7622 TLI.isTypeLegal(WideMaskVT)) {
7625 StVal = GetWidenedVector(StVal);
7627 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7629 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7630 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7631 ST->getAddressingMode());
7635 if (GenWidenVectorStores(StChain, ST)) {
7636 if (StChain.
size() == 1)
7645 SDValue WideStVal = GetWidenedVector(StVal);
7649 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
7650 ST->getOffset(), Mask,
ST->getMemoryVT(),
7651 ST->getMemOperand(),
ST->getAddressingMode(),
7652 ST->isTruncatingStore());
7658SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
7659 assert((OpNo == 1 || OpNo == 3) &&
7660 "Can widen only data or mask operand of vp_store");
7668 StVal = GetWidenedVector(StVal);
7674 "Unable to widen VP store");
7675 Mask = GetWidenedVector(Mask);
7677 Mask = GetWidenedVector(Mask);
7683 "Unable to widen VP store");
7684 StVal = GetWidenedVector(StVal);
7687 assert(
Mask.getValueType().getVectorElementCount() ==
7689 "Mask and data vectors should have the same number of elements");
7690 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
7691 ST->getOffset(), Mask,
ST->getVectorLength(),
7692 ST->getMemoryVT(),
ST->getMemOperand(),
7693 ST->getAddressingMode(),
ST->isTruncatingStore(),
7694 ST->isCompressingStore());
7699 assert((OpNo == 1 || OpNo == 4) &&
7700 "Can widen only data or mask operand of vp_strided_store");
7709 "Unable to widen VP strided store");
7713 "Unable to widen VP strided store");
7715 StVal = GetWidenedVector(StVal);
7716 Mask = GetWidenedVector(Mask);
7719 Mask.getValueType().getVectorElementCount() &&
7720 "Data and mask vectors should have the same number of elements");
7722 return DAG.getStridedStoreVP(
7729SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
7730 assert((OpNo == 1 || OpNo == 4) &&
7731 "Can widen only data or mask operand of mstore");
7734 EVT MaskVT =
Mask.getValueType();
7739 EVT WideVT, WideMaskVT;
7742 StVal = GetWidenedVector(StVal);
7749 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
7756 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7757 TLI.isTypeLegal(WideMaskVT)) {
7758 Mask = DAG.getInsertSubvector(dl, DAG.getUNDEF(WideMaskVT), Mask, 0);
7759 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7768 Mask = ModifyToType(Mask, WideMaskVT,
true);
7771 Mask = ModifyToType(Mask, WideMaskVT,
true);
7773 StVal = ModifyToType(StVal, WideVT);
7776 assert(
Mask.getValueType().getVectorElementCount() ==
7778 "Mask and data vectors should have the same number of elements");
7785SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
7786 assert(OpNo == 4 &&
"Can widen only the index of mgather");
7788 SDValue DataOp = MG->getPassThru();
7790 SDValue Scale = MG->getScale();
7798 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
7799 MG->getMemOperand(), MG->getIndexType(),
7800 MG->getExtensionType());
7806SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
7815 DataOp = GetWidenedVector(DataOp);
7819 EVT IndexVT =
Index.getValueType();
7822 Index = ModifyToType(Index, WideIndexVT);
7825 EVT MaskVT =
Mask.getValueType();
7828 Mask = ModifyToType(Mask, WideMaskVT,
true);
7833 }
else if (OpNo == 4) {
7835 Index = GetWidenedVector(Index);
7841 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
7846SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
7855 DataOp = GetWidenedVector(DataOp);
7856 Index = GetWidenedVector(Index);
7858 Mask = GetWidenedMask(Mask, WideEC);
7861 }
else if (OpNo == 3) {
7863 Index = GetWidenedVector(Index);
7870 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
7875 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
7876 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7878 EVT VT =
N->getValueType(0);
7893 SVT, InOp0, InOp1,
N->getOperand(2));
7899 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
7901 EVT OpVT =
N->getOperand(0).getValueType();
7904 return DAG.getNode(ExtendCode, dl, VT, CC);
7914 EVT VT =
N->getValueType(0);
7916 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7923 for (
unsigned i = 0; i != NumElts; ++i) {
7924 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7925 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7927 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7928 {Chain, LHSElem, RHSElem, CC});
7929 Chains[i] = Scalars[i].getValue(1);
7930 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7931 DAG.getBoolConstant(
true, dl, EltVT, VT),
7932 DAG.getBoolConstant(
false, dl, EltVT, VT));
7936 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7938 return DAG.getBuildVector(VT, dl, Scalars);
7962 SDValue Op = GetWidenedVector(
N->getOperand(0));
7963 EVT VT =
N->getValueType(0);
7964 EVT OrigVT =
N->getOperand(0).getValueType();
7965 EVT WideVT =
Op.getValueType();
7967 SDNodeFlags
Flags =
N->getFlags();
7969 unsigned Opc =
N->getOpcode();
7971 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
7972 assert(NeutralElem &&
"Neutral element must exist");
7982 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
7989 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
7990 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7996 unsigned GCD = std::gcd(OrigElts, WideElts);
7999 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8000 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8001 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8002 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8005 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8006 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8008 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8017 EVT VT =
N->getValueType(0);
8019 EVT WideVT =
Op.getValueType();
8021 SDNodeFlags
Flags =
N->getFlags();
8023 unsigned Opc =
N->getOpcode();
8025 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8035 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8038 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8039 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8045 unsigned GCD = std::gcd(OrigElts, WideElts);
8048 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8049 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8050 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8051 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8054 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8055 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8057 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8061 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8064 SDValue Op = GetWidenedVector(
N->getOperand(1));
8066 Op.getValueType().getVectorElementCount());
8068 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8069 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8077 EVT VT =
N->getValueType(0);
8081 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8082 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8087 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8093 EVT SrcVT =
Source.getValueType();
8097 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8098 {Source, Mask, N->getOperand(2)},
N->getFlags());
8115 unsigned WidenEx = 0) {
8120 unsigned AlignInBits =
Align*8;
8122 EVT RetVT = WidenEltVT;
8127 if (Width == WidenEltWidth)
8138 (WidenWidth % MemVTWidth) == 0 &&
8140 (MemVTWidth <= Width ||
8141 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8142 if (MemVTWidth == WidenWidth)
8161 (WidenWidth % MemVTWidth) == 0 &&
8163 (MemVTWidth <= Width ||
8164 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8173 return std::nullopt;
8184 unsigned Start,
unsigned End) {
8185 SDLoc dl(LdOps[Start]);
8186 EVT LdTy = LdOps[Start].getValueType();
8194 for (
unsigned i = Start + 1; i != End; ++i) {
8195 EVT NewLdTy = LdOps[i].getValueType();
8196 if (NewLdTy != LdTy) {
8215 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8216 EVT LdVT =
LD->getMemoryVT();
8226 AAMDNodes AAInfo =
LD->getAAInfo();
8230 TypeSize WidthDiff = WidenWidth - LdWidth;
8237 std::optional<EVT> FirstVT =
8238 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8245 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8250 std::optional<EVT> NewVT = FirstVT;
8251 TypeSize RemainingWidth = LdWidth;
8252 TypeSize NewVTWidth = FirstVTWidth;
8254 RemainingWidth -= NewVTWidth;
8261 NewVTWidth = NewVT->getSizeInBits();
8267 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8268 LD->getBaseAlign(), MMOFlags, AAInfo);
8272 if (MemVTs.
empty()) {
8274 if (!FirstVT->isVector()) {
8281 if (FirstVT == WidenVT)
8286 unsigned NumConcat =
8289 SDValue UndefVal = DAG.getUNDEF(*FirstVT);
8290 ConcatOps[0] = LdOp;
8291 for (
unsigned i = 1; i != NumConcat; ++i)
8292 ConcatOps[i] = UndefVal;
8300 uint64_t ScaledOffset = 0;
8301 MachinePointerInfo MPI =
LD->getPointerInfo();
8307 for (EVT MemVT : MemVTs) {
8308 Align NewAlign = ScaledOffset == 0
8309 ?
LD->getBaseAlign()
8312 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8320 unsigned End = LdOps.
size();
8331 EVT LdTy = LdOps[i].getValueType();
8334 for (--i; i >= 0; --i) {
8335 LdTy = LdOps[i].getValueType();
8342 ConcatOps[--Idx] = LdOps[i];
8343 for (--i; i >= 0; --i) {
8344 EVT NewLdTy = LdOps[i].getValueType();
8345 if (NewLdTy != LdTy) {
8355 for (;
j != End-Idx; ++
j)
8356 WidenOps[j] = ConcatOps[Idx+j];
8358 WidenOps[j] = DAG.getUNDEF(LdTy);
8365 ConcatOps[--Idx] = LdOps[i];
8370 ArrayRef(&ConcatOps[Idx], End - Idx));
8376 SDValue UndefVal = DAG.getUNDEF(LdTy);
8379 for (; i != End-Idx; ++i)
8380 WidenOps[i] = ConcatOps[Idx+i];
8382 WidenOps[i] = UndefVal;
8393 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8394 EVT LdVT =
LD->getMemoryVT();
8403 AAMDNodes AAInfo =
LD->getAAInfo();
8417 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8418 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8424 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8425 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8426 LD->getBaseAlign(), MMOFlags, AAInfo);
8431 SDValue UndefVal = DAG.getUNDEF(EltVT);
8432 for (; i != WidenNumElts; ++i)
8435 return DAG.getBuildVector(WidenVT, dl,
Ops);
8446 AAMDNodes AAInfo =
ST->getAAInfo();
8447 SDValue ValOp = GetWidenedVector(
ST->getValue());
8450 EVT StVT =
ST->getMemoryVT();
8458 "Mismatch between store and value types");
8462 MachinePointerInfo MPI =
ST->getPointerInfo();
8463 uint64_t ScaledOffset = 0;
8472 std::optional<EVT> NewVT =
8477 TypeSize NewVTWidth = NewVT->getSizeInBits();
8480 StWidth -= NewVTWidth;
8481 MemVTs.
back().second++;
8485 for (
const auto &Pair : MemVTs) {
8486 EVT NewVT = Pair.first;
8487 unsigned Count = Pair.second;
8493 Align NewAlign = ScaledOffset == 0
8494 ?
ST->getBaseAlign()
8496 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8497 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8513 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8514 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8515 ST->getBaseAlign(), MMOFlags, AAInfo);
8532 bool FillWithZeroes) {
8537 "input and widen element type must match");
8539 "cannot modify scalable vectors in this way");
8551 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
8554 for (
unsigned i = 1; i != NumConcat; ++i)
8561 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8564 "Scalable vectors should have been handled already.");
8572 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8574 for (Idx = 0; Idx < MinNumElts; ++Idx)
8575 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8577 SDValue UndefVal = DAG.getUNDEF(EltVT);
8578 for (; Idx < WidenNumElts; ++Idx)
8579 Ops[Idx] = UndefVal;
8581 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8582 if (!FillWithZeroes)
8586 "We expect to never want to FillWithZeroes for non-integral types.");
8589 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8590 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8592 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8593 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.
@ 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.
@ 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
@ 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
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.