35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
47 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
50 switch (
N->getOpcode()) {
53 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
62 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
68 R = ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(
N);
73 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
76 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
82 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
117 R = ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
N);
123 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
125 R = ScalarizeVecRes_VECTOR_MATCH(
N);
128 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
134 R = ScalarizeVecRes_VecInregOp(
N);
186 R = ScalarizeVecRes_UnaryOp(
N);
189 R = ScalarizeVecRes_ADDRSPACECAST(
N);
195 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
253 R = ScalarizeVecRes_BinOp(
N);
260 R = ScalarizeVecRes_MaskedBinOp(
N);
264 R = ScalarizeVecRes_FPOp_MultiType(
N);
269 R = ScalarizeVecRes_CMP(
N);
275 R = ScalarizeVecRes_TernaryOp(
N);
278#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
279 case ISD::STRICT_##DAGN:
280#include "llvm/IR/ConstrainedOps.def"
281 R = ScalarizeVecRes_StrictFPOp(
N);
286 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
295 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
305 R = ScalarizeVecRes_FIX(
N);
311 R = ScalarizeVecRes_PartialReduction(
N);
317 SetScalarizedVector(
SDValue(
N, ResNo), R);
321 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
322 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
323 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
329 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
330 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
332 EVT MaskVT =
Mask.getValueType();
337 Mask = GetScalarizedVector(Mask);
346 DAG.getConstant(1,
DL,
LHS.getValueType()));
348 LHS.getValueType(),
LHS, Divisor);
356 if (getTypeAction(
LHS.getValueType()) ==
358 LHS = GetScalarizedVector(
LHS);
359 RHS = GetScalarizedVector(
RHS);
361 EVT VT =
LHS.getValueType().getVectorElementType();
362 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
363 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
366 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
367 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
371 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
372 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
373 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
374 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
379 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
380 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
386SDValue DAGTypeLegalizer::ScalarizeVecRes_PartialReduction(
SDNode *
N) {
387 SDValue Acc = GetScalarizedVector(
N->getOperand(0));
391 EVT InVT =
L.getValueType();
406DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
408 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
409 "Unexpected vector type!");
410 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
412 EVT VT0 =
N->getValueType(0);
413 EVT VT1 =
N->getValueType(1);
417 DAG.getNode(
N->getOpcode(), dl,
418 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
422 unsigned OtherNo = 1 - ResNo;
423 EVT OtherVT =
N->getValueType(OtherNo);
425 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
429 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
432 return SDValue(ScalarNode, ResNo);
437 unsigned NumOpers =
N->getNumOperands();
439 EVT ValueVTs[] = {VT, MVT::Other};
448 for (
unsigned i = 1; i < NumOpers; ++i) {
454 Oper = GetScalarizedVector(Oper);
463 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
464 Opers,
N->getFlags());
475 EVT ResVT =
N->getValueType(0);
476 EVT OvVT =
N->getValueType(1);
480 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
481 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
484 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
485 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
486 ScalarLHS = ElemsLHS[0];
487 ScalarRHS = ElemsRHS[0];
490 SDVTList ScalarVTs = DAG.getVTList(
492 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
493 {ScalarLHS, ScalarRHS},
N->getFlags())
497 unsigned OtherNo = 1 - ResNo;
498 EVT OtherVT =
N->getValueType(OtherNo);
500 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
504 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
507 return SDValue(ScalarNode, ResNo);
512 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
513 return GetScalarizedVector(
Op);
516SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
521 N->getValueType(0).getScalarType(), Mask,
522 DAG.getVectorIdxConstant(0,
DL));
528 Op = GetScalarizedVector(
Op);
529 EVT NewVT =
N->getValueType(0).getVectorElementType();
534SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(
SDNode *
N) {
544SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
546 N->getValueType(0).getVectorElementType(),
547 N->getOperand(0),
N->getOperand(1));
553 EVT OpVT =
Op.getValueType();
557 Op = GetScalarizedVector(
Op);
560 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
563 N->getValueType(0).getVectorElementType(),
Op,
567SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
570 EVT OpVT =
Op.getValueType();
574 Op = GetScalarizedVector(
Op);
577 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
580 N->getValueType(0).getVectorElementType(),
Op,
584SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
587 EVT OpVT =
Op.getValueType();
590 Op = GetScalarizedVector(
Op);
593 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
596 N->getValueType(0).getVectorElementType(),
Op,
597 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
600SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
601 SDValue Op = GetScalarizedVector(
N->getOperand(0));
602 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
606SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOp_MultiType(
SDNode *
N) {
608 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
610 EVT RHSVT =
RHS.getValueType();
615 RHS = GetScalarizedVector(
RHS);
619 return DAG.getNode(
N->getOpcode(),
DL,
LHS.getValueType(),
LHS,
RHS,
623SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
628 if (
Op.getValueType() != EltVT)
636 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
637 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
648 N->getOpcode(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
649 N->getChain(),
N->getBasePtr(), GetScalarizedVector(
N->getVal()),
657 assert(
N->isUnindexed() &&
"Indexed vector load?");
661 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
662 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
663 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
664 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
665 N->getMMOMetadataForSubAccess());
677 EVT OpVT =
Op.getValueType();
687 Op = GetScalarizedVector(
Op);
690 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
692 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
698 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
699 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
700 LHS, DAG.getValueType(ExtVT));
707 EVT OpVT =
Op.getValueType();
712 Op = GetScalarizedVector(
Op);
714 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
717 switch (
N->getOpcode()) {
729SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
732 EVT OpVT =
Op.getValueType();
742 Op = GetScalarizedVector(
Op);
745 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
748 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
749 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
750 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS,
751 AddrSpaceCastN->getFlags());
754SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
765DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
766 assert(
N->getNumValues() ==
N->getNumOperands() &&
767 "Expected one result per operand");
771 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
772 SetScalarizedVector(
SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
778 EVT OpVT =
Cond.getValueType();
787 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
790 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
792 TLI.getBooleanContents(
false,
false);
799 if (TLI.getBooleanContents(
false,
false) !=
800 TLI.getBooleanContents(
false,
true)) {
804 EVT OpVT =
Cond->getOperand(0).getValueType();
806 VecBool = TLI.getBooleanContents(OpVT);
811 EVT CondVT =
Cond.getValueType();
812 if (ScalarBool != VecBool) {
813 switch (ScalarBool) {
821 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
828 Cond, DAG.getValueType(MVT::i1));
834 auto BoolVT = getSetCCResultType(CondVT);
835 if (BoolVT.bitsLT(CondVT))
838 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
839 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
843 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
844 return DAG.getSelect(SDLoc(
N),
845 LHS.getValueType(),
N->getOperand(0),
LHS,
846 GetScalarizedVector(
N->getOperand(2)));
850 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
852 N->getOperand(0),
N->getOperand(1),
853 LHS, GetScalarizedVector(
N->getOperand(3)),
858 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
861SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
865 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
867 return GetScalarizedVector(
N->getOperand(
Op));
870SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
872 EVT SrcVT = Src.getValueType();
877 Src = GetScalarizedVector(Src);
881 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
883 EVT DstVT =
N->getValueType(0).getVectorElementType();
884 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
888 assert(
N->getValueType(0).isVector() &&
889 N->getOperand(0).getValueType().isVector() &&
890 "Operand types must be vectors");
893 EVT OpVT =
LHS.getValueType();
894 EVT NVT =
N->getValueType(0).getVectorElementType();
899 LHS = GetScalarizedVector(
LHS);
900 RHS = GetScalarizedVector(
RHS);
903 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
904 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
914 return DAG.getNode(ExtendCode,
DL, NVT, Res);
925 Arg = GetScalarizedVector(Arg);
928 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
937 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
944bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
950 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
953 switch (
N->getOpcode()) {
956 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
963 Res = ScalarizeVecOp_BITCAST(
N);
966 Res = ScalarizeVecOp_FAKE_USE(
N);
980 Res = ScalarizeVecOp_UnaryOp(
N);
985 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
988 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
989 "Unexpected vector type!");
990 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
992 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
993 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
1001 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
1004 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
1007 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
1010 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
1013 Res = ScalarizeVecOp_VSELECT(
N);
1016 Res = ScalarizeVecOp_VSETCC(
N);
1020 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
1035 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
1038 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
1041 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
1044 Res = ScalarizeVecOp_FP_EXTEND(
N);
1063 Res = ScalarizeVecOp_VECREDUCE(
N);
1067 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
1071 Res = ScalarizeVecOp_CMP(
N);
1074 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
1078 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
1081 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
1087 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
1092 if (!Res.
getNode())
return false;
1100 "Invalid operand expansion");
1102 ReplaceValueWith(
SDValue(
N, 0), Res);
1109 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1111 N->getValueType(0), Elt);
1116 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1117 "Fake Use: Unexpected vector type!");
1118 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1119 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1125 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1126 "Unexpected vector type!");
1127 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1128 SDValue Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1129 N->getValueType(0).getScalarType(), Elt);
1137SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1138 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1139 "Unexpected vector type!");
1140 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1142 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1143 Elt,
N->getOperand(1));
1151SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1152 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1153 "Unexpected vector type!");
1154 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1156 {
N->getValueType(0).getScalarType(), MVT::Other },
1157 {
N->getOperand(0), Elt });
1167 ReplaceValueWith(
SDValue(
N, 0), Res);
1172SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1174 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1175 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1176 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1181SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1185 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1186 SDValue ContainingVec =
N->getOperand(0);
1194SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1195 EVT VT =
N->getValueType(0);
1196 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1208 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1209 EVT VT =
N->getValueType(0);
1211 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1220 assert(
N->getValueType(0).isVector() &&
1221 N->getOperand(0).getValueType().isVector() &&
1222 "Operand types must be vectors");
1223 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1224 "Expected single-element vector type");
1226 EVT VT =
N->getValueType(0);
1227 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1228 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1230 EVT OpVT =
N->getOperand(0).getValueType();
1242 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1248SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1250 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1251 assert(
N->getValueType(0).isVector() &&
1252 N->getOperand(1).getValueType().isVector() &&
1253 "Operand types must be vectors");
1254 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1255 "Expected single-element vector type");
1257 EVT VT =
N->getValueType(0);
1259 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1260 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1263 EVT OpVT =
N->getOperand(1).getValueType();
1267 {Ch, LHS, RHS, CC});
1276 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1281 ReplaceValueWith(
SDValue(
N, 0), Res);
1288 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1289 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1292 if (
N->isTruncatingStore())
1293 return DAG.getTruncStore(
1294 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1295 N->getBasePtr(),
N->getPointerInfo(),
1296 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1297 N->getMemOperand()->getFlags(),
N->getMMOMetadataForSubAccess());
1299 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1300 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1301 N->getMemOperand()->getFlags(),
1302 N->getMMOMetadataForSubAccess());
1308 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1310 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1311 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1318 assert(OpNo == 3 &&
"Can only scalarize the mask operand!");
1319 EVT DataVT =
N->getValueType(0);
1320 SDValue Mask = PromoteTargetBoolean(
N->getOperand(OpNo), DataVT);
1322 NewOps[OpNo] =
Mask;
1323 SDNode *Res = DAG.UpdateNodeOperands(
N, NewOps);
1337 assert(!
N->isCompressingStore() &&
"CompressingStore not expected");
1340 EVT DataVT =
N->getValue().getValueType();
1342 NewOps[OpNo] = PromoteTargetBoolean(
N->getOperand(OpNo), DataVT);
1343 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1348SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1349 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1350 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1352 N->getValueType(0).getVectorElementType(), Elt,
1357SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1359 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1360 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1363 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1373 ReplaceValueWith(
SDValue(
N, 0), Res);
1380 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1382 N->getValueType(0).getVectorElementType(), Elt);
1388SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1389 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1392 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1393 {
N->getOperand(0), Elt});
1402 ReplaceValueWith(
SDValue(
N, 0), Res);
1407 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1414SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1420 SDValue Op = GetScalarizedVector(VecOp);
1421 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1422 AccOp,
Op,
N->getFlags());
1426 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1427 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1434SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1442 EVT VT =
N->getValueType(0);
1443 return DAG.getConstant(0, SDLoc(
N), VT);
1450 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1451 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1453 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1454 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1455 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1458SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1463 N->getValueType(0).getScalarType(), Mask,
1464 DAG.getVectorIdxConstant(0,
DL));
1469 return TLI.expandVectorMatch(
N, DAG);
1472SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1473 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1476 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1477 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1486 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1498void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1503 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1506 switch (
N->getOpcode()) {
1509 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1518 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1521 SplitVecRes_MASK_BEFOREFIRST(
N,
Lo,
Hi);
1528 case ISD::VP_MERGE: SplitRes_Select(
N,
Lo,
Hi);
break;
1544 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1547 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1559 case ISD::VP_LOAD_FF:
1562 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1569 case ISD::VP_GATHER:
1573 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1576 SplitVecRes_SETCC(
N,
Lo,
Hi);
1579 SplitVecRes_VECTOR_REPEAT(
N,
Lo,
Hi);
1582 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1589 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1592 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1595 SplitVecRes_VECTOR_INTERLEAVE(
N);
1598 SplitVecRes_VAARG(
N,
Lo,
Hi);
1604 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1658 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1661 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1667 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1673 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1729 SplitVecRes_BinOp(
N,
Lo,
Hi);
1735 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1740 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1744 SplitVecRes_CMP(
N,
Lo,
Hi);
1747#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1748 case ISD::STRICT_##DAGN:
1749#include "llvm/IR/ConstrainedOps.def"
1750 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1755 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1764 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1774 SplitVecRes_FIX(
N,
Lo,
Hi);
1776 case ISD::EXPERIMENTAL_VP_SPLICE:
1777 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1779 case ISD::EXPERIMENTAL_VP_REVERSE:
1780 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1786 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1789 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1792 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1801void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1808 SDValue BytesIncrement = DAG.getVScale(
1811 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1813 *ScaledOffset += IncrementSize;
1823std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1824 return SplitMask(Mask, SDLoc(Mask));
1827std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1830 EVT MaskVT =
Mask.getValueType();
1832 GetSplitVector(Mask, MaskLo, MaskHi);
1834 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1835 return std::make_pair(MaskLo, MaskHi);
1840 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1842 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1845 const SDNodeFlags
Flags =
N->getFlags();
1846 unsigned Opcode =
N->getOpcode();
1847 if (
N->getNumOperands() == 2) {
1848 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1849 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1853 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1854 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
1855 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
1856 "Expected VP opcode");
1859 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1862 std::tie(EVLLo, EVLHi) =
1863 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1866 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1868 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1874 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1876 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1880 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1882 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1886 const SDNodeFlags
Flags =
N->getFlags();
1887 unsigned Opcode =
N->getOpcode();
1888 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1890 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1897 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1899 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1901 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1904 const SDNodeFlags
Flags =
N->getFlags();
1905 unsigned Opcode =
N->getOpcode();
1907 DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1909 DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1913 LLVMContext &Ctxt = *DAG.getContext();
1919 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1921 GetSplitVector(
LHS, LHSLo, LHSHi);
1922 GetSplitVector(
RHS, RHSLo, RHSHi);
1924 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1925 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1929 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1930 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1935 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1937 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1941 unsigned Opcode =
N->getOpcode();
1942 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1944 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1953 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1960 switch (getTypeAction(InVT)) {
1974 GetExpandedOp(InOp,
Lo,
Hi);
1975 if (DAG.getDataLayout().isBigEndian())
1985 GetSplitVector(InOp,
Lo,
Hi);
1994 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
2003 if (DAG.getDataLayout().isBigEndian())
2006 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
2008 if (DAG.getDataLayout().isBigEndian())
2014void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
2020 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2023 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
2028 unsigned LaneOffset =
2031 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
2033 DAG.getConstant(LaneOffset,
DL, MVT::i64));
2040 GetSplitVector(
N->getOperand(0), InLo, InHi);
2047 getSetCCResultType(MVT::i1), MVT::i1);
2056 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2059 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
2062 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
2067 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
2069 unsigned NumSubvectors =
N->getNumOperands() / 2;
2070 if (NumSubvectors == 1) {
2071 Lo =
N->getOperand(0);
2072 Hi =
N->getOperand(1);
2077 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2086void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
2093 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2108 GetSplitVector(Vec,
Lo,
Hi);
2111 EVT LoVT =
Lo.getValueType();
2120 unsigned IdxVal =
Idx->getAsZExtVal();
2121 if (IdxVal + SubElems <= LoElems) {
2129 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
2131 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
2137 SDValue WideSubVec = GetWidenedVector(SubVec);
2139 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2147 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2149 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2150 auto &MF = DAG.getMachineFunction();
2154 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2159 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2160 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2164 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2169 MachinePointerInfo MPI =
Load->getPointerInfo();
2170 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2173 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2182 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2187 EVT RHSVT =
RHS.getValueType();
2190 GetSplitVector(
RHS, RHSLo, RHSHi);
2192 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2207 SDValue FpValue =
N->getOperand(0);
2209 GetSplitVector(FpValue, ArgLo, ArgHi);
2211 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2213 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2222 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2226 std::tie(LoVT, HiVT) =
2230 DAG.getValueType(LoVT));
2232 DAG.getValueType(HiVT));
2237 unsigned Opcode =
N->getOpcode();
2244 GetSplitVector(N0, InLo, InHi);
2246 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2251 EVT OutLoVT, OutHiVT;
2252 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2254 assert((2 * OutNumElements) <= InNumElements &&
2255 "Illegal extend vector in reg split");
2264 SmallVector<int, 8> SplitHi(InNumElements, -1);
2265 for (
unsigned i = 0; i != OutNumElements; ++i)
2266 SplitHi[i] = i + OutNumElements;
2267 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2269 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2270 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2275 unsigned NumOps =
N->getNumOperands();
2279 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2289 for (
unsigned i = 1; i <
NumOps; ++i) {
2294 EVT InVT =
Op.getValueType();
2299 GetSplitVector(
Op, OpLo, OpHi);
2301 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2308 EVT LoValueVTs[] = {LoVT, MVT::Other};
2309 EVT HiValueVTs[] = {HiVT, MVT::Other};
2310 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2312 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2318 Lo.getValue(1),
Hi.getValue(1));
2322 ReplaceValueWith(
SDValue(
N, 1), Chain);
2325SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2326 EVT VT =
N->getValueType(0);
2341 else if (NE > ResNE)
2345 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2349 for (i = 0; i !=
NE; ++i) {
2351 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2352 SDValue Operand =
N->getOperand(j);
2356 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2362 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2370 for (; i < ResNE; ++i)
2371 Scalars.
push_back(DAG.getPOISON(EltVT));
2375 ReplaceValueWith(
SDValue(
N, 1), Chain);
2379 return DAG.getBuildVector(VecVT, dl, Scalars);
2382void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2385 EVT ResVT =
N->getValueType(0);
2386 EVT OvVT =
N->getValueType(1);
2387 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2388 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2389 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2391 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2393 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2394 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2396 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2397 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2400 unsigned Opcode =
N->getOpcode();
2401 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2402 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2404 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2406 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2412 unsigned OtherNo = 1 - ResNo;
2413 EVT OtherVT =
N->getValueType(OtherNo);
2415 SetSplitVector(
SDValue(
N, OtherNo),
2421 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2425void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2431 GetSplitVector(Vec,
Lo,
Hi);
2434 unsigned IdxVal = CIdx->getZExtValue();
2435 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2436 if (IdxVal < LoNumElts) {
2438 Lo.getValueType(),
Lo, Elt, Idx);
2441 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2461 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2463 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2464 auto &MF = DAG.getMachineFunction();
2468 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2473 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2474 Store = DAG.getTruncStore(
2480 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2483 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2487 MachinePointerInfo MPI =
Load->getPointerInfo();
2488 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2490 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2493 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2494 if (LoVT !=
Lo.getValueType())
2496 if (HiVT !=
Hi.getValueType())
2504 assert(
N->getValueType(0).isScalableVector() &&
2505 "Only scalable vectors are supported for STEP_VECTOR");
2506 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2527 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2528 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2530 Hi = DAG.getPOISON(HiVT);
2540 "Extended load during type legalization!");
2542 EVT VT =
LD->getValueType(0);
2544 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2552 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2553 Ch, Ptr,
LD->getMemOperand());
2558 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2560 Lo = DAG.getBitcast(LoVT, ExtractLo);
2561 Hi = DAG.getBitcast(HiVT, ExtractHi);
2573 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2579 EVT MemoryVT =
LD->getMemoryVT();
2581 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
2583 EVT LoMemVT, HiMemVT;
2584 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2588 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2589 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2590 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2595 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2598 MachinePointerInfo MPI;
2599 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2602 HiMemVT,
LD->getBaseAlign(), MMOFlags,
Metadata);
2611 ReplaceValueWith(
SDValue(LD, 1), Ch);
2616 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2619 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2625 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2629 EVT MemoryVT =
LD->getMemoryVT();
2631 EVT LoMemVT, HiMemVT;
2632 bool HiIsEmpty =
false;
2633 std::tie(LoMemVT, HiMemVT) =
2634 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2639 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2642 GetSplitVector(Mask, MaskLo, MaskHi);
2644 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2649 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2651 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2654 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2657 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2658 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2666 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2667 LD->isExpandingLoad());
2669 MachinePointerInfo MPI;
2671 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2673 MPI =
LD->getPointerInfo().getWithOffset(
2676 MMO = DAG.getMachineFunction().getMachineMemOperand(
2678 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2680 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2681 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2682 LD->isExpandingLoad());
2692 ReplaceValueWith(
SDValue(LD, 1), Ch);
2698 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2709 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2712 GetSplitVector(Mask, MaskLo, MaskHi);
2714 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2718 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2720 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2723 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2725 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2728 Hi = DAG.getPOISON(HiVT);
2730 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2731 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2737 "Indexed VP strided load during type legalization!");
2739 "Unexpected indexed variable-length load offset");
2744 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2746 EVT LoMemVT, HiMemVT;
2747 bool HiIsEmpty =
false;
2748 std::tie(LoMemVT, HiMemVT) =
2749 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2754 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2757 GetSplitVector(Mask, LoMask, HiMask);
2759 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2763 std::tie(LoEVL, HiEVL) =
2767 Lo = DAG.getStridedLoadVP(
2794 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2801 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2812 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2820 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2825 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2835 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2838 GetSplitVector(Mask, MaskLo, MaskHi);
2840 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2844 EVT LoMemVT, HiMemVT;
2845 bool HiIsEmpty =
false;
2846 std::tie(LoMemVT, HiMemVT) =
2847 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2849 SDValue PassThruLo, PassThruHi;
2851 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2853 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2855 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2860 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2870 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2873 MachinePointerInfo MPI;
2880 MMO = DAG.getMachineFunction().getMachineMemOperand(
2885 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2897 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2905 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2915 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2918 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2921 EVT MemoryVT =
N->getMemoryVT();
2927 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2929 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2932 EVT LoMemVT, HiMemVT;
2934 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2937 if (getTypeAction(
Ops.Index.getValueType()) ==
2939 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2941 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2944 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2946 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2949 SDValue PassThru = MGT->getPassThru();
2950 SDValue PassThruLo, PassThruHi;
2953 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2955 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2960 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2961 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2962 OpsLo, MMO, IndexTy, ExtType);
2964 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2965 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2966 OpsHi, MMO, IndexTy, ExtType);
2970 std::tie(EVLLo, EVLHi) =
2971 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2973 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2974 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2975 MMO, VPGT->getIndexType());
2977 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2978 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2979 MMO, VPGT->getIndexType());
2989 ReplaceValueWith(
SDValue(
N, 1), Ch);
3003 EVT VecVT =
N->getValueType(0);
3005 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
3006 bool HasCustomLowering =
false;
3013 HasCustomLowering =
true;
3019 SDValue Passthru =
N->getOperand(2);
3020 if (!HasCustomLowering) {
3021 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
3022 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
3029 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3030 std::tie(LoMask, HiMask) = SplitMask(Mask);
3032 SDValue UndefPassthru = DAG.getPOISON(LoVT);
3037 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
3050 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
3052 SDValue Chain = DAG.getEntryNode();
3053 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
3057 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
3061 EVT MaskVT =
Mask.getValueType();
3068 SDValue StepVector = DAG.getStepVector(
DL, WideMaskVT);
3069 SDValue SplatNumActiveElts = DAG.getSplat(WideMaskVT,
DL, NumActiveElts);
3071 DAG.getSetCC(
DL, MaskVT, StepVector, SplatNumActiveElts,
ISD::SETULT);
3074 Compressed, Passthru);
3076 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
3080 assert(
N->getValueType(0).isVector() &&
3081 N->getOperand(0).getValueType().isVector() &&
3082 "Operand types must be vectors");
3086 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3090 if (getTypeAction(
N->getOperand(0).getValueType()) ==
3092 GetSplitVector(
N->getOperand(0), LL, LH);
3094 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
3096 if (getTypeAction(
N->getOperand(1).getValueType()) ==
3098 GetSplitVector(
N->getOperand(1), RL, RH);
3100 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
3102 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
3103 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
3111 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3115 EVT InVT =
N->getOperand(0).getValueType();
3117 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3119 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3121 const SDNodeFlags
Flags =
N->getFlags();
3122 unsigned Opcode =
N->getOpcode();
3124 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
3125 N->getOperand(3), Flags);
3126 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
3127 N->getOperand(3), Flags);
3133 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
3134 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
3136 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
3137 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
3144 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3148 EVT InVT =
N->getOperand(0).getValueType();
3150 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3152 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3155 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3156 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3157 SDNodeFlags
Flags = AddrSpaceCastN->getFlags();
3158 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS, Flags);
3159 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS, Flags);
3162void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3167 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3168 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3172 EVT InVT =
N->getOperand(0).getValueType();
3174 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3176 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3178 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3179 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3181 SDNode *HiNode =
Hi.getNode();
3182 SDNode *LoNode =
Lo.getNode();
3185 unsigned OtherNo = 1 - ResNo;
3186 EVT OtherVT =
N->getValueType(OtherNo);
3194 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3201 EVT SrcVT =
N->getOperand(0).getValueType();
3202 EVT DestVT =
N->getValueType(0);
3204 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3221 LLVMContext &Ctx = *DAG.getContext();
3225 EVT SplitLoVT, SplitHiVT;
3226 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3227 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3228 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3229 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3230 N->dump(&DAG);
dbgs() <<
"\n");
3233 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3235 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3237 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3238 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3243 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3251 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3252 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3258 return N.getResNo() == 0 &&
3262 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3264 ArrayRef<int>
Mask) {
3267 "Expected build vector node.");
3270 for (
unsigned I = 0;
I < NewElts; ++
I) {
3275 Ops[
I] = Input2.getOperand(Idx - NewElts);
3277 Ops[
I] = Input1.getOperand(Idx);
3282 return DAG.getBuildVector(NewVT,
DL,
Ops);
3288 SmallVector<int> OrigMask(
N->getMask());
3290 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3291 &
DL](SmallVectorImpl<int> &
Mask) {
3293 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3294 for (
unsigned Idx = 0;
Idx < std::size(Inputs); ++
Idx) {
3298 Input.getOperand(0).getValueType() !=
Input.getValueType())
3300 ShufflesIdxs[std::make_pair(
Input.getOperand(0),
Input.getOperand(1))]
3302 ShufflesIdxs[std::make_pair(
Input.getOperand(1),
Input.getOperand(0))]
3305 for (
auto &
P : ShufflesIdxs) {
3306 if (
P.second.size() < 2)
3310 for (
int &Idx : Mask) {
3313 unsigned SrcRegIdx =
Idx / NewElts;
3314 if (Inputs[SrcRegIdx].
isUndef()) {
3322 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3327 Idx = MaskElt % NewElts +
3328 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3334 Inputs[
P.second[0]] =
P.first.first;
3335 Inputs[
P.second[1]] =
P.first.second;
3338 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3341 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3342 for (
int &Idx : Mask) {
3345 unsigned SrcRegIdx =
Idx / NewElts;
3346 if (Inputs[SrcRegIdx].
isUndef()) {
3353 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3354 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3357 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3359 if (UsedSubVector.count() > 1) {
3361 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3362 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3364 if (Pairs.
empty() || Pairs.
back().size() == 2)
3366 if (UsedSubVector.test(2 *
I)) {
3367 Pairs.
back().emplace_back(
I, 0);
3369 assert(UsedSubVector.test(2 *
I + 1) &&
3370 "Expected to be used one of the subvectors.");
3371 Pairs.
back().emplace_back(
I, 1);
3374 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3376 for (
int &Idx : Mask) {
3379 unsigned SrcRegIdx =
Idx / NewElts;
3381 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3382 return Idxs.front().first == SrcRegIdx ||
3383 Idxs.back().first == SrcRegIdx;
3385 if (It == Pairs.
end())
3387 Idx = It->front().first * NewElts + (
Idx % NewElts) % (NewElts / 2) +
3388 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3391 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3392 Inputs[Idxs.front().first] = DAG.
getNode(
3394 Inputs[Idxs.front().first].getValueType(),
3395 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3396 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3405 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3409 if (Shuffle->getOperand(0).getValueType() != NewVT)
3412 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3413 !Shuffle->isSplat()) {
3415 }
else if (!Inputs[
I].hasOneUse() &&
3416 !Shuffle->getOperand(1).isUndef()) {
3418 for (
int &Idx : Mask) {
3421 unsigned SrcRegIdx =
Idx / NewElts;
3424 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3429 int OpIdx = MaskElt / NewElts;
3442 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3443 if (Shuffle->getOperand(OpIdx).isUndef())
3445 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3446 if (It == std::end(Inputs))
3448 int FoundOp = std::distance(std::begin(Inputs), It);
3451 for (
int &Idx : Mask) {
3454 unsigned SrcRegIdx =
Idx / NewElts;
3457 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3462 int MaskIdx = MaskElt / NewElts;
3463 if (OpIdx == MaskIdx)
3464 Idx = MaskElt % NewElts + FoundOp * NewElts;
3467 Op = (OpIdx + 1) % 2;
3475 for (
int &Idx : Mask) {
3478 unsigned SrcRegIdx =
Idx / NewElts;
3481 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3482 int OpIdx = MaskElt / NewElts;
3485 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3491 TryPeekThroughShufflesInputs(OrigMask);
3493 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3494 NewElts](SmallVectorImpl<int> &
Mask) {
3495 SetVector<SDValue> UniqueInputs;
3496 SetVector<SDValue> UniqueConstantInputs;
3497 for (
const auto &
I : Inputs) {
3499 UniqueConstantInputs.
insert(
I);
3500 else if (!
I.isUndef())
3505 if (UniqueInputs.
size() != std::size(Inputs)) {
3506 auto &&UniqueVec = UniqueInputs.
takeVector();
3507 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3508 unsigned ConstNum = UniqueConstantVec.size();
3509 for (
int &Idx : Mask) {
3512 unsigned SrcRegIdx =
Idx / NewElts;
3513 if (Inputs[SrcRegIdx].
isUndef()) {
3517 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3518 if (It != UniqueConstantVec.end()) {
3520 NewElts * std::distance(UniqueConstantVec.begin(), It);
3521 assert(Idx >= 0 &&
"Expected defined mask idx.");
3524 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3525 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3527 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3528 assert(Idx >= 0 &&
"Expected defined mask idx.");
3530 copy(UniqueConstantVec, std::begin(Inputs));
3531 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3534 MakeUniqueInputs(OrigMask);
3536 copy(Inputs, std::begin(OrigInputs));
3542 unsigned FirstMaskIdx =
High * NewElts;
3545 assert(!Output &&
"Expected default initialized initial value.");
3546 TryPeekThroughShufflesInputs(Mask);
3547 MakeUniqueInputs(Mask);
3549 copy(Inputs, std::begin(TmpInputs));
3552 bool SecondIteration =
false;
3553 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3558 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3559 SecondIteration =
true;
3560 return SecondIteration;
3563 Mask, std::size(Inputs), std::size(Inputs),
3565 [&Output, &DAG = DAG, NewVT]() {
Output = DAG.getPOISON(NewVT); },
3566 [&
Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3567 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3569 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3571 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3572 DAG.getPOISON(NewVT), Mask);
3575 [&AccumulateResults, &
Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3576 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3577 unsigned Idx2,
bool ) {
3578 if (AccumulateResults(Idx1)) {
3581 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3583 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3584 Inputs[Idx2], Mask);
3588 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3590 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3591 TmpInputs[Idx2], Mask);
3595 copy(OrigInputs, std::begin(Inputs));
3600 EVT OVT =
N->getValueType(0);
3608 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3610 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV,
Alignment.value());
3611 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV,
Alignment.value());
3616 ReplaceValueWith(
SDValue(
N, 1), Chain);
3621 EVT DstVTLo, DstVTHi;
3622 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3626 EVT SrcVT =
N->getOperand(0).getValueType();
3628 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3630 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3632 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3633 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3638 EVT VT =
N->getValueType(0);
3640 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VT);
3641 assert(LoVT == HiVT &&
"Expected equal split types");
3646 auto [SrcLo, SrcHi] = DAG.SplitVector(Src,
DL);
3650 DAG.getVTList(SplitSrcVT, SplitSrcVT), SrcLo, SrcHi);
3656 DAG.getVTList(LoVT, LoVT), Even, Odd);
3664 GetSplitVector(
N->getOperand(0), InLo, InHi);
3675 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3676 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3681 EVT VT =
N->getValueType(0);
3704 EVT PtrVT =
StackPtr.getValueType();
3705 auto &MF = DAG.getMachineFunction();
3709 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3712 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3718 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3719 DAG.getConstant(1,
DL, PtrVT));
3721 DAG.getConstant(EltWidth,
DL, PtrVT));
3723 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3725 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3726 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3727 DAG.getPOISON(PtrVT), Stride, TrueMask,
3736 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3741 EVT VT =
N->getValueType(0);
3753 EVL1 = ZExtPromotedInteger(EVL1);
3772 EVT PtrVT =
StackPtr.getValueType();
3773 auto &MF = DAG.getMachineFunction();
3777 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3780 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3786 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3791 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3792 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3794 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3796 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3800 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3805 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3806 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3810 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3819 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3827 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3829 DAG.getVectorIdxConstant(0,
DL));
3835void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3843 GetSplitVector(Acc, AccLo, AccHi);
3844 unsigned Opcode =
N->getOpcode();
3856 GetSplitVector(Input1, Input1Lo, Input1Hi);
3857 GetSplitVector(Input2, Input2Lo, Input2Hi);
3860 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3861 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3864void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3872 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3883 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3885 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3889 N->getOperand(1), MaskLo,
N->getFlags());
3891 N->getOperand(1), MaskHi,
N->getFlags());
3894void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3895 unsigned Factor =
N->getNumOperands();
3898 for (
unsigned i = 0; i != Factor; ++i) {
3900 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3902 Ops[i * 2 + 1] = OpHi;
3913 for (
unsigned i = 0; i != Factor; ++i)
3917void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3918 unsigned Factor =
N->getNumOperands();
3921 for (
unsigned i = 0; i != Factor; ++i) {
3923 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3925 Ops[i + Factor] = OpHi;
3936 for (
unsigned i = 0; i != Factor; ++i) {
3937 unsigned IdxLo = 2 * i;
3938 unsigned IdxHi = 2 * i + 1;
3939 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3940 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3952bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3957 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3960 switch (
N->getOpcode()) {
3963 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3972 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3979 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3982 Res = SplitVecOp_TruncateHelper(
N);
3988 Res = SplitVecOp_FP_ROUND(
N);
4000 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
4007 case ISD::VP_SCATTER:
4011 case ISD::VP_GATHER:
4015 Res = SplitVecOp_VSELECT(
N, OpNo);
4021 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
4024 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
4030 if (
N->getValueType(0).bitsLT(
4031 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
4032 Res = SplitVecOp_TruncateHelper(
N);
4034 Res = SplitVecOp_UnaryOp(
N);
4038 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
4054 Res = SplitVecOp_UnaryOp(
N);
4057 Res = SplitVecOp_FPOpDifferentTypes(
N);
4062 Res = SplitVecOp_CMP(
N);
4066 Res = SplitVecOp_FAKE_USE(
N);
4071 Res = SplitVecOp_ExtVecInRegOp(
N);
4091 Res = SplitVecOp_VECREDUCE(
N, OpNo);
4095 Res = SplitVecOp_VECREDUCE_SEQ(
N);
4097 case ISD::VP_REDUCE_FADD:
4098 case ISD::VP_REDUCE_SEQ_FADD:
4099 case ISD::VP_REDUCE_FMUL:
4100 case ISD::VP_REDUCE_SEQ_FMUL:
4101 case ISD::VP_REDUCE_ADD:
4102 case ISD::VP_REDUCE_MUL:
4103 case ISD::VP_REDUCE_AND:
4104 case ISD::VP_REDUCE_OR:
4105 case ISD::VP_REDUCE_XOR:
4106 case ISD::VP_REDUCE_SMAX:
4107 case ISD::VP_REDUCE_SMIN:
4108 case ISD::VP_REDUCE_UMAX:
4109 case ISD::VP_REDUCE_UMIN:
4110 case ISD::VP_REDUCE_FMAX:
4111 case ISD::VP_REDUCE_FMIN:
4112 case ISD::VP_REDUCE_FMAXIMUM:
4113 case ISD::VP_REDUCE_FMINIMUM:
4114 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
4118 Res = SplitVecOp_CttzElts(
N);
4120 case ISD::VP_CTTZ_ELTS:
4121 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
4122 Res = SplitVecOp_VP_CttzElements(
N);
4125 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
4131 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
4134 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
4139 if (!Res.
getNode())
return false;
4146 if (
N->isStrictFPOpcode())
4148 "Invalid operand expansion");
4151 "Invalid operand expansion");
4153 ReplaceValueWith(
SDValue(
N, 0), Res);
4157SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4161 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4163 EVT VT =
N->getValueType(0);
4176 getSetCCResultType(MVT::i1), MVT::i1);
4181 DAG.getElementCount(
DL, VT, SplitEC)),
4185SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4188 assert(OpNo == 0 &&
"Illegal operand must be mask");
4193 EVT Src0VT =
Src0.getValueType();
4195 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4198 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4199 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4200 "Lo and Hi have differing types");
4203 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4204 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4207 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4208 std::tie(LoOp1,
HiOp1) = DAG.SplitVector(Src1,
DL);
4209 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4219SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4220 assert(OpNo == 2 &&
"Illegal operand must be mask");
4223 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4224 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4226 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4229 RHSLo, MaskLo,
N->getFlags());
4231 RHSHi, MaskHi,
N->getFlags());
4235SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4238 assert(OpNo == 1 &&
"Illegal operand must be mask");
4243 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4245 EVT VecVT =
N->getValueType(0);
4249SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4250 EVT ResVT =
N->getValueType(0);
4256 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4257 GetSplitVector(VecOp,
Lo,
Hi);
4259 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4264 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4265 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4269 EVT ResVT =
N->getValueType(0);
4275 SDNodeFlags
Flags =
N->getFlags();
4278 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4279 GetSplitVector(VecOp,
Lo,
Hi);
4281 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4287 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4290SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4291 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4292 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4294 unsigned Opc =
N->getOpcode();
4295 EVT ResVT =
N->getValueType(0);
4301 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4302 GetSplitVector(VecOp,
Lo,
Hi);
4305 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4308 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4310 const SDNodeFlags
Flags =
N->getFlags();
4314 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4319 EVT ResVT =
N->getValueType(0);
4322 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4323 EVT InVT =
Lo.getValueType();
4328 if (
N->isStrictFPOpcode()) {
4329 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4330 {N->getOperand(0), Lo});
4331 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4332 {N->getOperand(0), Hi});
4341 ReplaceValueWith(
SDValue(
N, 1), Ch);
4343 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4344 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4353 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4363 EVT ResVT =
N->getValueType(0);
4365 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4369 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4375 Lo = BitConvertToInteger(
Lo);
4376 Hi = BitConvertToInteger(
Hi);
4378 if (DAG.getDataLayout().isBigEndian())
4386 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4388 EVT ResVT =
N->getValueType(0);
4396 GetSplitVector(SubVec,
Lo,
Hi);
4405 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4407 return SecondInsertion;
4410SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4417 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4419 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4421 ElementCount IdxVal =
4425 EVT SrcVT =
N->getOperand(0).getValueType();
4444 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4445 LoEltsMin - IdxValMin);
4446 DAG.ExtractVectorElements(
Hi, Elts, 0,
4449 return DAG.getBuildVector(SubVT, dl, Elts);
4453 ElementCount ExtractIdx = IdxVal - LoElts;
4455 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4458 EVT HiVT =
Hi.getValueType();
4460 "Only fixed-vector extracts are supported in this case");
4470 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4471 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4477 "Extracting scalable subvector from fixed-width unsupported");
4485 "subvector from a scalable predicate vector");
4491 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4493 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4494 auto &MF = DAG.getMachineFunction();
4498 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4502 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4505 SubVT, dl,
Store, StackPtr,
4509SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4518 GetSplitVector(Vec,
Lo,
Hi);
4520 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4522 if (IdxVal < LoElts)
4523 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4526 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4527 Idx.getValueType())), 0);
4531 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4543 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4549 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4551 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4552 auto &MF = DAG.getMachineFunction();
4555 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4559 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4563 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4565 return DAG.getExtLoad(
4576 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4584 SplitVecRes_Gather(
N,
Lo,
Hi);
4587 ReplaceValueWith(
SDValue(
N, 0), Res);
4592 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4596 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4598 SDValue EVL =
N->getVectorLength();
4606 GetSplitVector(
Data, DataLo, DataHi);
4608 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4613 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4616 GetSplitVector(Mask, MaskLo, MaskHi);
4618 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4621 EVT MemoryVT =
N->getMemoryVT();
4622 EVT LoMemVT, HiMemVT;
4623 bool HiIsEmpty =
false;
4624 std::tie(LoMemVT, HiMemVT) =
4625 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4629 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4632 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4635 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4637 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4638 N->getAddressingMode(),
N->isTruncatingStore(),
4639 N->isCompressingStore());
4645 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4646 N->isCompressingStore());
4648 MachinePointerInfo MPI;
4652 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4657 MMO = DAG.getMachineFunction().getMachineMemOperand(
4659 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4661 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4662 N->getAddressingMode(),
N->isTruncatingStore(),
4663 N->isCompressingStore());
4672 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4673 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4680 GetSplitVector(
Data, LoData, HiData);
4682 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4684 EVT LoMemVT, HiMemVT;
4685 bool HiIsEmpty =
false;
4686 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4692 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4693 else if (getTypeAction(
Mask.getValueType()) ==
4695 GetSplitVector(Mask, LoMask, HiMask);
4697 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4700 std::tie(LoEVL, HiEVL) =
4701 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4705 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4706 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4707 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4718 EVT PtrVT =
N->getBasePtr().getValueType();
4721 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4729 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4730 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4732 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4735 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4736 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4737 N->isCompressingStore());
4746 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4750 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4759 GetSplitVector(
Data, DataLo, DataHi);
4761 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4766 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4769 GetSplitVector(Mask, MaskLo, MaskHi);
4771 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4774 EVT MemoryVT =
N->getMemoryVT();
4775 EVT LoMemVT, HiMemVT;
4776 bool HiIsEmpty =
false;
4777 std::tie(LoMemVT, HiMemVT) =
4778 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4781 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4784 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4786 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4787 N->getAddressingMode(),
N->isTruncatingStore(),
4788 N->isCompressingStore());
4796 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4797 N->isCompressingStore());
4799 MachinePointerInfo MPI;
4803 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4808 MMO = DAG.getMachineFunction().getMachineMemOperand(
4811 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4813 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4814 N->getAddressingMode(),
N->isTruncatingStore(),
4815 N->isCompressingStore());
4828 EVT MemoryVT =
N->getMemoryVT();
4838 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4842 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4847 EVT LoMemVT, HiMemVT;
4848 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4853 GetSplitVector(
Ops.Data, DataLo, DataHi);
4855 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4860 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4862 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4866 if (getTypeAction(
Ops.Index.getValueType()) ==
4868 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4870 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4874 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4876 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4879 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4881 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4882 MSC->getIndexType(), MSC->isTruncatingStore());
4887 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4888 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4889 MMO, MSC->getIndexType(),
4890 MSC->isTruncatingStore());
4894 std::tie(EVLLo, EVLHi) =
4895 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4897 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4898 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4899 VPSC->getIndexType());
4904 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4905 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4906 VPSC->getIndexType());
4910 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4911 assert(OpNo == 1 &&
"Can only split the stored value");
4914 bool isTruncating =
N->isTruncatingStore();
4917 EVT MemoryVT =
N->getMemoryVT();
4920 MMOMetadata
Metadata =
N->getMMOMetadataForSubAccess();
4922 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4924 EVT LoMemVT, HiMemVT;
4925 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4929 return TLI.scalarizeVectorStore(
N, DAG);
4932 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4935 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4938 MachinePointerInfo MPI;
4939 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4942 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI, HiMemVT, Alignment, MMOFlags,
4945 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags,
Metadata);
4952 LLVMContext &Ctx = *DAG.getContext();
4970 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4971 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4975 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4978 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4979 DAG.getBitcast(MemVecVT, Wide), 0);
4981 N->getBasePtr(),
N->getMemOperand());
4989 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4991 N->getBasePtr(),
N->getMemOperand());
5005 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
5011 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
5032 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
5033 SDValue InVec =
N->getOperand(OpNo);
5035 EVT OutVT =
N->getValueType(0);
5043 EVT LoOutVT, HiOutVT;
5044 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
5045 assert(LoOutVT == HiOutVT &&
"Unequal split?");
5050 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
5052 return SplitVecOp_UnaryOp(
N);
5061 return SplitVecOp_UnaryOp(
N);
5065 GetSplitVector(InVec, InLoVec, InHiVec);
5071 EVT HalfElementVT = IsFloat ?
5073 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
5080 if (
N->isStrictFPOpcode()) {
5081 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
5082 {N->getOperand(0), InLoVec});
5083 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
5084 {N->getOperand(0), InHiVec});
5090 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
5091 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
5095 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
5103 if (
N->isStrictFPOpcode()) {
5107 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
5115 DAG.getTargetConstant(
5116 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
5123 assert(
N->getValueType(0).isVector() &&
5124 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
5125 "Operand types must be vectors");
5127 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
5129 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
5130 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
5132 EVT VT =
N->getValueType(0);
5133 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
5139 assert(isStrict &&
"unexpected node");
5140 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5141 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
5142 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5143 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
5146 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5154 EVT OpVT =
N->getOperand(0).getValueType();
5157 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5163 EVT ResVT =
N->getValueType(0);
5166 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5167 EVT InVT =
Lo.getValueType();
5172 if (
N->isStrictFPOpcode()) {
5173 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5174 {N->getOperand(0), Lo, N->getOperand(2)});
5175 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5176 {N->getOperand(0), Hi, N->getOperand(2)});
5180 Lo.getValue(1),
Hi.getValue(1));
5181 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5183 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5184 N->getOperand(2),
N->getOperand(3));
5185 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5186 N->getOperand(2),
N->getOperand(3));
5188 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5189 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5200SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5203 EVT LHSLoVT, LHSHiVT;
5204 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5206 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5207 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5210 std::tie(LHSLo, LHSHi) =
5211 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5214 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5217 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5223 LLVMContext &Ctxt = *DAG.getContext();
5226 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5227 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5228 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5230 EVT ResVT =
N->getValueType(0);
5235 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5236 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5242 EVT ResVT =
N->getValueType(0);
5245 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5246 EVT InVT =
Lo.getValueType();
5252 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5253 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5260 EVT ResVT =
N->getValueType(0);
5264 GetSplitVector(VecOp,
Lo,
Hi);
5270 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5272 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5274 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5275 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5280 EVT ResVT =
N->getValueType(0);
5284 GetSplitVector(VecOp,
Lo,
Hi);
5286 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5287 auto [EVLLo, EVLHi] =
5289 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5295 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5297 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5298 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5301SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5312 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5313 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5314 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5315 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5316 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5317 OpsLo, MMO, IndexType);
5318 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5319 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5323SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5327 EVT LoResVT, HiResVT;
5328 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5330 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5332 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5335 N->getOperand(1), MaskLo,
N->getFlags());
5337 N->getOperand(1), MaskHi,
N->getFlags());
5343 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5346 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5350 NeedleLo,
N->getOperand(2),
N->getFlags());
5353 NeedleHi,
N->getOperand(2),
N->getFlags());
5354 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5357SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5360 "Accumulator should already be a legal type, and shouldn't need "
5361 "further splitting");
5364 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5365 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5366 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5367 unsigned Opcode =
N->getOpcode();
5370 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5371 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5378void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5379 unsigned WidenResNo) {
5380 unsigned NumResults =
N->getNumValues();
5381 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5382 if (ResNo == WidenResNo)
5384 EVT ResVT =
N->getValueType(ResNo);
5390 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5391 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5396void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5397 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5400 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5405 auto unrollExpandedOp = [&]() {
5410 EVT ResVT =
N->getValueType(ResNo);
5411 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5414 EVT VT0 =
N->getValueType(0);
5415 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5416 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT0.
getScalarType())) {
5420 if (
N->getNumValues() > 1)
5421 ReplaceOtherWidenResults(
N, Unrolled.
getNode(), ResNo);
5427 switch (
N->getOpcode()) {
5430 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5438 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5442 Res = WidenVecRes_ADDRSPACECAST(
N);
5449 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5456 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5460 Res = WidenVecRes_ScalarOp(
N);
5466 Res = WidenVecRes_Select(
N);
5469 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5471 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5478 case ISD::VP_LOAD_FF:
5481 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5485 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5493 case ISD::VP_GATHER:
5497 Res = WidenVecRes_VECTOR_REVERSE(
N);
5500 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5503 WidenVecRes_VECTOR_INTERLEAVE(
N);
5506 Res = WidenVecRes_VECTOR_MATCH(
N);
5509 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5565 Res = WidenVecRes_Binary(
N);
5572 Res = WidenVecRes_MaskedBinary(
N);
5577 Res = WidenVecRes_CMP(
N);
5583 if (unrollExpandedOp())
5598 Res = WidenVecRes_BinaryCanTrap(
N);
5607 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5610#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5611 case ISD::STRICT_##DAGN:
5612#include "llvm/IR/ConstrainedOps.def"
5613 Res = WidenVecRes_StrictFP(
N);
5622 Res = WidenVecRes_OverflowOp(
N, ResNo);
5626 Res = WidenVecRes_FCOPYSIGN(
N);
5631 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5636 if (!unrollExpandedOp())
5637 Res = WidenVecRes_ExpOp(
N);
5643 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5658 Res = WidenVecRes_Convert(
N);
5663 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5670 Res = WidenVecRes_XROUND(
N);
5696 if (unrollExpandedOp())
5719 Res = WidenVecRes_Unary(
N);
5724 Res = WidenVecRes_Ternary(
N);
5730 if (!unrollExpandedOp())
5731 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5738 Res = WidenVecRes_PARTIAL_REDUCE_MLA(
N);
5744 SetWidenedVector(
SDValue(
N, ResNo), Res);
5750 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5751 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5752 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5753 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5754 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5760 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5761 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5762 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5763 if (
N->getNumOperands() == 2)
5764 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5767 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5768 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5769 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5770 "Expected VP opcode");
5774 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5775 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5780 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5781 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5782 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5785 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5786 Mask = ModifyToType(Mask, WideMaskVT,
true);
5787 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5792 LLVMContext &Ctxt = *DAG.getContext();
5797 EVT OpVT =
LHS.getValueType();
5799 LHS = GetWidenedVector(
LHS);
5800 RHS = GetWidenedVector(
RHS);
5801 OpVT =
LHS.getValueType();
5804 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5807 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5813SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5816 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5817 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5818 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5820 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5829 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5832 if (ConcatEnd == 1) {
5833 VT = ConcatOps[0].getValueType();
5835 return ConcatOps[0];
5838 SDLoc dl(ConcatOps[0]);
5845 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
5846 int Idx = ConcatEnd - 1;
5847 VT = ConcatOps[Idx--].getValueType();
5848 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
5856 }
while (!
TLI.isTypeLegal(NextVT));
5861 unsigned NumToInsert = ConcatEnd - Idx - 1;
5862 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5864 ConcatOps[Idx+1] = VecOp;
5865 ConcatEnd = Idx + 2;
5871 unsigned RealVals = ConcatEnd - Idx - 1;
5872 unsigned SubConcatEnd = 0;
5873 unsigned SubConcatIdx = Idx + 1;
5874 while (SubConcatEnd < RealVals)
5875 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5876 while (SubConcatEnd < OpsToConcat)
5877 SubConcatOps[SubConcatEnd++] = undefVec;
5879 NextVT, SubConcatOps);
5880 ConcatEnd = SubConcatIdx + 1;
5885 if (ConcatEnd == 1) {
5886 VT = ConcatOps[0].getValueType();
5888 return ConcatOps[0];
5894 if (
NumOps != ConcatEnd ) {
5896 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5897 ConcatOps[j] = UndefVal;
5905 unsigned Opcode =
N->getOpcode();
5907 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5910 const SDNodeFlags
Flags =
N->getFlags();
5916 bool FoundLegalVectorType = TLI.isTypeLegal(VT) && !NumElts.
isScalar();
5917 if (FoundLegalVectorType && DAG.isSafeToSpeculativelyExecute(Opcode)) {
5919 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5920 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5921 return DAG.getNode(Opcode, dl, WidenVT, InOp1, InOp2, Flags);
5929 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5932 TLI.isTypeLegal(WideMaskVT)) {
5933 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5934 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5935 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5937 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5938 N->getValueType(0).getVectorElementCount());
5939 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5948 if (!TLI.isTypeLegal(VT))
5954 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5955 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5956 ElementCount CurNumElts =
N->getValueType(0).getVectorElementCount();
5959 unsigned ConcatEnd = 0;
5969 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5970 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5971 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5974 CurNumElts -= NumElts;
5989 SDValue EOp1 = DAG.getExtractVectorElt(dl, EltVT, InOp1, Idx);
5990 SDValue EOp2 = DAG.getExtractVectorElt(dl, EltVT, InOp2, Idx);
5991 ConcatOps[ConcatEnd++] =
5992 DAG.
getNode(Opcode, dl, EltVT, EOp1, EOp2, Flags);
5998 if (!TLI.isTypeLegal(VT))
6006 switch (
N->getOpcode()) {
6009 return WidenVecRes_STRICT_FSETCC(
N);
6016 return WidenVecRes_Convert_StrictFP(
N);
6023 unsigned Opcode =
N->getOpcode();
6025 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6029 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
6030 NumElts = NumElts / 2;
6041 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
6045 unsigned ConcatEnd = 0;
6052 for (
unsigned i = 1; i < NumOpers; ++i) {
6058 Oper = GetWidenedVector(Oper);
6064 DAG.getPOISON(WideOpVT), Oper,
6065 DAG.getVectorIdxConstant(0, dl));
6077 while (CurNumElts != 0) {
6078 while (CurNumElts >= NumElts) {
6081 for (
unsigned i = 0; i < NumOpers; ++i) {
6084 EVT OpVT =
Op.getValueType();
6089 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
6095 EVT OperVT[] = {VT, MVT::Other};
6097 ConcatOps[ConcatEnd++] = Oper;
6100 CurNumElts -= NumElts;
6103 NumElts = NumElts / 2;
6105 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
6108 for (
unsigned i = 0; i != CurNumElts; ++i, ++
Idx) {
6111 for (
unsigned i = 0; i < NumOpers; ++i) {
6114 EVT OpVT =
Op.getValueType();
6122 EVT WidenVT[] = {WidenEltVT, MVT::Other};
6124 ConcatOps[ConcatEnd++] = Oper;
6133 if (Chains.
size() == 1)
6134 NewChain = Chains[0];
6137 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6142SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
6144 EVT ResVT =
N->getValueType(0);
6145 EVT OvVT =
N->getValueType(1);
6146 EVT WideResVT, WideOvVT;
6151 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6156 WideLHS = GetWidenedVector(
N->getOperand(0));
6157 WideRHS = GetWidenedVector(
N->getOperand(1));
6159 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6168 N->getOperand(0),
Zero);
6170 N->getOperand(1),
Zero);
6173 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6174 SDNode *WideNode = DAG.getNode(
6175 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6178 unsigned OtherNo = 1 - ResNo;
6179 EVT OtherVT =
N->getValueType(OtherNo);
6186 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
6189 return SDValue(WideNode, ResNo);
6193 LLVMContext &Ctx = *DAG.getContext();
6197 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6202 unsigned Opcode =
N->getOpcode();
6203 const SDNodeFlags
Flags =
N->getFlags();
6209 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6211 InOp = ZExtPromotedInteger(InOp);
6223 if (
N->getNumOperands() == 1)
6224 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6226 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6227 N->getOperand(3), Flags);
6228 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6232 InOp = GetWidenedVector(
N->getOperand(0));
6235 if (InVTEC == WidenEC)
6236 return MakeConvertNode(WidenVT, InOp);
6261 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6265 if (TLI.isTypeLegal(InWidenVT)) {
6273 unsigned NumConcat =
6278 return MakeConvertNode(WidenVT, InVec);
6282 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6284 return MakeConvertNode(WidenVT, InVal);
6293 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6294 for (
unsigned i=0; i < MinElts; ++i) {
6295 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6296 Ops[i] = MakeConvertNode(EltVT, Val);
6299 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6304 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6308 EVT SrcVT = Src.getValueType();
6312 Src = GetWidenedVector(Src);
6313 SrcVT = Src.getValueType();
6320 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6325 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6329 EVT SrcVT = Src.getValueType();
6333 Src = GetWidenedVector(Src);
6334 SrcVT = Src.getValueType();
6341 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6344SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6349 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6355 unsigned Opcode =
N->getOpcode();
6361 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6366 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6367 for (
unsigned i=0; i < MinElts; ++i) {
6368 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6369 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6373 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6375 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6378SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6379 unsigned Opcode =
N->getOpcode();
6383 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6392 InOp = GetWidenedVector(InOp);
6399 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6406 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6407 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6424 while (
Ops.size() != WidenNumElts)
6425 Ops.push_back(DAG.getPOISON(WidenSVT));
6427 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6433 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6434 return WidenVecRes_BinaryCanTrap(
N);
6437 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6444SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6446 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6449 SDValue Arg = GetWidenedVector(FpValue);
6450 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6455 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6456 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6458 EVT ExpVT =
RHS.getValueType();
6463 ExpOp = ModifyToType(
RHS, WideExpVT);
6466 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6471 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6472 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6473 if (
N->getNumOperands() == 1)
6474 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6476 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6481 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6486 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6487 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6488 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6491SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6493 EVT VT0 =
N->getValueType(0);
6494 EVT VT1 =
N->getValueType(1);
6498 "expected both results to be vectors of matching element count");
6500 LLVMContext &Ctx = *DAG.getContext();
6501 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6503 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6510 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6513 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6514 return SDValue(WidenNode, ResNo);
6517SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6518 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6519 return GetWidenedVector(WidenVec);
6524 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6536 InOp = GetWidenedVector(InOp);
6540 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6543 return DAG.getAddrSpaceCast(
6544 DL, WidenVT, InOp, AddrSpaceCastN->getSrcAddressSpace(),
6545 AddrSpaceCastN->getDestAddressSpace(), AddrSpaceCastN->getFlags());
6551 EVT VT =
N->getValueType(0);
6552 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6555 switch (getTypeAction(InVT)) {
6569 SDValue NInOp = GetPromotedInteger(InOp);
6571 if (WidenVT.
bitsEq(NInVT)) {
6574 if (DAG.getDataLayout().isBigEndian()) {
6577 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6595 InOp = GetWidenedVector(InOp);
6597 if (WidenVT.
bitsEq(InVT))
6607 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6612 unsigned NewNumParts = WidenSize / InSize;
6625 EVT OrigInVT =
N->getOperand(0).getValueType();
6630 if (TLI.isTypeLegal(NewInVT)) {
6638 if (WidenSize % InSize == 0) {
6645 DAG.ExtractVectorElements(InOp,
Ops);
6646 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6658 return CreateStackStoreLoad(InOp, WidenVT);
6661SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6663 N->getOpcode(), SDLoc(
N),
6664 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6665 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6671 EVT VT =
N->getValueType(0);
6675 EVT EltVT =
N->getOperand(0).getValueType();
6678 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6682 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6683 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6685 return DAG.getBuildVector(WidenVT, dl, NewOps);
6689 EVT InVT =
N->getOperand(0).getValueType();
6690 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6692 unsigned NumOperands =
N->getNumOperands();
6694 bool InputWidened =
false;
6698 if (WidenNumElts % NumInElts == 0) {
6700 unsigned NumConcat = WidenNumElts / NumInElts;
6701 SDValue UndefVal = DAG.getPOISON(InVT);
6703 for (
unsigned i=0; i < NumOperands; ++i)
6704 Ops[i] =
N->getOperand(i);
6705 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6710 InputWidened =
true;
6711 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6714 for (i=1; i < NumOperands; ++i)
6715 if (!
N->getOperand(i).isUndef())
6718 if (i == NumOperands)
6721 return GetWidenedVector(
N->getOperand(0));
6723 if (NumOperands == 2) {
6725 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6730 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6731 for (
unsigned i = 0; i < NumInElts; ++i) {
6733 MaskOps[i + NumInElts] = i + WidenNumElts;
6735 return DAG.getVectorShuffle(WidenVT, dl,
6736 GetWidenedVector(
N->getOperand(0)),
6737 GetWidenedVector(
N->getOperand(1)),
6744 SDValue WideVec = DAG.getPOISON(WidenVT);
6746 for (
unsigned I = 0;
I < NumOperands; ++
I)
6748 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6759 for (
unsigned i=0; i < NumOperands; ++i) {
6762 InOp = GetWidenedVector(InOp);
6763 for (
unsigned j = 0;
j < NumInElts; ++
j)
6764 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6766 SDValue UndefVal = DAG.getPOISON(EltVT);
6767 for (;
Idx < WidenNumElts; ++
Idx)
6768 Ops[Idx] = UndefVal;
6769 return DAG.getBuildVector(WidenVT, dl,
Ops);
6772SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6773 EVT VT =
N->getValueType(0);
6774 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6775 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6782SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6783 EVT VT =
N->getValueType(0);
6785 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6790 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6792 InOp = GetWidenedVector(InOp);
6798 if (IdxVal == 0 && InVT == WidenVT)
6805 assert(IdxVal % VTNumElts == 0 &&
6806 "Expected Idx to be a multiple of subvector minimum vector length");
6807 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6820 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6821 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6822 "down type's element count");
6829 for (;
I < VTNumElts / GCD; ++
I)
6831 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6832 for (;
I < WidenNumElts / GCD; ++
I)
6854 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6861 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6862 return DAG.getMaskedLoad(
6863 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6871 for (i = 0; i < VTNumElts; ++i)
6872 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6874 SDValue UndefVal = DAG.getPOISON(EltVT);
6875 for (; i < WidenNumElts; ++i)
6877 return DAG.getBuildVector(WidenVT, dl,
Ops);
6883 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6888SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6889 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6892 N->getOperand(1),
N->getOperand(2));
6901 "Load width must be less than or equal to first value type width");
6910 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6927 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6938 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6939 EVT LdVT =
LD->getMemoryVT();
6948 TypeSize WidthDiff = WidenWidth - LdWidth;
6951 std::optional<EVT> FirstVT =
6952 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6958 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6961 Chain, BasePtr,
LD->getMemOperand());
6965 FirstVTWidth, dl, DAG);
6983 if (!
LD->getMemoryVT().isByteSized()) {
6985 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6987 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6996 EVT VT =
LD->getValueType(0);
6997 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6998 EVT WideMaskVT = getSetCCResultType(WideVT);
7001 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
7002 TLI.isTypeLegal(WideMaskVT)) {
7005 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7009 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
7010 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
7022 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
7024 Result = GenWidenVectorLoads(LdChain, LD);
7031 if (LdChain.
size() == 1)
7032 NewChain = LdChain[0];
7038 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7049 SDValue NewLoad = DAG.getMaskedLoad(
7050 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
7051 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
7052 LD->getAddressingMode(),
LD->getExtensionType());
7062 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7064 SDValue EVL =
N->getVectorLength();
7071 "Unable to widen binary VP op");
7072 Mask = GetWidenedVector(Mask);
7073 assert(
Mask.getValueType().getVectorElementCount() ==
7074 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7075 .getVectorElementCount() &&
7076 "Unable to widen vector load");
7079 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
7080 N->getBasePtr(),
N->getOffset(), Mask, EVL,
7081 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
7089 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7091 SDValue EVL =
N->getVectorLength();
7097 "Unable to widen binary VP op");
7098 Mask = GetWidenedVector(Mask);
7099 assert(
Mask.getValueType().getVectorElementCount() ==
7100 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7101 .getVectorElementCount() &&
7102 "Unable to widen vector load");
7104 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
7105 Mask, EVL,
N->getMemOperand());
7118 "Unable to widen VP strided load");
7119 Mask = GetWidenedVector(Mask);
7121 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7122 assert(
Mask.getValueType().getVectorElementCount() ==
7124 "Data and mask vectors should have the same number of elements");
7126 SDValue Res = DAG.getStridedLoadVP(
7127 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
7128 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
7129 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
7130 N->isExpandingLoad());
7138SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
7143 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
7145 Mask.getValueType().getVectorElementType(),
7148 SDValue WideVec = ModifyToType(Vec, WideVecVT);
7149 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
7150 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
7152 WideMask, WidePassthru);
7156 EVT VT =
N->getValueType(0);
7157 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7159 EVT MaskVT =
Mask.getValueType();
7160 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7169 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7170 TLI.isTypeLegal(WideMaskVT) &&
7176 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7177 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7181 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7182 N->getMemoryVT(),
N->getMemOperand());
7186 if (!
N->getPassThru()->isUndef()) {
7190 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7191 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7192 DAG.getPOISON(WidenVT), EVL);
7203 Mask = ModifyToType(Mask, WideMaskVT,
true);
7205 SDValue Res = DAG.getMaskedLoad(
7206 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7207 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7208 ExtType,
N->isExpandingLoad());
7217 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7219 EVT MaskVT =
Mask.getValueType();
7220 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7228 Mask = ModifyToType(Mask, WideMaskVT,
true);
7233 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7234 Index = ModifyToType(Index, WideIndexVT);
7240 N->getMemoryVT().getScalarType(), WideEC);
7241 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7242 WideMemVT, dl,
Ops,
N->getMemOperand(),
7243 N->getIndexType(),
N->getExtensionType());
7252 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7260 N->getMemoryVT().getScalarType(), WideEC);
7261 Mask = GetWidenedMask(Mask, WideEC);
7264 Mask,
N->getVectorLength()};
7265 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7266 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7275 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7276 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7304 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7305 return N->getOperand(OpNo).getValueType();
7313 N =
N.getOperand(0);
7315 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7316 if (!
N->getOperand(i)->isUndef())
7318 N =
N.getOperand(0);
7322 N =
N.getOperand(0);
7324 N =
N.getOperand(0);
7350 { MaskVT, MVT::Other },
Ops);
7351 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7357 return adjustMaskToType(Mask, ToMaskVT);
7363 LLVMContext &Ctx = *DAG.getContext();
7364 EVT MaskVT =
Mask.getValueType();
7367 if (MaskScalarBits < ToMaskScalBits) {
7371 }
else if (MaskScalarBits > ToMaskScalBits) {
7377 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7379 "Mask should have the right element size by now.");
7382 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7384 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7387 EVT SubVT =
Mask->getValueType(0);
7393 assert((
Mask->getValueType(0) == ToMaskVT) &&
7394 "A mask of ToMaskVT should have been produced by now.");
7401EVT DAGTypeLegalizer::unifyMaskTypes(
SDValue &Op0,
bool IsOpLenient0,
7402 SDValue &Op1,
bool IsOpLenient1,
7406 "unifyMaskTypes only handles scalar width differences");
7418 if (IsOpLenient0 != IsOpLenient1) {
7419 SDValue *LenientOp, *NonLenientOp;
7422 NonLenientOp = &Op1;
7425 NonLenientOp = &Op0;
7428 *LenientOp = adjustMaskToType(*LenientOp, OpVT);
7434 unsigned NarrowBits = std::min(Bits0, Bits1);
7435 unsigned WideBits = std::max(Bits0, Bits1);
7437 unsigned IntBits = NarrowBits == WideBits ? NarrowBits
7438 : ToBits >= WideBits ? WideBits
7439 : ToBits <= NarrowBits ? NarrowBits
7443 Op0 = adjustMaskToType(Op0, OpVT);
7444 Op1 = adjustMaskToType(Op1, OpVT);
7448std::pair<SDValue, bool>
7449DAGTypeLegalizer::convertMaskTreeImpl(
SDValue V,
EVT ToVT,
unsigned Depth) {
7481 if (
Depth >= DAG.MaxRecursionDepth)
7490 unsigned Opcode =
V.getOpcode();
7495 return {convertMask(
V, MaskVT, MaskVT),
false};
7503 return {DAG.getConstant(0,
DL, ToVT),
true};
7505 return {DAG.getAllOnesConstant(
DL, ToVT),
true};
7510 auto [Op0, IsLenientOp0] =
7511 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7514 auto [Op1, IsLenientOp1] =
7515 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7518 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7519 return {DAG.getNode(Opcode,
DL, OpVT, Op0, Op1),
7520 IsLenientOp0 && IsLenientOp1};
7525 auto [Inner, IsTypeLenient] =
7526 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7529 return {DAG.getNode(
ISD::FREEZE,
DL, Inner.getValueType(), Inner),
7536 auto [Op0, IsLenientOp0] =
7537 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7540 if (
V.getOperand(1).isUndef()) {
7542 return {DAG.getVectorShuffle(OpVT,
DL, Op0, DAG.getUNDEF(OpVT),
7546 auto [Op1, IsLenientOp1] =
7547 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7550 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7551 return {DAG.getVectorShuffle(OpVT,
DL, Op0, Op1, Shuf->getMask()),
7552 IsLenientOp0 && IsLenientOp1};
7557 auto [Op1, IsLenientOp1] =
7558 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7561 auto [Op2, IsLenientOp2] =
7562 convertMaskTreeImpl(
V.getOperand(2), ToVT,
Depth + 1);
7565 EVT OpVT = unifyMaskTypes(Op1, IsLenientOp1, Op2, IsLenientOp2, ToVT);
7575 return {DAG.getNode(Opcode,
DL, OpVT,
Cond, Op1, Op2),
7576 IsLenientOp1 && IsLenientOp2};
7590 *DAG.getContext(),
V.getValueType().getVectorElementCount());
7591 auto [
Result,
_] = convertMaskTreeImpl(
V, MaskTreeVT);
7594 return adjustMaskToType(Result, ToVT);
7602 LLVMContext &Ctx = *DAG.getContext();
7610 EVT CondVT =
Cond->getValueType(0);
7614 EVT VSelVT =
N->getValueType(0);
7626 EVT FinalVT = VSelVT;
7637 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7638 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7645 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7653 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7656 EVT ToMaskVT = VSelVT;
7661 return convertMaskTree(
Cond, ToMaskVT);
7665 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7670 unsigned Opcode =
N->getOpcode();
7672 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7673 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7674 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7676 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7682 Cond1 = GetWidenedVector(Cond1);
7690 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7691 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7696 Cond1 = ModifyToType(Cond1, CondWidenVT);
7699 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7700 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7702 if (Opcode == ISD::VP_MERGE)
7703 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7705 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7709 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7710 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7713 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7717 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7718 return DAG.getUNDEF(WidenVT);
7722 EVT VT =
N->getValueType(0);
7725 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7729 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7730 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7733 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7734 for (
unsigned i = 0; i != NumElts; ++i) {
7735 int Idx =
N->getMaskElt(i);
7736 if (Idx < (
int)NumElts)
7739 NewMask[i] =
Idx - NumElts + WidenNumElts;
7741 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7745 EVT VT =
N->getValueType(0);
7749 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7750 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7756 unsigned IdxVal = WidenNumElts - VTNumElts;
7769 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7772 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7773 "down type's element count");
7776 for (; i < VTNumElts / GCD; ++i)
7778 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7779 for (; i < WidenNumElts / GCD; ++i)
7787 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7788 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7790 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7794SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7795 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7799void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7800 EVT VT =
N->getValueType(0);
7803 unsigned Factor =
N->getNumOperands();
7806 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7810 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx)
7811 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7820 for (
unsigned Idx = 0;
Idx != Factor; ++
Idx)
7821 Slices[Idx] = Interleaved.
getValue(Idx);
7825 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx) {
7826 SDValue Narrow = DAG.getExtractSubvector(
DL, VT, Packed,
7829 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7830 SetWidenedVector(
SDValue(
N, Idx), Wide);
7836 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7837 EVT SourceVT =
N->getOperand(0).getValueType();
7842 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7843 N->getOperand(0), 0);
7844 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7845 N->getOperand(2), 0);
7847 N->getOperand(1), WideMask,
N->getFlags());
7850void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7851 EVT VT =
N->getValueType(0);
7854 unsigned Factor =
N->getNumOperands();
7857 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7867 EVT ConcatVT =
EVT::getVectorVT(*DAG.getContext(), EltVT, OrigEC * Factor);
7869 SDValue PackedWidenVec = DAG.getInsertSubvector(
7870 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7874 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx) {
7875 NewOps[
Idx] = DAG.getExtractSubvector(
DL, WidenVT, PackedWidenVec,
7882 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx)
7887 assert(
N->getValueType(0).isVector() &&
7888 N->getOperand(0).getValueType().isVector() &&
7889 "Operands must be vectors");
7890 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7903 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7904 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7911 InOp1 = GetWidenedVector(InOp1);
7912 InOp2 = GetWidenedVector(InOp2);
7915 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7926 "Input not widened to expected type!");
7928 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7933 assert(
N->getValueType(0).isVector() &&
7934 N->getOperand(1).getValueType().isVector() &&
7935 "Operands must be vectors");
7936 EVT VT =
N->getValueType(0);
7937 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7947 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7952 for (
unsigned i = 0; i != NumElts; ++i) {
7953 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7954 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7956 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7957 {Chain, LHSElem, RHSElem, CC});
7958 Chains[i] = Scalars[i].getValue(1);
7959 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7960 DAG.getBoolConstant(
true, dl, EltVT, VT),
7961 DAG.getBoolConstant(
false, dl, EltVT, VT));
7965 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7967 return DAG.getBuildVector(WidenVT, dl, Scalars);
7970SDValue DAGTypeLegalizer::WidenVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N) {
7972 EVT VT =
N->getValueType(0);
7975 SDValue Expanded = TLI.expandPartialReduceMLA(
N, DAG);
7976 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7977 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WideVT), Expanded, 0);
7983bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7984 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7988 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7991 switch (
N->getOpcode()) {
7994 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
8002 Res = WidenVecOp_FAKE_USE(
N);
8006 Res = WidenVecOp_VECTOR_REPEAT(
N);
8011 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
8015 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
8016 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
8017 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
8022 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
8024 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
8025 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
8027 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
8028 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
8038 Res = WidenVecOp_UnrollVectorOp(
N);
8045 Res = WidenVecOp_EXTEND(
N);
8050 Res = WidenVecOp_CMP(
N);
8068 Res = WidenVecOp_Convert(
N);
8073 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
8093 Res = WidenVecOp_VECREDUCE(
N);
8097 Res = WidenVecOp_VECREDUCE_SEQ(
N);
8099 case ISD::VP_REDUCE_FADD:
8100 case ISD::VP_REDUCE_SEQ_FADD:
8101 case ISD::VP_REDUCE_FMUL:
8102 case ISD::VP_REDUCE_SEQ_FMUL:
8103 case ISD::VP_REDUCE_ADD:
8104 case ISD::VP_REDUCE_MUL:
8105 case ISD::VP_REDUCE_AND:
8106 case ISD::VP_REDUCE_OR:
8107 case ISD::VP_REDUCE_XOR:
8108 case ISD::VP_REDUCE_SMAX:
8109 case ISD::VP_REDUCE_SMIN:
8110 case ISD::VP_REDUCE_UMAX:
8111 case ISD::VP_REDUCE_UMIN:
8112 case ISD::VP_REDUCE_FMAX:
8113 case ISD::VP_REDUCE_FMIN:
8114 case ISD::VP_REDUCE_FMAXIMUM:
8115 case ISD::VP_REDUCE_FMINIMUM:
8116 Res = WidenVecOp_VP_REDUCE(
N);
8120 Res = WidenVecOp_CttzElements(
N);
8122 case ISD::VP_CTTZ_ELTS:
8123 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
8124 Res = WidenVecOp_VP_CttzElements(
N);
8127 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
8130 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
8135 if (!Res.
getNode())
return false;
8143 if (
N->isStrictFPOpcode())
8145 "Invalid operand expansion");
8148 "Invalid operand expansion");
8150 ReplaceValueWith(
SDValue(
N, 0), Res);
8156 EVT VT =
N->getValueType(0);
8161 "Unexpected type action");
8162 InOp = GetWidenedVector(InOp);
8165 "Input wasn't widened!");
8173 EVT FixedEltVT = FixedVT.getVectorElementType();
8174 if (TLI.isTypeLegal(FixedVT) &&
8176 FixedEltVT == InEltVT) {
8178 "Not enough elements in the fixed type for the operand!");
8180 "We can't have the same type as we started with!");
8182 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
8184 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
8193 return WidenVecOp_Convert(
N);
8198 switch (
N->getOpcode()) {
8213 EVT OpVT =
N->getOperand(0).getValueType();
8214 EVT ResVT =
N->getValueType(0);
8221 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
8222 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
8228 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
8229 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
8231 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
8238 return DAG.UnrollVectorOp(
N);
8243 EVT ResultVT =
N->getValueType(0);
8245 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
8248 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
8254 {WideArg,
Test},
N->getFlags());
8260 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
8262 EVT OpVT =
N->getOperand(0).getValueType();
8265 return DAG.getNode(ExtendCode,
DL, ResultVT,
CC);
8270 EVT VT =
N->getValueType(0);
8276 "Unexpected type action");
8277 InOp = GetWidenedVector(InOp);
8279 unsigned Opcode =
N->getOpcode();
8284 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
8287 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
8288 return DAG.getNode(Opcode, dl, VT,
Op);
8295 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
8297 if (
N->isStrictFPOpcode()) {
8299 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8302 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8303 {
N->getOperand(0), InOp });
8308 Res = MakeConvertNode(WideVT, InOp);
8310 return DAG.getExtractSubvector(dl, VT, Res, 0);
8318 if (
N->isStrictFPOpcode()) {
8321 for (
unsigned i=0; i < NumElts; ++i) {
8322 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8323 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
8327 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8329 for (
unsigned i = 0; i < NumElts; ++i) {
8330 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8331 Ops[i] = MakeConvertNode(EltVT, Elt);
8335 return DAG.getBuildVector(VT, dl,
Ops);
8339 EVT DstVT =
N->getValueType(0);
8340 SDValue Src = GetWidenedVector(
N->getOperand(0));
8341 EVT SrcVT = Src.getValueType();
8348 if (TLI.isTypeLegal(WideDstVT)) {
8350 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
8353 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
8357 return DAG.UnrollVectorOp(
N);
8361 EVT VT =
N->getValueType(0);
8362 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8370 if (!VT.
isVector() && VT != MVT::x86mmx &&
8374 if (TLI.isTypeLegal(NewVT)) {
8376 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8388 ElementCount NewNumElts =
8390 .divideCoefficientBy(EltSize);
8392 if (TLI.isTypeLegal(NewVT)) {
8394 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8399 return CreateStackStoreLoad(InOp, VT);
8407 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8408 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8413 EVT VT =
N->getValueType(0);
8415 EVT InVT =
N->getOperand(0).getValueType();
8420 unsigned NumOperands =
N->getNumOperands();
8421 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8423 for (i = 1; i < NumOperands; ++i)
8424 if (!
N->getOperand(i).isUndef())
8427 if (i == NumOperands)
8428 return GetWidenedVector(
N->getOperand(0));
8434 for (
unsigned i = 0; i < NumOperands; ++i) {
8435 SDValue InOp = GetWidenedVector(
N->getOperand(i));
8437 InOp = DAG.getExtractSubvector(dl, InVT, InOp, 0);
8438 Result = DAG.getInsertSubvector(dl, Result, InOp, i * NumInElts);
8450 for (
unsigned i=0; i < NumOperands; ++i) {
8454 "Unexpected type action");
8455 InOp = GetWidenedVector(InOp);
8456 for (
unsigned j = 0;
j < NumInElts; ++
j)
8457 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8459 return DAG.getBuildVector(VT, dl,
Ops);
8464 EVT VT =
N->getValueType(0);
8466 EVT SrcVT = Src.getValueType();
8467 EVT WidenedSrcVT = TLI.getTypeToTransformTo(*DAG.getContext(), SrcVT);
8472 "Cannot widen VECTOR_REPEAT operand to an ElementCount that's not "
8473 "a known scalar multiple of the input ElementCount.");
8477 unsigned NumConcat =
8485 return DAG.getExtractSubvector(
DL, VT, Widened, 0);
8488SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8489 EVT VT =
N->getValueType(0);
8494 SubVec = GetWidenedVector(SubVec);
8499 bool IndicesValid =
false;
8502 IndicesValid =
true;
8506 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8507 Attribute::VScaleRange);
8512 IndicesValid =
true;
8518 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8524 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8531 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8553 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8561 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8562 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8567 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8572 unsigned Idx =
N->getConstantOperandVal(2);
8578 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8584SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8585 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8587 N->getValueType(0), InOp,
N->getOperand(1));
8590SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8591 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8593 N->getValueType(0), InOp,
N->getOperand(1));
8596SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8598 EVT ResVT =
N->getValueType(0);
8601 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8607 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8615 "Widened input size must be a multiple of result element size");
8618 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8620 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8621 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8629 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8630 return TLI.scalarizeVectorStore(ST, DAG);
8632 if (
ST->isTruncatingStore())
8633 return TLI.scalarizeVectorStore(ST, DAG);
8643 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8644 EVT WideMaskVT = getSetCCResultType(WideVT);
8646 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8647 TLI.isTypeLegal(WideMaskVT)) {
8650 StVal = GetWidenedVector(StVal);
8652 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8654 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8655 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8656 ST->getAddressingMode());
8660 if (GenWidenVectorStores(StChain, ST)) {
8661 if (StChain.
size() == 1)
8670 SDValue WideStVal = GetWidenedVector(StVal);
8674 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8675 ST->getOffset(), Mask,
ST->getMemoryVT(),
8676 ST->getMemOperand(),
ST->getAddressingMode(),
8677 ST->isTruncatingStore());
8684 EVT StVT =
ST->getMemoryVT();
8687 SDValue StVal = GetWidenedVector(
ST->getVal());
8692 TypeSize WidthDiff = WidenWidth - StWidth;
8698 std::optional<EVT> FirstVT =
8699 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8704 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8710 ST->getBasePtr(),
ST->getMemOperand());
8713SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8714 assert((OpNo == 1 || OpNo == 3) &&
8715 "Can widen only data or mask operand of vp_store");
8723 StVal = GetWidenedVector(StVal);
8729 "Unable to widen VP store");
8730 Mask = GetWidenedVector(Mask);
8732 Mask = GetWidenedVector(Mask);
8738 "Unable to widen VP store");
8739 StVal = GetWidenedVector(StVal);
8742 assert(
Mask.getValueType().getVectorElementCount() ==
8744 "Mask and data vectors should have the same number of elements");
8745 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8746 ST->getOffset(), Mask,
ST->getVectorLength(),
8747 ST->getMemoryVT(),
ST->getMemOperand(),
8748 ST->getAddressingMode(),
ST->isTruncatingStore(),
8749 ST->isCompressingStore());
8754 assert((OpNo == 1 || OpNo == 4) &&
8755 "Can widen only data or mask operand of vp_strided_store");
8764 "Unable to widen VP strided store");
8768 "Unable to widen VP strided store");
8770 StVal = GetWidenedVector(StVal);
8771 Mask = GetWidenedVector(Mask);
8774 Mask.getValueType().getVectorElementCount() &&
8775 "Data and mask vectors should have the same number of elements");
8777 return DAG.getStridedStoreVP(
8784SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8785 assert((OpNo == 1 || OpNo == 4) &&
8786 "Can widen only data or mask operand of mstore");
8789 EVT MaskVT =
Mask.getValueType();
8794 EVT WideVT, WideMaskVT;
8797 StVal = GetWidenedVector(StVal);
8804 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8811 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8813 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8814 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8823 Mask = ModifyToType(Mask, WideMaskVT,
true);
8826 Mask = ModifyToType(Mask, WideMaskVT,
true);
8828 StVal = ModifyToType(StVal, WideVT);
8831 assert(
Mask.getValueType().getVectorElementCount() ==
8833 "Mask and data vectors should have the same number of elements");
8840SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8841 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8843 SDValue DataOp = MG->getPassThru();
8845 SDValue Scale = MG->getScale();
8853 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8854 MG->getMemOperand(), MG->getIndexType(),
8855 MG->getExtensionType());
8861SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8870 DataOp = GetWidenedVector(DataOp);
8874 EVT IndexVT =
Index.getValueType();
8877 Index = ModifyToType(Index, WideIndexVT);
8880 EVT MaskVT =
Mask.getValueType();
8883 Mask = ModifyToType(Mask, WideMaskVT,
true);
8888 }
else if (OpNo == 4) {
8890 Index = GetWidenedVector(Index);
8896 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8901SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8910 DataOp = GetWidenedVector(DataOp);
8911 Index = GetWidenedVector(Index);
8913 Mask = GetWidenedMask(Mask, WideEC);
8916 }
else if (OpNo == 3) {
8918 Index = GetWidenedVector(Index);
8925 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8930 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8931 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8933 EVT VT =
N->getValueType(0);
8948 SVT, InOp0, InOp1,
N->getOperand(2));
8954 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8956 EVT OpVT =
N->getOperand(0).getValueType();
8959 return DAG.getNode(ExtendCode, dl, VT,
CC);
8969 EVT VT =
N->getValueType(0);
8971 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8978 for (
unsigned i = 0; i != NumElts; ++i) {
8979 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8980 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8982 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8983 {Chain, LHSElem, RHSElem, CC});
8984 Chains[i] = Scalars[i].getValue(1);
8985 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8986 DAG.getBoolConstant(
true, dl, EltVT, VT),
8987 DAG.getBoolConstant(
false, dl, EltVT, VT));
8991 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8993 return DAG.getBuildVector(VT, dl, Scalars);
9017 SDValue Op = GetWidenedVector(
N->getOperand(0));
9018 EVT VT =
N->getValueType(0);
9019 EVT OrigVT =
N->getOperand(0).getValueType();
9020 EVT WideVT =
Op.getValueType();
9022 SDNodeFlags
Flags =
N->getFlags();
9024 unsigned Opc =
N->getOpcode();
9026 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
9027 assert(NeutralElem &&
"Neutral element must exist");
9037 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
9044 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
9045 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
9051 unsigned GCD = std::gcd(OrigElts, WideElts);
9054 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
9055 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx =
Idx + GCD)
9056 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
9057 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
9060 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx++)
9061 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
9063 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
9072 EVT VT =
N->getValueType(0);
9074 EVT WideVT =
Op.getValueType();
9076 SDNodeFlags
Flags =
N->getFlags();
9078 unsigned Opc =
N->getOpcode();
9080 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
9090 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
9093 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
9094 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
9100 unsigned GCD = std::gcd(OrigElts, WideElts);
9103 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
9104 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx =
Idx + GCD)
9105 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
9106 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
9109 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx++)
9110 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
9112 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
9116 assert(
N->isVPOpcode() &&
"Expected VP opcode");
9119 SDValue Op = GetWidenedVector(
N->getOperand(1));
9121 Op.getValueType().getVectorElementCount());
9123 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
9124 {N->getOperand(0), Op, Mask, N->getOperand(3)},
9132 EVT VT =
N->getValueType(0);
9136 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
9137 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
9142 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
9148 EVT SourceVT =
Source.getValueType();
9149 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9153 WideSource = GetWidenedVector(Source);
9160 WideSource = GetWidenedVector(Source);
9162 SmallVector<int>
Mask(WideElts);
9163 std::iota(
Mask.begin(),
Mask.end(), 0);
9165 Mask[
I] += WideElts;
9166 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
9168 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
9172 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
9179 EVT SrcVT =
Source.getValueType();
9183 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
9184 {Source, Mask, N->getOperand(2)},
N->getFlags());
9187SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
9190 EVT OrigMaskVT =
Mask.getValueType();
9191 SDValue WideMask = GetWidenedVector(Mask);
9197 if (OrigElts != WideElts) {
9198 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
9200 Mask, DAG.getVectorIdxConstant(0,
DL));
9207SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
9210 EVT ResVT =
N->getValueType(0);
9211 EVT SourceVT =
N->getOperand(0).getValueType();
9212 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9217 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
9218 N->getOperand(0), 0);
9219 SDValue WideMask = DAG.getInsertSubvector(
9220 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
9222 N->getOperand(1), WideMask,
N->getFlags());
9223 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
9227 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
9233 return TLI.expandVectorMatch(
N, DAG);
9235 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
9239 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
9240 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
9243 N->getOperand(0), WideNeedle,
N->getOperand(2),
9261 unsigned WidenEx = 0) {
9266 unsigned AlignInBits =
Align*8;
9268 EVT RetVT = WidenEltVT;
9273 if (Width == WidenEltWidth)
9284 (WidenWidth % MemVTWidth) == 0 &&
9286 (MemVTWidth <= Width ||
9287 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9288 if (MemVTWidth == WidenWidth)
9307 (WidenWidth % MemVTWidth) == 0 &&
9309 (MemVTWidth <= Width ||
9310 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9319 return std::nullopt;
9330 unsigned Start,
unsigned End) {
9331 SDLoc dl(LdOps[Start]);
9332 EVT LdTy = LdOps[Start].getValueType();
9340 for (
unsigned i = Start + 1; i !=
End; ++i) {
9341 EVT NewLdTy = LdOps[i].getValueType();
9342 if (NewLdTy != LdTy) {
9361 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9362 EVT LdVT =
LD->getMemoryVT();
9372 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9376 TypeSize WidthDiff = WidenWidth - LdWidth;
9383 std::optional<EVT> FirstVT =
9384 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
9391 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
9396 std::optional<EVT> NewVT = FirstVT;
9397 TypeSize RemainingWidth = LdWidth;
9398 TypeSize NewVTWidth = FirstVTWidth;
9400 RemainingWidth -= NewVTWidth;
9407 NewVTWidth = NewVT->getSizeInBits();
9413 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9427 MachinePointerInfo MPI =
LD->getPointerInfo();
9433 for (EVT MemVT : MemVTs) {
9434 Align NewAlign = ScaledOffset == 0
9435 ?
LD->getBaseAlign()
9437 SDValue L = DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags,
9457 EVT LdTy = LdOps[i].getValueType();
9460 for (--i; i >= 0; --i) {
9461 LdTy = LdOps[i].getValueType();
9468 ConcatOps[--
Idx] = LdOps[i];
9469 for (--i; i >= 0; --i) {
9470 EVT NewLdTy = LdOps[i].getValueType();
9471 if (NewLdTy != LdTy) {
9482 WidenOps[j] = ConcatOps[Idx+j];
9484 WidenOps[j] = DAG.getPOISON(LdTy);
9491 ConcatOps[--
Idx] = LdOps[i];
9502 SDValue UndefVal = DAG.getPOISON(LdTy);
9505 for (; i !=
End-
Idx; ++i)
9506 WidenOps[i] = ConcatOps[Idx+i];
9508 WidenOps[i] = UndefVal;
9519 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9520 EVT LdVT =
LD->getMemoryVT();
9529 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9543 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9544 LdEltVT,
LD->getBaseAlign(), MMOFlags,
Metadata);
9550 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9551 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9557 SDValue UndefVal = DAG.getPOISON(EltVT);
9558 for (; i != WidenNumElts; ++i)
9561 return DAG.getBuildVector(WidenVT, dl,
Ops);
9572 MMOMetadata
Metadata =
ST->getMMOMetadataForSubAccess();
9573 SDValue ValOp = GetWidenedVector(
ST->getValue());
9576 EVT StVT =
ST->getMemoryVT();
9584 "Mismatch between store and value types");
9588 MachinePointerInfo MPI =
ST->getPointerInfo();
9598 std::optional<EVT> NewVT =
9603 TypeSize NewVTWidth = NewVT->getSizeInBits();
9606 StWidth -= NewVTWidth;
9607 MemVTs.
back().second++;
9611 for (
const auto &Pair : MemVTs) {
9612 EVT NewVT = Pair.first;
9613 unsigned Count = Pair.second;
9619 Align NewAlign = ScaledOffset == 0
9620 ?
ST->getBaseAlign()
9622 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9623 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9639 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9641 DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
ST->getBaseAlign(),
9659 bool FillWithZeroes) {
9664 "input and widen element type must match");
9666 "cannot modify scalable vectors in this way");
9679 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9681 for (
unsigned i = 1; i != NumConcat; ++i)
9688 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9694 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9699 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9700 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9702 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9704 unsigned NumResultParts = NewNumElts / CommonFactor;
9705 if (NumResultParts > NumCopiedParts) {
9706 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9707 : DAG.getPOISON(PartVT);
9708 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9715 "Scalable vectors should have been handled already.");
9723 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9725 for (Idx = 0;
Idx < MinNumElts; ++
Idx)
9726 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9728 SDValue UndefVal = DAG.getPOISON(EltVT);
9729 for (;
Idx < WidenNumElts; ++
Idx)
9730 Ops[Idx] = UndefVal;
9732 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9733 if (!FillWithZeroes)
9737 "We expect to never want to FillWithZeroes for non-integral types.");
9740 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9741 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9743 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9744 DAG.getBuildVector(NVT, dl, MaskOps));
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT, TypeSize FirstVTWidth, const SDLoc &dl, SelectionDAG &DAG)
Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the widened value so it can b...
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
SmallVector< MachineOperand, 4 > Cond
const MachineOperand & HiOp1
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file implements the SmallBitVector class.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
constexpr bool isScalar() const
Exactly one element.
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
const MDNode * getMemCacheHint() const
Returns the cache hint metadata for this memory access.
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
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() 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
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
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*X will result in a value whose quantity matches our ...
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*X will result in a value whose quantity matches our own.
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.
constexpr bool isZero() const
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 ...
@ ATOMIC_LOAD_FMINIMUMNUM
@ LOOP_DEPENDENCE_RAW_MASK
@ MASK_BEFOREFIRST
Has one mask vector operand.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ AVGSUBFLOORS
AVGSUBFLOORS/AVGSUBFLOORU - Averaging subtract - Subtract two integers using an integer of type i[N+1...
@ 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.
@ VECREDUCE_FMAXIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM nodes do not propagate NaNs and order signed zeroes using the llvm....
@ 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 - Same as FMINNUM/FMAXNUM, except that a signaling NaN operand deterministi...
@ 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 - Same semantics as the llvm.minnum/maxnum intrinsics.
@ 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...
@ ATOMIC_LOAD_FMAXIMUMNUM
@ 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 - Same semantics as the llvm.minimum/maximum intrinsics.
@ 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_MATCH
VECTOR_MATCH - this corresponds to the llvm.experimental.vector.match intrinsic.
@ 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.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ 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_REPEAT
VECTOR_REPEAT(FIXED_LENGTH_VECTOR) Repeatedly copies the elements of the source fixed-length vector t...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - Same semantics as the llvm.minimumnum/maximumnum intrinsics.
@ 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 isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
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.
Type * getValueType(Value *V, bool ReVec, bool LookThroughCmp)
Returns the "element type" of the given value/instruction V.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
@ Mul
Product of integers.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
@ End
Run the machine verifier once, at the end of the pipeline.
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.
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.
EVT changeVectorElementCount(LLVMContext &Context, ElementCount EC) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element coun...
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.