35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
46 switch (
N->getOpcode()) {
49 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
58 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
66 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
69 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
75 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
87 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
89 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
95 R = ScalarizeVecRes_VecInregOp(
N);
147 R = ScalarizeVecRes_UnaryOp(
N);
150 R = ScalarizeVecRes_ADDRSPACECAST(
N);
156 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
215 R = ScalarizeVecRes_BinOp(
N);
222 R = ScalarizeVecRes_MaskedBinOp(
N);
227 R = ScalarizeVecRes_CMP(
N);
233 R = ScalarizeVecRes_TernaryOp(
N);
236#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
237 case ISD::STRICT_##DAGN:
238#include "llvm/IR/ConstrainedOps.def"
239 R = ScalarizeVecRes_StrictFPOp(
N);
244 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
253 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
263 R = ScalarizeVecRes_FIX(
N);
269 SetScalarizedVector(
SDValue(
N, ResNo), R);
273 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
274 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
275 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
281 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
282 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
284 EVT MaskVT =
Mask.getValueType();
289 Mask = GetScalarizedVector(Mask);
298 DAG.getConstant(1,
DL,
LHS.getValueType()));
300 LHS.getValueType(),
LHS, Divisor);
308 if (getTypeAction(
LHS.getValueType()) ==
310 LHS = GetScalarizedVector(
LHS);
311 RHS = GetScalarizedVector(
RHS);
313 EVT VT =
LHS.getValueType().getVectorElementType();
314 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
315 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
318 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
319 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
323 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
324 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
325 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
326 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
331 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
332 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
339DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
341 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
342 "Unexpected vector type!");
343 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
345 EVT VT0 =
N->getValueType(0);
346 EVT VT1 =
N->getValueType(1);
350 DAG.getNode(
N->getOpcode(), dl,
351 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
355 unsigned OtherNo = 1 - ResNo;
356 EVT OtherVT =
N->getValueType(OtherNo);
358 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
362 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
365 return SDValue(ScalarNode, ResNo);
370 unsigned NumOpers =
N->getNumOperands();
372 EVT ValueVTs[] = {VT, MVT::Other};
381 for (
unsigned i = 1; i < NumOpers; ++i) {
387 Oper = GetScalarizedVector(Oper);
396 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
397 Opers,
N->getFlags());
408 EVT ResVT =
N->getValueType(0);
409 EVT OvVT =
N->getValueType(1);
413 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
414 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
417 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
418 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
419 ScalarLHS = ElemsLHS[0];
420 ScalarRHS = ElemsRHS[0];
423 SDVTList ScalarVTs = DAG.getVTList(
425 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
426 {ScalarLHS, ScalarRHS},
N->getFlags())
430 unsigned OtherNo = 1 - ResNo;
431 EVT OtherVT =
N->getValueType(OtherNo);
433 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
437 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
440 return SDValue(ScalarNode, ResNo);
445 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
446 return GetScalarizedVector(
Op);
449SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
451 SDValue SourceValue =
N->getOperand(0);
452 SDValue SinkValue =
N->getOperand(1);
453 SDValue EltSizeInBytes =
N->getOperand(2);
454 SDValue LaneOffset =
N->getOperand(3);
462 if (IsReadAfterWrite)
470 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
475 return DAG.getNode(
ISD::OR,
DL, CmpVT, Cmp,
482 Op = GetScalarizedVector(
Op);
483 EVT NewVT =
N->getValueType(0).getVectorElementType();
488SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
498SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
500 N->getValueType(0).getVectorElementType(),
501 N->getOperand(0),
N->getOperand(1));
507 EVT OpVT =
Op.getValueType();
511 Op = GetScalarizedVector(
Op);
514 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
517 N->getValueType(0).getVectorElementType(),
Op,
521SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
524 EVT OpVT =
Op.getValueType();
528 Op = GetScalarizedVector(
Op);
531 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
534 N->getValueType(0).getVectorElementType(),
Op,
538SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
541 EVT OpVT =
Op.getValueType();
544 Op = GetScalarizedVector(
Op);
547 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
550 N->getValueType(0).getVectorElementType(),
Op,
551 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
554SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
555 SDValue Op = GetScalarizedVector(
N->getOperand(0));
556 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
560SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
565 if (
Op.getValueType() != EltVT)
573 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
574 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
584 assert(
N->isUnindexed() &&
"Indexed vector load?");
588 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
589 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
590 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
591 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
603 EVT OpVT =
Op.getValueType();
613 Op = GetScalarizedVector(
Op);
616 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
618 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
624 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
625 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
626 LHS, DAG.getValueType(ExtVT));
633 EVT OpVT =
Op.getValueType();
638 Op = GetScalarizedVector(
Op);
640 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
643 switch (
N->getOpcode()) {
655SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
658 EVT OpVT =
Op.getValueType();
668 Op = GetScalarizedVector(
Op);
671 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
674 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
675 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
676 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
679SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
691 EVT OpVT =
Cond.getValueType();
700 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
703 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
705 TLI.getBooleanContents(
false,
false);
712 if (TLI.getBooleanContents(
false,
false) !=
713 TLI.getBooleanContents(
false,
true)) {
717 EVT OpVT =
Cond->getOperand(0).getValueType();
719 VecBool = TLI.getBooleanContents(OpVT);
724 EVT CondVT =
Cond.getValueType();
725 if (ScalarBool != VecBool) {
726 switch (ScalarBool) {
734 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
741 Cond, DAG.getValueType(MVT::i1));
747 auto BoolVT = getSetCCResultType(CondVT);
748 if (BoolVT.bitsLT(CondVT))
751 return DAG.getSelect(SDLoc(
N),
753 GetScalarizedVector(
N->getOperand(2)));
757 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
758 return DAG.getSelect(SDLoc(
N),
759 LHS.getValueType(),
N->getOperand(0),
LHS,
760 GetScalarizedVector(
N->getOperand(2)));
764 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
766 N->getOperand(0),
N->getOperand(1),
767 LHS, GetScalarizedVector(
N->getOperand(3)),
772 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
775SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
779 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
781 return GetScalarizedVector(
N->getOperand(
Op));
784SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
786 EVT SrcVT = Src.getValueType();
791 Src = GetScalarizedVector(Src);
795 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
797 EVT DstVT =
N->getValueType(0).getVectorElementType();
798 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
802 assert(
N->getValueType(0).isVector() &&
803 N->getOperand(0).getValueType().isVector() &&
804 "Operand types must be vectors");
807 EVT OpVT =
LHS.getValueType();
808 EVT NVT =
N->getValueType(0).getVectorElementType();
813 LHS = GetScalarizedVector(
LHS);
814 RHS = GetScalarizedVector(
RHS);
817 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
818 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
828 return DAG.getNode(ExtendCode,
DL, NVT, Res);
839 Arg = GetScalarizedVector(Arg);
842 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
851 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
858bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
863 switch (
N->getOpcode()) {
866 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
873 Res = ScalarizeVecOp_BITCAST(
N);
876 Res = ScalarizeVecOp_FAKE_USE(
N);
890 Res = ScalarizeVecOp_UnaryOp(
N);
895 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
898 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
899 "Unexpected vector type!");
900 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
902 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
903 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
911 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
914 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
917 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
920 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
923 Res = ScalarizeVecOp_VSELECT(
N);
926 Res = ScalarizeVecOp_VSETCC(
N);
930 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
939 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
942 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
945 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
948 Res = ScalarizeVecOp_FP_EXTEND(
N);
965 Res = ScalarizeVecOp_VECREDUCE(
N);
969 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
973 Res = ScalarizeVecOp_CMP(
N);
976 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
980 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
986 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
991 if (!Res.
getNode())
return false;
999 "Invalid operand expansion");
1001 ReplaceValueWith(
SDValue(
N, 0), Res);
1008 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1010 N->getValueType(0), Elt);
1015 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1016 "Fake Use: Unexpected vector type!");
1017 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1018 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1024 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1025 "Unexpected vector type!");
1026 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1027 SDValue Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1028 N->getValueType(0).getScalarType(), Elt);
1036SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1037 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1038 "Unexpected vector type!");
1039 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1041 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1042 Elt,
N->getOperand(1));
1050SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1051 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1052 "Unexpected vector type!");
1053 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1055 {
N->getValueType(0).getScalarType(), MVT::Other },
1056 {
N->getOperand(0), Elt });
1066 ReplaceValueWith(
SDValue(
N, 0), Res);
1071SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1073 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1074 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1075 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1080SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1084 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1085 SDValue ContainingVec =
N->getOperand(0);
1093SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1094 EVT VT =
N->getValueType(0);
1095 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1107 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1108 EVT VT =
N->getValueType(0);
1110 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1118 assert(
N->getValueType(0).isVector() &&
1119 N->getOperand(0).getValueType().isVector() &&
1120 "Operand types must be vectors");
1121 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1123 EVT VT =
N->getValueType(0);
1124 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1125 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1127 EVT OpVT =
N->getOperand(0).getValueType();
1139 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1145SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1147 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1148 assert(
N->getValueType(0).isVector() &&
1149 N->getOperand(1).getValueType().isVector() &&
1150 "Operand types must be vectors");
1151 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1153 EVT VT =
N->getValueType(0);
1155 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1156 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1159 EVT OpVT =
N->getOperand(1).getValueType();
1163 {Ch, LHS, RHS, CC});
1172 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1177 ReplaceValueWith(
SDValue(
N, 0), Res);
1184 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1185 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1188 if (
N->isTruncatingStore())
1189 return DAG.getTruncStore(
1190 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1191 N->getBasePtr(),
N->getPointerInfo(),
1192 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1193 N->getMemOperand()->getFlags(),
N->getAAInfo());
1195 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1196 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1197 N->getMemOperand()->getFlags(),
N->getAAInfo());
1203 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1205 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1206 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1211SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1212 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1213 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1215 N->getValueType(0).getVectorElementType(), Elt,
1220SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1222 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1223 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1226 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1236 ReplaceValueWith(
SDValue(
N, 0), Res);
1243 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1245 N->getValueType(0).getVectorElementType(), Elt);
1251SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1252 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1255 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1256 {
N->getOperand(0), Elt});
1265 ReplaceValueWith(
SDValue(
N, 0), Res);
1270 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1277SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1283 SDValue Op = GetScalarizedVector(VecOp);
1284 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1285 AccOp,
Op,
N->getFlags());
1289 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1290 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1297SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1305 EVT VT =
N->getValueType(0);
1306 return DAG.getConstant(0, SDLoc(
N), VT);
1313 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1314 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1316 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1317 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1318 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1321SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1322 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1325 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1326 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1335 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1347void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1352 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1355 switch (
N->getOpcode()) {
1358 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1367 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1375 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1391 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1394 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1406 case ISD::VP_LOAD_FF:
1409 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1416 case ISD::VP_GATHER:
1420 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1424 SplitVecRes_SETCC(
N,
Lo,
Hi);
1427 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1434 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1437 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1440 SplitVecRes_VECTOR_INTERLEAVE(
N);
1443 SplitVecRes_VAARG(
N,
Lo,
Hi);
1449 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1456 case ISD::VP_BITREVERSE:
1464 case ISD::VP_CTLZ_ZERO_POISON:
1466 case ISD::VP_CTTZ_ZERO_POISON:
1481 case ISD::VP_FFLOOR:
1486 case ISD::VP_FNEARBYINT:
1491 case ISD::VP_FP_EXTEND:
1493 case ISD::VP_FP_ROUND:
1495 case ISD::VP_FP_TO_SINT:
1497 case ISD::VP_FP_TO_UINT:
1503 case ISD::VP_LLRINT:
1505 case ISD::VP_FROUND:
1507 case ISD::VP_FROUNDEVEN:
1516 case ISD::VP_FROUNDTOZERO:
1518 case ISD::VP_SINT_TO_FP:
1520 case ISD::VP_TRUNCATE:
1522 case ISD::VP_UINT_TO_FP:
1527 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1530 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1536 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1542 case ISD::VP_SIGN_EXTEND:
1543 case ISD::VP_ZERO_EXTEND:
1544 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1568 case ISD::VP_FMINNUM:
1571 case ISD::VP_FMAXNUM:
1573 case ISD::VP_FMINIMUM:
1575 case ISD::VP_FMAXIMUM:
1584 case ISD::OR:
case ISD::VP_OR:
1604 case ISD::VP_FCOPYSIGN:
1605 SplitVecRes_BinOp(
N,
Lo,
Hi);
1611 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1618 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1622 SplitVecRes_CMP(
N,
Lo,
Hi);
1625#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1626 case ISD::STRICT_##DAGN:
1627#include "llvm/IR/ConstrainedOps.def"
1628 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1633 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1642 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1652 SplitVecRes_FIX(
N,
Lo,
Hi);
1654 case ISD::EXPERIMENTAL_VP_SPLICE:
1655 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1657 case ISD::EXPERIMENTAL_VP_REVERSE:
1658 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1664 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1667 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1676void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1678 uint64_t *ScaledOffset) {
1683 SDValue BytesIncrement = DAG.getVScale(
1686 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1688 *ScaledOffset += IncrementSize;
1698std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1699 return SplitMask(Mask, SDLoc(Mask));
1702std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1705 EVT MaskVT =
Mask.getValueType();
1707 GetSplitVector(Mask, MaskLo, MaskHi);
1709 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1710 return std::make_pair(MaskLo, MaskHi);
1715 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1717 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1720 const SDNodeFlags
Flags =
N->getFlags();
1721 unsigned Opcode =
N->getOpcode();
1722 if (
N->getNumOperands() == 2) {
1723 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1724 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1728 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1729 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1732 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1735 std::tie(EVLLo, EVLHi) =
1736 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1739 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1741 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1747 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1749 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1750 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(2));
1753 const SDNodeFlags
Flags =
N->getFlags();
1754 unsigned Opcode =
N->getOpcode();
1755 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1757 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1764 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1766 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1768 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1771 const SDNodeFlags
Flags =
N->getFlags();
1772 unsigned Opcode =
N->getOpcode();
1773 if (
N->getNumOperands() == 3) {
1774 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1775 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1779 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1780 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1783 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1786 std::tie(EVLLo, EVLHi) =
1787 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1790 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1792 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1796 LLVMContext &Ctxt = *DAG.getContext();
1802 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1804 GetSplitVector(
LHS, LHSLo, LHSHi);
1805 GetSplitVector(
RHS, RHSLo, RHSHi);
1807 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1808 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1812 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1813 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1818 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1820 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1824 unsigned Opcode =
N->getOpcode();
1825 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1827 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1836 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1843 switch (getTypeAction(InVT)) {
1857 GetExpandedOp(InOp,
Lo,
Hi);
1858 if (DAG.getDataLayout().isBigEndian())
1868 GetSplitVector(InOp,
Lo,
Hi);
1877 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1886 if (DAG.getDataLayout().isBigEndian())
1889 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1891 if (DAG.getDataLayout().isBigEndian())
1897void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1903 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1906 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1911 unsigned LaneOffset =
1914 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1916 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1923 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1926 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1929 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1934 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1936 unsigned NumSubvectors =
N->getNumOperands() / 2;
1937 if (NumSubvectors == 1) {
1938 Lo =
N->getOperand(0);
1939 Hi =
N->getOperand(1);
1944 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1953void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1960 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1975 GetSplitVector(Vec,
Lo,
Hi);
1978 EVT LoVT =
Lo.getValueType();
1988 if (IdxVal + SubElems <= LoElems) {
1996 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1998 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
2004 SDValue WideSubVec = GetWidenedVector(SubVec);
2006 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2014 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2016 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2017 auto &MF = DAG.getMachineFunction();
2021 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2026 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2027 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
2031 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
2036 MachinePointerInfo MPI =
Load->getPointerInfo();
2037 IncrementPointer(Load, LoVT, MPI, StackPtr);
2040 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
2049 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2054 EVT RHSVT =
RHS.getValueType();
2057 GetSplitVector(
RHS, RHSLo, RHSHi);
2059 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2074 SDValue FpValue =
N->getOperand(0);
2076 GetSplitVector(FpValue, ArgLo, ArgHi);
2078 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2080 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2089 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2093 std::tie(LoVT, HiVT) =
2097 DAG.getValueType(LoVT));
2099 DAG.getValueType(HiVT));
2104 unsigned Opcode =
N->getOpcode();
2111 GetSplitVector(N0, InLo, InHi);
2113 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2118 EVT OutLoVT, OutHiVT;
2119 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2121 assert((2 * OutNumElements) <= InNumElements &&
2122 "Illegal extend vector in reg split");
2131 SmallVector<int, 8> SplitHi(InNumElements, -1);
2132 for (
unsigned i = 0; i != OutNumElements; ++i)
2133 SplitHi[i] = i + OutNumElements;
2134 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2136 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2137 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2142 unsigned NumOps =
N->getNumOperands();
2146 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2156 for (
unsigned i = 1; i <
NumOps; ++i) {
2161 EVT InVT =
Op.getValueType();
2166 GetSplitVector(
Op, OpLo, OpHi);
2168 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2175 EVT LoValueVTs[] = {LoVT, MVT::Other};
2176 EVT HiValueVTs[] = {HiVT, MVT::Other};
2177 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2179 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2185 Lo.getValue(1),
Hi.getValue(1));
2189 ReplaceValueWith(
SDValue(
N, 1), Chain);
2192SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2194 EVT VT =
N->getValueType(0);
2205 else if (NE > ResNE)
2209 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2213 for (i = 0; i !=
NE; ++i) {
2214 Operands[0] = Chain;
2215 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2216 SDValue Operand =
N->getOperand(j);
2220 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2222 Operands[
j] = Operand;
2226 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2234 for (; i < ResNE; ++i)
2235 Scalars.
push_back(DAG.getPOISON(EltVT));
2239 ReplaceValueWith(
SDValue(
N, 1), Chain);
2243 return DAG.getBuildVector(VecVT, dl, Scalars);
2246void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2249 EVT ResVT =
N->getValueType(0);
2250 EVT OvVT =
N->getValueType(1);
2251 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2252 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2253 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2255 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2257 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2258 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2260 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2261 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2264 unsigned Opcode =
N->getOpcode();
2265 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2266 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2268 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2270 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2276 unsigned OtherNo = 1 - ResNo;
2277 EVT OtherVT =
N->getValueType(OtherNo);
2279 SetSplitVector(
SDValue(
N, OtherNo),
2285 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2289void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2295 GetSplitVector(Vec,
Lo,
Hi);
2298 unsigned IdxVal = CIdx->getZExtValue();
2299 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2300 if (IdxVal < LoNumElts) {
2302 Lo.getValueType(),
Lo, Elt, Idx);
2305 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2325 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2327 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2328 auto &MF = DAG.getMachineFunction();
2332 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2337 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2338 Store = DAG.getTruncStore(
2344 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2347 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2351 MachinePointerInfo MPI =
Load->getPointerInfo();
2352 IncrementPointer(Load, LoVT, MPI, StackPtr);
2354 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2357 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2358 if (LoVT !=
Lo.getValueType())
2360 if (HiVT !=
Hi.getValueType())
2368 assert(
N->getValueType(0).isScalableVector() &&
2369 "Only scalable vectors are supported for STEP_VECTOR");
2370 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2391 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2392 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2394 Hi = DAG.getPOISON(HiVT);
2404 "Extended load during type legalization!");
2406 EVT VT =
LD->getValueType(0);
2408 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2416 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2417 Ch, Ptr,
LD->getMemOperand());
2422 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2424 Lo = DAG.getBitcast(LoVT, ExtractLo);
2425 Hi = DAG.getBitcast(HiVT, ExtractHi);
2437 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2443 EVT MemoryVT =
LD->getMemoryVT();
2445 AAMDNodes AAInfo =
LD->getAAInfo();
2447 EVT LoMemVT, HiMemVT;
2448 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2452 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2453 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2454 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2459 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2462 MachinePointerInfo MPI;
2463 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2466 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2475 ReplaceValueWith(
SDValue(LD, 1), Ch);
2480 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2483 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2489 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2490 Align Alignment =
LD->getBaseAlign();
2493 EVT MemoryVT =
LD->getMemoryVT();
2495 EVT LoMemVT, HiMemVT;
2496 bool HiIsEmpty =
false;
2497 std::tie(LoMemVT, HiMemVT) =
2498 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2503 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2506 GetSplitVector(Mask, MaskLo, MaskHi);
2508 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2513 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2515 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2521 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2522 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2530 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2531 LD->isExpandingLoad());
2533 MachinePointerInfo MPI;
2535 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2537 MPI =
LD->getPointerInfo().getWithOffset(
2540 MMO = DAG.getMachineFunction().getMachineMemOperand(
2542 Alignment,
LD->getAAInfo(),
LD->getRanges());
2544 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2545 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2546 LD->isExpandingLoad());
2556 ReplaceValueWith(
SDValue(LD, 1), Ch);
2562 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2566 Align Alignment =
LD->getBaseAlign();
2573 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2576 GetSplitVector(Mask, MaskLo, MaskHi);
2578 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2582 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2584 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2589 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2592 Hi = DAG.getPOISON(HiVT);
2594 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2595 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2601 "Indexed VP strided load during type legalization!");
2603 "Unexpected indexed variable-length load offset");
2608 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2610 EVT LoMemVT, HiMemVT;
2611 bool HiIsEmpty =
false;
2612 std::tie(LoMemVT, HiMemVT) =
2613 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2618 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2621 GetSplitVector(Mask, LoMask, HiMask);
2623 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2627 std::tie(LoEVL, HiEVL) =
2631 Lo = DAG.getStridedLoadVP(
2658 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2665 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2676 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2684 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2689 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2699 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2702 GetSplitVector(Mask, MaskLo, MaskHi);
2704 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2708 EVT LoMemVT, HiMemVT;
2709 bool HiIsEmpty =
false;
2710 std::tie(LoMemVT, HiMemVT) =
2711 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2713 SDValue PassThruLo, PassThruHi;
2715 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2717 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2719 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2723 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2733 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2736 MachinePointerInfo MPI;
2743 MMO = DAG.getMachineFunction().getMachineMemOperand(
2747 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2759 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2767 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2775 }
Ops = [&]() -> Operands {
2777 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2780 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2783 EVT MemoryVT =
N->getMemoryVT();
2784 Align Alignment =
N->getBaseAlign();
2789 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2791 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2794 EVT LoMemVT, HiMemVT;
2796 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2799 if (getTypeAction(
Ops.Index.getValueType()) ==
2801 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2803 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2806 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2808 Alignment,
N->getAAInfo(),
N->getRanges());
2811 SDValue PassThru = MGT->getPassThru();
2812 SDValue PassThruLo, PassThruHi;
2815 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2817 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2822 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2823 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2824 OpsLo, MMO, IndexTy, ExtType);
2826 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2827 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2828 OpsHi, MMO, IndexTy, ExtType);
2832 std::tie(EVLLo, EVLHi) =
2833 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2835 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2836 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2837 MMO, VPGT->getIndexType());
2839 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2840 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2841 MMO, VPGT->getIndexType());
2851 ReplaceValueWith(
SDValue(
N, 1), Ch);
2865 EVT VecVT =
N->getValueType(0);
2867 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2868 bool HasCustomLowering =
false;
2875 HasCustomLowering =
true;
2881 SDValue Passthru =
N->getOperand(2);
2882 if (!HasCustomLowering) {
2883 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2884 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2891 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2892 std::tie(LoMask, HiMask) = SplitMask(Mask);
2894 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2899 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2900 MachineFunction &MF = DAG.getMachineFunction();
2912 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2914 SDValue Chain = DAG.getEntryNode();
2915 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2919 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2924 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2928 assert(
N->getValueType(0).isVector() &&
2929 N->getOperand(0).getValueType().isVector() &&
2930 "Operand types must be vectors");
2934 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2938 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2940 GetSplitVector(
N->getOperand(0), LL, LH);
2942 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2944 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2946 GetSplitVector(
N->getOperand(1), RL, RH);
2948 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2951 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2952 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2954 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2955 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2956 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2957 std::tie(EVLLo, EVLHi) =
2958 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2959 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2961 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2971 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2975 EVT InVT =
N->getOperand(0).getValueType();
2977 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2979 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2981 const SDNodeFlags
Flags =
N->getFlags();
2982 unsigned Opcode =
N->getOpcode();
2984 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
2985 N->getOperand(3), Flags);
2986 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
2987 N->getOperand(3), Flags);
2990 if (
N->getNumOperands() <= 2) {
2993 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2994 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2996 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2997 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
3002 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
3003 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3006 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3009 std::tie(EVLLo, EVLHi) =
3010 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3013 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
3019 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3023 EVT InVT =
N->getOperand(0).getValueType();
3025 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3027 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3030 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3031 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3032 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
3033 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
3036void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3041 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3042 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3046 EVT InVT =
N->getOperand(0).getValueType();
3048 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3050 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3052 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3053 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3055 SDNode *HiNode =
Hi.getNode();
3056 SDNode *LoNode =
Lo.getNode();
3059 unsigned OtherNo = 1 - ResNo;
3060 EVT OtherVT =
N->getValueType(OtherNo);
3068 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3075 EVT SrcVT =
N->getOperand(0).getValueType();
3076 EVT DestVT =
N->getValueType(0);
3078 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3095 LLVMContext &Ctx = *DAG.getContext();
3099 EVT SplitLoVT, SplitHiVT;
3100 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3101 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3102 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3103 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3104 N->dump(&DAG);
dbgs() <<
"\n");
3105 if (!
N->isVPOpcode()) {
3108 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3110 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3112 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3113 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3119 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
3120 N->getOperand(1),
N->getOperand(2));
3122 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3125 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3128 std::tie(EVLLo, EVLHi) =
3129 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3131 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
3132 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
3137 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3145 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3146 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3152 return N.getResNo() == 0 &&
3156 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3158 ArrayRef<int>
Mask) {
3161 "Expected build vector node.");
3164 for (
unsigned I = 0;
I < NewElts; ++
I) {
3167 unsigned Idx =
Mask[
I];
3169 Ops[
I] = Input2.getOperand(Idx - NewElts);
3171 Ops[
I] = Input1.getOperand(Idx);
3176 return DAG.getBuildVector(NewVT,
DL,
Ops);
3182 SmallVector<int> OrigMask(
N->getMask());
3184 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3185 &
DL](SmallVectorImpl<int> &
Mask) {
3187 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3188 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3199 for (
auto &
P : ShufflesIdxs) {
3200 if (
P.second.size() < 2)
3204 for (
int &Idx : Mask) {
3207 unsigned SrcRegIdx = Idx / NewElts;
3208 if (Inputs[SrcRegIdx].
isUndef()) {
3216 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3221 Idx = MaskElt % NewElts +
3222 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3228 Inputs[
P.second[0]] =
P.first.first;
3229 Inputs[
P.second[1]] =
P.first.second;
3232 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3235 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3236 for (
int &Idx : Mask) {
3239 unsigned SrcRegIdx = Idx / NewElts;
3240 if (Inputs[SrcRegIdx].
isUndef()) {
3247 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3248 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3251 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3253 if (UsedSubVector.count() > 1) {
3255 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3256 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3258 if (Pairs.
empty() || Pairs.
back().size() == 2)
3260 if (UsedSubVector.test(2 *
I)) {
3261 Pairs.
back().emplace_back(
I, 0);
3263 assert(UsedSubVector.test(2 *
I + 1) &&
3264 "Expected to be used one of the subvectors.");
3265 Pairs.
back().emplace_back(
I, 1);
3268 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3270 for (
int &Idx : Mask) {
3273 unsigned SrcRegIdx = Idx / NewElts;
3275 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3276 return Idxs.front().first == SrcRegIdx ||
3277 Idxs.back().first == SrcRegIdx;
3279 if (It == Pairs.
end())
3281 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3282 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3285 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3286 Inputs[Idxs.front().first] = DAG.
getNode(
3288 Inputs[Idxs.front().first].getValueType(),
3289 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3290 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3299 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3303 if (Shuffle->getOperand(0).getValueType() != NewVT)
3306 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3307 !Shuffle->isSplat()) {
3309 }
else if (!Inputs[
I].hasOneUse() &&
3310 !Shuffle->getOperand(1).isUndef()) {
3312 for (
int &Idx : Mask) {
3315 unsigned SrcRegIdx = Idx / NewElts;
3318 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3323 int OpIdx = MaskElt / NewElts;
3337 if (Shuffle->getOperand(
OpIdx).isUndef())
3339 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3340 if (It == std::end(Inputs))
3342 int FoundOp = std::distance(std::begin(Inputs), It);
3345 for (
int &Idx : Mask) {
3348 unsigned SrcRegIdx = Idx / NewElts;
3351 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3356 int MaskIdx = MaskElt / NewElts;
3357 if (
OpIdx == MaskIdx)
3358 Idx = MaskElt % NewElts + FoundOp * NewElts;
3369 for (
int &Idx : Mask) {
3372 unsigned SrcRegIdx = Idx / NewElts;
3375 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3376 int OpIdx = MaskElt / NewElts;
3379 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3385 TryPeekThroughShufflesInputs(OrigMask);
3387 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3388 NewElts](SmallVectorImpl<int> &
Mask) {
3389 SetVector<SDValue> UniqueInputs;
3390 SetVector<SDValue> UniqueConstantInputs;
3391 for (
const auto &
I : Inputs) {
3393 UniqueConstantInputs.
insert(
I);
3394 else if (!
I.isUndef())
3399 if (UniqueInputs.
size() != std::size(Inputs)) {
3400 auto &&UniqueVec = UniqueInputs.
takeVector();
3401 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3402 unsigned ConstNum = UniqueConstantVec.size();
3403 for (
int &Idx : Mask) {
3406 unsigned SrcRegIdx = Idx / NewElts;
3407 if (Inputs[SrcRegIdx].
isUndef()) {
3411 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3412 if (It != UniqueConstantVec.end()) {
3413 Idx = (Idx % NewElts) +
3414 NewElts * std::distance(UniqueConstantVec.begin(), It);
3415 assert(Idx >= 0 &&
"Expected defined mask idx.");
3418 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3419 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3420 Idx = (Idx % NewElts) +
3421 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3422 assert(Idx >= 0 &&
"Expected defined mask idx.");
3424 copy(UniqueConstantVec, std::begin(Inputs));
3425 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3428 MakeUniqueInputs(OrigMask);
3430 copy(Inputs, std::begin(OrigInputs));
3436 unsigned FirstMaskIdx =
High * NewElts;
3439 assert(!Output &&
"Expected default initialized initial value.");
3440 TryPeekThroughShufflesInputs(Mask);
3441 MakeUniqueInputs(Mask);
3443 copy(Inputs, std::begin(TmpInputs));
3446 bool SecondIteration =
false;
3447 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3452 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3453 SecondIteration =
true;
3454 return SecondIteration;
3457 Mask, std::size(Inputs), std::size(Inputs),
3459 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3460 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3461 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3463 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3465 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3466 DAG.getPOISON(NewVT), Mask);
3467 Inputs[Idx] = Output;
3469 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3470 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3471 unsigned Idx2,
bool ) {
3472 if (AccumulateResults(Idx1)) {
3475 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3477 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3478 Inputs[Idx2], Mask);
3482 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3484 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3485 TmpInputs[Idx2], Mask);
3487 Inputs[Idx1] = Output;
3489 copy(OrigInputs, std::begin(Inputs));
3494 EVT OVT =
N->getValueType(0);
3501 const Align Alignment =
3502 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3504 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3505 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3510 ReplaceValueWith(
SDValue(
N, 1), Chain);
3515 EVT DstVTLo, DstVTHi;
3516 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3520 EVT SrcVT =
N->getOperand(0).getValueType();
3522 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3524 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3526 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3527 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3533 GetSplitVector(
N->getOperand(0), InLo, InHi);
3544 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3545 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3550 EVT VT =
N->getValueType(0);
3568 Align Alignment = DAG.getReducedAlign(VT,
false);
3573 EVT PtrVT =
StackPtr.getValueType();
3574 auto &MF = DAG.getMachineFunction();
3578 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3581 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3587 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3588 DAG.getConstant(1,
DL, PtrVT));
3590 DAG.getConstant(EltWidth,
DL, PtrVT));
3592 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3594 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3595 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3596 DAG.getPOISON(PtrVT), Stride, TrueMask,
3599 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3605 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3610 EVT VT =
N->getValueType(0);
3622 EVL1 = ZExtPromotedInteger(EVL1);
3636 Align Alignment = DAG.getReducedAlign(VT,
false);
3641 EVT PtrVT =
StackPtr.getValueType();
3642 auto &MF = DAG.getMachineFunction();
3646 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3649 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3655 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3660 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3661 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3663 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3665 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3669 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3674 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3675 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3677 uint64_t TrailingElts = -
Imm;
3679 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3688 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3696 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3698 DAG.getVectorIdxConstant(0,
DL));
3704void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3712 GetSplitVector(Acc, AccLo, AccHi);
3713 unsigned Opcode =
N->getOpcode();
3725 GetSplitVector(Input1, Input1Lo, Input1Hi);
3726 GetSplitVector(Input2, Input2Lo, Input2Hi);
3729 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3730 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3733void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3741 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3749void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3750 unsigned Factor =
N->getNumOperands();
3753 for (
unsigned i = 0; i != Factor; ++i) {
3755 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3757 Ops[i * 2 + 1] = OpHi;
3768 for (
unsigned i = 0; i != Factor; ++i)
3772void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3773 unsigned Factor =
N->getNumOperands();
3776 for (
unsigned i = 0; i != Factor; ++i) {
3778 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3780 Ops[i + Factor] = OpHi;
3791 for (
unsigned i = 0; i != Factor; ++i) {
3792 unsigned IdxLo = 2 * i;
3793 unsigned IdxHi = 2 * i + 1;
3794 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3795 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3807bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3812 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3815 switch (
N->getOpcode()) {
3818 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3828 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3835 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3837 case ISD::VP_TRUNCATE:
3839 Res = SplitVecOp_TruncateHelper(
N);
3842 case ISD::VP_FP_ROUND:
3846 Res = SplitVecOp_FP_ROUND(
N);
3858 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3865 case ISD::VP_SCATTER:
3869 case ISD::VP_GATHER:
3873 Res = SplitVecOp_VSELECT(
N, OpNo);
3876 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3882 case ISD::VP_SINT_TO_FP:
3883 case ISD::VP_UINT_TO_FP:
3884 if (
N->getValueType(0).bitsLT(
3885 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3886 Res = SplitVecOp_TruncateHelper(
N);
3888 Res = SplitVecOp_UnaryOp(
N);
3892 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3896 case ISD::VP_FP_TO_SINT:
3897 case ISD::VP_FP_TO_UINT:
3910 Res = SplitVecOp_UnaryOp(
N);
3913 Res = SplitVecOp_FPOpDifferentTypes(
N);
3918 Res = SplitVecOp_CMP(
N);
3922 Res = SplitVecOp_FAKE_USE(
N);
3927 Res = SplitVecOp_ExtVecInRegOp(
N);
3945 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3949 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3951 case ISD::VP_REDUCE_FADD:
3952 case ISD::VP_REDUCE_SEQ_FADD:
3953 case ISD::VP_REDUCE_FMUL:
3954 case ISD::VP_REDUCE_SEQ_FMUL:
3955 case ISD::VP_REDUCE_ADD:
3956 case ISD::VP_REDUCE_MUL:
3957 case ISD::VP_REDUCE_AND:
3958 case ISD::VP_REDUCE_OR:
3959 case ISD::VP_REDUCE_XOR:
3960 case ISD::VP_REDUCE_SMAX:
3961 case ISD::VP_REDUCE_SMIN:
3962 case ISD::VP_REDUCE_UMAX:
3963 case ISD::VP_REDUCE_UMIN:
3964 case ISD::VP_REDUCE_FMAX:
3965 case ISD::VP_REDUCE_FMIN:
3966 case ISD::VP_REDUCE_FMAXIMUM:
3967 case ISD::VP_REDUCE_FMINIMUM:
3968 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3972 Res = SplitVecOp_CttzElts(
N);
3974 case ISD::VP_CTTZ_ELTS:
3975 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3976 Res = SplitVecOp_VP_CttzElements(
N);
3979 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3985 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3990 if (!Res.
getNode())
return false;
3997 if (
N->isStrictFPOpcode())
3999 "Invalid operand expansion");
4002 "Invalid operand expansion");
4004 ReplaceValueWith(
SDValue(
N, 0), Res);
4008SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4012 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4014 EVT VT =
N->getValueType(0);
4027 getSetCCResultType(MVT::i1), MVT::i1);
4032 DAG.getElementCount(
DL, VT, SplitEC)),
4036SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4039 assert(OpNo == 0 &&
"Illegal operand must be mask");
4046 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4049 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4050 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4051 "Lo and Hi have differing types");
4054 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4055 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4057 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4058 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4059 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4060 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4070SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4073 assert(OpNo == 1 &&
"Illegal operand must be mask");
4078 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4080 EVT VecVT =
N->getValueType(0);
4084SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4085 EVT ResVT =
N->getValueType(0);
4091 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4092 GetSplitVector(VecOp,
Lo,
Hi);
4094 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4099 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4100 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4104 EVT ResVT =
N->getValueType(0);
4110 SDNodeFlags
Flags =
N->getFlags();
4113 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4114 GetSplitVector(VecOp,
Lo,
Hi);
4116 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4122 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4125SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4126 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4127 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4129 unsigned Opc =
N->getOpcode();
4130 EVT ResVT =
N->getValueType(0);
4136 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4137 GetSplitVector(VecOp,
Lo,
Hi);
4140 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4143 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4145 const SDNodeFlags
Flags =
N->getFlags();
4149 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4154 EVT ResVT =
N->getValueType(0);
4157 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4158 EVT InVT =
Lo.getValueType();
4163 if (
N->isStrictFPOpcode()) {
4164 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4165 {N->getOperand(0), Lo});
4166 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4167 {N->getOperand(0), Hi});
4176 ReplaceValueWith(
SDValue(
N, 1), Ch);
4177 }
else if (
N->getNumOperands() == 3) {
4178 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4179 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4180 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4181 std::tie(EVLLo, EVLHi) =
4182 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4183 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4184 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4186 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4187 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4196 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4206 EVT ResVT =
N->getValueType(0);
4208 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4212 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4218 Lo = BitConvertToInteger(
Lo);
4219 Hi = BitConvertToInteger(
Hi);
4221 if (DAG.getDataLayout().isBigEndian())
4229 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4231 EVT ResVT =
N->getValueType(0);
4239 GetSplitVector(SubVec,
Lo,
Hi);
4248 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4250 return SecondInsertion;
4253SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4260 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4262 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4264 ElementCount IdxVal =
4268 EVT SrcVT =
N->getOperand(0).getValueType();
4287 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4288 LoEltsMin - IdxValMin);
4289 DAG.ExtractVectorElements(
Hi, Elts, 0,
4292 return DAG.getBuildVector(SubVT, dl, Elts);
4296 ElementCount ExtractIdx = IdxVal - LoElts;
4298 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4301 EVT HiVT =
Hi.getValueType();
4303 "Only fixed-vector extracts are supported in this case");
4313 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4314 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4320 "Extracting scalable subvector from fixed-width unsupported");
4328 "subvector from a scalable predicate vector");
4334 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4336 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4337 auto &MF = DAG.getMachineFunction();
4341 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4345 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4348 SubVT, dl, Store, StackPtr,
4352SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4358 uint64_t IdxVal =
Index->getZExtValue();
4361 GetSplitVector(Vec,
Lo,
Hi);
4363 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4365 if (IdxVal < LoElts)
4366 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4369 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4374 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4386 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4392 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4394 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4395 auto &MF = DAG.getMachineFunction();
4398 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4402 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4406 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4408 return DAG.getExtLoad(
4419 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4427 SplitVecRes_Gather(
N,
Lo,
Hi);
4430 ReplaceValueWith(
SDValue(
N, 0), Res);
4435 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4439 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4441 SDValue EVL =
N->getVectorLength();
4443 Align Alignment =
N->getBaseAlign();
4449 GetSplitVector(
Data, DataLo, DataHi);
4451 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4456 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4459 GetSplitVector(Mask, MaskLo, MaskHi);
4461 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4464 EVT MemoryVT =
N->getMemoryVT();
4465 EVT LoMemVT, HiMemVT;
4466 bool HiIsEmpty =
false;
4467 std::tie(LoMemVT, HiMemVT) =
4468 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4472 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4475 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4480 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4481 N->getAddressingMode(),
N->isTruncatingStore(),
4482 N->isCompressingStore());
4488 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4489 N->isCompressingStore());
4491 MachinePointerInfo MPI;
4495 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4500 MMO = DAG.getMachineFunction().getMachineMemOperand(
4502 Alignment,
N->getAAInfo(),
N->getRanges());
4504 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4505 N->getAddressingMode(),
N->isTruncatingStore(),
4506 N->isCompressingStore());
4515 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4516 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4523 GetSplitVector(
Data, LoData, HiData);
4525 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4527 EVT LoMemVT, HiMemVT;
4528 bool HiIsEmpty =
false;
4529 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4535 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4536 else if (getTypeAction(
Mask.getValueType()) ==
4538 GetSplitVector(Mask, LoMask, HiMask);
4540 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4543 std::tie(LoEVL, HiEVL) =
4544 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4548 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4549 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4550 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4561 EVT PtrVT =
N->getBasePtr().getValueType();
4564 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4567 Align Alignment =
N->getBaseAlign();
4572 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4573 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4575 Alignment,
N->getAAInfo(),
N->getRanges());
4578 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4579 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4580 N->isCompressingStore());
4589 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4593 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4596 Align Alignment =
N->getBaseAlign();
4602 GetSplitVector(
Data, DataLo, DataHi);
4604 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4609 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4612 GetSplitVector(Mask, MaskLo, MaskHi);
4614 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4617 EVT MemoryVT =
N->getMemoryVT();
4618 EVT LoMemVT, HiMemVT;
4619 bool HiIsEmpty =
false;
4620 std::tie(LoMemVT, HiMemVT) =
4621 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4624 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4629 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4630 N->getAddressingMode(),
N->isTruncatingStore(),
4631 N->isCompressingStore());
4639 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4640 N->isCompressingStore());
4642 MachinePointerInfo MPI;
4646 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4651 MMO = DAG.getMachineFunction().getMachineMemOperand(
4653 Alignment,
N->getAAInfo(),
N->getRanges());
4655 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4656 N->getAddressingMode(),
N->isTruncatingStore(),
4657 N->isCompressingStore());
4670 EVT MemoryVT =
N->getMemoryVT();
4671 Align Alignment =
N->getBaseAlign();
4678 }
Ops = [&]() -> Operands {
4680 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4684 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4689 EVT LoMemVT, HiMemVT;
4690 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4695 GetSplitVector(
Ops.Data, DataLo, DataHi);
4697 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4702 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4704 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4708 if (getTypeAction(
Ops.Index.getValueType()) ==
4710 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4712 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4716 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4718 Alignment,
N->getAAInfo(),
N->getRanges());
4721 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4723 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4724 MSC->getIndexType(), MSC->isTruncatingStore());
4729 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4730 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4731 MMO, MSC->getIndexType(),
4732 MSC->isTruncatingStore());
4736 std::tie(EVLLo, EVLHi) =
4737 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4739 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4740 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4741 VPSC->getIndexType());
4746 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4747 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4748 VPSC->getIndexType());
4752 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4753 assert(OpNo == 1 &&
"Can only split the stored value");
4756 bool isTruncating =
N->isTruncatingStore();
4759 EVT MemoryVT =
N->getMemoryVT();
4760 Align Alignment =
N->getBaseAlign();
4762 AAMDNodes AAInfo =
N->getAAInfo();
4764 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4766 EVT LoMemVT, HiMemVT;
4767 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4771 return TLI.scalarizeVectorStore(
N, DAG);
4774 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4775 Alignment, MMOFlags, AAInfo);
4777 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4780 MachinePointerInfo MPI;
4781 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4784 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4785 HiMemVT, Alignment, MMOFlags, AAInfo);
4787 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4794 LLVMContext &Ctx = *DAG.getContext();
4812 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4813 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4817 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4820 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4821 DAG.getBitcast(MemVecVT, Wide), 0);
4823 N->getBasePtr(),
N->getMemOperand());
4831 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4833 N->getBasePtr(),
N->getMemOperand());
4847 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4853 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4874 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4875 SDValue InVec =
N->getOperand(OpNo);
4877 EVT OutVT =
N->getValueType(0);
4885 EVT LoOutVT, HiOutVT;
4886 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4887 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4892 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4894 return SplitVecOp_UnaryOp(
N);
4903 return SplitVecOp_UnaryOp(
N);
4907 GetSplitVector(InVec, InLoVec, InHiVec);
4913 EVT HalfElementVT = IsFloat ?
4915 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4922 if (
N->isStrictFPOpcode()) {
4923 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4924 {N->getOperand(0), InLoVec});
4925 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4926 {N->getOperand(0), InHiVec});
4932 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4933 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4937 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4945 if (
N->isStrictFPOpcode()) {
4949 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4957 DAG.getTargetConstant(
4958 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4965 assert(
N->getValueType(0).isVector() &&
4966 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4967 "Operand types must be vectors");
4969 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4971 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4972 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4974 EVT VT =
N->getValueType(0);
4975 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4980 }
else if (isStrict) {
4981 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4982 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4983 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4984 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4987 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4989 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4990 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4991 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4992 std::tie(EVLLo, EVLHi) =
4993 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4994 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4995 N->getOperand(2), MaskLo, EVLLo);
4996 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4997 N->getOperand(2), MaskHi, EVLHi);
5005 EVT OpVT =
N->getOperand(0).getValueType();
5008 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5014 EVT ResVT =
N->getValueType(0);
5017 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5018 EVT InVT =
Lo.getValueType();
5023 if (
N->isStrictFPOpcode()) {
5024 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5025 {N->getOperand(0), Lo, N->getOperand(2)});
5026 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5027 {N->getOperand(0), Hi, N->getOperand(2)});
5031 Lo.getValue(1),
Hi.getValue(1));
5032 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5033 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
5034 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
5035 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
5036 std::tie(EVLLo, EVLHi) =
5037 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
5038 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
5039 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
5041 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5042 N->getOperand(2),
N->getOperand(3));
5043 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5044 N->getOperand(2),
N->getOperand(3));
5046 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5047 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5058SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5061 EVT LHSLoVT, LHSHiVT;
5062 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5064 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5065 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5068 std::tie(LHSLo, LHSHi) =
5069 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5072 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5075 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5081 LLVMContext &Ctxt = *DAG.getContext();
5084 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5085 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5086 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5088 EVT ResVT =
N->getValueType(0);
5093 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5094 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5100 EVT ResVT =
N->getValueType(0);
5103 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5104 EVT InVT =
Lo.getValueType();
5110 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5111 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5118 EVT ResVT =
N->getValueType(0);
5122 GetSplitVector(VecOp,
Lo,
Hi);
5128 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5130 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5132 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5133 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5138 EVT ResVT =
N->getValueType(0);
5142 GetSplitVector(VecOp,
Lo,
Hi);
5144 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5145 auto [EVLLo, EVLHi] =
5147 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5153 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5155 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5156 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5159SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5170 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5171 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5172 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5173 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5174 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5175 OpsLo, MMO, IndexType);
5176 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5177 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5181SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5184 "Accumulator should already be a legal type, and shouldn't need "
5185 "further splitting");
5188 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5189 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5190 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5191 unsigned Opcode =
N->getOpcode();
5194 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5195 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5202void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5203 unsigned WidenResNo) {
5204 unsigned NumResults =
N->getNumValues();
5205 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5206 if (ResNo == WidenResNo)
5208 EVT ResVT =
N->getValueType(ResNo);
5214 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5215 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5220void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5221 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5224 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5229 auto unrollExpandedOp = [&]() {
5234 EVT VT =
N->getValueType(0);
5235 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5236 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5237 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5239 if (
N->getNumValues() > 1)
5240 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5246 switch (
N->getOpcode()) {
5249 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5257 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5261 Res = WidenVecRes_ADDRSPACECAST(
N);
5268 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5275 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5279 Res = WidenVecRes_ScalarOp(
N);
5284 case ISD::VP_SELECT:
5286 Res = WidenVecRes_Select(
N);
5290 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5292 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5299 case ISD::VP_LOAD_FF:
5302 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5306 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5314 case ISD::VP_GATHER:
5318 Res = WidenVecRes_VECTOR_REVERSE(
N);
5321 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5324 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5334 case ISD::OR:
case ISD::VP_OR:
5347 case ISD::VP_FMINNUM:
5350 case ISD::VP_FMAXNUM:
5352 case ISD::VP_FMINIMUM:
5354 case ISD::VP_FMAXIMUM:
5387 case ISD::VP_FCOPYSIGN:
5388 Res = WidenVecRes_Binary(
N);
5395 Res = WidenVecRes_MaskedBinary(
N);
5400 Res = WidenVecRes_CMP(
N);
5406 if (unrollExpandedOp())
5421 Res = WidenVecRes_BinaryCanTrap(
N);
5430 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5433#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5434 case ISD::STRICT_##DAGN:
5435#include "llvm/IR/ConstrainedOps.def"
5436 Res = WidenVecRes_StrictFP(
N);
5445 Res = WidenVecRes_OverflowOp(
N, ResNo);
5449 Res = WidenVecRes_FCOPYSIGN(
N);
5454 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5459 if (!unrollExpandedOp())
5460 Res = WidenVecRes_ExpOp(
N);
5466 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5471 case ISD::VP_FP_EXTEND:
5473 case ISD::VP_FP_ROUND:
5475 case ISD::VP_FP_TO_SINT:
5477 case ISD::VP_FP_TO_UINT:
5479 case ISD::VP_SIGN_EXTEND:
5481 case ISD::VP_SINT_TO_FP:
5482 case ISD::VP_TRUNCATE:
5485 case ISD::VP_UINT_TO_FP:
5487 case ISD::VP_ZERO_EXTEND:
5490 Res = WidenVecRes_Convert(
N);
5495 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5501 case ISD::VP_LLRINT:
5504 Res = WidenVecRes_XROUND(
N);
5530 if (unrollExpandedOp())
5541 case ISD::VP_BITREVERSE:
5547 case ISD::VP_CTLZ_ZERO_POISON:
5553 case ISD::VP_CTTZ_ZERO_POISON:
5558 case ISD::VP_FFLOOR:
5560 case ISD::VP_FNEARBYINT:
5561 case ISD::VP_FROUND:
5562 case ISD::VP_FROUNDEVEN:
5563 case ISD::VP_FROUNDTOZERO:
5568 Res = WidenVecRes_Unary(
N);
5575 Res = WidenVecRes_Ternary(
N);
5581 if (!unrollExpandedOp())
5582 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5589 SetWidenedVector(
SDValue(
N, ResNo), Res);
5595 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5596 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5597 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5598 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5599 if (
N->getNumOperands() == 3)
5600 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5602 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5603 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5607 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5608 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5614 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5615 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5616 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5617 if (
N->getNumOperands() == 2)
5618 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5621 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5622 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5626 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5627 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5632 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5633 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5634 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5637 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5638 Mask = ModifyToType(Mask, WideMaskVT,
true);
5639 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5644 LLVMContext &Ctxt = *DAG.getContext();
5649 EVT OpVT =
LHS.getValueType();
5651 LHS = GetWidenedVector(
LHS);
5652 RHS = GetWidenedVector(
RHS);
5653 OpVT =
LHS.getValueType();
5656 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5659 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5665SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5668 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5669 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5670 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5672 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5681 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5684 if (ConcatEnd == 1) {
5685 VT = ConcatOps[0].getValueType();
5687 return ConcatOps[0];
5690 SDLoc dl(ConcatOps[0]);
5697 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5698 int Idx = ConcatEnd - 1;
5699 VT = ConcatOps[Idx--].getValueType();
5700 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5713 unsigned NumToInsert = ConcatEnd - Idx - 1;
5714 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5716 ConcatOps[Idx+1] = VecOp;
5717 ConcatEnd = Idx + 2;
5723 unsigned RealVals = ConcatEnd - Idx - 1;
5724 unsigned SubConcatEnd = 0;
5725 unsigned SubConcatIdx = Idx + 1;
5726 while (SubConcatEnd < RealVals)
5727 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5728 while (SubConcatEnd < OpsToConcat)
5729 SubConcatOps[SubConcatEnd++] = undefVec;
5731 NextVT, SubConcatOps);
5732 ConcatEnd = SubConcatIdx + 1;
5737 if (ConcatEnd == 1) {
5738 VT = ConcatOps[0].getValueType();
5740 return ConcatOps[0];
5745 if (
NumOps != ConcatEnd ) {
5747 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5748 ConcatOps[j] = UndefVal;
5756 unsigned Opcode =
N->getOpcode();
5758 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5762 const SDNodeFlags
Flags =
N->getFlags();
5763 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5764 NumElts = NumElts / 2;
5768 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5770 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5771 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5772 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5780 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5783 TLI.isTypeLegal(WideMaskVT)) {
5784 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5785 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5786 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5788 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5789 N->getValueType(0).getVectorElementCount());
5790 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5804 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5805 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5806 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5809 unsigned ConcatEnd = 0;
5817 while (CurNumElts != 0) {
5818 while (CurNumElts >= NumElts) {
5819 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5820 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5821 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5823 CurNumElts -= NumElts;
5826 NumElts = NumElts / 2;
5828 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5831 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5832 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5833 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5834 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5845 switch (
N->getOpcode()) {
5848 return WidenVecRes_STRICT_FSETCC(
N);
5855 return WidenVecRes_Convert_StrictFP(
N);
5862 unsigned Opcode =
N->getOpcode();
5864 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5868 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5869 NumElts = NumElts / 2;
5880 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5884 unsigned ConcatEnd = 0;
5891 for (
unsigned i = 1; i < NumOpers; ++i) {
5897 Oper = GetWidenedVector(Oper);
5903 DAG.getPOISON(WideOpVT), Oper,
5904 DAG.getVectorIdxConstant(0, dl));
5916 while (CurNumElts != 0) {
5917 while (CurNumElts >= NumElts) {
5920 for (
unsigned i = 0; i < NumOpers; ++i) {
5923 EVT OpVT =
Op.getValueType();
5928 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5934 EVT OperVT[] = {VT, MVT::Other};
5936 ConcatOps[ConcatEnd++] = Oper;
5939 CurNumElts -= NumElts;
5942 NumElts = NumElts / 2;
5944 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5947 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5950 for (
unsigned i = 0; i < NumOpers; ++i) {
5953 EVT OpVT =
Op.getValueType();
5961 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5963 ConcatOps[ConcatEnd++] = Oper;
5972 if (Chains.
size() == 1)
5973 NewChain = Chains[0];
5976 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5981SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5983 EVT ResVT =
N->getValueType(0);
5984 EVT OvVT =
N->getValueType(1);
5985 EVT WideResVT, WideOvVT;
5990 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5995 WideLHS = GetWidenedVector(
N->getOperand(0));
5996 WideRHS = GetWidenedVector(
N->getOperand(1));
5998 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6007 N->getOperand(0), Zero);
6009 N->getOperand(1), Zero);
6012 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6013 SDNode *WideNode = DAG.getNode(
6014 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6017 unsigned OtherNo = 1 - ResNo;
6018 EVT OtherVT =
N->getValueType(OtherNo);
6025 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
6028 return SDValue(WideNode, ResNo);
6032 LLVMContext &Ctx = *DAG.getContext();
6036 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6041 unsigned Opcode =
N->getOpcode();
6042 const SDNodeFlags
Flags =
N->getFlags();
6048 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6050 InOp = ZExtPromotedInteger(InOp);
6062 if (
N->getNumOperands() == 1)
6063 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6065 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6066 N->getOperand(3), Flags);
6067 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6071 InOp = GetWidenedVector(
N->getOperand(0));
6074 if (InVTEC == WidenEC) {
6075 if (
N->getNumOperands() == 3 &&
N->isVPOpcode()) {
6078 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
6080 return MakeConvertNode(WidenVT, InOp);
6106 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6110 if (TLI.isTypeLegal(InWidenVT)) {
6118 unsigned NumConcat =
6123 return MakeConvertNode(WidenVT, InVec);
6127 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6129 return MakeConvertNode(WidenVT, InVal);
6138 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6139 for (
unsigned i=0; i < MinElts; ++i) {
6140 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6141 Ops[i] = MakeConvertNode(EltVT, Val);
6144 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6149 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6153 EVT SrcVT = Src.getValueType();
6157 Src = GetWidenedVector(Src);
6158 SrcVT = Src.getValueType();
6165 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6170 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6174 EVT SrcVT = Src.getValueType();
6178 Src = GetWidenedVector(Src);
6179 SrcVT = Src.getValueType();
6186 if (
N->getNumOperands() == 1)
6187 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6189 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6190 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6194 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6197SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6202 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6208 unsigned Opcode =
N->getOpcode();
6214 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6219 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6220 for (
unsigned i=0; i < MinElts; ++i) {
6221 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6222 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6226 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6228 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6231SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6232 unsigned Opcode =
N->getOpcode();
6236 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6245 InOp = GetWidenedVector(InOp);
6252 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6259 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6260 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6277 while (
Ops.size() != WidenNumElts)
6278 Ops.push_back(DAG.getPOISON(WidenSVT));
6280 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6286 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6287 return WidenVecRes_BinaryCanTrap(
N);
6290 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6297SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6299 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6302 SDValue Arg = GetWidenedVector(FpValue);
6303 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6308 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6309 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6311 EVT ExpVT =
RHS.getValueType();
6316 ExpOp = ModifyToType(
RHS, WideExpVT);
6319 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6324 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6325 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6326 if (
N->getNumOperands() == 1)
6327 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6329 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6330 N->getOperand(1),
N->getFlags());
6332 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6333 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6337 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6338 {InOp,
Mask,
N->getOperand(2)});
6342 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6347 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6348 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6349 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6352SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6354 EVT VT0 =
N->getValueType(0);
6355 EVT VT1 =
N->getValueType(1);
6359 "expected both results to be vectors of matching element count");
6361 LLVMContext &Ctx = *DAG.getContext();
6362 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6364 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6371 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6374 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6375 return SDValue(WidenNode, ResNo);
6378SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6379 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6380 return GetWidenedVector(WidenVec);
6384 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6385 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6388 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6389 AddrSpaceCastN->getSrcAddressSpace(),
6390 AddrSpaceCastN->getDestAddressSpace());
6396 EVT VT =
N->getValueType(0);
6397 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6400 switch (getTypeAction(InVT)) {
6414 SDValue NInOp = GetPromotedInteger(InOp);
6416 if (WidenVT.
bitsEq(NInVT)) {
6419 if (DAG.getDataLayout().isBigEndian()) {
6422 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6440 InOp = GetWidenedVector(InOp);
6442 if (WidenVT.
bitsEq(InVT))
6452 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6457 unsigned NewNumParts = WidenSize / InSize;
6470 EVT OrigInVT =
N->getOperand(0).getValueType();
6475 if (TLI.isTypeLegal(NewInVT)) {
6483 if (WidenSize % InSize == 0) {
6490 DAG.ExtractVectorElements(InOp,
Ops);
6491 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6503 return CreateStackStoreLoad(InOp, WidenVT);
6506SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6508 N->getOpcode(), SDLoc(
N),
6509 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6510 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6516 EVT VT =
N->getValueType(0);
6520 EVT EltVT =
N->getOperand(0).getValueType();
6523 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6527 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6528 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6530 return DAG.getBuildVector(WidenVT, dl, NewOps);
6534 EVT InVT =
N->getOperand(0).getValueType();
6535 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6537 unsigned NumOperands =
N->getNumOperands();
6539 bool InputWidened =
false;
6543 if (WidenNumElts % NumInElts == 0) {
6545 unsigned NumConcat = WidenNumElts / NumInElts;
6546 SDValue UndefVal = DAG.getPOISON(InVT);
6548 for (
unsigned i=0; i < NumOperands; ++i)
6549 Ops[i] =
N->getOperand(i);
6550 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6555 InputWidened =
true;
6556 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6559 for (i=1; i < NumOperands; ++i)
6560 if (!
N->getOperand(i).isUndef())
6563 if (i == NumOperands)
6566 return GetWidenedVector(
N->getOperand(0));
6568 if (NumOperands == 2) {
6570 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6575 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6576 for (
unsigned i = 0; i < NumInElts; ++i) {
6578 MaskOps[i + NumInElts] = i + WidenNumElts;
6580 return DAG.getVectorShuffle(WidenVT, dl,
6581 GetWidenedVector(
N->getOperand(0)),
6582 GetWidenedVector(
N->getOperand(1)),
6589 "Cannot use build vectors to widen CONCAT_VECTOR result");
6597 for (
unsigned i=0; i < NumOperands; ++i) {
6600 InOp = GetWidenedVector(InOp);
6601 for (
unsigned j = 0;
j < NumInElts; ++
j)
6602 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6604 SDValue UndefVal = DAG.getPOISON(EltVT);
6605 for (; Idx < WidenNumElts; ++Idx)
6606 Ops[Idx] = UndefVal;
6607 return DAG.getBuildVector(WidenVT, dl,
Ops);
6610SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6611 EVT VT =
N->getValueType(0);
6612 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6613 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6620SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6621 EVT VT =
N->getValueType(0);
6623 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6628 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6630 InOp = GetWidenedVector(InOp);
6636 if (IdxVal == 0 && InVT == WidenVT)
6643 assert(IdxVal % VTNumElts == 0 &&
6644 "Expected Idx to be a multiple of subvector minimum vector length");
6645 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6658 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6659 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6660 "down type's element count");
6667 for (;
I < VTNumElts / GCD; ++
I)
6669 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6670 for (;
I < WidenNumElts / GCD; ++
I)
6678 Align Alignment = DAG.getReducedAlign(InVT,
false);
6680 MachineFunction &MF = DAG.getMachineFunction();
6692 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6699 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6700 return DAG.getMaskedLoad(
6701 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6709 for (i = 0; i < VTNumElts; ++i)
6710 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6712 SDValue UndefVal = DAG.getPOISON(EltVT);
6713 for (; i < WidenNumElts; ++i)
6715 return DAG.getBuildVector(WidenVT, dl,
Ops);
6721 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6726SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6727 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6730 N->getOperand(1),
N->getOperand(2));
6739 "Load width must be less than or equal to first value type width");
6748 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6765 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6776 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6777 EVT LdVT =
LD->getMemoryVT();
6786 TypeSize WidthDiff = WidenWidth - LdWidth;
6789 std::optional<EVT> FirstVT =
6790 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6797 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6800 Chain, BasePtr,
LD->getMemOperand());
6804 FirstVTWidth, dl, DAG);
6822 if (!
LD->getMemoryVT().isByteSized()) {
6824 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6826 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6835 EVT VT =
LD->getValueType(0);
6836 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6837 EVT WideMaskVT = getSetCCResultType(WideVT);
6840 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6841 TLI.isTypeLegal(WideMaskVT)) {
6844 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6848 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6849 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6861 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6863 Result = GenWidenVectorLoads(LdChain, LD);
6870 if (LdChain.
size() == 1)
6871 NewChain = LdChain[0];
6877 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6888 SDValue NewLoad = DAG.getMaskedLoad(
6889 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6890 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6891 LD->getAddressingMode(),
LD->getExtensionType());
6901 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6903 SDValue EVL =
N->getVectorLength();
6910 "Unable to widen binary VP op");
6911 Mask = GetWidenedVector(Mask);
6912 assert(
Mask.getValueType().getVectorElementCount() ==
6913 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6914 .getVectorElementCount() &&
6915 "Unable to widen vector load");
6918 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6919 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6920 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6928 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6930 SDValue EVL =
N->getVectorLength();
6936 "Unable to widen binary VP op");
6937 Mask = GetWidenedVector(Mask);
6938 assert(
Mask.getValueType().getVectorElementCount() ==
6939 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6940 .getVectorElementCount() &&
6941 "Unable to widen vector load");
6943 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6944 Mask, EVL,
N->getMemOperand());
6957 "Unable to widen VP strided load");
6958 Mask = GetWidenedVector(Mask);
6960 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6961 assert(
Mask.getValueType().getVectorElementCount() ==
6963 "Data and mask vectors should have the same number of elements");
6965 SDValue Res = DAG.getStridedLoadVP(
6966 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6967 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6968 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6969 N->isExpandingLoad());
6977SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6982 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6984 Mask.getValueType().getVectorElementType(),
6987 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6988 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6989 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6991 WideMask, WidePassthru);
6995 EVT VT =
N->getValueType(0);
6996 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6998 EVT MaskVT =
Mask.getValueType();
6999 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7008 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7009 TLI.isTypeLegal(WideMaskVT) &&
7015 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7016 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7020 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7021 N->getMemoryVT(),
N->getMemOperand());
7025 if (!
N->getPassThru()->isUndef()) {
7029 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7030 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7031 DAG.getPOISON(WidenVT), EVL);
7042 Mask = ModifyToType(Mask, WideMaskVT,
true);
7044 SDValue Res = DAG.getMaskedLoad(
7045 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7046 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7047 ExtType,
N->isExpandingLoad());
7056 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7058 EVT MaskVT =
Mask.getValueType();
7059 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7067 Mask = ModifyToType(Mask, WideMaskVT,
true);
7072 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7073 Index = ModifyToType(Index, WideIndexVT);
7079 N->getMemoryVT().getScalarType(), WideEC);
7080 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7081 WideMemVT, dl,
Ops,
N->getMemOperand(),
7082 N->getIndexType(),
N->getExtensionType());
7091 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7099 N->getMemoryVT().getScalarType(), WideEC);
7100 Mask = GetWidenedMask(Mask, WideEC);
7103 Mask,
N->getVectorLength()};
7104 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7105 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7114 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7115 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7143 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7144 return N->getOperand(OpNo).getValueType();
7152 N =
N.getOperand(0);
7154 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7155 if (!
N->getOperand(i)->isUndef())
7157 N =
N.getOperand(0);
7161 N =
N.getOperand(0);
7163 N =
N.getOperand(0);
7190 { MaskVT, MVT::Other },
Ops);
7191 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7199 LLVMContext &Ctx = *DAG.getContext();
7202 if (MaskScalarBits < ToMaskScalBits) {
7206 }
else if (MaskScalarBits > ToMaskScalBits) {
7212 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7214 "Mask should have the right element size by now.");
7217 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7219 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7222 EVT SubVT =
Mask->getValueType(0);
7228 assert((
Mask->getValueType(0) == ToMaskVT) &&
7229 "A mask of ToMaskVT should have been produced by now.");
7239 LLVMContext &Ctx = *DAG.getContext();
7250 EVT CondVT =
Cond->getValueType(0);
7254 EVT VSelVT =
N->getValueType(0);
7266 EVT FinalVT = VSelVT;
7277 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7278 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7285 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7293 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7296 EVT ToMaskVT = VSelVT;
7303 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7319 if (ScalarBits0 != ScalarBits1) {
7320 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7321 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7333 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7334 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7335 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7338 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7346 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7351 unsigned Opcode =
N->getOpcode();
7353 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7354 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7355 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7357 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7363 Cond1 = GetWidenedVector(Cond1);
7371 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7372 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7377 Cond1 = ModifyToType(Cond1, CondWidenVT);
7380 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7381 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7383 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7384 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7386 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7390 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7391 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7394 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7398 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7399 return DAG.getUNDEF(WidenVT);
7403 EVT VT =
N->getValueType(0);
7406 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7410 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7411 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7414 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7415 for (
unsigned i = 0; i != NumElts; ++i) {
7416 int Idx =
N->getMaskElt(i);
7417 if (Idx < (
int)NumElts)
7420 NewMask[i] = Idx - NumElts + WidenNumElts;
7422 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7426 EVT VT =
N->getValueType(0);
7430 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7431 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7437 unsigned IdxVal = WidenNumElts - VTNumElts;
7450 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7453 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7454 "down type's element count");
7457 for (; i < VTNumElts / GCD; ++i)
7459 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7460 for (; i < WidenNumElts / GCD; ++i)
7468 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7469 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7471 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7475SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7476 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7480void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7481 EVT VT =
N->getValueType(0);
7484 unsigned Factor =
N->getNumOperands();
7487 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7496 SDValue PackedWidenVec = DAG.getUNDEF(PackedWidenVT);
7497 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7501 PackedWidenVec = DAG.getInsertSubvector(
7502 DL, PackedWidenVec, GetWidenedVector(
Op),
7508 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7509 NewOps[Idx] = DAG.getExtractSubvector(
7510 DL, WidenVT, PackedWidenVec,
7517 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7522 assert(
N->getValueType(0).isVector() &&
7523 N->getOperand(0).getValueType().isVector() &&
7524 "Operands must be vectors");
7525 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7538 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7539 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7546 InOp1 = GetWidenedVector(InOp1);
7547 InOp2 = GetWidenedVector(InOp2);
7550 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7561 "Input not widened to expected type!");
7563 if (
N->getOpcode() == ISD::VP_SETCC) {
7566 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7567 N->getOperand(2), Mask,
N->getOperand(4));
7569 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7574 assert(
N->getValueType(0).isVector() &&
7575 N->getOperand(1).getValueType().isVector() &&
7576 "Operands must be vectors");
7577 EVT VT =
N->getValueType(0);
7578 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7588 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7593 for (
unsigned i = 0; i != NumElts; ++i) {
7594 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7595 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7597 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7598 {Chain, LHSElem, RHSElem, CC});
7599 Chains[i] = Scalars[i].getValue(1);
7600 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7601 DAG.getBoolConstant(
true, dl, EltVT, VT),
7602 DAG.getBoolConstant(
false, dl, EltVT, VT));
7606 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7608 return DAG.getBuildVector(WidenVT, dl, Scalars);
7614bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7615 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7619 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7622 switch (
N->getOpcode()) {
7625 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7633 Res = WidenVecOp_FAKE_USE(
N);
7639 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7643 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7644 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7645 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7650 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7652 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7653 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7655 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7656 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7666 Res = WidenVecOp_UnrollVectorOp(
N);
7673 Res = WidenVecOp_EXTEND(
N);
7678 Res = WidenVecOp_CMP(
N);
7696 Res = WidenVecOp_Convert(
N);
7701 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7719 Res = WidenVecOp_VECREDUCE(
N);
7723 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7725 case ISD::VP_REDUCE_FADD:
7726 case ISD::VP_REDUCE_SEQ_FADD:
7727 case ISD::VP_REDUCE_FMUL:
7728 case ISD::VP_REDUCE_SEQ_FMUL:
7729 case ISD::VP_REDUCE_ADD:
7730 case ISD::VP_REDUCE_MUL:
7731 case ISD::VP_REDUCE_AND:
7732 case ISD::VP_REDUCE_OR:
7733 case ISD::VP_REDUCE_XOR:
7734 case ISD::VP_REDUCE_SMAX:
7735 case ISD::VP_REDUCE_SMIN:
7736 case ISD::VP_REDUCE_UMAX:
7737 case ISD::VP_REDUCE_UMIN:
7738 case ISD::VP_REDUCE_FMAX:
7739 case ISD::VP_REDUCE_FMIN:
7740 case ISD::VP_REDUCE_FMAXIMUM:
7741 case ISD::VP_REDUCE_FMINIMUM:
7742 Res = WidenVecOp_VP_REDUCE(
N);
7746 Res = WidenVecOp_CttzElements(
N);
7748 case ISD::VP_CTTZ_ELTS:
7749 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7750 Res = WidenVecOp_VP_CttzElements(
N);
7753 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7758 if (!Res.
getNode())
return false;
7766 if (
N->isStrictFPOpcode())
7768 "Invalid operand expansion");
7771 "Invalid operand expansion");
7773 ReplaceValueWith(
SDValue(
N, 0), Res);
7779 EVT VT =
N->getValueType(0);
7784 "Unexpected type action");
7785 InOp = GetWidenedVector(InOp);
7788 "Input wasn't widened!");
7796 EVT FixedEltVT = FixedVT.getVectorElementType();
7797 if (TLI.isTypeLegal(FixedVT) &&
7799 FixedEltVT == InEltVT) {
7801 "Not enough elements in the fixed type for the operand!");
7803 "We can't have the same type as we started with!");
7805 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7807 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7816 return WidenVecOp_Convert(
N);
7821 switch (
N->getOpcode()) {
7836 EVT OpVT =
N->getOperand(0).getValueType();
7837 EVT ResVT =
N->getValueType(0);
7844 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7845 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7851 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7852 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7854 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7861 return DAG.UnrollVectorOp(
N);
7866 EVT ResultVT =
N->getValueType(0);
7868 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7871 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7877 {WideArg,
Test},
N->getFlags());
7883 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7885 EVT OpVT =
N->getOperand(0).getValueType();
7888 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7893 EVT VT =
N->getValueType(0);
7899 "Unexpected type action");
7900 InOp = GetWidenedVector(InOp);
7902 unsigned Opcode =
N->getOpcode();
7907 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7910 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7911 return DAG.getNode(Opcode, dl, VT,
Op);
7918 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7920 if (
N->isStrictFPOpcode()) {
7922 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7925 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7926 {
N->getOperand(0), InOp });
7931 Res = MakeConvertNode(WideVT, InOp);
7933 return DAG.getExtractSubvector(dl, VT, Res, 0);
7941 if (
N->isStrictFPOpcode()) {
7944 for (
unsigned i=0; i < NumElts; ++i) {
7945 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7946 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7950 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7952 for (
unsigned i = 0; i < NumElts; ++i) {
7953 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7954 Ops[i] = MakeConvertNode(EltVT, Elt);
7958 return DAG.getBuildVector(VT, dl,
Ops);
7962 EVT DstVT =
N->getValueType(0);
7963 SDValue Src = GetWidenedVector(
N->getOperand(0));
7964 EVT SrcVT = Src.getValueType();
7971 if (TLI.isTypeLegal(WideDstVT)) {
7973 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7976 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7980 return DAG.UnrollVectorOp(
N);
7984 EVT VT =
N->getValueType(0);
7985 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7993 if (!VT.
isVector() && VT != MVT::x86mmx &&
7997 if (TLI.isTypeLegal(NewVT)) {
7999 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8011 ElementCount NewNumElts =
8013 .divideCoefficientBy(EltSize);
8015 if (TLI.isTypeLegal(NewVT)) {
8017 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8022 return CreateStackStoreLoad(InOp, VT);
8030 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8031 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8036 EVT VT =
N->getValueType(0);
8038 EVT InVT =
N->getOperand(0).getValueType();
8043 unsigned NumOperands =
N->getNumOperands();
8044 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8046 for (i = 1; i < NumOperands; ++i)
8047 if (!
N->getOperand(i).isUndef())
8050 if (i == NumOperands)
8051 return GetWidenedVector(
N->getOperand(0));
8061 for (
unsigned i=0; i < NumOperands; ++i) {
8065 "Unexpected type action");
8066 InOp = GetWidenedVector(InOp);
8067 for (
unsigned j = 0;
j < NumInElts; ++
j)
8068 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8070 return DAG.getBuildVector(VT, dl,
Ops);
8073SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8074 EVT VT =
N->getValueType(0);
8079 SubVec = GetWidenedVector(SubVec);
8084 bool IndicesValid =
false;
8087 IndicesValid =
true;
8091 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8092 Attribute::VScaleRange);
8097 IndicesValid =
true;
8103 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8109 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8116 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8123 Align Alignment = DAG.getReducedAlign(VT,
false);
8125 MachineFunction &MF = DAG.getMachineFunction();
8138 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8146 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8147 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8152 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8157 unsigned Idx =
N->getConstantOperandVal(2);
8163 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8169SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8170 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8172 N->getValueType(0), InOp,
N->getOperand(1));
8175SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8176 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8178 N->getValueType(0), InOp,
N->getOperand(1));
8181SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8183 EVT ResVT =
N->getValueType(0);
8186 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8192 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8200 "Widened input size must be a multiple of result element size");
8203 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8205 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8206 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8214 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8215 return TLI.scalarizeVectorStore(ST, DAG);
8217 if (
ST->isTruncatingStore())
8218 return TLI.scalarizeVectorStore(ST, DAG);
8228 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8229 EVT WideMaskVT = getSetCCResultType(WideVT);
8231 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8232 TLI.isTypeLegal(WideMaskVT)) {
8235 StVal = GetWidenedVector(StVal);
8237 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8239 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8240 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8241 ST->getAddressingMode());
8245 if (GenWidenVectorStores(StChain, ST)) {
8246 if (StChain.
size() == 1)
8255 SDValue WideStVal = GetWidenedVector(StVal);
8259 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8260 ST->getOffset(), Mask,
ST->getMemoryVT(),
8261 ST->getMemOperand(),
ST->getAddressingMode(),
8262 ST->isTruncatingStore());
8269 EVT StVT =
ST->getMemoryVT();
8272 SDValue StVal = GetWidenedVector(
ST->getVal());
8277 TypeSize WidthDiff = WidenWidth - StWidth;
8283 std::optional<EVT> FirstVT =
8284 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8289 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8295 ST->getBasePtr(),
ST->getMemOperand());
8298SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8299 assert((OpNo == 1 || OpNo == 3) &&
8300 "Can widen only data or mask operand of vp_store");
8308 StVal = GetWidenedVector(StVal);
8314 "Unable to widen VP store");
8315 Mask = GetWidenedVector(Mask);
8317 Mask = GetWidenedVector(Mask);
8323 "Unable to widen VP store");
8324 StVal = GetWidenedVector(StVal);
8327 assert(
Mask.getValueType().getVectorElementCount() ==
8329 "Mask and data vectors should have the same number of elements");
8330 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8331 ST->getOffset(), Mask,
ST->getVectorLength(),
8332 ST->getMemoryVT(),
ST->getMemOperand(),
8333 ST->getAddressingMode(),
ST->isTruncatingStore(),
8334 ST->isCompressingStore());
8339 assert((OpNo == 1 || OpNo == 4) &&
8340 "Can widen only data or mask operand of vp_strided_store");
8349 "Unable to widen VP strided store");
8353 "Unable to widen VP strided store");
8355 StVal = GetWidenedVector(StVal);
8356 Mask = GetWidenedVector(Mask);
8359 Mask.getValueType().getVectorElementCount() &&
8360 "Data and mask vectors should have the same number of elements");
8362 return DAG.getStridedStoreVP(
8369SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8370 assert((OpNo == 1 || OpNo == 4) &&
8371 "Can widen only data or mask operand of mstore");
8374 EVT MaskVT =
Mask.getValueType();
8379 EVT WideVT, WideMaskVT;
8382 StVal = GetWidenedVector(StVal);
8389 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8396 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8398 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8399 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8408 Mask = ModifyToType(Mask, WideMaskVT,
true);
8411 Mask = ModifyToType(Mask, WideMaskVT,
true);
8413 StVal = ModifyToType(StVal, WideVT);
8416 assert(
Mask.getValueType().getVectorElementCount() ==
8418 "Mask and data vectors should have the same number of elements");
8425SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8426 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8428 SDValue DataOp = MG->getPassThru();
8430 SDValue Scale = MG->getScale();
8438 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8439 MG->getMemOperand(), MG->getIndexType(),
8440 MG->getExtensionType());
8446SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8455 DataOp = GetWidenedVector(DataOp);
8459 EVT IndexVT =
Index.getValueType();
8462 Index = ModifyToType(Index, WideIndexVT);
8465 EVT MaskVT =
Mask.getValueType();
8468 Mask = ModifyToType(Mask, WideMaskVT,
true);
8473 }
else if (OpNo == 4) {
8475 Index = GetWidenedVector(Index);
8481 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8486SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8495 DataOp = GetWidenedVector(DataOp);
8496 Index = GetWidenedVector(Index);
8498 Mask = GetWidenedMask(Mask, WideEC);
8501 }
else if (OpNo == 3) {
8503 Index = GetWidenedVector(Index);
8510 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8515 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8516 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8518 EVT VT =
N->getValueType(0);
8533 SVT, InOp0, InOp1,
N->getOperand(2));
8539 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8541 EVT OpVT =
N->getOperand(0).getValueType();
8544 return DAG.getNode(ExtendCode, dl, VT, CC);
8554 EVT VT =
N->getValueType(0);
8556 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8563 for (
unsigned i = 0; i != NumElts; ++i) {
8564 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8565 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8567 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8568 {Chain, LHSElem, RHSElem, CC});
8569 Chains[i] = Scalars[i].getValue(1);
8570 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8571 DAG.getBoolConstant(
true, dl, EltVT, VT),
8572 DAG.getBoolConstant(
false, dl, EltVT, VT));
8576 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8578 return DAG.getBuildVector(VT, dl, Scalars);
8602 SDValue Op = GetWidenedVector(
N->getOperand(0));
8603 EVT VT =
N->getValueType(0);
8604 EVT OrigVT =
N->getOperand(0).getValueType();
8605 EVT WideVT =
Op.getValueType();
8607 SDNodeFlags
Flags =
N->getFlags();
8609 unsigned Opc =
N->getOpcode();
8611 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8612 assert(NeutralElem &&
"Neutral element must exist");
8622 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8629 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8630 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8636 unsigned GCD = std::gcd(OrigElts, WideElts);
8639 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8640 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8641 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8642 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8645 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8646 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8648 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8657 EVT VT =
N->getValueType(0);
8659 EVT WideVT =
Op.getValueType();
8661 SDNodeFlags
Flags =
N->getFlags();
8663 unsigned Opc =
N->getOpcode();
8665 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8675 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8678 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8679 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8685 unsigned GCD = std::gcd(OrigElts, WideElts);
8688 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8689 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8690 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8691 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8694 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8695 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8697 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8701 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8704 SDValue Op = GetWidenedVector(
N->getOperand(1));
8706 Op.getValueType().getVectorElementCount());
8708 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8709 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8717 EVT VT =
N->getValueType(0);
8721 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8722 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8727 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8734 TLI.getTypeToTransformTo(*DAG.getContext(),
Source.getValueType());
8738 WideSource = GetWidenedVector(Source);
8743 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8746 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8753 EVT SrcVT =
Source.getValueType();
8757 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8758 {Source, Mask, N->getOperand(2)},
N->getFlags());
8761SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8764 EVT OrigMaskVT =
Mask.getValueType();
8765 SDValue WideMask = GetWidenedVector(Mask);
8771 if (OrigElts != WideElts) {
8772 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8774 Mask, DAG.getVectorIdxConstant(0,
DL));
8795 unsigned WidenEx = 0) {
8800 unsigned AlignInBits =
Align*8;
8802 EVT RetVT = WidenEltVT;
8807 if (Width == WidenEltWidth)
8818 (WidenWidth % MemVTWidth) == 0 &&
8820 (MemVTWidth <= Width ||
8821 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8822 if (MemVTWidth == WidenWidth)
8841 (WidenWidth % MemVTWidth) == 0 &&
8843 (MemVTWidth <= Width ||
8844 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8853 return std::nullopt;
8864 unsigned Start,
unsigned End) {
8865 SDLoc dl(LdOps[Start]);
8866 EVT LdTy = LdOps[Start].getValueType();
8874 for (
unsigned i = Start + 1; i != End; ++i) {
8875 EVT NewLdTy = LdOps[i].getValueType();
8876 if (NewLdTy != LdTy) {
8895 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8896 EVT LdVT =
LD->getMemoryVT();
8906 AAMDNodes AAInfo =
LD->getAAInfo();
8910 TypeSize WidthDiff = WidenWidth - LdWidth;
8917 std::optional<EVT> FirstVT =
8918 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8925 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8930 std::optional<EVT> NewVT = FirstVT;
8931 TypeSize RemainingWidth = LdWidth;
8932 TypeSize NewVTWidth = FirstVTWidth;
8934 RemainingWidth -= NewVTWidth;
8941 NewVTWidth = NewVT->getSizeInBits();
8947 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8948 LD->getBaseAlign(), MMOFlags, AAInfo);
8960 uint64_t ScaledOffset = 0;
8961 MachinePointerInfo MPI =
LD->getPointerInfo();
8967 for (EVT MemVT : MemVTs) {
8968 Align NewAlign = ScaledOffset == 0
8969 ?
LD->getBaseAlign()
8972 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8980 unsigned End = LdOps.
size();
8991 EVT LdTy = LdOps[i].getValueType();
8994 for (--i; i >= 0; --i) {
8995 LdTy = LdOps[i].getValueType();
9002 ConcatOps[--Idx] = LdOps[i];
9003 for (--i; i >= 0; --i) {
9004 EVT NewLdTy = LdOps[i].getValueType();
9005 if (NewLdTy != LdTy) {
9015 for (;
j != End-Idx; ++
j)
9016 WidenOps[j] = ConcatOps[Idx+j];
9018 WidenOps[j] = DAG.getPOISON(LdTy);
9025 ConcatOps[--Idx] = LdOps[i];
9030 ArrayRef(&ConcatOps[Idx], End - Idx));
9036 SDValue UndefVal = DAG.getPOISON(LdTy);
9039 for (; i != End-Idx; ++i)
9040 WidenOps[i] = ConcatOps[Idx+i];
9042 WidenOps[i] = UndefVal;
9053 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9054 EVT LdVT =
LD->getMemoryVT();
9063 AAMDNodes AAInfo =
LD->getAAInfo();
9077 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9078 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9084 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9085 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9086 LD->getBaseAlign(), MMOFlags, AAInfo);
9091 SDValue UndefVal = DAG.getPOISON(EltVT);
9092 for (; i != WidenNumElts; ++i)
9095 return DAG.getBuildVector(WidenVT, dl,
Ops);
9106 AAMDNodes AAInfo =
ST->getAAInfo();
9107 SDValue ValOp = GetWidenedVector(
ST->getValue());
9110 EVT StVT =
ST->getMemoryVT();
9118 "Mismatch between store and value types");
9122 MachinePointerInfo MPI =
ST->getPointerInfo();
9123 uint64_t ScaledOffset = 0;
9132 std::optional<EVT> NewVT =
9137 TypeSize NewVTWidth = NewVT->getSizeInBits();
9140 StWidth -= NewVTWidth;
9141 MemVTs.
back().second++;
9145 for (
const auto &Pair : MemVTs) {
9146 EVT NewVT = Pair.first;
9147 unsigned Count = Pair.second;
9153 Align NewAlign = ScaledOffset == 0
9154 ?
ST->getBaseAlign()
9156 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9157 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9173 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9174 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9175 ST->getBaseAlign(), MMOFlags, AAInfo);
9192 bool FillWithZeroes) {
9197 "input and widen element type must match");
9199 "cannot modify scalable vectors in this way");
9212 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9214 for (
unsigned i = 1; i != NumConcat; ++i)
9221 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9224 "Scalable vectors should have been handled already.");
9232 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9234 for (Idx = 0; Idx < MinNumElts; ++Idx)
9235 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9237 SDValue UndefVal = DAG.getPOISON(EltVT);
9238 for (; Idx < WidenNumElts; ++Idx)
9239 Ops[Idx] = UndefVal;
9241 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9242 if (!FillWithZeroes)
9246 "We expect to never want to FillWithZeroes for non-integral types.");
9249 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9250 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9252 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9253 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.
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 base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return 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
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue 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.
Context & getContext() const
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.
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.