35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
47 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
50 switch (
N->getOpcode()) {
53 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
62 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
70 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
73 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
79 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
89 R = ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
N);
95 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
97 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
103 R = ScalarizeVecRes_VecInregOp(
N);
155 R = ScalarizeVecRes_UnaryOp(
N);
158 R = ScalarizeVecRes_ADDRSPACECAST(
N);
164 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
223 R = ScalarizeVecRes_BinOp(
N);
230 R = ScalarizeVecRes_MaskedBinOp(
N);
235 R = ScalarizeVecRes_CMP(
N);
241 R = ScalarizeVecRes_TernaryOp(
N);
244#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
245 case ISD::STRICT_##DAGN:
246#include "llvm/IR/ConstrainedOps.def"
247 R = ScalarizeVecRes_StrictFPOp(
N);
252 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
261 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
271 R = ScalarizeVecRes_FIX(
N);
277 SetScalarizedVector(
SDValue(
N, ResNo), R);
281 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
282 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
283 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
289 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
290 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
292 EVT MaskVT =
Mask.getValueType();
297 Mask = GetScalarizedVector(Mask);
306 DAG.getConstant(1,
DL,
LHS.getValueType()));
308 LHS.getValueType(),
LHS, Divisor);
316 if (getTypeAction(
LHS.getValueType()) ==
318 LHS = GetScalarizedVector(
LHS);
319 RHS = GetScalarizedVector(
RHS);
321 EVT VT =
LHS.getValueType().getVectorElementType();
322 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
323 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
326 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
327 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
331 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
332 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
333 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
334 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
339 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
340 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
347DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
349 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
350 "Unexpected vector type!");
351 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
353 EVT VT0 =
N->getValueType(0);
354 EVT VT1 =
N->getValueType(1);
358 DAG.getNode(
N->getOpcode(), dl,
359 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
363 unsigned OtherNo = 1 - ResNo;
364 EVT OtherVT =
N->getValueType(OtherNo);
366 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
370 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
373 return SDValue(ScalarNode, ResNo);
378 unsigned NumOpers =
N->getNumOperands();
380 EVT ValueVTs[] = {VT, MVT::Other};
389 for (
unsigned i = 1; i < NumOpers; ++i) {
395 Oper = GetScalarizedVector(Oper);
404 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
405 Opers,
N->getFlags());
416 EVT ResVT =
N->getValueType(0);
417 EVT OvVT =
N->getValueType(1);
421 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
422 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
425 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
426 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
427 ScalarLHS = ElemsLHS[0];
428 ScalarRHS = ElemsRHS[0];
431 SDVTList ScalarVTs = DAG.getVTList(
433 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
434 {ScalarLHS, ScalarRHS},
N->getFlags())
438 unsigned OtherNo = 1 - ResNo;
439 EVT OtherVT =
N->getValueType(OtherNo);
441 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
445 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
448 return SDValue(ScalarNode, ResNo);
453 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
454 return GetScalarizedVector(
Op);
457SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
462 N->getValueType(0).getScalarType(), Mask,
463 DAG.getVectorIdxConstant(0,
DL));
469 Op = GetScalarizedVector(
Op);
470 EVT NewVT =
N->getValueType(0).getVectorElementType();
475SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
485SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
487 N->getValueType(0).getVectorElementType(),
488 N->getOperand(0),
N->getOperand(1));
494 EVT OpVT =
Op.getValueType();
498 Op = GetScalarizedVector(
Op);
501 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
504 N->getValueType(0).getVectorElementType(),
Op,
508SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
511 EVT OpVT =
Op.getValueType();
515 Op = GetScalarizedVector(
Op);
518 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
521 N->getValueType(0).getVectorElementType(),
Op,
525SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
528 EVT OpVT =
Op.getValueType();
531 Op = GetScalarizedVector(
Op);
534 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
537 N->getValueType(0).getVectorElementType(),
Op,
538 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
541SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
542 SDValue Op = GetScalarizedVector(
N->getOperand(0));
543 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
547SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
552 if (
Op.getValueType() != EltVT)
560 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
561 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
571 assert(
N->isUnindexed() &&
"Indexed vector load?");
575 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
576 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
577 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
578 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
590 EVT OpVT =
Op.getValueType();
600 Op = GetScalarizedVector(
Op);
603 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
605 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
611 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
612 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
613 LHS, DAG.getValueType(ExtVT));
620 EVT OpVT =
Op.getValueType();
625 Op = GetScalarizedVector(
Op);
627 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
630 switch (
N->getOpcode()) {
642SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
645 EVT OpVT =
Op.getValueType();
655 Op = GetScalarizedVector(
Op);
658 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
661 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
662 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
663 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
666SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
677DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
678 assert(
N->getNumValues() ==
N->getNumOperands() &&
679 "Expected one result per operand");
683 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
684 SetScalarizedVector(
SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
690 EVT OpVT =
Cond.getValueType();
699 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
702 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
704 TLI.getBooleanContents(
false,
false);
711 if (TLI.getBooleanContents(
false,
false) !=
712 TLI.getBooleanContents(
false,
true)) {
716 EVT OpVT =
Cond->getOperand(0).getValueType();
718 VecBool = TLI.getBooleanContents(OpVT);
723 EVT CondVT =
Cond.getValueType();
724 if (ScalarBool != VecBool) {
725 switch (ScalarBool) {
733 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
740 Cond, DAG.getValueType(MVT::i1));
746 auto BoolVT = getSetCCResultType(CondVT);
747 if (BoolVT.bitsLT(CondVT))
750 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
751 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
755 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
756 return DAG.getSelect(SDLoc(
N),
757 LHS.getValueType(),
N->getOperand(0),
LHS,
758 GetScalarizedVector(
N->getOperand(2)));
762 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
764 N->getOperand(0),
N->getOperand(1),
765 LHS, GetScalarizedVector(
N->getOperand(3)),
770 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
773SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
777 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
779 return GetScalarizedVector(
N->getOperand(
Op));
782SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
784 EVT SrcVT = Src.getValueType();
789 Src = GetScalarizedVector(Src);
793 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
795 EVT DstVT =
N->getValueType(0).getVectorElementType();
796 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
800 assert(
N->getValueType(0).isVector() &&
801 N->getOperand(0).getValueType().isVector() &&
802 "Operand types must be vectors");
805 EVT OpVT =
LHS.getValueType();
806 EVT NVT =
N->getValueType(0).getVectorElementType();
811 LHS = GetScalarizedVector(
LHS);
812 RHS = GetScalarizedVector(
RHS);
815 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
816 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
826 return DAG.getNode(ExtendCode,
DL, NVT, Res);
837 Arg = GetScalarizedVector(Arg);
840 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
849 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
856bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
862 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
865 switch (
N->getOpcode()) {
868 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
875 Res = ScalarizeVecOp_BITCAST(
N);
878 Res = ScalarizeVecOp_FAKE_USE(
N);
892 Res = ScalarizeVecOp_UnaryOp(
N);
897 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
900 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
901 "Unexpected vector type!");
902 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
904 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
905 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
913 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
916 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
919 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
922 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
925 Res = ScalarizeVecOp_VSELECT(
N);
928 Res = ScalarizeVecOp_VSETCC(
N);
932 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
941 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
944 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
947 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
950 Res = ScalarizeVecOp_FP_EXTEND(
N);
967 Res = ScalarizeVecOp_VECREDUCE(
N);
971 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
975 Res = ScalarizeVecOp_CMP(
N);
978 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
982 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
988 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
993 if (!Res.
getNode())
return false;
1001 "Invalid operand expansion");
1003 ReplaceValueWith(
SDValue(
N, 0), Res);
1010 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1012 N->getValueType(0), Elt);
1017 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1018 "Fake Use: Unexpected vector type!");
1019 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1020 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1026 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1027 "Unexpected vector type!");
1028 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1029 SDValue Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1030 N->getValueType(0).getScalarType(), Elt);
1038SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1039 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1040 "Unexpected vector type!");
1041 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1043 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1044 Elt,
N->getOperand(1));
1052SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1053 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1054 "Unexpected vector type!");
1055 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1057 {
N->getValueType(0).getScalarType(), MVT::Other },
1058 {
N->getOperand(0), Elt });
1068 ReplaceValueWith(
SDValue(
N, 0), Res);
1073SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1075 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1076 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1077 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1082SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1086 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1087 SDValue ContainingVec =
N->getOperand(0);
1095SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1096 EVT VT =
N->getValueType(0);
1097 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1109 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1110 EVT VT =
N->getValueType(0);
1112 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1120 assert(
N->getValueType(0).isVector() &&
1121 N->getOperand(0).getValueType().isVector() &&
1122 "Operand types must be vectors");
1123 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1125 EVT VT =
N->getValueType(0);
1126 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1127 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1129 EVT OpVT =
N->getOperand(0).getValueType();
1141 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1147SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1149 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1150 assert(
N->getValueType(0).isVector() &&
1151 N->getOperand(1).getValueType().isVector() &&
1152 "Operand types must be vectors");
1153 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1155 EVT VT =
N->getValueType(0);
1157 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1158 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1161 EVT OpVT =
N->getOperand(1).getValueType();
1165 {Ch, LHS, RHS, CC});
1174 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1179 ReplaceValueWith(
SDValue(
N, 0), Res);
1186 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1187 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1190 if (
N->isTruncatingStore())
1191 return DAG.getTruncStore(
1192 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1193 N->getBasePtr(),
N->getPointerInfo(),
1194 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1195 N->getMemOperand()->getFlags(),
N->getAAInfo());
1197 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1198 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1199 N->getMemOperand()->getFlags(),
N->getAAInfo());
1205 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1207 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1208 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1213SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1214 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1215 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1217 N->getValueType(0).getVectorElementType(), Elt,
1222SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1224 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1225 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1228 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1238 ReplaceValueWith(
SDValue(
N, 0), Res);
1245 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1247 N->getValueType(0).getVectorElementType(), Elt);
1253SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1254 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1257 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1258 {
N->getOperand(0), Elt});
1267 ReplaceValueWith(
SDValue(
N, 0), Res);
1272 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1279SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1285 SDValue Op = GetScalarizedVector(VecOp);
1286 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1287 AccOp,
Op,
N->getFlags());
1291 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1292 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1299SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1307 EVT VT =
N->getValueType(0);
1308 return DAG.getConstant(0, SDLoc(
N), VT);
1315 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1316 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1318 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1319 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1320 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1323SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1324 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1327 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1328 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1337 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1349void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1354 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1357 switch (
N->getOpcode()) {
1360 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1369 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1377 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1393 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1396 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1408 case ISD::VP_LOAD_FF:
1411 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1418 case ISD::VP_GATHER:
1422 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1426 SplitVecRes_SETCC(
N,
Lo,
Hi);
1429 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1436 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1439 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1442 SplitVecRes_VECTOR_INTERLEAVE(
N);
1445 SplitVecRes_VAARG(
N,
Lo,
Hi);
1451 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1458 case ISD::VP_BITREVERSE:
1466 case ISD::VP_CTLZ_ZERO_POISON:
1468 case ISD::VP_CTTZ_ZERO_POISON:
1483 case ISD::VP_FFLOOR:
1488 case ISD::VP_FNEARBYINT:
1493 case ISD::VP_FP_EXTEND:
1495 case ISD::VP_FP_ROUND:
1497 case ISD::VP_FP_TO_SINT:
1499 case ISD::VP_FP_TO_UINT:
1505 case ISD::VP_LLRINT:
1507 case ISD::VP_FROUND:
1509 case ISD::VP_FROUNDEVEN:
1518 case ISD::VP_FROUNDTOZERO:
1520 case ISD::VP_SINT_TO_FP:
1522 case ISD::VP_TRUNCATE:
1524 case ISD::VP_UINT_TO_FP:
1529 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1532 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1538 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1544 case ISD::VP_SIGN_EXTEND:
1545 case ISD::VP_ZERO_EXTEND:
1546 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1570 case ISD::VP_FMINNUM:
1573 case ISD::VP_FMAXNUM:
1575 case ISD::VP_FMINIMUM:
1577 case ISD::VP_FMAXIMUM:
1586 case ISD::OR:
case ISD::VP_OR:
1606 case ISD::VP_FCOPYSIGN:
1607 SplitVecRes_BinOp(
N,
Lo,
Hi);
1613 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1620 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1624 SplitVecRes_CMP(
N,
Lo,
Hi);
1627#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1628 case ISD::STRICT_##DAGN:
1629#include "llvm/IR/ConstrainedOps.def"
1630 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1635 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1644 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1654 SplitVecRes_FIX(
N,
Lo,
Hi);
1656 case ISD::EXPERIMENTAL_VP_SPLICE:
1657 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1659 case ISD::EXPERIMENTAL_VP_REVERSE:
1660 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1666 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1669 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1678void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1680 uint64_t *ScaledOffset) {
1685 SDValue BytesIncrement = DAG.getVScale(
1688 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1690 *ScaledOffset += IncrementSize;
1700std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1701 return SplitMask(Mask, SDLoc(Mask));
1704std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1707 EVT MaskVT =
Mask.getValueType();
1709 GetSplitVector(Mask, MaskLo, MaskHi);
1711 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1712 return std::make_pair(MaskLo, MaskHi);
1717 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1719 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1722 const SDNodeFlags
Flags =
N->getFlags();
1723 unsigned Opcode =
N->getOpcode();
1724 if (
N->getNumOperands() == 2) {
1725 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1726 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1730 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1731 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1734 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1737 std::tie(EVLLo, EVLHi) =
1738 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1741 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1743 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1749 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1751 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1755 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1757 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1761 const SDNodeFlags
Flags =
N->getFlags();
1762 unsigned Opcode =
N->getOpcode();
1763 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1765 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1772 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1774 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1776 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1779 const SDNodeFlags
Flags =
N->getFlags();
1780 unsigned Opcode =
N->getOpcode();
1781 if (
N->getNumOperands() == 3) {
1782 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1783 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1787 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1788 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1791 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1794 std::tie(EVLLo, EVLHi) =
1795 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1798 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1800 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1804 LLVMContext &Ctxt = *DAG.getContext();
1810 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1812 GetSplitVector(
LHS, LHSLo, LHSHi);
1813 GetSplitVector(
RHS, RHSLo, RHSHi);
1815 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1816 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1820 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1821 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1826 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1828 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1832 unsigned Opcode =
N->getOpcode();
1833 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1835 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1844 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1851 switch (getTypeAction(InVT)) {
1865 GetExpandedOp(InOp,
Lo,
Hi);
1866 if (DAG.getDataLayout().isBigEndian())
1876 GetSplitVector(InOp,
Lo,
Hi);
1885 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1894 if (DAG.getDataLayout().isBigEndian())
1897 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1899 if (DAG.getDataLayout().isBigEndian())
1905void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1911 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1914 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1919 unsigned LaneOffset =
1922 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1924 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1931 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1934 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1937 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1942 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1944 unsigned NumSubvectors =
N->getNumOperands() / 2;
1945 if (NumSubvectors == 1) {
1946 Lo =
N->getOperand(0);
1947 Hi =
N->getOperand(1);
1952 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1961void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1968 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1983 GetSplitVector(Vec,
Lo,
Hi);
1986 EVT LoVT =
Lo.getValueType();
1996 if (IdxVal + SubElems <= LoElems) {
2004 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
2006 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
2012 SDValue WideSubVec = GetWidenedVector(SubVec);
2014 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2022 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2024 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2025 auto &MF = DAG.getMachineFunction();
2029 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2034 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2035 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2039 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2044 MachinePointerInfo MPI =
Load->getPointerInfo();
2045 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2048 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2057 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2062 EVT RHSVT =
RHS.getValueType();
2065 GetSplitVector(
RHS, RHSLo, RHSHi);
2067 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2082 SDValue FpValue =
N->getOperand(0);
2084 GetSplitVector(FpValue, ArgLo, ArgHi);
2086 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2088 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2097 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2101 std::tie(LoVT, HiVT) =
2105 DAG.getValueType(LoVT));
2107 DAG.getValueType(HiVT));
2112 unsigned Opcode =
N->getOpcode();
2119 GetSplitVector(N0, InLo, InHi);
2121 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2126 EVT OutLoVT, OutHiVT;
2127 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2129 assert((2 * OutNumElements) <= InNumElements &&
2130 "Illegal extend vector in reg split");
2139 SmallVector<int, 8> SplitHi(InNumElements, -1);
2140 for (
unsigned i = 0; i != OutNumElements; ++i)
2141 SplitHi[i] = i + OutNumElements;
2142 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2144 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2145 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2150 unsigned NumOps =
N->getNumOperands();
2154 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2164 for (
unsigned i = 1; i <
NumOps; ++i) {
2169 EVT InVT =
Op.getValueType();
2174 GetSplitVector(
Op, OpLo, OpHi);
2176 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2183 EVT LoValueVTs[] = {LoVT, MVT::Other};
2184 EVT HiValueVTs[] = {HiVT, MVT::Other};
2185 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2187 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2193 Lo.getValue(1),
Hi.getValue(1));
2197 ReplaceValueWith(
SDValue(
N, 1), Chain);
2200SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2202 EVT VT =
N->getValueType(0);
2213 else if (NE > ResNE)
2217 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2221 for (i = 0; i !=
NE; ++i) {
2223 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2224 SDValue Operand =
N->getOperand(j);
2228 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2234 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2242 for (; i < ResNE; ++i)
2243 Scalars.
push_back(DAG.getPOISON(EltVT));
2247 ReplaceValueWith(
SDValue(
N, 1), Chain);
2251 return DAG.getBuildVector(VecVT, dl, Scalars);
2254void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2257 EVT ResVT =
N->getValueType(0);
2258 EVT OvVT =
N->getValueType(1);
2259 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2260 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2261 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2263 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2265 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2266 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2268 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2269 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2272 unsigned Opcode =
N->getOpcode();
2273 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2274 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2276 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2278 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2284 unsigned OtherNo = 1 - ResNo;
2285 EVT OtherVT =
N->getValueType(OtherNo);
2287 SetSplitVector(
SDValue(
N, OtherNo),
2293 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2297void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2303 GetSplitVector(Vec,
Lo,
Hi);
2306 unsigned IdxVal = CIdx->getZExtValue();
2307 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2308 if (IdxVal < LoNumElts) {
2310 Lo.getValueType(),
Lo, Elt, Idx);
2313 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2333 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2335 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2336 auto &MF = DAG.getMachineFunction();
2340 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2345 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2346 Store = DAG.getTruncStore(
2352 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2355 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2359 MachinePointerInfo MPI =
Load->getPointerInfo();
2360 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2362 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2365 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2366 if (LoVT !=
Lo.getValueType())
2368 if (HiVT !=
Hi.getValueType())
2376 assert(
N->getValueType(0).isScalableVector() &&
2377 "Only scalable vectors are supported for STEP_VECTOR");
2378 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2399 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2400 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2402 Hi = DAG.getPOISON(HiVT);
2412 "Extended load during type legalization!");
2414 EVT VT =
LD->getValueType(0);
2416 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2424 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2425 Ch, Ptr,
LD->getMemOperand());
2430 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2432 Lo = DAG.getBitcast(LoVT, ExtractLo);
2433 Hi = DAG.getBitcast(HiVT, ExtractHi);
2445 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2451 EVT MemoryVT =
LD->getMemoryVT();
2453 AAMDNodes AAInfo =
LD->getAAInfo();
2455 EVT LoMemVT, HiMemVT;
2456 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2460 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2461 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2462 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2467 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2470 MachinePointerInfo MPI;
2471 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2474 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2483 ReplaceValueWith(
SDValue(LD, 1), Ch);
2488 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2491 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2497 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2498 Align Alignment =
LD->getBaseAlign();
2501 EVT MemoryVT =
LD->getMemoryVT();
2503 EVT LoMemVT, HiMemVT;
2504 bool HiIsEmpty =
false;
2505 std::tie(LoMemVT, HiMemVT) =
2506 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2511 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2514 GetSplitVector(Mask, MaskLo, MaskHi);
2516 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2521 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2523 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2526 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2529 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2530 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2538 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2539 LD->isExpandingLoad());
2541 MachinePointerInfo MPI;
2543 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2545 MPI =
LD->getPointerInfo().getWithOffset(
2548 MMO = DAG.getMachineFunction().getMachineMemOperand(
2550 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2552 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2553 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2554 LD->isExpandingLoad());
2564 ReplaceValueWith(
SDValue(LD, 1), Ch);
2570 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2574 Align Alignment =
LD->getBaseAlign();
2581 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2584 GetSplitVector(Mask, MaskLo, MaskHi);
2586 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2590 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2592 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2595 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2597 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2600 Hi = DAG.getPOISON(HiVT);
2602 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2603 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2609 "Indexed VP strided load during type legalization!");
2611 "Unexpected indexed variable-length load offset");
2616 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2618 EVT LoMemVT, HiMemVT;
2619 bool HiIsEmpty =
false;
2620 std::tie(LoMemVT, HiMemVT) =
2621 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2626 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2629 GetSplitVector(Mask, LoMask, HiMask);
2631 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2635 std::tie(LoEVL, HiEVL) =
2639 Lo = DAG.getStridedLoadVP(
2666 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2673 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2684 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2692 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2697 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2707 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2710 GetSplitVector(Mask, MaskLo, MaskHi);
2712 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2716 EVT LoMemVT, HiMemVT;
2717 bool HiIsEmpty =
false;
2718 std::tie(LoMemVT, HiMemVT) =
2719 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2721 SDValue PassThruLo, PassThruHi;
2723 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2725 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2727 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2731 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2741 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2744 MachinePointerInfo MPI;
2751 MMO = DAG.getMachineFunction().getMachineMemOperand(
2755 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2767 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2775 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2785 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2788 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2791 EVT MemoryVT =
N->getMemoryVT();
2792 Align Alignment =
N->getBaseAlign();
2797 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2799 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2802 EVT LoMemVT, HiMemVT;
2804 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2807 if (getTypeAction(
Ops.Index.getValueType()) ==
2809 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2811 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2814 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2816 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2819 SDValue PassThru = MGT->getPassThru();
2820 SDValue PassThruLo, PassThruHi;
2823 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2825 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2830 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2831 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2832 OpsLo, MMO, IndexTy, ExtType);
2834 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2835 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2836 OpsHi, MMO, IndexTy, ExtType);
2840 std::tie(EVLLo, EVLHi) =
2841 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2843 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2844 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2845 MMO, VPGT->getIndexType());
2847 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2848 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2849 MMO, VPGT->getIndexType());
2859 ReplaceValueWith(
SDValue(
N, 1), Ch);
2873 EVT VecVT =
N->getValueType(0);
2875 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2876 bool HasCustomLowering =
false;
2883 HasCustomLowering =
true;
2889 SDValue Passthru =
N->getOperand(2);
2890 if (!HasCustomLowering) {
2891 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2892 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2899 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2900 std::tie(LoMask, HiMask) = SplitMask(Mask);
2902 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2907 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2908 MachineFunction &MF = DAG.getMachineFunction();
2920 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2922 SDValue Chain = DAG.getEntryNode();
2923 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2927 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2932 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2936 assert(
N->getValueType(0).isVector() &&
2937 N->getOperand(0).getValueType().isVector() &&
2938 "Operand types must be vectors");
2942 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2946 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2948 GetSplitVector(
N->getOperand(0), LL, LH);
2950 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2952 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2954 GetSplitVector(
N->getOperand(1), RL, RH);
2956 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2959 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2960 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2962 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2963 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2964 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2965 std::tie(EVLLo, EVLHi) =
2966 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2967 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2969 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2979 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2983 EVT InVT =
N->getOperand(0).getValueType();
2985 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2987 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2989 const SDNodeFlags
Flags =
N->getFlags();
2990 unsigned Opcode =
N->getOpcode();
2992 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
2993 N->getOperand(3), Flags);
2994 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
2995 N->getOperand(3), Flags);
2998 if (
N->getNumOperands() <= 2) {
3001 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
3002 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
3004 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
3005 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
3010 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
3011 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3014 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3017 std::tie(EVLLo, EVLHi) =
3018 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3021 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
3027 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3031 EVT InVT =
N->getOperand(0).getValueType();
3033 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3035 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3038 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3039 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3040 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
3041 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
3044void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3049 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3050 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3054 EVT InVT =
N->getOperand(0).getValueType();
3056 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3058 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3060 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3061 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3063 SDNode *HiNode =
Hi.getNode();
3064 SDNode *LoNode =
Lo.getNode();
3067 unsigned OtherNo = 1 - ResNo;
3068 EVT OtherVT =
N->getValueType(OtherNo);
3076 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3083 EVT SrcVT =
N->getOperand(0).getValueType();
3084 EVT DestVT =
N->getValueType(0);
3086 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3103 LLVMContext &Ctx = *DAG.getContext();
3107 EVT SplitLoVT, SplitHiVT;
3108 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3109 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3110 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3111 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3112 N->dump(&DAG);
dbgs() <<
"\n");
3113 if (!
N->isVPOpcode()) {
3116 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3118 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3120 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3121 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3127 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
3128 N->getOperand(1),
N->getOperand(2));
3130 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3133 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3136 std::tie(EVLLo, EVLHi) =
3137 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3139 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
3140 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
3145 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3153 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3154 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3160 return N.getResNo() == 0 &&
3164 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3166 ArrayRef<int>
Mask) {
3169 "Expected build vector node.");
3172 for (
unsigned I = 0;
I < NewElts; ++
I) {
3175 unsigned Idx =
Mask[
I];
3177 Ops[
I] = Input2.getOperand(Idx - NewElts);
3179 Ops[
I] = Input1.getOperand(Idx);
3184 return DAG.getBuildVector(NewVT,
DL,
Ops);
3190 SmallVector<int> OrigMask(
N->getMask());
3192 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3193 &
DL](SmallVectorImpl<int> &
Mask) {
3195 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3196 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3207 for (
auto &
P : ShufflesIdxs) {
3208 if (
P.second.size() < 2)
3212 for (
int &Idx : Mask) {
3215 unsigned SrcRegIdx = Idx / NewElts;
3216 if (Inputs[SrcRegIdx].
isUndef()) {
3224 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3229 Idx = MaskElt % NewElts +
3230 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3236 Inputs[
P.second[0]] =
P.first.first;
3237 Inputs[
P.second[1]] =
P.first.second;
3240 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3243 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3244 for (
int &Idx : Mask) {
3247 unsigned SrcRegIdx = Idx / NewElts;
3248 if (Inputs[SrcRegIdx].
isUndef()) {
3255 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3256 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3259 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3261 if (UsedSubVector.count() > 1) {
3263 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3264 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3266 if (Pairs.
empty() || Pairs.
back().size() == 2)
3268 if (UsedSubVector.test(2 *
I)) {
3269 Pairs.
back().emplace_back(
I, 0);
3271 assert(UsedSubVector.test(2 *
I + 1) &&
3272 "Expected to be used one of the subvectors.");
3273 Pairs.
back().emplace_back(
I, 1);
3276 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3278 for (
int &Idx : Mask) {
3281 unsigned SrcRegIdx = Idx / NewElts;
3283 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3284 return Idxs.front().first == SrcRegIdx ||
3285 Idxs.back().first == SrcRegIdx;
3287 if (It == Pairs.
end())
3289 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3290 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3293 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3294 Inputs[Idxs.front().first] = DAG.
getNode(
3296 Inputs[Idxs.front().first].getValueType(),
3297 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3298 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3307 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3311 if (Shuffle->getOperand(0).getValueType() != NewVT)
3314 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3315 !Shuffle->isSplat()) {
3317 }
else if (!Inputs[
I].hasOneUse() &&
3318 !Shuffle->getOperand(1).isUndef()) {
3320 for (
int &Idx : Mask) {
3323 unsigned SrcRegIdx = Idx / NewElts;
3326 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3331 int OpIdx = MaskElt / NewElts;
3345 if (Shuffle->getOperand(
OpIdx).isUndef())
3347 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3348 if (It == std::end(Inputs))
3350 int FoundOp = std::distance(std::begin(Inputs), It);
3353 for (
int &Idx : Mask) {
3356 unsigned SrcRegIdx = Idx / NewElts;
3359 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3364 int MaskIdx = MaskElt / NewElts;
3365 if (
OpIdx == MaskIdx)
3366 Idx = MaskElt % NewElts + FoundOp * NewElts;
3377 for (
int &Idx : Mask) {
3380 unsigned SrcRegIdx = Idx / NewElts;
3383 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3384 int OpIdx = MaskElt / NewElts;
3387 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3393 TryPeekThroughShufflesInputs(OrigMask);
3395 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3396 NewElts](SmallVectorImpl<int> &
Mask) {
3397 SetVector<SDValue> UniqueInputs;
3398 SetVector<SDValue> UniqueConstantInputs;
3399 for (
const auto &
I : Inputs) {
3401 UniqueConstantInputs.
insert(
I);
3402 else if (!
I.isUndef())
3407 if (UniqueInputs.
size() != std::size(Inputs)) {
3408 auto &&UniqueVec = UniqueInputs.
takeVector();
3409 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3410 unsigned ConstNum = UniqueConstantVec.size();
3411 for (
int &Idx : Mask) {
3414 unsigned SrcRegIdx = Idx / NewElts;
3415 if (Inputs[SrcRegIdx].
isUndef()) {
3419 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3420 if (It != UniqueConstantVec.end()) {
3421 Idx = (Idx % NewElts) +
3422 NewElts * std::distance(UniqueConstantVec.begin(), It);
3423 assert(Idx >= 0 &&
"Expected defined mask idx.");
3426 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3427 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3428 Idx = (Idx % NewElts) +
3429 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3430 assert(Idx >= 0 &&
"Expected defined mask idx.");
3432 copy(UniqueConstantVec, std::begin(Inputs));
3433 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3436 MakeUniqueInputs(OrigMask);
3438 copy(Inputs, std::begin(OrigInputs));
3444 unsigned FirstMaskIdx =
High * NewElts;
3447 assert(!Output &&
"Expected default initialized initial value.");
3448 TryPeekThroughShufflesInputs(Mask);
3449 MakeUniqueInputs(Mask);
3451 copy(Inputs, std::begin(TmpInputs));
3454 bool SecondIteration =
false;
3455 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3460 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3461 SecondIteration =
true;
3462 return SecondIteration;
3465 Mask, std::size(Inputs), std::size(Inputs),
3467 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3468 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3469 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3471 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3473 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3474 DAG.getPOISON(NewVT), Mask);
3475 Inputs[Idx] = Output;
3477 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3478 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3479 unsigned Idx2,
bool ) {
3480 if (AccumulateResults(Idx1)) {
3483 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3485 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3486 Inputs[Idx2], Mask);
3490 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3492 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3493 TmpInputs[Idx2], Mask);
3495 Inputs[Idx1] = Output;
3497 copy(OrigInputs, std::begin(Inputs));
3502 EVT OVT =
N->getValueType(0);
3509 const Align Alignment =
3510 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3512 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3513 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3518 ReplaceValueWith(
SDValue(
N, 1), Chain);
3523 EVT DstVTLo, DstVTHi;
3524 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3528 EVT SrcVT =
N->getOperand(0).getValueType();
3530 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3532 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3534 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3535 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3541 GetSplitVector(
N->getOperand(0), InLo, InHi);
3552 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3553 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3558 EVT VT =
N->getValueType(0);
3576 Align Alignment = DAG.getReducedAlign(VT,
false);
3581 EVT PtrVT =
StackPtr.getValueType();
3582 auto &MF = DAG.getMachineFunction();
3586 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3589 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3595 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3596 DAG.getConstant(1,
DL, PtrVT));
3598 DAG.getConstant(EltWidth,
DL, PtrVT));
3600 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3602 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3603 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3604 DAG.getPOISON(PtrVT), Stride, TrueMask,
3613 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3618 EVT VT =
N->getValueType(0);
3630 EVL1 = ZExtPromotedInteger(EVL1);
3644 Align Alignment = DAG.getReducedAlign(VT,
false);
3649 EVT PtrVT =
StackPtr.getValueType();
3650 auto &MF = DAG.getMachineFunction();
3654 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3657 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3663 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3668 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3669 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3671 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3673 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3677 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3682 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3683 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3685 uint64_t TrailingElts = -
Imm;
3687 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3696 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3704 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3706 DAG.getVectorIdxConstant(0,
DL));
3712void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3720 GetSplitVector(Acc, AccLo, AccHi);
3721 unsigned Opcode =
N->getOpcode();
3733 GetSplitVector(Input1, Input1Lo, Input1Hi);
3734 GetSplitVector(Input2, Input2Lo, Input2Hi);
3737 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3738 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3741void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3749 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3757void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3758 unsigned Factor =
N->getNumOperands();
3761 for (
unsigned i = 0; i != Factor; ++i) {
3763 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3765 Ops[i * 2 + 1] = OpHi;
3776 for (
unsigned i = 0; i != Factor; ++i)
3780void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3781 unsigned Factor =
N->getNumOperands();
3784 for (
unsigned i = 0; i != Factor; ++i) {
3786 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3788 Ops[i + Factor] = OpHi;
3799 for (
unsigned i = 0; i != Factor; ++i) {
3800 unsigned IdxLo = 2 * i;
3801 unsigned IdxHi = 2 * i + 1;
3802 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3803 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3815bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3820 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3823 switch (
N->getOpcode()) {
3826 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3836 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3843 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3845 case ISD::VP_TRUNCATE:
3847 Res = SplitVecOp_TruncateHelper(
N);
3850 case ISD::VP_FP_ROUND:
3854 Res = SplitVecOp_FP_ROUND(
N);
3866 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3873 case ISD::VP_SCATTER:
3877 case ISD::VP_GATHER:
3881 Res = SplitVecOp_VSELECT(
N, OpNo);
3887 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3890 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3896 case ISD::VP_SINT_TO_FP:
3897 case ISD::VP_UINT_TO_FP:
3898 if (
N->getValueType(0).bitsLT(
3899 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3900 Res = SplitVecOp_TruncateHelper(
N);
3902 Res = SplitVecOp_UnaryOp(
N);
3906 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3910 case ISD::VP_FP_TO_SINT:
3911 case ISD::VP_FP_TO_UINT:
3924 Res = SplitVecOp_UnaryOp(
N);
3927 Res = SplitVecOp_FPOpDifferentTypes(
N);
3932 Res = SplitVecOp_CMP(
N);
3936 Res = SplitVecOp_FAKE_USE(
N);
3941 Res = SplitVecOp_ExtVecInRegOp(
N);
3959 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3963 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3965 case ISD::VP_REDUCE_FADD:
3966 case ISD::VP_REDUCE_SEQ_FADD:
3967 case ISD::VP_REDUCE_FMUL:
3968 case ISD::VP_REDUCE_SEQ_FMUL:
3969 case ISD::VP_REDUCE_ADD:
3970 case ISD::VP_REDUCE_MUL:
3971 case ISD::VP_REDUCE_AND:
3972 case ISD::VP_REDUCE_OR:
3973 case ISD::VP_REDUCE_XOR:
3974 case ISD::VP_REDUCE_SMAX:
3975 case ISD::VP_REDUCE_SMIN:
3976 case ISD::VP_REDUCE_UMAX:
3977 case ISD::VP_REDUCE_UMIN:
3978 case ISD::VP_REDUCE_FMAX:
3979 case ISD::VP_REDUCE_FMIN:
3980 case ISD::VP_REDUCE_FMAXIMUM:
3981 case ISD::VP_REDUCE_FMINIMUM:
3982 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3986 Res = SplitVecOp_CttzElts(
N);
3988 case ISD::VP_CTTZ_ELTS:
3989 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3990 Res = SplitVecOp_VP_CttzElements(
N);
3993 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3999 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
4004 if (!Res.
getNode())
return false;
4011 if (
N->isStrictFPOpcode())
4013 "Invalid operand expansion");
4016 "Invalid operand expansion");
4018 ReplaceValueWith(
SDValue(
N, 0), Res);
4022SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4026 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4028 EVT VT =
N->getValueType(0);
4041 getSetCCResultType(MVT::i1), MVT::i1);
4046 DAG.getElementCount(
DL, VT, SplitEC)),
4050SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4053 assert(OpNo == 0 &&
"Illegal operand must be mask");
4060 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4063 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4064 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4065 "Lo and Hi have differing types");
4068 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4069 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4071 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4072 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4073 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4074 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4084SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4085 assert(OpNo == 2 &&
"Illegal operand must be mask");
4088 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4089 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4091 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4094 RHSLo, MaskLo,
N->getFlags());
4096 RHSHi, MaskHi,
N->getFlags());
4100SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4103 assert(OpNo == 1 &&
"Illegal operand must be mask");
4108 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4110 EVT VecVT =
N->getValueType(0);
4114SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4115 EVT ResVT =
N->getValueType(0);
4121 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4122 GetSplitVector(VecOp,
Lo,
Hi);
4124 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4129 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4130 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4134 EVT ResVT =
N->getValueType(0);
4140 SDNodeFlags
Flags =
N->getFlags();
4143 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4144 GetSplitVector(VecOp,
Lo,
Hi);
4146 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4152 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4155SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4156 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4157 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4159 unsigned Opc =
N->getOpcode();
4160 EVT ResVT =
N->getValueType(0);
4166 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4167 GetSplitVector(VecOp,
Lo,
Hi);
4170 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4173 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4175 const SDNodeFlags
Flags =
N->getFlags();
4179 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4184 EVT ResVT =
N->getValueType(0);
4187 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4188 EVT InVT =
Lo.getValueType();
4193 if (
N->isStrictFPOpcode()) {
4194 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4195 {N->getOperand(0), Lo});
4196 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4197 {N->getOperand(0), Hi});
4206 ReplaceValueWith(
SDValue(
N, 1), Ch);
4207 }
else if (
N->getNumOperands() == 3) {
4208 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4209 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4210 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4211 std::tie(EVLLo, EVLHi) =
4212 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4213 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4214 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4216 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4217 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4226 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4236 EVT ResVT =
N->getValueType(0);
4238 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4242 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4248 Lo = BitConvertToInteger(
Lo);
4249 Hi = BitConvertToInteger(
Hi);
4251 if (DAG.getDataLayout().isBigEndian())
4259 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4261 EVT ResVT =
N->getValueType(0);
4269 GetSplitVector(SubVec,
Lo,
Hi);
4278 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4280 return SecondInsertion;
4283SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4290 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4292 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4294 ElementCount IdxVal =
4298 EVT SrcVT =
N->getOperand(0).getValueType();
4317 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4318 LoEltsMin - IdxValMin);
4319 DAG.ExtractVectorElements(
Hi, Elts, 0,
4322 return DAG.getBuildVector(SubVT, dl, Elts);
4326 ElementCount ExtractIdx = IdxVal - LoElts;
4328 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4331 EVT HiVT =
Hi.getValueType();
4333 "Only fixed-vector extracts are supported in this case");
4343 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4344 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4350 "Extracting scalable subvector from fixed-width unsupported");
4358 "subvector from a scalable predicate vector");
4364 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4366 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4367 auto &MF = DAG.getMachineFunction();
4371 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4375 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4378 SubVT, dl,
Store, StackPtr,
4382SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4388 uint64_t IdxVal =
Index->getZExtValue();
4391 GetSplitVector(Vec,
Lo,
Hi);
4393 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4395 if (IdxVal < LoElts)
4396 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4399 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4404 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4416 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4422 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4424 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4425 auto &MF = DAG.getMachineFunction();
4428 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4432 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4436 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4438 return DAG.getExtLoad(
4449 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4457 SplitVecRes_Gather(
N,
Lo,
Hi);
4460 ReplaceValueWith(
SDValue(
N, 0), Res);
4465 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4469 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4471 SDValue EVL =
N->getVectorLength();
4473 Align Alignment =
N->getBaseAlign();
4479 GetSplitVector(
Data, DataLo, DataHi);
4481 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4486 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4489 GetSplitVector(Mask, MaskLo, MaskHi);
4491 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4494 EVT MemoryVT =
N->getMemoryVT();
4495 EVT LoMemVT, HiMemVT;
4496 bool HiIsEmpty =
false;
4497 std::tie(LoMemVT, HiMemVT) =
4498 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4502 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4505 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4508 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4510 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4511 N->getAddressingMode(),
N->isTruncatingStore(),
4512 N->isCompressingStore());
4518 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4519 N->isCompressingStore());
4521 MachinePointerInfo MPI;
4525 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4530 MMO = DAG.getMachineFunction().getMachineMemOperand(
4532 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4534 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4535 N->getAddressingMode(),
N->isTruncatingStore(),
4536 N->isCompressingStore());
4545 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4546 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4553 GetSplitVector(
Data, LoData, HiData);
4555 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4557 EVT LoMemVT, HiMemVT;
4558 bool HiIsEmpty =
false;
4559 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4565 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4566 else if (getTypeAction(
Mask.getValueType()) ==
4568 GetSplitVector(Mask, LoMask, HiMask);
4570 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4573 std::tie(LoEVL, HiEVL) =
4574 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4578 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4579 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4580 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4591 EVT PtrVT =
N->getBasePtr().getValueType();
4594 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4597 Align Alignment =
N->getBaseAlign();
4602 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4603 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4605 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4608 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4609 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4610 N->isCompressingStore());
4619 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4623 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4626 Align Alignment =
N->getBaseAlign();
4632 GetSplitVector(
Data, DataLo, DataHi);
4634 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4639 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4642 GetSplitVector(Mask, MaskLo, MaskHi);
4644 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4647 EVT MemoryVT =
N->getMemoryVT();
4648 EVT LoMemVT, HiMemVT;
4649 bool HiIsEmpty =
false;
4650 std::tie(LoMemVT, HiMemVT) =
4651 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4654 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4657 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4659 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4660 N->getAddressingMode(),
N->isTruncatingStore(),
4661 N->isCompressingStore());
4669 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4670 N->isCompressingStore());
4672 MachinePointerInfo MPI;
4676 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4681 MMO = DAG.getMachineFunction().getMachineMemOperand(
4683 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4685 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4686 N->getAddressingMode(),
N->isTruncatingStore(),
4687 N->isCompressingStore());
4700 EVT MemoryVT =
N->getMemoryVT();
4701 Align Alignment =
N->getBaseAlign();
4710 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4714 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4719 EVT LoMemVT, HiMemVT;
4720 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4725 GetSplitVector(
Ops.Data, DataLo, DataHi);
4727 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4732 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4734 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4738 if (getTypeAction(
Ops.Index.getValueType()) ==
4740 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4742 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4746 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4748 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4751 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4753 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4754 MSC->getIndexType(), MSC->isTruncatingStore());
4759 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4760 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4761 MMO, MSC->getIndexType(),
4762 MSC->isTruncatingStore());
4766 std::tie(EVLLo, EVLHi) =
4767 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4769 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4770 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4771 VPSC->getIndexType());
4776 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4777 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4778 VPSC->getIndexType());
4782 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4783 assert(OpNo == 1 &&
"Can only split the stored value");
4786 bool isTruncating =
N->isTruncatingStore();
4789 EVT MemoryVT =
N->getMemoryVT();
4790 Align Alignment =
N->getBaseAlign();
4792 AAMDNodes AAInfo =
N->getAAInfo();
4794 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4796 EVT LoMemVT, HiMemVT;
4797 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4801 return TLI.scalarizeVectorStore(
N, DAG);
4804 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4805 Alignment, MMOFlags, AAInfo);
4807 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4810 MachinePointerInfo MPI;
4811 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4814 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4815 HiMemVT, Alignment, MMOFlags, AAInfo);
4817 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4824 LLVMContext &Ctx = *DAG.getContext();
4842 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4843 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4847 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4850 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4851 DAG.getBitcast(MemVecVT, Wide), 0);
4853 N->getBasePtr(),
N->getMemOperand());
4861 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4863 N->getBasePtr(),
N->getMemOperand());
4877 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4883 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4904 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4905 SDValue InVec =
N->getOperand(OpNo);
4907 EVT OutVT =
N->getValueType(0);
4915 EVT LoOutVT, HiOutVT;
4916 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4917 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4922 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4924 return SplitVecOp_UnaryOp(
N);
4933 return SplitVecOp_UnaryOp(
N);
4937 GetSplitVector(InVec, InLoVec, InHiVec);
4943 EVT HalfElementVT = IsFloat ?
4945 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4952 if (
N->isStrictFPOpcode()) {
4953 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4954 {N->getOperand(0), InLoVec});
4955 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4956 {N->getOperand(0), InHiVec});
4962 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4963 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4967 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4975 if (
N->isStrictFPOpcode()) {
4979 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4987 DAG.getTargetConstant(
4988 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4995 assert(
N->getValueType(0).isVector() &&
4996 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4997 "Operand types must be vectors");
4999 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
5001 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
5002 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
5004 EVT VT =
N->getValueType(0);
5005 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
5010 }
else if (isStrict) {
5011 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5012 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
5013 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5014 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
5017 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5019 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
5020 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
5021 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
5022 std::tie(EVLLo, EVLHi) =
5023 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
5024 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
5025 N->getOperand(2), MaskLo, EVLLo);
5026 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
5027 N->getOperand(2), MaskHi, EVLHi);
5035 EVT OpVT =
N->getOperand(0).getValueType();
5038 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5044 EVT ResVT =
N->getValueType(0);
5047 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5048 EVT InVT =
Lo.getValueType();
5053 if (
N->isStrictFPOpcode()) {
5054 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5055 {N->getOperand(0), Lo, N->getOperand(2)});
5056 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5057 {N->getOperand(0), Hi, N->getOperand(2)});
5061 Lo.getValue(1),
Hi.getValue(1));
5062 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5063 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
5064 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
5065 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
5066 std::tie(EVLLo, EVLHi) =
5067 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
5068 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
5069 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
5071 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5072 N->getOperand(2),
N->getOperand(3));
5073 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5074 N->getOperand(2),
N->getOperand(3));
5076 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5077 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5088SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5091 EVT LHSLoVT, LHSHiVT;
5092 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5094 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5095 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5098 std::tie(LHSLo, LHSHi) =
5099 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5102 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5105 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5111 LLVMContext &Ctxt = *DAG.getContext();
5114 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5115 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5116 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5118 EVT ResVT =
N->getValueType(0);
5123 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5124 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5130 EVT ResVT =
N->getValueType(0);
5133 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5134 EVT InVT =
Lo.getValueType();
5140 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5141 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5148 EVT ResVT =
N->getValueType(0);
5152 GetSplitVector(VecOp,
Lo,
Hi);
5158 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5160 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5162 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5163 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5168 EVT ResVT =
N->getValueType(0);
5172 GetSplitVector(VecOp,
Lo,
Hi);
5174 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5175 auto [EVLLo, EVLHi] =
5177 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5183 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5185 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5186 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5189SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5200 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5201 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5202 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5203 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5204 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5205 OpsLo, MMO, IndexType);
5206 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5207 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5211SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5214 "Accumulator should already be a legal type, and shouldn't need "
5215 "further splitting");
5218 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5219 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5220 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5221 unsigned Opcode =
N->getOpcode();
5224 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5225 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5232void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5233 unsigned WidenResNo) {
5234 unsigned NumResults =
N->getNumValues();
5235 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5236 if (ResNo == WidenResNo)
5238 EVT ResVT =
N->getValueType(ResNo);
5244 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5245 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5250void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5251 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5254 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5259 auto unrollExpandedOp = [&]() {
5264 EVT VT =
N->getValueType(0);
5265 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5266 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5267 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5269 if (
N->getNumValues() > 1)
5270 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5276 switch (
N->getOpcode()) {
5279 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5287 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5291 Res = WidenVecRes_ADDRSPACECAST(
N);
5298 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5305 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5309 Res = WidenVecRes_ScalarOp(
N);
5314 case ISD::VP_SELECT:
5316 Res = WidenVecRes_Select(
N);
5320 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5322 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5329 case ISD::VP_LOAD_FF:
5332 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5336 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5344 case ISD::VP_GATHER:
5348 Res = WidenVecRes_VECTOR_REVERSE(
N);
5351 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5354 WidenVecRes_VECTOR_INTERLEAVE(
N);
5357 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5367 case ISD::OR:
case ISD::VP_OR:
5380 case ISD::VP_FMINNUM:
5383 case ISD::VP_FMAXNUM:
5385 case ISD::VP_FMINIMUM:
5387 case ISD::VP_FMAXIMUM:
5420 case ISD::VP_FCOPYSIGN:
5421 Res = WidenVecRes_Binary(
N);
5428 Res = WidenVecRes_MaskedBinary(
N);
5433 Res = WidenVecRes_CMP(
N);
5439 if (unrollExpandedOp())
5454 Res = WidenVecRes_BinaryCanTrap(
N);
5463 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5466#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5467 case ISD::STRICT_##DAGN:
5468#include "llvm/IR/ConstrainedOps.def"
5469 Res = WidenVecRes_StrictFP(
N);
5478 Res = WidenVecRes_OverflowOp(
N, ResNo);
5482 Res = WidenVecRes_FCOPYSIGN(
N);
5487 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5492 if (!unrollExpandedOp())
5493 Res = WidenVecRes_ExpOp(
N);
5499 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5504 case ISD::VP_FP_EXTEND:
5506 case ISD::VP_FP_ROUND:
5508 case ISD::VP_FP_TO_SINT:
5510 case ISD::VP_FP_TO_UINT:
5512 case ISD::VP_SIGN_EXTEND:
5514 case ISD::VP_SINT_TO_FP:
5515 case ISD::VP_TRUNCATE:
5518 case ISD::VP_UINT_TO_FP:
5520 case ISD::VP_ZERO_EXTEND:
5523 Res = WidenVecRes_Convert(
N);
5528 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5534 case ISD::VP_LLRINT:
5537 Res = WidenVecRes_XROUND(
N);
5563 if (unrollExpandedOp())
5574 case ISD::VP_BITREVERSE:
5580 case ISD::VP_CTLZ_ZERO_POISON:
5586 case ISD::VP_CTTZ_ZERO_POISON:
5591 case ISD::VP_FFLOOR:
5593 case ISD::VP_FNEARBYINT:
5594 case ISD::VP_FROUND:
5595 case ISD::VP_FROUNDEVEN:
5596 case ISD::VP_FROUNDTOZERO:
5601 Res = WidenVecRes_Unary(
N);
5608 Res = WidenVecRes_Ternary(
N);
5614 if (!unrollExpandedOp())
5615 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5622 SetWidenedVector(
SDValue(
N, ResNo), Res);
5628 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5629 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5630 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5631 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5632 if (
N->getNumOperands() == 3)
5633 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5635 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5636 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5640 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5641 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5647 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5648 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5649 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5650 if (
N->getNumOperands() == 2)
5651 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5654 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5655 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5659 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5660 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5665 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5666 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5667 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5670 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5671 Mask = ModifyToType(Mask, WideMaskVT,
true);
5672 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5677 LLVMContext &Ctxt = *DAG.getContext();
5682 EVT OpVT =
LHS.getValueType();
5684 LHS = GetWidenedVector(
LHS);
5685 RHS = GetWidenedVector(
RHS);
5686 OpVT =
LHS.getValueType();
5689 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5692 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5698SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5701 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5702 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5703 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5705 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5714 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5717 if (ConcatEnd == 1) {
5718 VT = ConcatOps[0].getValueType();
5720 return ConcatOps[0];
5723 SDLoc dl(ConcatOps[0]);
5730 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5731 int Idx = ConcatEnd - 1;
5732 VT = ConcatOps[Idx--].getValueType();
5733 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5746 unsigned NumToInsert = ConcatEnd - Idx - 1;
5747 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5749 ConcatOps[Idx+1] = VecOp;
5750 ConcatEnd = Idx + 2;
5756 unsigned RealVals = ConcatEnd - Idx - 1;
5757 unsigned SubConcatEnd = 0;
5758 unsigned SubConcatIdx = Idx + 1;
5759 while (SubConcatEnd < RealVals)
5760 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5761 while (SubConcatEnd < OpsToConcat)
5762 SubConcatOps[SubConcatEnd++] = undefVec;
5764 NextVT, SubConcatOps);
5765 ConcatEnd = SubConcatIdx + 1;
5770 if (ConcatEnd == 1) {
5771 VT = ConcatOps[0].getValueType();
5773 return ConcatOps[0];
5778 if (
NumOps != ConcatEnd ) {
5780 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5781 ConcatOps[j] = UndefVal;
5789 unsigned Opcode =
N->getOpcode();
5791 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5795 const SDNodeFlags
Flags =
N->getFlags();
5796 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5797 NumElts = NumElts / 2;
5801 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5803 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5804 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5805 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5813 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5816 TLI.isTypeLegal(WideMaskVT)) {
5817 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5818 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5819 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5821 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5822 N->getValueType(0).getVectorElementCount());
5823 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5837 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5838 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5839 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5842 unsigned ConcatEnd = 0;
5850 while (CurNumElts != 0) {
5851 while (CurNumElts >= NumElts) {
5852 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5853 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5854 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5856 CurNumElts -= NumElts;
5859 NumElts = NumElts / 2;
5861 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5864 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5865 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5866 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5867 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5878 switch (
N->getOpcode()) {
5881 return WidenVecRes_STRICT_FSETCC(
N);
5888 return WidenVecRes_Convert_StrictFP(
N);
5895 unsigned Opcode =
N->getOpcode();
5897 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5901 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5902 NumElts = NumElts / 2;
5913 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5917 unsigned ConcatEnd = 0;
5924 for (
unsigned i = 1; i < NumOpers; ++i) {
5930 Oper = GetWidenedVector(Oper);
5936 DAG.getPOISON(WideOpVT), Oper,
5937 DAG.getVectorIdxConstant(0, dl));
5949 while (CurNumElts != 0) {
5950 while (CurNumElts >= NumElts) {
5953 for (
unsigned i = 0; i < NumOpers; ++i) {
5956 EVT OpVT =
Op.getValueType();
5961 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5967 EVT OperVT[] = {VT, MVT::Other};
5969 ConcatOps[ConcatEnd++] = Oper;
5972 CurNumElts -= NumElts;
5975 NumElts = NumElts / 2;
5977 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5980 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5983 for (
unsigned i = 0; i < NumOpers; ++i) {
5986 EVT OpVT =
Op.getValueType();
5994 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5996 ConcatOps[ConcatEnd++] = Oper;
6005 if (Chains.
size() == 1)
6006 NewChain = Chains[0];
6009 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6014SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
6016 EVT ResVT =
N->getValueType(0);
6017 EVT OvVT =
N->getValueType(1);
6018 EVT WideResVT, WideOvVT;
6023 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6028 WideLHS = GetWidenedVector(
N->getOperand(0));
6029 WideRHS = GetWidenedVector(
N->getOperand(1));
6031 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6040 N->getOperand(0), Zero);
6042 N->getOperand(1), Zero);
6045 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6046 SDNode *WideNode = DAG.getNode(
6047 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6050 unsigned OtherNo = 1 - ResNo;
6051 EVT OtherVT =
N->getValueType(OtherNo);
6058 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
6061 return SDValue(WideNode, ResNo);
6065 LLVMContext &Ctx = *DAG.getContext();
6069 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6074 unsigned Opcode =
N->getOpcode();
6075 const SDNodeFlags
Flags =
N->getFlags();
6081 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6083 InOp = ZExtPromotedInteger(InOp);
6095 if (
N->getNumOperands() == 1)
6096 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6098 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6099 N->getOperand(3), Flags);
6100 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6104 InOp = GetWidenedVector(
N->getOperand(0));
6107 if (InVTEC == WidenEC) {
6108 if (
N->getNumOperands() == 3 &&
N->isVPOpcode()) {
6111 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
6113 return MakeConvertNode(WidenVT, InOp);
6139 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6143 if (TLI.isTypeLegal(InWidenVT)) {
6151 unsigned NumConcat =
6156 return MakeConvertNode(WidenVT, InVec);
6160 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6162 return MakeConvertNode(WidenVT, InVal);
6171 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6172 for (
unsigned i=0; i < MinElts; ++i) {
6173 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6174 Ops[i] = MakeConvertNode(EltVT, Val);
6177 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6182 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6186 EVT SrcVT = Src.getValueType();
6190 Src = GetWidenedVector(Src);
6191 SrcVT = Src.getValueType();
6198 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6203 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6207 EVT SrcVT = Src.getValueType();
6211 Src = GetWidenedVector(Src);
6212 SrcVT = Src.getValueType();
6219 if (
N->getNumOperands() == 1)
6220 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6222 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6223 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6227 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6230SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6235 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6241 unsigned Opcode =
N->getOpcode();
6247 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6252 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6253 for (
unsigned i=0; i < MinElts; ++i) {
6254 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6255 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6259 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6261 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6264SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6265 unsigned Opcode =
N->getOpcode();
6269 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6278 InOp = GetWidenedVector(InOp);
6285 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6292 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6293 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6310 while (
Ops.size() != WidenNumElts)
6311 Ops.push_back(DAG.getPOISON(WidenSVT));
6313 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6319 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6320 return WidenVecRes_BinaryCanTrap(
N);
6323 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6330SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6332 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6335 SDValue Arg = GetWidenedVector(FpValue);
6336 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6341 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6342 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6344 EVT ExpVT =
RHS.getValueType();
6349 ExpOp = ModifyToType(
RHS, WideExpVT);
6352 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6357 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6358 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6359 if (
N->getNumOperands() == 1)
6360 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6362 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6363 N->getOperand(1),
N->getFlags());
6365 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6366 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6370 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6371 {InOp,
Mask,
N->getOperand(2)});
6375 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6380 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6381 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6382 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6385SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6387 EVT VT0 =
N->getValueType(0);
6388 EVT VT1 =
N->getValueType(1);
6392 "expected both results to be vectors of matching element count");
6394 LLVMContext &Ctx = *DAG.getContext();
6395 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6397 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6404 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6407 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6408 return SDValue(WidenNode, ResNo);
6411SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6412 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6413 return GetWidenedVector(WidenVec);
6417 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6418 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6421 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6422 AddrSpaceCastN->getSrcAddressSpace(),
6423 AddrSpaceCastN->getDestAddressSpace());
6429 EVT VT =
N->getValueType(0);
6430 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6433 switch (getTypeAction(InVT)) {
6447 SDValue NInOp = GetPromotedInteger(InOp);
6449 if (WidenVT.
bitsEq(NInVT)) {
6452 if (DAG.getDataLayout().isBigEndian()) {
6455 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6473 InOp = GetWidenedVector(InOp);
6475 if (WidenVT.
bitsEq(InVT))
6485 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6490 unsigned NewNumParts = WidenSize / InSize;
6503 EVT OrigInVT =
N->getOperand(0).getValueType();
6508 if (TLI.isTypeLegal(NewInVT)) {
6516 if (WidenSize % InSize == 0) {
6523 DAG.ExtractVectorElements(InOp,
Ops);
6524 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6536 return CreateStackStoreLoad(InOp, WidenVT);
6539SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6541 N->getOpcode(), SDLoc(
N),
6542 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6543 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6549 EVT VT =
N->getValueType(0);
6553 EVT EltVT =
N->getOperand(0).getValueType();
6556 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6560 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6561 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6563 return DAG.getBuildVector(WidenVT, dl, NewOps);
6567 EVT InVT =
N->getOperand(0).getValueType();
6568 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6570 unsigned NumOperands =
N->getNumOperands();
6572 bool InputWidened =
false;
6576 if (WidenNumElts % NumInElts == 0) {
6578 unsigned NumConcat = WidenNumElts / NumInElts;
6579 SDValue UndefVal = DAG.getPOISON(InVT);
6581 for (
unsigned i=0; i < NumOperands; ++i)
6582 Ops[i] =
N->getOperand(i);
6583 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6588 InputWidened =
true;
6589 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6592 for (i=1; i < NumOperands; ++i)
6593 if (!
N->getOperand(i).isUndef())
6596 if (i == NumOperands)
6599 return GetWidenedVector(
N->getOperand(0));
6601 if (NumOperands == 2) {
6603 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6608 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6609 for (
unsigned i = 0; i < NumInElts; ++i) {
6611 MaskOps[i + NumInElts] = i + WidenNumElts;
6613 return DAG.getVectorShuffle(WidenVT, dl,
6614 GetWidenedVector(
N->getOperand(0)),
6615 GetWidenedVector(
N->getOperand(1)),
6622 SDValue WideVec = DAG.getPOISON(WidenVT);
6624 for (
unsigned I = 0;
I < NumOperands; ++
I)
6626 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6637 for (
unsigned i=0; i < NumOperands; ++i) {
6640 InOp = GetWidenedVector(InOp);
6641 for (
unsigned j = 0;
j < NumInElts; ++
j)
6642 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6644 SDValue UndefVal = DAG.getPOISON(EltVT);
6645 for (; Idx < WidenNumElts; ++Idx)
6646 Ops[Idx] = UndefVal;
6647 return DAG.getBuildVector(WidenVT, dl,
Ops);
6650SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6651 EVT VT =
N->getValueType(0);
6652 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6653 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6660SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6661 EVT VT =
N->getValueType(0);
6663 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6668 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6670 InOp = GetWidenedVector(InOp);
6676 if (IdxVal == 0 && InVT == WidenVT)
6683 assert(IdxVal % VTNumElts == 0 &&
6684 "Expected Idx to be a multiple of subvector minimum vector length");
6685 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6698 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6699 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6700 "down type's element count");
6707 for (;
I < VTNumElts / GCD; ++
I)
6709 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6710 for (;
I < WidenNumElts / GCD; ++
I)
6718 Align Alignment = DAG.getReducedAlign(InVT,
false);
6720 MachineFunction &MF = DAG.getMachineFunction();
6732 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6739 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6740 return DAG.getMaskedLoad(
6741 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6749 for (i = 0; i < VTNumElts; ++i)
6750 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6752 SDValue UndefVal = DAG.getPOISON(EltVT);
6753 for (; i < WidenNumElts; ++i)
6755 return DAG.getBuildVector(WidenVT, dl,
Ops);
6761 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6766SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6767 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6770 N->getOperand(1),
N->getOperand(2));
6779 "Load width must be less than or equal to first value type width");
6788 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6805 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6816 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6817 EVT LdVT =
LD->getMemoryVT();
6826 TypeSize WidthDiff = WidenWidth - LdWidth;
6829 std::optional<EVT> FirstVT =
6830 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6837 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6840 Chain, BasePtr,
LD->getMemOperand());
6844 FirstVTWidth, dl, DAG);
6862 if (!
LD->getMemoryVT().isByteSized()) {
6864 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6866 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6875 EVT VT =
LD->getValueType(0);
6876 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6877 EVT WideMaskVT = getSetCCResultType(WideVT);
6880 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6881 TLI.isTypeLegal(WideMaskVT)) {
6884 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6888 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6889 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6901 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6903 Result = GenWidenVectorLoads(LdChain, LD);
6910 if (LdChain.
size() == 1)
6911 NewChain = LdChain[0];
6917 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6928 SDValue NewLoad = DAG.getMaskedLoad(
6929 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6930 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6931 LD->getAddressingMode(),
LD->getExtensionType());
6941 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6943 SDValue EVL =
N->getVectorLength();
6950 "Unable to widen binary VP op");
6951 Mask = GetWidenedVector(Mask);
6952 assert(
Mask.getValueType().getVectorElementCount() ==
6953 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6954 .getVectorElementCount() &&
6955 "Unable to widen vector load");
6958 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6959 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6960 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6968 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6970 SDValue EVL =
N->getVectorLength();
6976 "Unable to widen binary VP op");
6977 Mask = GetWidenedVector(Mask);
6978 assert(
Mask.getValueType().getVectorElementCount() ==
6979 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6980 .getVectorElementCount() &&
6981 "Unable to widen vector load");
6983 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6984 Mask, EVL,
N->getMemOperand());
6997 "Unable to widen VP strided load");
6998 Mask = GetWidenedVector(Mask);
7000 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7001 assert(
Mask.getValueType().getVectorElementCount() ==
7003 "Data and mask vectors should have the same number of elements");
7005 SDValue Res = DAG.getStridedLoadVP(
7006 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
7007 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
7008 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
7009 N->isExpandingLoad());
7017SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
7022 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
7024 Mask.getValueType().getVectorElementType(),
7027 SDValue WideVec = ModifyToType(Vec, WideVecVT);
7028 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
7029 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
7031 WideMask, WidePassthru);
7035 EVT VT =
N->getValueType(0);
7036 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7038 EVT MaskVT =
Mask.getValueType();
7039 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7048 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7049 TLI.isTypeLegal(WideMaskVT) &&
7055 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7056 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7060 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7061 N->getMemoryVT(),
N->getMemOperand());
7065 if (!
N->getPassThru()->isUndef()) {
7069 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7070 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7071 DAG.getPOISON(WidenVT), EVL);
7082 Mask = ModifyToType(Mask, WideMaskVT,
true);
7084 SDValue Res = DAG.getMaskedLoad(
7085 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7086 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7087 ExtType,
N->isExpandingLoad());
7096 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7098 EVT MaskVT =
Mask.getValueType();
7099 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7107 Mask = ModifyToType(Mask, WideMaskVT,
true);
7112 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7113 Index = ModifyToType(Index, WideIndexVT);
7119 N->getMemoryVT().getScalarType(), WideEC);
7120 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7121 WideMemVT, dl,
Ops,
N->getMemOperand(),
7122 N->getIndexType(),
N->getExtensionType());
7131 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7139 N->getMemoryVT().getScalarType(), WideEC);
7140 Mask = GetWidenedMask(Mask, WideEC);
7143 Mask,
N->getVectorLength()};
7144 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7145 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7154 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7155 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7183 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7184 return N->getOperand(OpNo).getValueType();
7192 N =
N.getOperand(0);
7194 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7195 if (!
N->getOperand(i)->isUndef())
7197 N =
N.getOperand(0);
7201 N =
N.getOperand(0);
7203 N =
N.getOperand(0);
7230 { MaskVT, MVT::Other },
Ops);
7231 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7239 LLVMContext &Ctx = *DAG.getContext();
7242 if (MaskScalarBits < ToMaskScalBits) {
7246 }
else if (MaskScalarBits > ToMaskScalBits) {
7252 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7254 "Mask should have the right element size by now.");
7257 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7259 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7262 EVT SubVT =
Mask->getValueType(0);
7268 assert((
Mask->getValueType(0) == ToMaskVT) &&
7269 "A mask of ToMaskVT should have been produced by now.");
7279 LLVMContext &Ctx = *DAG.getContext();
7290 EVT CondVT =
Cond->getValueType(0);
7294 EVT VSelVT =
N->getValueType(0);
7306 EVT FinalVT = VSelVT;
7317 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7318 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7325 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7333 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7336 EVT ToMaskVT = VSelVT;
7343 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7359 if (ScalarBits0 != ScalarBits1) {
7360 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7361 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7373 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7374 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7375 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7378 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7386 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7391 unsigned Opcode =
N->getOpcode();
7393 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7394 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7395 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7397 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7403 Cond1 = GetWidenedVector(Cond1);
7411 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7412 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7417 Cond1 = ModifyToType(Cond1, CondWidenVT);
7420 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7421 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7423 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7424 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7426 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7430 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7431 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7434 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7438 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7439 return DAG.getUNDEF(WidenVT);
7443 EVT VT =
N->getValueType(0);
7446 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7450 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7451 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7454 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7455 for (
unsigned i = 0; i != NumElts; ++i) {
7456 int Idx =
N->getMaskElt(i);
7457 if (Idx < (
int)NumElts)
7460 NewMask[i] = Idx - NumElts + WidenNumElts;
7462 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7466 EVT VT =
N->getValueType(0);
7470 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7471 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7477 unsigned IdxVal = WidenNumElts - VTNumElts;
7490 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7493 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7494 "down type's element count");
7497 for (; i < VTNumElts / GCD; ++i)
7499 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7500 for (; i < WidenNumElts / GCD; ++i)
7508 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7509 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7511 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7515SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7516 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7520void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7521 EVT VT =
N->getValueType(0);
7524 unsigned Factor =
N->getNumOperands();
7527 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7531 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7532 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7541 for (
unsigned Idx = 0; Idx != Factor; ++Idx)
7542 Slices[Idx] = Interleaved.
getValue(Idx);
7546 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7547 SDValue Narrow = DAG.getExtractSubvector(
7550 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7551 SetWidenedVector(
SDValue(
N, Idx), Wide);
7555void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7556 EVT VT =
N->getValueType(0);
7559 unsigned Factor =
N->getNumOperands();
7562 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7575 SDValue PackedWidenVec = DAG.getInsertSubvector(
7576 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7580 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7581 NewOps[Idx] = DAG.getExtractSubvector(
7582 DL, WidenVT, PackedWidenVec,
7589 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7594 assert(
N->getValueType(0).isVector() &&
7595 N->getOperand(0).getValueType().isVector() &&
7596 "Operands must be vectors");
7597 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7610 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7611 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7618 InOp1 = GetWidenedVector(InOp1);
7619 InOp2 = GetWidenedVector(InOp2);
7622 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7633 "Input not widened to expected type!");
7635 if (
N->getOpcode() == ISD::VP_SETCC) {
7638 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7639 N->getOperand(2), Mask,
N->getOperand(4));
7641 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7646 assert(
N->getValueType(0).isVector() &&
7647 N->getOperand(1).getValueType().isVector() &&
7648 "Operands must be vectors");
7649 EVT VT =
N->getValueType(0);
7650 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7660 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7665 for (
unsigned i = 0; i != NumElts; ++i) {
7666 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7667 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7669 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7670 {Chain, LHSElem, RHSElem, CC});
7671 Chains[i] = Scalars[i].getValue(1);
7672 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7673 DAG.getBoolConstant(
true, dl, EltVT, VT),
7674 DAG.getBoolConstant(
false, dl, EltVT, VT));
7678 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7680 return DAG.getBuildVector(WidenVT, dl, Scalars);
7686bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7687 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7691 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7694 switch (
N->getOpcode()) {
7697 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7705 Res = WidenVecOp_FAKE_USE(
N);
7711 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7715 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7716 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7717 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7722 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7724 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7725 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7727 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7728 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7738 Res = WidenVecOp_UnrollVectorOp(
N);
7745 Res = WidenVecOp_EXTEND(
N);
7750 Res = WidenVecOp_CMP(
N);
7768 Res = WidenVecOp_Convert(
N);
7773 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7791 Res = WidenVecOp_VECREDUCE(
N);
7795 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7797 case ISD::VP_REDUCE_FADD:
7798 case ISD::VP_REDUCE_SEQ_FADD:
7799 case ISD::VP_REDUCE_FMUL:
7800 case ISD::VP_REDUCE_SEQ_FMUL:
7801 case ISD::VP_REDUCE_ADD:
7802 case ISD::VP_REDUCE_MUL:
7803 case ISD::VP_REDUCE_AND:
7804 case ISD::VP_REDUCE_OR:
7805 case ISD::VP_REDUCE_XOR:
7806 case ISD::VP_REDUCE_SMAX:
7807 case ISD::VP_REDUCE_SMIN:
7808 case ISD::VP_REDUCE_UMAX:
7809 case ISD::VP_REDUCE_UMIN:
7810 case ISD::VP_REDUCE_FMAX:
7811 case ISD::VP_REDUCE_FMIN:
7812 case ISD::VP_REDUCE_FMAXIMUM:
7813 case ISD::VP_REDUCE_FMINIMUM:
7814 Res = WidenVecOp_VP_REDUCE(
N);
7818 Res = WidenVecOp_CttzElements(
N);
7820 case ISD::VP_CTTZ_ELTS:
7821 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7822 Res = WidenVecOp_VP_CttzElements(
N);
7825 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7830 if (!Res.
getNode())
return false;
7838 if (
N->isStrictFPOpcode())
7840 "Invalid operand expansion");
7843 "Invalid operand expansion");
7845 ReplaceValueWith(
SDValue(
N, 0), Res);
7851 EVT VT =
N->getValueType(0);
7856 "Unexpected type action");
7857 InOp = GetWidenedVector(InOp);
7860 "Input wasn't widened!");
7868 EVT FixedEltVT = FixedVT.getVectorElementType();
7869 if (TLI.isTypeLegal(FixedVT) &&
7871 FixedEltVT == InEltVT) {
7873 "Not enough elements in the fixed type for the operand!");
7875 "We can't have the same type as we started with!");
7877 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7879 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7888 return WidenVecOp_Convert(
N);
7893 switch (
N->getOpcode()) {
7908 EVT OpVT =
N->getOperand(0).getValueType();
7909 EVT ResVT =
N->getValueType(0);
7916 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7917 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7923 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7924 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7926 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7933 return DAG.UnrollVectorOp(
N);
7938 EVT ResultVT =
N->getValueType(0);
7940 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7943 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7949 {WideArg,
Test},
N->getFlags());
7955 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7957 EVT OpVT =
N->getOperand(0).getValueType();
7960 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7965 EVT VT =
N->getValueType(0);
7971 "Unexpected type action");
7972 InOp = GetWidenedVector(InOp);
7974 unsigned Opcode =
N->getOpcode();
7979 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7982 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7983 return DAG.getNode(Opcode, dl, VT,
Op);
7990 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7992 if (
N->isStrictFPOpcode()) {
7994 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7997 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7998 {
N->getOperand(0), InOp });
8003 Res = MakeConvertNode(WideVT, InOp);
8005 return DAG.getExtractSubvector(dl, VT, Res, 0);
8013 if (
N->isStrictFPOpcode()) {
8016 for (
unsigned i=0; i < NumElts; ++i) {
8017 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8018 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
8022 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8024 for (
unsigned i = 0; i < NumElts; ++i) {
8025 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8026 Ops[i] = MakeConvertNode(EltVT, Elt);
8030 return DAG.getBuildVector(VT, dl,
Ops);
8034 EVT DstVT =
N->getValueType(0);
8035 SDValue Src = GetWidenedVector(
N->getOperand(0));
8036 EVT SrcVT = Src.getValueType();
8043 if (TLI.isTypeLegal(WideDstVT)) {
8045 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
8048 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
8052 return DAG.UnrollVectorOp(
N);
8056 EVT VT =
N->getValueType(0);
8057 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8065 if (!VT.
isVector() && VT != MVT::x86mmx &&
8069 if (TLI.isTypeLegal(NewVT)) {
8071 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8083 ElementCount NewNumElts =
8085 .divideCoefficientBy(EltSize);
8087 if (TLI.isTypeLegal(NewVT)) {
8089 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8094 return CreateStackStoreLoad(InOp, VT);
8102 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8103 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8108 EVT VT =
N->getValueType(0);
8110 EVT InVT =
N->getOperand(0).getValueType();
8115 unsigned NumOperands =
N->getNumOperands();
8116 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8118 for (i = 1; i < NumOperands; ++i)
8119 if (!
N->getOperand(i).isUndef())
8122 if (i == NumOperands)
8123 return GetWidenedVector(
N->getOperand(0));
8133 for (
unsigned i=0; i < NumOperands; ++i) {
8137 "Unexpected type action");
8138 InOp = GetWidenedVector(InOp);
8139 for (
unsigned j = 0;
j < NumInElts; ++
j)
8140 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8142 return DAG.getBuildVector(VT, dl,
Ops);
8145SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8146 EVT VT =
N->getValueType(0);
8151 SubVec = GetWidenedVector(SubVec);
8156 bool IndicesValid =
false;
8159 IndicesValid =
true;
8163 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8164 Attribute::VScaleRange);
8169 IndicesValid =
true;
8175 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8181 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8188 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8195 Align Alignment = DAG.getReducedAlign(VT,
false);
8197 MachineFunction &MF = DAG.getMachineFunction();
8210 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8218 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8219 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8224 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8229 unsigned Idx =
N->getConstantOperandVal(2);
8235 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8241SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8242 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8244 N->getValueType(0), InOp,
N->getOperand(1));
8247SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8248 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8250 N->getValueType(0), InOp,
N->getOperand(1));
8253SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8255 EVT ResVT =
N->getValueType(0);
8258 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8264 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8272 "Widened input size must be a multiple of result element size");
8275 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8277 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8278 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8286 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8287 return TLI.scalarizeVectorStore(ST, DAG);
8289 if (
ST->isTruncatingStore())
8290 return TLI.scalarizeVectorStore(ST, DAG);
8300 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8301 EVT WideMaskVT = getSetCCResultType(WideVT);
8303 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8304 TLI.isTypeLegal(WideMaskVT)) {
8307 StVal = GetWidenedVector(StVal);
8309 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8311 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8312 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8313 ST->getAddressingMode());
8317 if (GenWidenVectorStores(StChain, ST)) {
8318 if (StChain.
size() == 1)
8327 SDValue WideStVal = GetWidenedVector(StVal);
8331 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8332 ST->getOffset(), Mask,
ST->getMemoryVT(),
8333 ST->getMemOperand(),
ST->getAddressingMode(),
8334 ST->isTruncatingStore());
8341 EVT StVT =
ST->getMemoryVT();
8344 SDValue StVal = GetWidenedVector(
ST->getVal());
8349 TypeSize WidthDiff = WidenWidth - StWidth;
8355 std::optional<EVT> FirstVT =
8356 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8361 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8367 ST->getBasePtr(),
ST->getMemOperand());
8370SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8371 assert((OpNo == 1 || OpNo == 3) &&
8372 "Can widen only data or mask operand of vp_store");
8380 StVal = GetWidenedVector(StVal);
8386 "Unable to widen VP store");
8387 Mask = GetWidenedVector(Mask);
8389 Mask = GetWidenedVector(Mask);
8395 "Unable to widen VP store");
8396 StVal = GetWidenedVector(StVal);
8399 assert(
Mask.getValueType().getVectorElementCount() ==
8401 "Mask and data vectors should have the same number of elements");
8402 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8403 ST->getOffset(), Mask,
ST->getVectorLength(),
8404 ST->getMemoryVT(),
ST->getMemOperand(),
8405 ST->getAddressingMode(),
ST->isTruncatingStore(),
8406 ST->isCompressingStore());
8411 assert((OpNo == 1 || OpNo == 4) &&
8412 "Can widen only data or mask operand of vp_strided_store");
8421 "Unable to widen VP strided store");
8425 "Unable to widen VP strided store");
8427 StVal = GetWidenedVector(StVal);
8428 Mask = GetWidenedVector(Mask);
8431 Mask.getValueType().getVectorElementCount() &&
8432 "Data and mask vectors should have the same number of elements");
8434 return DAG.getStridedStoreVP(
8441SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8442 assert((OpNo == 1 || OpNo == 4) &&
8443 "Can widen only data or mask operand of mstore");
8446 EVT MaskVT =
Mask.getValueType();
8451 EVT WideVT, WideMaskVT;
8454 StVal = GetWidenedVector(StVal);
8461 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8468 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8470 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8471 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8480 Mask = ModifyToType(Mask, WideMaskVT,
true);
8483 Mask = ModifyToType(Mask, WideMaskVT,
true);
8485 StVal = ModifyToType(StVal, WideVT);
8488 assert(
Mask.getValueType().getVectorElementCount() ==
8490 "Mask and data vectors should have the same number of elements");
8497SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8498 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8500 SDValue DataOp = MG->getPassThru();
8502 SDValue Scale = MG->getScale();
8510 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8511 MG->getMemOperand(), MG->getIndexType(),
8512 MG->getExtensionType());
8518SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8527 DataOp = GetWidenedVector(DataOp);
8531 EVT IndexVT =
Index.getValueType();
8534 Index = ModifyToType(Index, WideIndexVT);
8537 EVT MaskVT =
Mask.getValueType();
8540 Mask = ModifyToType(Mask, WideMaskVT,
true);
8545 }
else if (OpNo == 4) {
8547 Index = GetWidenedVector(Index);
8553 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8558SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8567 DataOp = GetWidenedVector(DataOp);
8568 Index = GetWidenedVector(Index);
8570 Mask = GetWidenedMask(Mask, WideEC);
8573 }
else if (OpNo == 3) {
8575 Index = GetWidenedVector(Index);
8582 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8587 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8588 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8590 EVT VT =
N->getValueType(0);
8605 SVT, InOp0, InOp1,
N->getOperand(2));
8611 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8613 EVT OpVT =
N->getOperand(0).getValueType();
8616 return DAG.getNode(ExtendCode, dl, VT, CC);
8626 EVT VT =
N->getValueType(0);
8628 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8635 for (
unsigned i = 0; i != NumElts; ++i) {
8636 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8637 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8639 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8640 {Chain, LHSElem, RHSElem, CC});
8641 Chains[i] = Scalars[i].getValue(1);
8642 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8643 DAG.getBoolConstant(
true, dl, EltVT, VT),
8644 DAG.getBoolConstant(
false, dl, EltVT, VT));
8648 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8650 return DAG.getBuildVector(VT, dl, Scalars);
8674 SDValue Op = GetWidenedVector(
N->getOperand(0));
8675 EVT VT =
N->getValueType(0);
8676 EVT OrigVT =
N->getOperand(0).getValueType();
8677 EVT WideVT =
Op.getValueType();
8679 SDNodeFlags
Flags =
N->getFlags();
8681 unsigned Opc =
N->getOpcode();
8683 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8684 assert(NeutralElem &&
"Neutral element must exist");
8694 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8701 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8702 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8708 unsigned GCD = std::gcd(OrigElts, WideElts);
8711 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8712 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8713 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8714 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8717 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8718 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8720 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8729 EVT VT =
N->getValueType(0);
8731 EVT WideVT =
Op.getValueType();
8733 SDNodeFlags
Flags =
N->getFlags();
8735 unsigned Opc =
N->getOpcode();
8737 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8747 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8750 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8751 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8757 unsigned GCD = std::gcd(OrigElts, WideElts);
8760 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8761 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8762 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8763 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8766 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8767 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8769 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8773 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8776 SDValue Op = GetWidenedVector(
N->getOperand(1));
8778 Op.getValueType().getVectorElementCount());
8780 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8781 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8789 EVT VT =
N->getValueType(0);
8793 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8794 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8799 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8806 TLI.getTypeToTransformTo(*DAG.getContext(),
Source.getValueType());
8810 WideSource = GetWidenedVector(Source);
8815 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8818 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8825 EVT SrcVT =
Source.getValueType();
8829 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8830 {Source, Mask, N->getOperand(2)},
N->getFlags());
8833SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8836 EVT OrigMaskVT =
Mask.getValueType();
8837 SDValue WideMask = GetWidenedVector(Mask);
8843 if (OrigElts != WideElts) {
8844 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8846 Mask, DAG.getVectorIdxConstant(0,
DL));
8867 unsigned WidenEx = 0) {
8872 unsigned AlignInBits =
Align*8;
8874 EVT RetVT = WidenEltVT;
8879 if (Width == WidenEltWidth)
8890 (WidenWidth % MemVTWidth) == 0 &&
8892 (MemVTWidth <= Width ||
8893 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8894 if (MemVTWidth == WidenWidth)
8913 (WidenWidth % MemVTWidth) == 0 &&
8915 (MemVTWidth <= Width ||
8916 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8925 return std::nullopt;
8936 unsigned Start,
unsigned End) {
8937 SDLoc dl(LdOps[Start]);
8938 EVT LdTy = LdOps[Start].getValueType();
8946 for (
unsigned i = Start + 1; i != End; ++i) {
8947 EVT NewLdTy = LdOps[i].getValueType();
8948 if (NewLdTy != LdTy) {
8967 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8968 EVT LdVT =
LD->getMemoryVT();
8978 AAMDNodes AAInfo =
LD->getAAInfo();
8982 TypeSize WidthDiff = WidenWidth - LdWidth;
8989 std::optional<EVT> FirstVT =
8990 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8997 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
9002 std::optional<EVT> NewVT = FirstVT;
9003 TypeSize RemainingWidth = LdWidth;
9004 TypeSize NewVTWidth = FirstVTWidth;
9006 RemainingWidth -= NewVTWidth;
9013 NewVTWidth = NewVT->getSizeInBits();
9019 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9020 LD->getBaseAlign(), MMOFlags, AAInfo);
9032 uint64_t ScaledOffset = 0;
9033 MachinePointerInfo MPI =
LD->getPointerInfo();
9039 for (EVT MemVT : MemVTs) {
9040 Align NewAlign = ScaledOffset == 0
9041 ?
LD->getBaseAlign()
9044 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
9052 unsigned End = LdOps.
size();
9063 EVT LdTy = LdOps[i].getValueType();
9066 for (--i; i >= 0; --i) {
9067 LdTy = LdOps[i].getValueType();
9074 ConcatOps[--Idx] = LdOps[i];
9075 for (--i; i >= 0; --i) {
9076 EVT NewLdTy = LdOps[i].getValueType();
9077 if (NewLdTy != LdTy) {
9087 for (;
j != End-Idx; ++
j)
9088 WidenOps[j] = ConcatOps[Idx+j];
9090 WidenOps[j] = DAG.getPOISON(LdTy);
9097 ConcatOps[--Idx] = LdOps[i];
9102 ArrayRef(&ConcatOps[Idx], End - Idx));
9108 SDValue UndefVal = DAG.getPOISON(LdTy);
9111 for (; i != End-Idx; ++i)
9112 WidenOps[i] = ConcatOps[Idx+i];
9114 WidenOps[i] = UndefVal;
9125 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9126 EVT LdVT =
LD->getMemoryVT();
9135 AAMDNodes AAInfo =
LD->getAAInfo();
9149 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9150 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9156 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9157 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9158 LD->getBaseAlign(), MMOFlags, AAInfo);
9163 SDValue UndefVal = DAG.getPOISON(EltVT);
9164 for (; i != WidenNumElts; ++i)
9167 return DAG.getBuildVector(WidenVT, dl,
Ops);
9178 AAMDNodes AAInfo =
ST->getAAInfo();
9179 SDValue ValOp = GetWidenedVector(
ST->getValue());
9182 EVT StVT =
ST->getMemoryVT();
9190 "Mismatch between store and value types");
9194 MachinePointerInfo MPI =
ST->getPointerInfo();
9195 uint64_t ScaledOffset = 0;
9204 std::optional<EVT> NewVT =
9209 TypeSize NewVTWidth = NewVT->getSizeInBits();
9212 StWidth -= NewVTWidth;
9213 MemVTs.
back().second++;
9217 for (
const auto &Pair : MemVTs) {
9218 EVT NewVT = Pair.first;
9219 unsigned Count = Pair.second;
9225 Align NewAlign = ScaledOffset == 0
9226 ?
ST->getBaseAlign()
9228 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9229 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9245 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9246 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9247 ST->getBaseAlign(), MMOFlags, AAInfo);
9264 bool FillWithZeroes) {
9269 "input and widen element type must match");
9271 "cannot modify scalable vectors in this way");
9284 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9286 for (
unsigned i = 1; i != NumConcat; ++i)
9293 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9296 "Scalable vectors should have been handled already.");
9304 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9306 for (Idx = 0; Idx < MinNumElts; ++Idx)
9307 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9309 SDValue UndefVal = DAG.getPOISON(EltVT);
9310 for (; Idx < WidenNumElts; ++Idx)
9311 Ops[Idx] = UndefVal;
9313 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9314 if (!FillWithZeroes)
9318 "We expect to never want to FillWithZeroes for non-integral types.");
9321 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9322 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9324 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9325 DAG.getBuildVector(NVT, dl, MaskOps));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT, TypeSize FirstVTWidth, const SDLoc &dl, SelectionDAG &DAG)
Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the widened value so it can b...
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V, bool LookThroughCmp=false)
Returns the "element type" of the given value/instruction V.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file implements the SmallBitVector class.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
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 getExtractVectorElt(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Extract element at Idx from Vec.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr LeafTy multiplyCoefficientBy(ScalarTy RHS) const
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by OFFSET elements an...
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ MASKED_UDIV
Masked vector arithmetic that returns poison on disabled lanes.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
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.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.