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(
3653 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3654 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3656 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3658 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3662 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3667 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3668 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3670 uint64_t TrailingElts = -
Imm;
3672 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3681 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3689 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3691 DAG.getVectorIdxConstant(0,
DL));
3697void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3705 GetSplitVector(Acc, AccLo, AccHi);
3706 unsigned Opcode =
N->getOpcode();
3718 GetSplitVector(Input1, Input1Lo, Input1Hi);
3719 GetSplitVector(Input2, Input2Lo, Input2Hi);
3722 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3723 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3726void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3734 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3742void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3743 unsigned Factor =
N->getNumOperands();
3746 for (
unsigned i = 0; i != Factor; ++i) {
3748 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3750 Ops[i * 2 + 1] = OpHi;
3761 for (
unsigned i = 0; i != Factor; ++i)
3765void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3766 unsigned Factor =
N->getNumOperands();
3769 for (
unsigned i = 0; i != Factor; ++i) {
3771 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3773 Ops[i + Factor] = OpHi;
3784 for (
unsigned i = 0; i != Factor; ++i) {
3785 unsigned IdxLo = 2 * i;
3786 unsigned IdxHi = 2 * i + 1;
3787 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3788 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3800bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3805 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3808 switch (
N->getOpcode()) {
3811 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3821 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3828 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3830 case ISD::VP_TRUNCATE:
3832 Res = SplitVecOp_TruncateHelper(
N);
3835 case ISD::VP_FP_ROUND:
3839 Res = SplitVecOp_FP_ROUND(
N);
3851 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3858 case ISD::VP_SCATTER:
3862 case ISD::VP_GATHER:
3866 Res = SplitVecOp_VSELECT(
N, OpNo);
3869 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3875 case ISD::VP_SINT_TO_FP:
3876 case ISD::VP_UINT_TO_FP:
3877 if (
N->getValueType(0).bitsLT(
3878 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3879 Res = SplitVecOp_TruncateHelper(
N);
3881 Res = SplitVecOp_UnaryOp(
N);
3885 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3889 case ISD::VP_FP_TO_SINT:
3890 case ISD::VP_FP_TO_UINT:
3903 Res = SplitVecOp_UnaryOp(
N);
3906 Res = SplitVecOp_FPOpDifferentTypes(
N);
3911 Res = SplitVecOp_CMP(
N);
3915 Res = SplitVecOp_FAKE_USE(
N);
3920 Res = SplitVecOp_ExtVecInRegOp(
N);
3938 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3942 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3944 case ISD::VP_REDUCE_FADD:
3945 case ISD::VP_REDUCE_SEQ_FADD:
3946 case ISD::VP_REDUCE_FMUL:
3947 case ISD::VP_REDUCE_SEQ_FMUL:
3948 case ISD::VP_REDUCE_ADD:
3949 case ISD::VP_REDUCE_MUL:
3950 case ISD::VP_REDUCE_AND:
3951 case ISD::VP_REDUCE_OR:
3952 case ISD::VP_REDUCE_XOR:
3953 case ISD::VP_REDUCE_SMAX:
3954 case ISD::VP_REDUCE_SMIN:
3955 case ISD::VP_REDUCE_UMAX:
3956 case ISD::VP_REDUCE_UMIN:
3957 case ISD::VP_REDUCE_FMAX:
3958 case ISD::VP_REDUCE_FMIN:
3959 case ISD::VP_REDUCE_FMAXIMUM:
3960 case ISD::VP_REDUCE_FMINIMUM:
3961 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3965 Res = SplitVecOp_CttzElts(
N);
3967 case ISD::VP_CTTZ_ELTS:
3968 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3969 Res = SplitVecOp_VP_CttzElements(
N);
3972 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3978 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3983 if (!Res.
getNode())
return false;
3990 if (
N->isStrictFPOpcode())
3992 "Invalid operand expansion");
3995 "Invalid operand expansion");
3997 ReplaceValueWith(
SDValue(
N, 0), Res);
4001SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4005 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4007 EVT VT =
N->getValueType(0);
4020 getSetCCResultType(MVT::i1), MVT::i1);
4025 DAG.getElementCount(
DL, VT, SplitEC)),
4029SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4032 assert(OpNo == 0 &&
"Illegal operand must be mask");
4039 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4042 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4043 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4044 "Lo and Hi have differing types");
4047 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4048 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4050 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4051 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4052 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4053 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4063SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4066 assert(OpNo == 1 &&
"Illegal operand must be mask");
4071 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4073 EVT VecVT =
N->getValueType(0);
4077SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4078 EVT ResVT =
N->getValueType(0);
4084 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4085 GetSplitVector(VecOp,
Lo,
Hi);
4087 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4092 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4093 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4097 EVT ResVT =
N->getValueType(0);
4103 SDNodeFlags
Flags =
N->getFlags();
4106 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4107 GetSplitVector(VecOp,
Lo,
Hi);
4109 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4115 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4118SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4119 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4120 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4122 unsigned Opc =
N->getOpcode();
4123 EVT ResVT =
N->getValueType(0);
4129 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4130 GetSplitVector(VecOp,
Lo,
Hi);
4133 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4136 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4138 const SDNodeFlags
Flags =
N->getFlags();
4142 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4147 EVT ResVT =
N->getValueType(0);
4150 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4151 EVT InVT =
Lo.getValueType();
4156 if (
N->isStrictFPOpcode()) {
4157 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4158 {N->getOperand(0), Lo});
4159 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4160 {N->getOperand(0), Hi});
4169 ReplaceValueWith(
SDValue(
N, 1), Ch);
4170 }
else if (
N->getNumOperands() == 3) {
4171 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4172 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4173 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4174 std::tie(EVLLo, EVLHi) =
4175 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4176 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4177 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4179 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4180 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4189 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4199 EVT ResVT =
N->getValueType(0);
4201 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4205 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4211 Lo = BitConvertToInteger(
Lo);
4212 Hi = BitConvertToInteger(
Hi);
4214 if (DAG.getDataLayout().isBigEndian())
4222 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4224 EVT ResVT =
N->getValueType(0);
4232 GetSplitVector(SubVec,
Lo,
Hi);
4241 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4243 return SecondInsertion;
4246SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4253 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4255 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4257 ElementCount IdxVal =
4261 EVT SrcVT =
N->getOperand(0).getValueType();
4280 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4281 LoEltsMin - IdxValMin);
4282 DAG.ExtractVectorElements(
Hi, Elts, 0,
4285 return DAG.getBuildVector(SubVT, dl, Elts);
4289 ElementCount ExtractIdx = IdxVal - LoElts;
4291 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4294 EVT HiVT =
Hi.getValueType();
4296 "Only fixed-vector extracts are supported in this case");
4306 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4307 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4313 "Extracting scalable subvector from fixed-width unsupported");
4321 "subvector from a scalable predicate vector");
4327 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4329 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4330 auto &MF = DAG.getMachineFunction();
4334 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4338 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4341 SubVT, dl, Store, StackPtr,
4345SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4351 uint64_t IdxVal =
Index->getZExtValue();
4354 GetSplitVector(Vec,
Lo,
Hi);
4356 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4358 if (IdxVal < LoElts)
4359 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4362 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4367 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4379 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4385 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4387 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4388 auto &MF = DAG.getMachineFunction();
4391 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4395 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4399 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4401 return DAG.getExtLoad(
4412 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4420 SplitVecRes_Gather(
N,
Lo,
Hi);
4423 ReplaceValueWith(
SDValue(
N, 0), Res);
4428 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4432 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4434 SDValue EVL =
N->getVectorLength();
4436 Align Alignment =
N->getBaseAlign();
4442 GetSplitVector(
Data, DataLo, DataHi);
4444 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4449 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4452 GetSplitVector(Mask, MaskLo, MaskHi);
4454 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4457 EVT MemoryVT =
N->getMemoryVT();
4458 EVT LoMemVT, HiMemVT;
4459 bool HiIsEmpty =
false;
4460 std::tie(LoMemVT, HiMemVT) =
4461 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4465 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4468 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4473 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4474 N->getAddressingMode(),
N->isTruncatingStore(),
4475 N->isCompressingStore());
4481 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4482 N->isCompressingStore());
4484 MachinePointerInfo MPI;
4488 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4493 MMO = DAG.getMachineFunction().getMachineMemOperand(
4495 Alignment,
N->getAAInfo(),
N->getRanges());
4497 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4498 N->getAddressingMode(),
N->isTruncatingStore(),
4499 N->isCompressingStore());
4508 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4509 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4516 GetSplitVector(
Data, LoData, HiData);
4518 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4520 EVT LoMemVT, HiMemVT;
4521 bool HiIsEmpty =
false;
4522 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4528 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4529 else if (getTypeAction(
Mask.getValueType()) ==
4531 GetSplitVector(Mask, LoMask, HiMask);
4533 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4536 std::tie(LoEVL, HiEVL) =
4537 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4541 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4542 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4543 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4554 EVT PtrVT =
N->getBasePtr().getValueType();
4557 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4560 Align Alignment =
N->getBaseAlign();
4565 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4566 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4568 Alignment,
N->getAAInfo(),
N->getRanges());
4571 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4572 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4573 N->isCompressingStore());
4582 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4586 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4589 Align Alignment =
N->getBaseAlign();
4595 GetSplitVector(
Data, DataLo, DataHi);
4597 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4602 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4605 GetSplitVector(Mask, MaskLo, MaskHi);
4607 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4610 EVT MemoryVT =
N->getMemoryVT();
4611 EVT LoMemVT, HiMemVT;
4612 bool HiIsEmpty =
false;
4613 std::tie(LoMemVT, HiMemVT) =
4614 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4617 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4622 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4623 N->getAddressingMode(),
N->isTruncatingStore(),
4624 N->isCompressingStore());
4632 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4633 N->isCompressingStore());
4635 MachinePointerInfo MPI;
4639 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4644 MMO = DAG.getMachineFunction().getMachineMemOperand(
4646 Alignment,
N->getAAInfo(),
N->getRanges());
4648 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4649 N->getAddressingMode(),
N->isTruncatingStore(),
4650 N->isCompressingStore());
4663 EVT MemoryVT =
N->getMemoryVT();
4664 Align Alignment =
N->getBaseAlign();
4671 }
Ops = [&]() -> Operands {
4673 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4677 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4682 EVT LoMemVT, HiMemVT;
4683 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4688 GetSplitVector(
Ops.Data, DataLo, DataHi);
4690 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4695 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4697 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4701 if (getTypeAction(
Ops.Index.getValueType()) ==
4703 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4705 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4709 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4711 Alignment,
N->getAAInfo(),
N->getRanges());
4714 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4716 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4717 MSC->getIndexType(), MSC->isTruncatingStore());
4722 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4723 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4724 MMO, MSC->getIndexType(),
4725 MSC->isTruncatingStore());
4729 std::tie(EVLLo, EVLHi) =
4730 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4732 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4733 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4734 VPSC->getIndexType());
4739 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4740 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4741 VPSC->getIndexType());
4745 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4746 assert(OpNo == 1 &&
"Can only split the stored value");
4749 bool isTruncating =
N->isTruncatingStore();
4752 EVT MemoryVT =
N->getMemoryVT();
4753 Align Alignment =
N->getBaseAlign();
4755 AAMDNodes AAInfo =
N->getAAInfo();
4757 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4759 EVT LoMemVT, HiMemVT;
4760 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4764 return TLI.scalarizeVectorStore(
N, DAG);
4767 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4768 Alignment, MMOFlags, AAInfo);
4770 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4773 MachinePointerInfo MPI;
4774 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4777 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4778 HiMemVT, Alignment, MMOFlags, AAInfo);
4780 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4787 LLVMContext &Ctx = *DAG.getContext();
4805 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4806 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4810 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4813 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4814 DAG.getBitcast(MemVecVT, Wide), 0);
4816 N->getBasePtr(),
N->getMemOperand());
4824 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4826 N->getBasePtr(),
N->getMemOperand());
4840 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4846 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4867 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4868 SDValue InVec =
N->getOperand(OpNo);
4870 EVT OutVT =
N->getValueType(0);
4878 EVT LoOutVT, HiOutVT;
4879 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4880 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4885 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4887 return SplitVecOp_UnaryOp(
N);
4896 return SplitVecOp_UnaryOp(
N);
4900 GetSplitVector(InVec, InLoVec, InHiVec);
4906 EVT HalfElementVT = IsFloat ?
4908 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4915 if (
N->isStrictFPOpcode()) {
4916 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4917 {N->getOperand(0), InLoVec});
4918 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4919 {N->getOperand(0), InHiVec});
4925 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4926 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4930 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4938 if (
N->isStrictFPOpcode()) {
4942 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4950 DAG.getTargetConstant(
4951 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4958 assert(
N->getValueType(0).isVector() &&
4959 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4960 "Operand types must be vectors");
4962 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4964 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4965 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4967 EVT VT =
N->getValueType(0);
4968 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4973 }
else if (isStrict) {
4974 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4975 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4976 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4977 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4980 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4982 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4983 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4984 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4985 std::tie(EVLLo, EVLHi) =
4986 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4987 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4988 N->getOperand(2), MaskLo, EVLLo);
4989 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4990 N->getOperand(2), MaskHi, EVLHi);
4998 EVT OpVT =
N->getOperand(0).getValueType();
5001 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5007 EVT ResVT =
N->getValueType(0);
5010 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5011 EVT InVT =
Lo.getValueType();
5016 if (
N->isStrictFPOpcode()) {
5017 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5018 {N->getOperand(0), Lo, N->getOperand(2)});
5019 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5020 {N->getOperand(0), Hi, N->getOperand(2)});
5024 Lo.getValue(1),
Hi.getValue(1));
5025 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5026 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
5027 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
5028 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
5029 std::tie(EVLLo, EVLHi) =
5030 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
5031 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
5032 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
5034 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5035 N->getOperand(2),
N->getOperand(3));
5036 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5037 N->getOperand(2),
N->getOperand(3));
5039 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5040 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5051SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5054 EVT LHSLoVT, LHSHiVT;
5055 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5057 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5058 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5061 std::tie(LHSLo, LHSHi) =
5062 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5065 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5068 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5074 LLVMContext &Ctxt = *DAG.getContext();
5077 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5078 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5079 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5081 EVT ResVT =
N->getValueType(0);
5086 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5087 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5093 EVT ResVT =
N->getValueType(0);
5096 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5097 EVT InVT =
Lo.getValueType();
5103 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5104 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5111 EVT ResVT =
N->getValueType(0);
5115 GetSplitVector(VecOp,
Lo,
Hi);
5121 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5123 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5125 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5126 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5131 EVT ResVT =
N->getValueType(0);
5135 GetSplitVector(VecOp,
Lo,
Hi);
5137 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5138 auto [EVLLo, EVLHi] =
5140 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5146 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5148 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5149 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5152SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5163 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5164 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5165 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5166 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5167 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5168 OpsLo, MMO, IndexType);
5169 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5170 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5174SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5177 "Accumulator should already be a legal type, and shouldn't need "
5178 "further splitting");
5181 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5182 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5183 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5184 unsigned Opcode =
N->getOpcode();
5187 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5188 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5195void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5196 unsigned WidenResNo) {
5197 unsigned NumResults =
N->getNumValues();
5198 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5199 if (ResNo == WidenResNo)
5201 EVT ResVT =
N->getValueType(ResNo);
5207 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5208 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5213void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5214 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5217 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5222 auto unrollExpandedOp = [&]() {
5227 EVT VT =
N->getValueType(0);
5228 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5229 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5230 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5232 if (
N->getNumValues() > 1)
5233 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5239 switch (
N->getOpcode()) {
5242 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5250 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5254 Res = WidenVecRes_ADDRSPACECAST(
N);
5261 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5268 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5272 Res = WidenVecRes_ScalarOp(
N);
5277 case ISD::VP_SELECT:
5279 Res = WidenVecRes_Select(
N);
5283 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5285 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5292 case ISD::VP_LOAD_FF:
5295 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5299 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5307 case ISD::VP_GATHER:
5311 Res = WidenVecRes_VECTOR_REVERSE(
N);
5314 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5324 case ISD::OR:
case ISD::VP_OR:
5337 case ISD::VP_FMINNUM:
5340 case ISD::VP_FMAXNUM:
5342 case ISD::VP_FMINIMUM:
5344 case ISD::VP_FMAXIMUM:
5377 case ISD::VP_FCOPYSIGN:
5378 Res = WidenVecRes_Binary(
N);
5385 Res = WidenVecRes_MaskedBinary(
N);
5390 Res = WidenVecRes_CMP(
N);
5396 if (unrollExpandedOp())
5411 Res = WidenVecRes_BinaryCanTrap(
N);
5420 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5423#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5424 case ISD::STRICT_##DAGN:
5425#include "llvm/IR/ConstrainedOps.def"
5426 Res = WidenVecRes_StrictFP(
N);
5435 Res = WidenVecRes_OverflowOp(
N, ResNo);
5439 Res = WidenVecRes_FCOPYSIGN(
N);
5444 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5449 if (!unrollExpandedOp())
5450 Res = WidenVecRes_ExpOp(
N);
5456 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5461 case ISD::VP_FP_EXTEND:
5463 case ISD::VP_FP_ROUND:
5465 case ISD::VP_FP_TO_SINT:
5467 case ISD::VP_FP_TO_UINT:
5469 case ISD::VP_SIGN_EXTEND:
5471 case ISD::VP_SINT_TO_FP:
5472 case ISD::VP_TRUNCATE:
5475 case ISD::VP_UINT_TO_FP:
5477 case ISD::VP_ZERO_EXTEND:
5480 Res = WidenVecRes_Convert(
N);
5485 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5491 case ISD::VP_LLRINT:
5494 Res = WidenVecRes_XROUND(
N);
5520 if (unrollExpandedOp())
5531 case ISD::VP_BITREVERSE:
5537 case ISD::VP_CTLZ_ZERO_POISON:
5543 case ISD::VP_CTTZ_ZERO_POISON:
5548 case ISD::VP_FFLOOR:
5550 case ISD::VP_FNEARBYINT:
5551 case ISD::VP_FROUND:
5552 case ISD::VP_FROUNDEVEN:
5553 case ISD::VP_FROUNDTOZERO:
5558 Res = WidenVecRes_Unary(
N);
5565 Res = WidenVecRes_Ternary(
N);
5571 if (!unrollExpandedOp())
5572 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5579 SetWidenedVector(
SDValue(
N, ResNo), Res);
5585 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5586 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5587 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5588 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5589 if (
N->getNumOperands() == 3)
5590 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5592 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5593 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5597 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5598 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5604 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5605 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5606 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5607 if (
N->getNumOperands() == 2)
5608 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5611 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5612 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5616 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5617 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5622 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5623 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5624 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5627 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5628 Mask = ModifyToType(Mask, WideMaskVT,
true);
5629 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5634 LLVMContext &Ctxt = *DAG.getContext();
5639 EVT OpVT =
LHS.getValueType();
5641 LHS = GetWidenedVector(
LHS);
5642 RHS = GetWidenedVector(
RHS);
5643 OpVT =
LHS.getValueType();
5646 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5649 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5655SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5658 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5659 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5660 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5662 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5671 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5674 if (ConcatEnd == 1) {
5675 VT = ConcatOps[0].getValueType();
5677 return ConcatOps[0];
5680 SDLoc dl(ConcatOps[0]);
5687 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5688 int Idx = ConcatEnd - 1;
5689 VT = ConcatOps[Idx--].getValueType();
5690 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5703 unsigned NumToInsert = ConcatEnd - Idx - 1;
5704 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5706 ConcatOps[Idx+1] = VecOp;
5707 ConcatEnd = Idx + 2;
5713 unsigned RealVals = ConcatEnd - Idx - 1;
5714 unsigned SubConcatEnd = 0;
5715 unsigned SubConcatIdx = Idx + 1;
5716 while (SubConcatEnd < RealVals)
5717 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5718 while (SubConcatEnd < OpsToConcat)
5719 SubConcatOps[SubConcatEnd++] = undefVec;
5721 NextVT, SubConcatOps);
5722 ConcatEnd = SubConcatIdx + 1;
5727 if (ConcatEnd == 1) {
5728 VT = ConcatOps[0].getValueType();
5730 return ConcatOps[0];
5735 if (
NumOps != ConcatEnd ) {
5737 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5738 ConcatOps[j] = UndefVal;
5746 unsigned Opcode =
N->getOpcode();
5748 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5752 const SDNodeFlags
Flags =
N->getFlags();
5753 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5754 NumElts = NumElts / 2;
5758 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5760 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5761 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5762 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5770 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5773 TLI.isTypeLegal(WideMaskVT)) {
5774 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5775 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5776 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5778 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5779 N->getValueType(0).getVectorElementCount());
5780 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5794 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5795 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5796 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5799 unsigned ConcatEnd = 0;
5807 while (CurNumElts != 0) {
5808 while (CurNumElts >= NumElts) {
5809 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5810 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5811 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5813 CurNumElts -= NumElts;
5816 NumElts = NumElts / 2;
5818 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5821 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5822 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5823 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5824 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5835 switch (
N->getOpcode()) {
5838 return WidenVecRes_STRICT_FSETCC(
N);
5845 return WidenVecRes_Convert_StrictFP(
N);
5852 unsigned Opcode =
N->getOpcode();
5854 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5858 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5859 NumElts = NumElts / 2;
5870 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5874 unsigned ConcatEnd = 0;
5881 for (
unsigned i = 1; i < NumOpers; ++i) {
5887 Oper = GetWidenedVector(Oper);
5893 DAG.getPOISON(WideOpVT), Oper,
5894 DAG.getVectorIdxConstant(0, dl));
5906 while (CurNumElts != 0) {
5907 while (CurNumElts >= NumElts) {
5910 for (
unsigned i = 0; i < NumOpers; ++i) {
5913 EVT OpVT =
Op.getValueType();
5918 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5924 EVT OperVT[] = {VT, MVT::Other};
5926 ConcatOps[ConcatEnd++] = Oper;
5929 CurNumElts -= NumElts;
5932 NumElts = NumElts / 2;
5934 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5937 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5940 for (
unsigned i = 0; i < NumOpers; ++i) {
5943 EVT OpVT =
Op.getValueType();
5951 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5953 ConcatOps[ConcatEnd++] = Oper;
5962 if (Chains.
size() == 1)
5963 NewChain = Chains[0];
5966 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5971SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5973 EVT ResVT =
N->getValueType(0);
5974 EVT OvVT =
N->getValueType(1);
5975 EVT WideResVT, WideOvVT;
5980 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5985 WideLHS = GetWidenedVector(
N->getOperand(0));
5986 WideRHS = GetWidenedVector(
N->getOperand(1));
5988 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5997 N->getOperand(0), Zero);
5999 N->getOperand(1), Zero);
6002 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6003 SDNode *WideNode = DAG.getNode(
6004 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6007 unsigned OtherNo = 1 - ResNo;
6008 EVT OtherVT =
N->getValueType(OtherNo);
6015 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
6018 return SDValue(WideNode, ResNo);
6022 LLVMContext &Ctx = *DAG.getContext();
6026 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6031 unsigned Opcode =
N->getOpcode();
6032 const SDNodeFlags
Flags =
N->getFlags();
6038 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6040 InOp = ZExtPromotedInteger(InOp);
6052 if (
N->getNumOperands() == 1)
6053 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6055 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6056 N->getOperand(3), Flags);
6057 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6061 InOp = GetWidenedVector(
N->getOperand(0));
6064 if (InVTEC == WidenEC) {
6065 if (
N->getNumOperands() == 3 &&
N->isVPOpcode()) {
6068 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
6070 return MakeConvertNode(WidenVT, InOp);
6096 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6100 if (TLI.isTypeLegal(InWidenVT)) {
6108 unsigned NumConcat =
6113 return MakeConvertNode(WidenVT, InVec);
6117 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6119 return MakeConvertNode(WidenVT, InVal);
6128 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6129 for (
unsigned i=0; i < MinElts; ++i) {
6130 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6131 Ops[i] = MakeConvertNode(EltVT, Val);
6134 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6139 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6143 EVT SrcVT = Src.getValueType();
6147 Src = GetWidenedVector(Src);
6148 SrcVT = Src.getValueType();
6155 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6160 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6164 EVT SrcVT = Src.getValueType();
6168 Src = GetWidenedVector(Src);
6169 SrcVT = Src.getValueType();
6176 if (
N->getNumOperands() == 1)
6177 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6179 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6180 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6184 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6187SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6192 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6198 unsigned Opcode =
N->getOpcode();
6204 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6209 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6210 for (
unsigned i=0; i < MinElts; ++i) {
6211 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6212 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6216 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6218 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6221SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6222 unsigned Opcode =
N->getOpcode();
6226 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6235 InOp = GetWidenedVector(InOp);
6242 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6249 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6250 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6267 while (
Ops.size() != WidenNumElts)
6268 Ops.push_back(DAG.getPOISON(WidenSVT));
6270 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6276 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6277 return WidenVecRes_BinaryCanTrap(
N);
6280 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6287SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6289 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6292 SDValue Arg = GetWidenedVector(FpValue);
6293 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6298 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6299 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6301 EVT ExpVT =
RHS.getValueType();
6306 ExpOp = ModifyToType(
RHS, WideExpVT);
6309 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6314 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6315 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6316 if (
N->getNumOperands() == 1)
6317 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6319 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6320 N->getOperand(1),
N->getFlags());
6322 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6323 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6327 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6328 {InOp,
Mask,
N->getOperand(2)});
6332 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6337 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6338 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6339 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6342SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6344 EVT VT0 =
N->getValueType(0);
6345 EVT VT1 =
N->getValueType(1);
6349 "expected both results to be vectors of matching element count");
6351 LLVMContext &Ctx = *DAG.getContext();
6352 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6354 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6361 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6364 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6365 return SDValue(WidenNode, ResNo);
6368SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6369 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6370 return GetWidenedVector(WidenVec);
6374 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6375 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6378 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6379 AddrSpaceCastN->getSrcAddressSpace(),
6380 AddrSpaceCastN->getDestAddressSpace());
6386 EVT VT =
N->getValueType(0);
6387 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6390 switch (getTypeAction(InVT)) {
6404 SDValue NInOp = GetPromotedInteger(InOp);
6406 if (WidenVT.
bitsEq(NInVT)) {
6409 if (DAG.getDataLayout().isBigEndian()) {
6412 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6430 InOp = GetWidenedVector(InOp);
6432 if (WidenVT.
bitsEq(InVT))
6442 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6447 unsigned NewNumParts = WidenSize / InSize;
6460 EVT OrigInVT =
N->getOperand(0).getValueType();
6465 if (TLI.isTypeLegal(NewInVT)) {
6473 if (WidenSize % InSize == 0) {
6480 DAG.ExtractVectorElements(InOp,
Ops);
6481 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6493 return CreateStackStoreLoad(InOp, WidenVT);
6496SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6498 N->getOpcode(), SDLoc(
N),
6499 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6500 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6506 EVT VT =
N->getValueType(0);
6510 EVT EltVT =
N->getOperand(0).getValueType();
6513 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6517 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6518 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6520 return DAG.getBuildVector(WidenVT, dl, NewOps);
6524 EVT InVT =
N->getOperand(0).getValueType();
6525 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6527 unsigned NumOperands =
N->getNumOperands();
6529 bool InputWidened =
false;
6533 if (WidenNumElts % NumInElts == 0) {
6535 unsigned NumConcat = WidenNumElts / NumInElts;
6536 SDValue UndefVal = DAG.getPOISON(InVT);
6538 for (
unsigned i=0; i < NumOperands; ++i)
6539 Ops[i] =
N->getOperand(i);
6540 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6545 InputWidened =
true;
6546 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6549 for (i=1; i < NumOperands; ++i)
6550 if (!
N->getOperand(i).isUndef())
6553 if (i == NumOperands)
6556 return GetWidenedVector(
N->getOperand(0));
6558 if (NumOperands == 2) {
6560 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6565 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6566 for (
unsigned i = 0; i < NumInElts; ++i) {
6568 MaskOps[i + NumInElts] = i + WidenNumElts;
6570 return DAG.getVectorShuffle(WidenVT, dl,
6571 GetWidenedVector(
N->getOperand(0)),
6572 GetWidenedVector(
N->getOperand(1)),
6579 "Cannot use build vectors to widen CONCAT_VECTOR result");
6587 for (
unsigned i=0; i < NumOperands; ++i) {
6590 InOp = GetWidenedVector(InOp);
6591 for (
unsigned j = 0;
j < NumInElts; ++
j)
6592 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6594 SDValue UndefVal = DAG.getPOISON(EltVT);
6595 for (; Idx < WidenNumElts; ++Idx)
6596 Ops[Idx] = UndefVal;
6597 return DAG.getBuildVector(WidenVT, dl,
Ops);
6600SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6601 EVT VT =
N->getValueType(0);
6602 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6603 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6610SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6611 EVT VT =
N->getValueType(0);
6613 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6618 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6620 InOp = GetWidenedVector(InOp);
6626 if (IdxVal == 0 && InVT == WidenVT)
6633 assert(IdxVal % VTNumElts == 0 &&
6634 "Expected Idx to be a multiple of subvector minimum vector length");
6635 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6648 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6649 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6650 "down type's element count");
6657 for (;
I < VTNumElts / GCD; ++
I)
6659 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6660 for (;
I < WidenNumElts / GCD; ++
I)
6668 Align Alignment = DAG.getReducedAlign(InVT,
false);
6670 MachineFunction &MF = DAG.getMachineFunction();
6682 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6689 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6690 return DAG.getMaskedLoad(
6691 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6699 for (i = 0; i < VTNumElts; ++i)
6700 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6702 SDValue UndefVal = DAG.getPOISON(EltVT);
6703 for (; i < WidenNumElts; ++i)
6705 return DAG.getBuildVector(WidenVT, dl,
Ops);
6711 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6716SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6717 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6720 N->getOperand(1),
N->getOperand(2));
6729 "Load width must be less than or equal to first value type width");
6738 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6755 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6766 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6767 EVT LdVT =
LD->getMemoryVT();
6776 TypeSize WidthDiff = WidenWidth - LdWidth;
6779 std::optional<EVT> FirstVT =
6780 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6787 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6790 Chain, BasePtr,
LD->getMemOperand());
6794 FirstVTWidth, dl, DAG);
6812 if (!
LD->getMemoryVT().isByteSized()) {
6814 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6816 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6825 EVT VT =
LD->getValueType(0);
6826 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6827 EVT WideMaskVT = getSetCCResultType(WideVT);
6830 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6831 TLI.isTypeLegal(WideMaskVT)) {
6834 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6838 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6839 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6851 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6853 Result = GenWidenVectorLoads(LdChain, LD);
6860 if (LdChain.
size() == 1)
6861 NewChain = LdChain[0];
6867 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6878 SDValue NewLoad = DAG.getMaskedLoad(
6879 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6880 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6881 LD->getAddressingMode(),
LD->getExtensionType());
6891 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6893 SDValue EVL =
N->getVectorLength();
6900 "Unable to widen binary VP op");
6901 Mask = GetWidenedVector(Mask);
6902 assert(
Mask.getValueType().getVectorElementCount() ==
6903 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6904 .getVectorElementCount() &&
6905 "Unable to widen vector load");
6908 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6909 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6910 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6918 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6920 SDValue EVL =
N->getVectorLength();
6926 "Unable to widen binary VP op");
6927 Mask = GetWidenedVector(Mask);
6928 assert(
Mask.getValueType().getVectorElementCount() ==
6929 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6930 .getVectorElementCount() &&
6931 "Unable to widen vector load");
6933 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6934 Mask, EVL,
N->getMemOperand());
6947 "Unable to widen VP strided load");
6948 Mask = GetWidenedVector(Mask);
6950 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6951 assert(
Mask.getValueType().getVectorElementCount() ==
6953 "Data and mask vectors should have the same number of elements");
6955 SDValue Res = DAG.getStridedLoadVP(
6956 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6957 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6958 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6959 N->isExpandingLoad());
6967SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6972 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6974 Mask.getValueType().getVectorElementType(),
6977 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6978 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6979 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6981 WideMask, WidePassthru);
6985 EVT VT =
N->getValueType(0);
6986 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6988 EVT MaskVT =
Mask.getValueType();
6989 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6998 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6999 TLI.isTypeLegal(WideMaskVT) &&
7005 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7006 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7010 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7011 N->getMemoryVT(),
N->getMemOperand());
7015 if (!
N->getPassThru()->isUndef()) {
7019 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7020 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7021 DAG.getPOISON(WidenVT), EVL);
7032 Mask = ModifyToType(Mask, WideMaskVT,
true);
7034 SDValue Res = DAG.getMaskedLoad(
7035 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7036 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7037 ExtType,
N->isExpandingLoad());
7046 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7048 EVT MaskVT =
Mask.getValueType();
7049 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7057 Mask = ModifyToType(Mask, WideMaskVT,
true);
7062 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7063 Index = ModifyToType(Index, WideIndexVT);
7069 N->getMemoryVT().getScalarType(), WideEC);
7070 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7071 WideMemVT, dl,
Ops,
N->getMemOperand(),
7072 N->getIndexType(),
N->getExtensionType());
7081 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7089 N->getMemoryVT().getScalarType(), WideEC);
7090 Mask = GetWidenedMask(Mask, WideEC);
7093 Mask,
N->getVectorLength()};
7094 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7095 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7104 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7105 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7133 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7134 return N->getOperand(OpNo).getValueType();
7142 N =
N.getOperand(0);
7144 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7145 if (!
N->getOperand(i)->isUndef())
7147 N =
N.getOperand(0);
7151 N =
N.getOperand(0);
7153 N =
N.getOperand(0);
7180 { MaskVT, MVT::Other },
Ops);
7181 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7189 LLVMContext &Ctx = *DAG.getContext();
7192 if (MaskScalarBits < ToMaskScalBits) {
7196 }
else if (MaskScalarBits > ToMaskScalBits) {
7202 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7204 "Mask should have the right element size by now.");
7207 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7209 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7212 EVT SubVT =
Mask->getValueType(0);
7218 assert((
Mask->getValueType(0) == ToMaskVT) &&
7219 "A mask of ToMaskVT should have been produced by now.");
7229 LLVMContext &Ctx = *DAG.getContext();
7240 EVT CondVT =
Cond->getValueType(0);
7244 EVT VSelVT =
N->getValueType(0);
7256 EVT FinalVT = VSelVT;
7267 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7268 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7275 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7283 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7286 EVT ToMaskVT = VSelVT;
7293 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7309 if (ScalarBits0 != ScalarBits1) {
7310 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7311 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7323 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7324 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7325 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7328 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7336 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7341 unsigned Opcode =
N->getOpcode();
7343 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7344 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7345 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7347 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7353 Cond1 = GetWidenedVector(Cond1);
7361 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7362 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7367 Cond1 = ModifyToType(Cond1, CondWidenVT);
7370 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7371 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7373 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7374 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7376 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7380 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7381 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7384 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7388 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7389 return DAG.getUNDEF(WidenVT);
7393 EVT VT =
N->getValueType(0);
7396 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7400 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7401 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7404 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7405 for (
unsigned i = 0; i != NumElts; ++i) {
7406 int Idx =
N->getMaskElt(i);
7407 if (Idx < (
int)NumElts)
7410 NewMask[i] = Idx - NumElts + WidenNumElts;
7412 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7416 EVT VT =
N->getValueType(0);
7420 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7421 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7427 unsigned IdxVal = WidenNumElts - VTNumElts;
7440 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7443 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7444 "down type's element count");
7447 for (; i < VTNumElts / GCD; ++i)
7449 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7450 for (; i < WidenNumElts / GCD; ++i)
7458 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7459 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7461 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7465SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7466 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7471 assert(
N->getValueType(0).isVector() &&
7472 N->getOperand(0).getValueType().isVector() &&
7473 "Operands must be vectors");
7474 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7487 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7488 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7495 InOp1 = GetWidenedVector(InOp1);
7496 InOp2 = GetWidenedVector(InOp2);
7499 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7510 "Input not widened to expected type!");
7512 if (
N->getOpcode() == ISD::VP_SETCC) {
7515 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7516 N->getOperand(2), Mask,
N->getOperand(4));
7518 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7523 assert(
N->getValueType(0).isVector() &&
7524 N->getOperand(1).getValueType().isVector() &&
7525 "Operands must be vectors");
7526 EVT VT =
N->getValueType(0);
7527 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7537 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7542 for (
unsigned i = 0; i != NumElts; ++i) {
7543 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7544 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7546 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7547 {Chain, LHSElem, RHSElem, CC});
7548 Chains[i] = Scalars[i].getValue(1);
7549 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7550 DAG.getBoolConstant(
true, dl, EltVT, VT),
7551 DAG.getBoolConstant(
false, dl, EltVT, VT));
7555 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7557 return DAG.getBuildVector(WidenVT, dl, Scalars);
7563bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7564 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7568 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7571 switch (
N->getOpcode()) {
7574 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7582 Res = WidenVecOp_FAKE_USE(
N);
7588 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7592 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7593 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7594 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7599 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7601 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7602 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7604 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7605 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7615 Res = WidenVecOp_UnrollVectorOp(
N);
7622 Res = WidenVecOp_EXTEND(
N);
7627 Res = WidenVecOp_CMP(
N);
7645 Res = WidenVecOp_Convert(
N);
7650 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7668 Res = WidenVecOp_VECREDUCE(
N);
7672 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7674 case ISD::VP_REDUCE_FADD:
7675 case ISD::VP_REDUCE_SEQ_FADD:
7676 case ISD::VP_REDUCE_FMUL:
7677 case ISD::VP_REDUCE_SEQ_FMUL:
7678 case ISD::VP_REDUCE_ADD:
7679 case ISD::VP_REDUCE_MUL:
7680 case ISD::VP_REDUCE_AND:
7681 case ISD::VP_REDUCE_OR:
7682 case ISD::VP_REDUCE_XOR:
7683 case ISD::VP_REDUCE_SMAX:
7684 case ISD::VP_REDUCE_SMIN:
7685 case ISD::VP_REDUCE_UMAX:
7686 case ISD::VP_REDUCE_UMIN:
7687 case ISD::VP_REDUCE_FMAX:
7688 case ISD::VP_REDUCE_FMIN:
7689 case ISD::VP_REDUCE_FMAXIMUM:
7690 case ISD::VP_REDUCE_FMINIMUM:
7691 Res = WidenVecOp_VP_REDUCE(
N);
7693 case ISD::VP_CTTZ_ELTS:
7694 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7695 Res = WidenVecOp_VP_CttzElements(
N);
7698 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7703 if (!Res.
getNode())
return false;
7711 if (
N->isStrictFPOpcode())
7713 "Invalid operand expansion");
7716 "Invalid operand expansion");
7718 ReplaceValueWith(
SDValue(
N, 0), Res);
7724 EVT VT =
N->getValueType(0);
7729 "Unexpected type action");
7730 InOp = GetWidenedVector(InOp);
7733 "Input wasn't widened!");
7741 EVT FixedEltVT = FixedVT.getVectorElementType();
7742 if (TLI.isTypeLegal(FixedVT) &&
7744 FixedEltVT == InEltVT) {
7746 "Not enough elements in the fixed type for the operand!");
7748 "We can't have the same type as we started with!");
7750 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7752 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7761 return WidenVecOp_Convert(
N);
7766 switch (
N->getOpcode()) {
7781 EVT OpVT =
N->getOperand(0).getValueType();
7782 EVT ResVT =
N->getValueType(0);
7789 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7790 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7796 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7797 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7799 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7806 return DAG.UnrollVectorOp(
N);
7811 EVT ResultVT =
N->getValueType(0);
7813 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7816 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7822 {WideArg,
Test},
N->getFlags());
7828 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7830 EVT OpVT =
N->getOperand(0).getValueType();
7833 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7838 EVT VT =
N->getValueType(0);
7844 "Unexpected type action");
7845 InOp = GetWidenedVector(InOp);
7847 unsigned Opcode =
N->getOpcode();
7852 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7855 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7856 return DAG.getNode(Opcode, dl, VT,
Op);
7863 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7865 if (
N->isStrictFPOpcode()) {
7867 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7870 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7871 {
N->getOperand(0), InOp });
7876 Res = MakeConvertNode(WideVT, InOp);
7878 return DAG.getExtractSubvector(dl, VT, Res, 0);
7886 if (
N->isStrictFPOpcode()) {
7889 for (
unsigned i=0; i < NumElts; ++i) {
7890 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7891 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7895 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7897 for (
unsigned i = 0; i < NumElts; ++i) {
7898 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7899 Ops[i] = MakeConvertNode(EltVT, Elt);
7903 return DAG.getBuildVector(VT, dl,
Ops);
7907 EVT DstVT =
N->getValueType(0);
7908 SDValue Src = GetWidenedVector(
N->getOperand(0));
7909 EVT SrcVT = Src.getValueType();
7916 if (TLI.isTypeLegal(WideDstVT)) {
7918 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7921 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7925 return DAG.UnrollVectorOp(
N);
7929 EVT VT =
N->getValueType(0);
7930 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7938 if (!VT.
isVector() && VT != MVT::x86mmx &&
7942 if (TLI.isTypeLegal(NewVT)) {
7944 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7956 ElementCount NewNumElts =
7958 .divideCoefficientBy(EltSize);
7960 if (TLI.isTypeLegal(NewVT)) {
7962 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7967 return CreateStackStoreLoad(InOp, VT);
7975 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7976 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7981 EVT VT =
N->getValueType(0);
7983 EVT InVT =
N->getOperand(0).getValueType();
7988 unsigned NumOperands =
N->getNumOperands();
7989 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7991 for (i = 1; i < NumOperands; ++i)
7992 if (!
N->getOperand(i).isUndef())
7995 if (i == NumOperands)
7996 return GetWidenedVector(
N->getOperand(0));
8006 for (
unsigned i=0; i < NumOperands; ++i) {
8010 "Unexpected type action");
8011 InOp = GetWidenedVector(InOp);
8012 for (
unsigned j = 0;
j < NumInElts; ++
j)
8013 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8015 return DAG.getBuildVector(VT, dl,
Ops);
8018SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8019 EVT VT =
N->getValueType(0);
8024 SubVec = GetWidenedVector(SubVec);
8029 bool IndicesValid =
false;
8032 IndicesValid =
true;
8036 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8037 Attribute::VScaleRange);
8042 IndicesValid =
true;
8048 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8054 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8061 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8068 Align Alignment = DAG.getReducedAlign(VT,
false);
8070 MachineFunction &MF = DAG.getMachineFunction();
8083 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8091 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8092 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8097 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8102 unsigned Idx =
N->getConstantOperandVal(2);
8108 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8114SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8115 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8117 N->getValueType(0), InOp,
N->getOperand(1));
8120SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8121 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8123 N->getValueType(0), InOp,
N->getOperand(1));
8126SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8128 EVT ResVT =
N->getValueType(0);
8131 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8137 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8145 "Widened input size must be a multiple of result element size");
8148 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8150 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8151 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8159 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8160 return TLI.scalarizeVectorStore(ST, DAG);
8162 if (
ST->isTruncatingStore())
8163 return TLI.scalarizeVectorStore(ST, DAG);
8173 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8174 EVT WideMaskVT = getSetCCResultType(WideVT);
8176 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8177 TLI.isTypeLegal(WideMaskVT)) {
8180 StVal = GetWidenedVector(StVal);
8182 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8184 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8185 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8186 ST->getAddressingMode());
8190 if (GenWidenVectorStores(StChain, ST)) {
8191 if (StChain.
size() == 1)
8200 SDValue WideStVal = GetWidenedVector(StVal);
8204 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8205 ST->getOffset(), Mask,
ST->getMemoryVT(),
8206 ST->getMemOperand(),
ST->getAddressingMode(),
8207 ST->isTruncatingStore());
8214 EVT StVT =
ST->getMemoryVT();
8217 SDValue StVal = GetWidenedVector(
ST->getVal());
8222 TypeSize WidthDiff = WidenWidth - StWidth;
8228 std::optional<EVT> FirstVT =
8229 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8234 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8240 ST->getBasePtr(),
ST->getMemOperand());
8243SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8244 assert((OpNo == 1 || OpNo == 3) &&
8245 "Can widen only data or mask operand of vp_store");
8253 StVal = GetWidenedVector(StVal);
8259 "Unable to widen VP store");
8260 Mask = GetWidenedVector(Mask);
8262 Mask = GetWidenedVector(Mask);
8268 "Unable to widen VP store");
8269 StVal = GetWidenedVector(StVal);
8272 assert(
Mask.getValueType().getVectorElementCount() ==
8274 "Mask and data vectors should have the same number of elements");
8275 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8276 ST->getOffset(), Mask,
ST->getVectorLength(),
8277 ST->getMemoryVT(),
ST->getMemOperand(),
8278 ST->getAddressingMode(),
ST->isTruncatingStore(),
8279 ST->isCompressingStore());
8284 assert((OpNo == 1 || OpNo == 4) &&
8285 "Can widen only data or mask operand of vp_strided_store");
8294 "Unable to widen VP strided store");
8298 "Unable to widen VP strided store");
8300 StVal = GetWidenedVector(StVal);
8301 Mask = GetWidenedVector(Mask);
8304 Mask.getValueType().getVectorElementCount() &&
8305 "Data and mask vectors should have the same number of elements");
8307 return DAG.getStridedStoreVP(
8314SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8315 assert((OpNo == 1 || OpNo == 4) &&
8316 "Can widen only data or mask operand of mstore");
8319 EVT MaskVT =
Mask.getValueType();
8324 EVT WideVT, WideMaskVT;
8327 StVal = GetWidenedVector(StVal);
8334 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8341 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8343 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8344 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8353 Mask = ModifyToType(Mask, WideMaskVT,
true);
8356 Mask = ModifyToType(Mask, WideMaskVT,
true);
8358 StVal = ModifyToType(StVal, WideVT);
8361 assert(
Mask.getValueType().getVectorElementCount() ==
8363 "Mask and data vectors should have the same number of elements");
8370SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8371 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8373 SDValue DataOp = MG->getPassThru();
8375 SDValue Scale = MG->getScale();
8383 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8384 MG->getMemOperand(), MG->getIndexType(),
8385 MG->getExtensionType());
8391SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8400 DataOp = GetWidenedVector(DataOp);
8404 EVT IndexVT =
Index.getValueType();
8407 Index = ModifyToType(Index, WideIndexVT);
8410 EVT MaskVT =
Mask.getValueType();
8413 Mask = ModifyToType(Mask, WideMaskVT,
true);
8418 }
else if (OpNo == 4) {
8420 Index = GetWidenedVector(Index);
8426 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8431SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8440 DataOp = GetWidenedVector(DataOp);
8441 Index = GetWidenedVector(Index);
8443 Mask = GetWidenedMask(Mask, WideEC);
8446 }
else if (OpNo == 3) {
8448 Index = GetWidenedVector(Index);
8455 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8460 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8461 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8463 EVT VT =
N->getValueType(0);
8478 SVT, InOp0, InOp1,
N->getOperand(2));
8484 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8486 EVT OpVT =
N->getOperand(0).getValueType();
8489 return DAG.getNode(ExtendCode, dl, VT, CC);
8499 EVT VT =
N->getValueType(0);
8501 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8508 for (
unsigned i = 0; i != NumElts; ++i) {
8509 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8510 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8512 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8513 {Chain, LHSElem, RHSElem, CC});
8514 Chains[i] = Scalars[i].getValue(1);
8515 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8516 DAG.getBoolConstant(
true, dl, EltVT, VT),
8517 DAG.getBoolConstant(
false, dl, EltVT, VT));
8521 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8523 return DAG.getBuildVector(VT, dl, Scalars);
8547 SDValue Op = GetWidenedVector(
N->getOperand(0));
8548 EVT VT =
N->getValueType(0);
8549 EVT OrigVT =
N->getOperand(0).getValueType();
8550 EVT WideVT =
Op.getValueType();
8552 SDNodeFlags
Flags =
N->getFlags();
8554 unsigned Opc =
N->getOpcode();
8556 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8557 assert(NeutralElem &&
"Neutral element must exist");
8567 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8574 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8575 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8581 unsigned GCD = std::gcd(OrigElts, WideElts);
8584 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8585 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8586 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8587 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8590 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8591 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8593 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8602 EVT VT =
N->getValueType(0);
8604 EVT WideVT =
Op.getValueType();
8606 SDNodeFlags
Flags =
N->getFlags();
8608 unsigned Opc =
N->getOpcode();
8610 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8620 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8623 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8624 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8630 unsigned GCD = std::gcd(OrigElts, WideElts);
8633 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8634 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8635 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8636 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8639 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8640 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8642 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8646 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8649 SDValue Op = GetWidenedVector(
N->getOperand(1));
8651 Op.getValueType().getVectorElementCount());
8653 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8654 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8662 EVT VT =
N->getValueType(0);
8666 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8667 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8672 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8678 EVT SrcVT =
Source.getValueType();
8682 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8683 {Source, Mask, N->getOperand(2)},
N->getFlags());
8686SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8689 EVT OrigMaskVT =
Mask.getValueType();
8690 SDValue WideMask = GetWidenedVector(Mask);
8696 if (OrigElts != WideElts) {
8697 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8699 Mask, DAG.getVectorIdxConstant(0,
DL));
8720 unsigned WidenEx = 0) {
8725 unsigned AlignInBits =
Align*8;
8727 EVT RetVT = WidenEltVT;
8732 if (Width == WidenEltWidth)
8743 (WidenWidth % MemVTWidth) == 0 &&
8745 (MemVTWidth <= Width ||
8746 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8747 if (MemVTWidth == WidenWidth)
8766 (WidenWidth % MemVTWidth) == 0 &&
8768 (MemVTWidth <= Width ||
8769 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8778 return std::nullopt;
8789 unsigned Start,
unsigned End) {
8790 SDLoc dl(LdOps[Start]);
8791 EVT LdTy = LdOps[Start].getValueType();
8799 for (
unsigned i = Start + 1; i != End; ++i) {
8800 EVT NewLdTy = LdOps[i].getValueType();
8801 if (NewLdTy != LdTy) {
8820 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8821 EVT LdVT =
LD->getMemoryVT();
8831 AAMDNodes AAInfo =
LD->getAAInfo();
8835 TypeSize WidthDiff = WidenWidth - LdWidth;
8842 std::optional<EVT> FirstVT =
8843 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8850 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8855 std::optional<EVT> NewVT = FirstVT;
8856 TypeSize RemainingWidth = LdWidth;
8857 TypeSize NewVTWidth = FirstVTWidth;
8859 RemainingWidth -= NewVTWidth;
8866 NewVTWidth = NewVT->getSizeInBits();
8872 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8873 LD->getBaseAlign(), MMOFlags, AAInfo);
8885 uint64_t ScaledOffset = 0;
8886 MachinePointerInfo MPI =
LD->getPointerInfo();
8892 for (EVT MemVT : MemVTs) {
8893 Align NewAlign = ScaledOffset == 0
8894 ?
LD->getBaseAlign()
8897 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8905 unsigned End = LdOps.
size();
8916 EVT LdTy = LdOps[i].getValueType();
8919 for (--i; i >= 0; --i) {
8920 LdTy = LdOps[i].getValueType();
8927 ConcatOps[--Idx] = LdOps[i];
8928 for (--i; i >= 0; --i) {
8929 EVT NewLdTy = LdOps[i].getValueType();
8930 if (NewLdTy != LdTy) {
8940 for (;
j != End-Idx; ++
j)
8941 WidenOps[j] = ConcatOps[Idx+j];
8943 WidenOps[j] = DAG.getPOISON(LdTy);
8950 ConcatOps[--Idx] = LdOps[i];
8955 ArrayRef(&ConcatOps[Idx], End - Idx));
8961 SDValue UndefVal = DAG.getPOISON(LdTy);
8964 for (; i != End-Idx; ++i)
8965 WidenOps[i] = ConcatOps[Idx+i];
8967 WidenOps[i] = UndefVal;
8978 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8979 EVT LdVT =
LD->getMemoryVT();
8988 AAMDNodes AAInfo =
LD->getAAInfo();
9002 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9003 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9009 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9010 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9011 LD->getBaseAlign(), MMOFlags, AAInfo);
9016 SDValue UndefVal = DAG.getPOISON(EltVT);
9017 for (; i != WidenNumElts; ++i)
9020 return DAG.getBuildVector(WidenVT, dl,
Ops);
9031 AAMDNodes AAInfo =
ST->getAAInfo();
9032 SDValue ValOp = GetWidenedVector(
ST->getValue());
9035 EVT StVT =
ST->getMemoryVT();
9043 "Mismatch between store and value types");
9047 MachinePointerInfo MPI =
ST->getPointerInfo();
9048 uint64_t ScaledOffset = 0;
9057 std::optional<EVT> NewVT =
9062 TypeSize NewVTWidth = NewVT->getSizeInBits();
9065 StWidth -= NewVTWidth;
9066 MemVTs.
back().second++;
9070 for (
const auto &Pair : MemVTs) {
9071 EVT NewVT = Pair.first;
9072 unsigned Count = Pair.second;
9078 Align NewAlign = ScaledOffset == 0
9079 ?
ST->getBaseAlign()
9081 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9082 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9098 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9099 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9100 ST->getBaseAlign(), MMOFlags, AAInfo);
9117 bool FillWithZeroes) {
9122 "input and widen element type must match");
9124 "cannot modify scalable vectors in this way");
9137 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9139 for (
unsigned i = 1; i != NumConcat; ++i)
9146 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9149 "Scalable vectors should have been handled already.");
9157 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9159 for (Idx = 0; Idx < MinNumElts; ++Idx)
9160 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9162 SDValue UndefVal = DAG.getPOISON(EltVT);
9163 for (; Idx < WidenNumElts; ++Idx)
9164 Ops[Idx] = UndefVal;
9166 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9167 if (!FillWithZeroes)
9171 "We expect to never want to FillWithZeroes for non-integral types.");
9174 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9175 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9177 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9178 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)
static Value * getOpcode(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
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 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.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
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.