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));
331 SDValue
Mask =
N->getOperand(2);
332 EVT MaskVT =
Mask.getValueType();
337 Mask = GetScalarizedVector(Mask);
345 SDValue Divisor = DAG.getSelect(
DL,
LHS.getValueType(), Mask,
RHS,
346 DAG.getConstant(1,
DL,
LHS.getValueType()));
348 LHS.getValueType(),
LHS, Divisor);
354 SDValue
LHS =
N->getOperand(0);
355 SDValue
RHS =
N->getOperand(1);
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));
388 SDValue
L =
N->getOperand(1);
389 SDValue
R =
N->getOperand(2);
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));
428 SDValue(ScalarNode, OtherNo));
429 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
432 return SDValue(ScalarNode, ResNo);
437 unsigned NumOpers =
N->getNumOperands();
438 SDValue Chain =
N->getOperand(0);
439 EVT ValueVTs[] = {VT, MVT::Other};
448 for (
unsigned i = 1; i < NumOpers; ++i) {
449 SDValue Oper =
N->getOperand(i);
454 Oper = GetScalarizedVector(Oper);
463 SDValue
Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
464 Opers,
N->getFlags());
468 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
475 EVT ResVT =
N->getValueType(0);
476 EVT OvVT =
N->getValueType(1);
478 SDValue ScalarLHS, ScalarRHS;
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));
502 SDValue OtherVal = DAG.
getNode(
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) {
519 SDValue
Mask = TLI.expandLoopDependenceMask(
N, DAG);
521 N->getValueType(0).getScalarType(), Mask,
522 DAG.getVectorIdxConstant(0,
DL));
526 SDValue
Op =
N->getOperand(0);
528 Op = GetScalarizedVector(
Op);
529 EVT NewVT =
N->getValueType(0).getVectorElementType();
534SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(
SDNode *
N) {
536 SDValue InOp =
N->getOperand(0);
544SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
546 N->getValueType(0).getVectorElementType(),
547 N->getOperand(0),
N->getOperand(1));
552 SDValue
Op =
N->getOperand(0);
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) {
569 SDValue
Op =
N->getOperand(0);
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) {
586 SDValue
Op =
N->getOperand(0);
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));
609 SDValue
RHS =
N->getOperand(1);
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) {
626 SDValue
Op =
N->getOperand(1);
628 if (
Op.getValueType() != EltVT)
635 SDValue
Result = DAG.getAtomicLoad(
636 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
637 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
642 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
647 SDValue
Result = DAG.getAtomic(
648 N->getOpcode(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
649 N->getChain(),
N->getBasePtr(), GetScalarizedVector(
N->getVal()),
652 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
657 assert(
N->isUnindexed() &&
"Indexed vector load?");
659 SDValue
Result = DAG.getLoad(
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());
669 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
676 SDValue
Op =
N->getOperand(0);
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));
705 SDValue
Op =
N->getOperand(0);
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) {
731 SDValue
Op =
N->getOperand(0);
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)));
777 SDValue
Cond =
N->getOperand(0);
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) {
871 SDValue Src =
N->getOperand(0);
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");
891 SDValue
LHS =
N->getOperand(0);
892 SDValue
RHS =
N->getOperand(1);
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) {
947 SDValue Res = SDValue();
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));
991 SDValue
Op = DAG.getNode(
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));
1155 SDValue Res = DAG.
getNode(
N->getOpcode(), SDLoc(
N),
1156 {
N->getValueType(0).getScalarType(), MVT::Other },
1157 {
N->getOperand(0), Elt });
1160 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
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);
1258 SDValue Ch =
N->getOperand(0);
1259 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
1260 SDValue
RHS = GetScalarizedVector(
N->getOperand(2));
1261 SDValue
CC =
N->getOperand(3);
1263 EVT OpVT =
N->getOperand(1).getValueType();
1266 SDValue Res = DAG.
getNode(
N->getOpcode(),
DL, {MVT::i1, MVT::Other},
1267 {Ch, LHS, RHS, CC});
1271 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
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);
1325 return SDValue(Res, 0);
1328 ReplaceValueWith(SDValue(
N, 0), SDValue(Res, 0));
1329 ReplaceValueWith(SDValue(
N, 1), SDValue(Res, 1));
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},
1367 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
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});
1396 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
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));
1430 SDValue
Cmp = DAG.getNode(
N->getOpcode(), SDLoc(
N), ResVT,
LHS,
RHS);
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) {
1461 SDValue
Mask = TLI.expandVectorMatch(
N, DAG);
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);
1478 SDValue
Mask = GetScalarizedVector(
N->getOperand(2));
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);
1798 SetSplitVector(SDValue(
N, ResNo),
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,
1829 SDValue MaskLo, MaskHi;
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);
1839 SDValue LHSLo, LHSHi;
1840 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1841 SDValue RHSLo, RHSHi;
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");
1858 SDValue MaskLo, MaskHi;
1859 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1861 SDValue EVLLo, EVLHi;
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);
1873 SDValue LHSLo, LHSHi;
1874 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1875 SDValue RHSLo, RHSHi;
1876 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1878 SDValue MaskLo, MaskHi,
Mask =
N->getOperand(2);
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,
1896 SDValue Op0Lo, Op0Hi;
1897 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1898 SDValue Op1Lo, Op1Hi;
1899 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1900 SDValue Op2Lo, Op2Hi;
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();
1916 SDValue
LHS =
N->getOperand(0);
1917 SDValue
RHS =
N->getOperand(1);
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);
1934 SDValue LHSLo, LHSHi;
1935 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1936 SDValue RHSLo, RHSHi;
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,
2018 SDValue PtrA =
N->getOperand(0);
2019 SDValue PtrB =
N->getOperand(1);
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);
2046 SDValue
Cond = DAG.getBoolExtOrTrunc(AnyLoActive,
DL,
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,
2088 SDValue Vec =
N->getOperand(0);
2089 SDValue
Idx =
N->getOperand(1);
2093 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2106 SDValue
Idx =
N->getOperand(2);
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);
2181 SDValue LHSLo, LHSHi;
2182 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2185 SDValue RHSLo, RHSHi;
2186 SDValue
RHS =
N->getOperand(1);
2187 EVT RHSVT =
RHS.getValueType();
2190 GetSplitVector(
RHS, RHSLo, RHSHi);
2192 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2205 SDValue ArgLo, ArgHi;
2206 SDValue
Test =
N->getOperand(1);
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));
2221 SDValue LHSLo, LHSHi;
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();
2238 SDValue N0 =
N->getOperand(0);
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) {
2290 SDValue
Op =
N->getOperand(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();
2408 Lo = SDValue(LoNode, ResNo);
2409 Hi = SDValue(HiNode, ResNo);
2412 unsigned OtherNo = 1 - ResNo;
2413 EVT OtherVT =
N->getValueType(OtherNo);
2415 SetSplitVector(SDValue(
N, OtherNo),
2416 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2418 SDValue OtherVal = DAG.
getNode(
2420 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2421 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
2425void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2429 SDValue
Idx =
N->getOperand(2);
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));
2507 SDValue Step =
N->getOperand(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);
2546 SDValue Ch =
LD->getChain();
2547 SDValue Ptr =
LD->getBasePtr();
2552 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2553 Ch, Ptr,
LD->getMemOperand());
2557 SDValue ExtractLo, ExtractHi;
2558 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2560 Lo = DAG.getBitcast(LoVT, ExtractLo);
2561 Hi = DAG.getBitcast(HiVT, ExtractHi);
2565 ReplaceValueWith(SDValue(LD, 1), ALD.
getValue(1));
2573 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2576 SDValue Ch =
LD->getChain();
2577 SDValue Ptr =
LD->getBasePtr();
2579 EVT MemoryVT =
LD->getMemoryVT();
2581 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
2583 EVT LoMemVT, HiMemVT;
2584 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2587 SDValue
Value, NewChain;
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));
2622 SDValue Ch =
LD->getChain();
2623 SDValue Ptr =
LD->getBasePtr();
2625 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2627 SDValue
Mask =
LD->getMask();
2628 SDValue EVL =
LD->getVectorLength();
2629 EVT MemoryVT =
LD->getMemoryVT();
2631 EVT LoMemVT, HiMemVT;
2632 bool HiIsEmpty =
false;
2633 std::tie(LoMemVT, HiMemVT) =
2634 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2637 SDValue MaskLo, MaskHi;
2639 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2642 GetSplitVector(Mask, MaskLo, MaskHi);
2644 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2648 SDValue EVLLo, EVLHi;
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));
2700 SDValue Ch =
LD->getChain();
2701 SDValue Ptr =
LD->getBasePtr();
2703 SDValue
Mask =
LD->getMask();
2704 SDValue EVL =
LD->getVectorLength();
2707 SDValue MaskLo, MaskHi;
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);
2752 SDValue LoMask, HiMask;
2754 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2757 GetSplitVector(Mask, LoMask, HiMask);
2759 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2762 SDValue LoEVL, HiEVL;
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");
2833 SDValue MaskLo, MaskHi;
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));
2907 SDValue Ch =
N->getChain();
2908 SDValue Ptr =
N->getBasePtr();
2915 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2918 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2921 EVT MemoryVT =
N->getMemoryVT();
2925 SDValue MaskLo, MaskHi;
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);
2936 SDValue IndexHi, IndexLo;
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);
2969 SDValue EVLLo, EVLHi;
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);
3027 SDValue
Mask =
N->getOperand(1);
3028 SDValue LoMask, HiMask;
3029 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3030 std::tie(LoMask, HiMask) = SplitMask(Mask);
3032 SDValue UndefPassthru = DAG.getPOISON(LoVT);
3036 SDValue
StackPtr = DAG.CreateStackTemporary(
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();
3065 SDValue NumActiveElts =
3068 SDValue StepVector = DAG.getStepVector(
DL, WideMaskVT);
3069 SDValue SplatNumActiveElts = DAG.getSplat(WideMaskVT,
DL, NumActiveElts);
3070 SDValue CompressedMask =
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));
3089 SDValue LL, LH, RL, RH;
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);
3188 SetSplitVector(SDValue(
N, OtherNo), SDValue(LoNode, OtherNo),
3189 SDValue(HiNode, OtherNo));
3193 SDValue(HiNode, 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);
3535 SDValue OrigInputs[4];
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);
3548 SDValue TmpInputs[4];
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);
3604 SDValue
SV =
N->getOperand(2);
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));
3625 SDValue SrcLo, SrcHi;
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);
3639 SDValue Src =
N->getOperand(0);
3640 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VT);
3641 assert(LoVT == HiVT &&
"Expected equal split types");
3646 auto [SrcLo, SrcHi] = DAG.SplitVector(Src,
DL);
3648 SDValue Deinterleaved =
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);
3682 SDValue Val =
N->getOperand(0);
3683 SDValue
Mask =
N->getOperand(1);
3704 EVT PtrVT =
StackPtr.getValueType();
3705 auto &MF = DAG.getMachineFunction();
3709 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3712 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3717 SDValue NumElemMinus1 =
3718 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3719 DAG.getConstant(1,
DL, PtrVT));
3720 SDValue StartOffset = DAG.getNode(
ISD::MUL,
DL, PtrVT, NumElemMinus1,
3721 DAG.getConstant(EltWidth,
DL, PtrVT));
3722 SDValue StorePtr = DAG.getNode(
ISD::ADD,
DL, PtrVT, StackPtr, StartOffset);
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,
3730 SDValue
Load = DAG.getLoadVP(VT,
DL,
Store, StackPtr, Mask, EVL, LoadMMO);
3736 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3741 EVT VT =
N->getValueType(0);
3742 SDValue
V1 =
N->getOperand(0);
3743 SDValue V2 =
N->getOperand(1);
3745 SDValue
Mask =
N->getOperand(3);
3746 SDValue EVL1 =
N->getOperand(4);
3747 SDValue EVL2 =
N->getOperand(5);
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(
3784 SDValue EltByteSize =
3786 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3787 SDValue EVL1Bytes = DAG.getNode(
ISD::MUL,
DL, PtrVT, EVL1Ptr, EltByteSize);
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);
3813 SDValue OffsetToV2 = DAG.getNode(
ISD::SUB,
DL, PtrVT, StackPtr2, StackPtr);
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,
3842 SDValue AccLo, AccHi;
3843 GetSplitVector(Acc, AccLo, AccHi);
3844 unsigned Opcode =
N->getOpcode();
3854 SDValue Input1Lo, Input1Hi;
3855 SDValue Input2Lo, Input2Hi;
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));
3876 SDValue HiStartVal = DAG.getNode(
ISD::UADDSAT,
DL, OpVT, Op0, LoElts);
3882 SDValue SourceLo, SourceHi;
3883 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3884 SDValue MaskLo, MaskHi;
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) {
3954 SDValue Res = SDValue();
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) {
4160 SDValue LoMask, HiMask;
4161 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4163 EVT VT =
N->getValueType(0);
4175 SDValue
Cond = DAG.getBoolExtOrTrunc(AnyHiActive,
DL,
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");
4190 SDValue
Mask =
N->getOperand(0);
4191 SDValue
Src0 =
N->getOperand(1);
4192 SDValue
Src1 =
N->getOperand(2);
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?");
4206 SDValue LoOp0, HiOp0, LoOp1,
HiOp1, LoMask, HiMask;
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);
4225 SDValue MaskLo, MaskHi;
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);
4284 SDValue Partial = DAG.
getNode(
N->getOpcode(), dl, ResVT, AccOp,
Lo, Flags);
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);
4304 SDValue MaskLo, MaskHi;
4305 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4307 SDValue EVLLo, EVLHi;
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);
4392 SDValue
Idx =
N->getOperand(2);
4396 GetSplitVector(SubVec,
Lo,
Hi);
4401 SDValue FirstInsertion =
4403 SDValue SecondInsertion =
4405 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4407 return SecondInsertion;
4410SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4413 SDValue
Idx =
N->getOperand(1);
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) {
4511 SDValue
Idx =
N->getOperand(1);
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);
4525 return SDValue(DAG.UpdateNodeOperands(
N,
Hi,
4526 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4527 Idx.getValueType())), 0);
4531 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4541 SDValue NewExtract =
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?");
4593 SDValue Ch =
N->getChain();
4594 SDValue Ptr =
N->getBasePtr();
4595 SDValue
Offset =
N->getOffset();
4596 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4597 SDValue
Mask =
N->getMask();
4598 SDValue EVL =
N->getVectorLength();
4599 SDValue
Data =
N->getValue();
4603 SDValue DataLo, DataHi;
4606 GetSplitVector(
Data, DataLo, DataHi);
4608 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4611 SDValue MaskLo, MaskHi;
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);
4628 SDValue EVLLo, EVLHi;
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");
4677 SDValue
Data =
N->getValue();
4678 SDValue LoData, HiData;
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(
4689 SDValue
Mask =
N->getMask();
4690 SDValue LoMask, HiMask;
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);
4699 SDValue LoEVL, HiEVL;
4700 std::tie(LoEVL, HiEVL) =
4701 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4704 SDValue
Lo = DAG.getStridedStoreVP(
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()));
4734 SDValue
Hi = DAG.getStridedStoreVP(
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?");
4747 SDValue Ch =
N->getChain();
4748 SDValue Ptr =
N->getBasePtr();
4749 SDValue
Offset =
N->getOffset();
4750 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4751 SDValue
Mask =
N->getMask();
4752 SDValue
Data =
N->getValue();
4756 SDValue DataLo, DataHi;
4759 GetSplitVector(
Data, DataLo, DataHi);
4761 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4764 SDValue MaskLo, MaskHi;
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);
4780 SDValue
Lo,
Hi, Res;
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());
4826 SDValue Ch =
N->getChain();
4827 SDValue Ptr =
N->getBasePtr();
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);
4850 SDValue DataLo, DataHi;
4853 GetSplitVector(
Ops.Data, DataLo, DataHi);
4855 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4858 SDValue MaskLo, MaskHi;
4860 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4862 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4865 SDValue IndexHi, IndexLo;
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());
4893 SDValue EVLLo, EVLHi;
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();
4915 SDValue Ch =
N->getChain();
4916 SDValue Ptr =
N->getBasePtr();
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();
4953 SDValue StVal =
N->getVal();
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());
5004 for (
const SDValue &
Op :
N->op_values()) {
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);
5064 SDValue InLoVec, InHiVec;
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()))});
5109 ReplaceValueWith(SDValue(
N, 1), SDValue(Res.
getNode(), 1));
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());
5209 SDValue LHSLo, LHSHi;
5210 std::tie(LHSLo, LHSHi) =
5211 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5213 SDValue RHSLo, RHSHi;
5214 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5216 SDValue
Lo = DAG.
getNode(
N->getOpcode(),
DL, LHSLoVT, LHSLo, RHSLo);
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());
5271 SDValue ResLoNotVL =
5272 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5273 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi);
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);
5293 SDValue ResLo = DAG.
getNode(ISD::VP_CTTZ_ELTS,
DL, ResVT,
Lo, MaskLo, EVLLo);
5294 SDValue ResLoNotEVL =
5295 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5296 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi, MaskHi, EVLHi);
5297 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5298 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5301SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5304 SDValue Inc = HG->
getInc();
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));
5329 SDValue SourceLo, SourceHi;
5330 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5331 SDValue MaskLo, MaskHi;
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");
5345 SDValue NeedleLo, NeedleHi;
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);
5386 SetWidenedVector(SDValue(
N, ResNo), SDValue(WidenNode, 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)))
5403 SDValue Res = SDValue();
5405 auto unrollExpandedOp = [&]() {
5410 EVT ResVT =
N->getValueType(ResNo);
5411 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5412 EVT VT0 =
N->getValueType(0);
5413 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5414 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT0.
getScalarType())) {
5418 if (
N->getNumValues() > 1)
5419 ReplaceOtherWidenResults(
N, Unrolled.
getNode(), ResNo);
5425 switch (
N->getOpcode()) {
5428 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5436 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5440 Res = WidenVecRes_ADDRSPACECAST(
N);
5447 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5454 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5458 Res = WidenVecRes_ScalarOp(
N);
5464 Res = WidenVecRes_Select(
N);
5467 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5469 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5476 case ISD::VP_LOAD_FF:
5479 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5483 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5491 case ISD::VP_GATHER:
5495 Res = WidenVecRes_VECTOR_REVERSE(
N);
5498 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5501 WidenVecRes_VECTOR_INTERLEAVE(
N);
5504 Res = WidenVecRes_VECTOR_MATCH(
N);
5507 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5563 Res = WidenVecRes_Binary(
N);
5570 Res = WidenVecRes_MaskedBinary(
N);
5575 Res = WidenVecRes_CMP(
N);
5581 if (unrollExpandedOp())
5596 Res = WidenVecRes_BinaryCanTrap(
N);
5605 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5608#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5609 case ISD::STRICT_##DAGN:
5610#include "llvm/IR/ConstrainedOps.def"
5611 Res = WidenVecRes_StrictFP(
N);
5620 Res = WidenVecRes_OverflowOp(
N, ResNo);
5624 Res = WidenVecRes_FCOPYSIGN(
N);
5629 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5634 if (!unrollExpandedOp())
5635 Res = WidenVecRes_ExpOp(
N);
5641 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5656 Res = WidenVecRes_Convert(
N);
5661 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5668 Res = WidenVecRes_XROUND(
N);
5694 if (unrollExpandedOp())
5717 Res = WidenVecRes_Unary(
N);
5722 Res = WidenVecRes_Ternary(
N);
5728 if (!unrollExpandedOp())
5729 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5736 Res = WidenVecRes_PARTIAL_REDUCE_MLA(
N);
5742 SetWidenedVector(SDValue(
N, ResNo), Res);
5748 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5749 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5750 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5751 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5752 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5758 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5759 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5760 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5761 if (
N->getNumOperands() == 2)
5762 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5765 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5766 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5767 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5768 "Expected VP opcode");
5772 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5773 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5778 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5779 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5780 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5781 SDValue
Mask =
N->getOperand(2);
5783 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5784 Mask = ModifyToType(Mask, WideMaskVT,
true);
5785 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5790 LLVMContext &Ctxt = *DAG.getContext();
5793 SDValue
LHS =
N->getOperand(0);
5794 SDValue
RHS =
N->getOperand(1);
5795 EVT OpVT =
LHS.getValueType();
5797 LHS = GetWidenedVector(
LHS);
5798 RHS = GetWidenedVector(
RHS);
5799 OpVT =
LHS.getValueType();
5802 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5805 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5811SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5814 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5815 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5816 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5818 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5827 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5830 if (ConcatEnd == 1) {
5831 VT = ConcatOps[0].getValueType();
5833 return ConcatOps[0];
5836 SDLoc dl(ConcatOps[0]);
5843 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
5844 int Idx = ConcatEnd - 1;
5845 VT = ConcatOps[Idx--].getValueType();
5846 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
5859 unsigned NumToInsert = ConcatEnd - Idx - 1;
5860 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5862 ConcatOps[Idx+1] = VecOp;
5863 ConcatEnd = Idx + 2;
5869 unsigned RealVals = ConcatEnd - Idx - 1;
5870 unsigned SubConcatEnd = 0;
5871 unsigned SubConcatIdx = Idx + 1;
5872 while (SubConcatEnd < RealVals)
5873 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5874 while (SubConcatEnd < OpsToConcat)
5875 SubConcatOps[SubConcatEnd++] = undefVec;
5877 NextVT, SubConcatOps);
5878 ConcatEnd = SubConcatIdx + 1;
5883 if (ConcatEnd == 1) {
5884 VT = ConcatOps[0].getValueType();
5886 return ConcatOps[0];
5891 if (
NumOps != ConcatEnd ) {
5893 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5894 ConcatOps[j] = UndefVal;
5902 unsigned Opcode =
N->getOpcode();
5904 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5908 const SDNodeFlags
Flags =
N->getFlags();
5909 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5910 NumElts = NumElts / 2;
5914 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5916 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5917 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5918 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5926 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5929 TLI.isTypeLegal(WideMaskVT)) {
5930 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5931 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5932 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5934 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5935 N->getValueType(0).getVectorElementCount());
5936 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5950 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5951 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5952 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5955 unsigned ConcatEnd = 0;
5963 while (CurNumElts != 0) {
5964 while (CurNumElts >= NumElts) {
5965 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5966 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5967 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5969 CurNumElts -= NumElts;
5972 NumElts = NumElts / 2;
5974 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5977 for (
unsigned i = 0; i != CurNumElts; ++i, ++
Idx) {
5978 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5979 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5980 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5991 switch (
N->getOpcode()) {
5994 return WidenVecRes_STRICT_FSETCC(
N);
6001 return WidenVecRes_Convert_StrictFP(
N);
6008 unsigned Opcode =
N->getOpcode();
6010 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6014 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
6015 NumElts = NumElts / 2;
6026 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
6030 unsigned ConcatEnd = 0;
6037 for (
unsigned i = 1; i < NumOpers; ++i) {
6043 Oper = GetWidenedVector(Oper);
6049 DAG.getPOISON(WideOpVT), Oper,
6050 DAG.getVectorIdxConstant(0, dl));
6062 while (CurNumElts != 0) {
6063 while (CurNumElts >= NumElts) {
6066 for (
unsigned i = 0; i < NumOpers; ++i) {
6067 SDValue
Op = InOps[i];
6069 EVT OpVT =
Op.getValueType();
6074 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
6080 EVT OperVT[] = {VT, MVT::Other};
6081 SDValue Oper = DAG.
getNode(Opcode, dl, OperVT, EOps);
6082 ConcatOps[ConcatEnd++] = Oper;
6085 CurNumElts -= NumElts;
6088 NumElts = NumElts / 2;
6090 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
6093 for (
unsigned i = 0; i != CurNumElts; ++i, ++
Idx) {
6096 for (
unsigned i = 0; i < NumOpers; ++i) {
6097 SDValue
Op = InOps[i];
6099 EVT OpVT =
Op.getValueType();
6107 EVT WidenVT[] = {WidenEltVT, MVT::Other};
6108 SDValue Oper = DAG.
getNode(Opcode, dl, WidenVT, EOps);
6109 ConcatOps[ConcatEnd++] = Oper;
6118 if (Chains.
size() == 1)
6119 NewChain = Chains[0];
6122 ReplaceValueWith(SDValue(
N, 1), NewChain);
6127SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
6129 EVT ResVT =
N->getValueType(0);
6130 EVT OvVT =
N->getValueType(1);
6131 EVT WideResVT, WideOvVT;
6132 SDValue WideLHS, WideRHS;
6136 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6141 WideLHS = GetWidenedVector(
N->getOperand(0));
6142 WideRHS = GetWidenedVector(
N->getOperand(1));
6144 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6149 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
6150 SDValue
Poison = DAG.getPOISON(WideResVT);
6153 N->getOperand(0), Zero);
6155 N->getOperand(1), Zero);
6158 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6159 SDNode *WideNode = DAG.getNode(
6160 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6163 unsigned OtherNo = 1 - ResNo;
6164 EVT OtherVT =
N->getValueType(OtherNo);
6166 SetWidenedVector(SDValue(
N, OtherNo), SDValue(WideNode, OtherNo));
6168 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
6169 SDValue OtherVal = DAG.
getNode(
6171 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
6174 return SDValue(WideNode, ResNo);
6178 LLVMContext &Ctx = *DAG.getContext();
6182 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6187 unsigned Opcode =
N->getOpcode();
6188 const SDNodeFlags
Flags =
N->getFlags();
6194 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6196 InOp = ZExtPromotedInteger(InOp);
6207 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
6208 if (
N->getNumOperands() == 1)
6209 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6211 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6212 N->getOperand(3), Flags);
6213 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6217 InOp = GetWidenedVector(
N->getOperand(0));
6220 if (InVTEC == WidenEC)
6221 return MakeConvertNode(WidenVT, InOp);
6245 SDValue MidRes = DAG.getNode(
ISD::TRUNCATE,
DL, MidResVT, InOp, Flags);
6246 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6250 if (TLI.isTypeLegal(InWidenVT)) {
6258 unsigned NumConcat =
6263 return MakeConvertNode(WidenVT, InVec);
6267 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6269 return MakeConvertNode(WidenVT, InVal);
6278 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6279 for (
unsigned i=0; i < MinElts; ++i) {
6280 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6281 Ops[i] = MakeConvertNode(EltVT, Val);
6284 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6289 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6292 SDValue Src =
N->getOperand(0);
6293 EVT SrcVT = Src.getValueType();
6297 Src = GetWidenedVector(Src);
6298 SrcVT = Src.getValueType();
6305 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6310 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6313 SDValue Src =
N->getOperand(0);
6314 EVT SrcVT = Src.getValueType();
6318 Src = GetWidenedVector(Src);
6319 SrcVT = Src.getValueType();
6326 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6329SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6334 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6340 unsigned Opcode =
N->getOpcode();
6346 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6351 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6352 for (
unsigned i=0; i < MinElts; ++i) {
6353 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6354 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6358 ReplaceValueWith(SDValue(
N, 1), NewChain);
6360 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6363SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6364 unsigned Opcode =
N->getOpcode();
6368 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6377 InOp = GetWidenedVector(InOp);
6384 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6391 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6392 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6409 while (
Ops.size() != WidenNumElts)
6410 Ops.push_back(DAG.getPOISON(WidenSVT));
6412 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6418 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6419 return WidenVecRes_BinaryCanTrap(
N);
6422 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6429SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6431 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6434 SDValue Arg = GetWidenedVector(FpValue);
6435 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6440 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6441 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6442 SDValue
RHS =
N->getOperand(1);
6443 EVT ExpVT =
RHS.getValueType();
6444 SDValue ExpOp =
RHS;
6448 ExpOp = ModifyToType(
RHS, WideExpVT);
6451 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6456 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6457 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6458 if (
N->getNumOperands() == 1)
6459 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6461 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6466 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6471 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6472 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6473 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6476SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6478 EVT VT0 =
N->getValueType(0);
6479 EVT VT1 =
N->getValueType(1);
6483 "expected both results to be vectors of matching element count");
6485 LLVMContext &Ctx = *DAG.getContext();
6486 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6488 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6495 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6498 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6499 return SDValue(WidenNode, ResNo);
6502SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6503 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6504 return GetWidenedVector(WidenVec);
6509 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6521 InOp = GetWidenedVector(InOp);
6525 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6528 return DAG.getAddrSpaceCast(
6529 DL, WidenVT, InOp, AddrSpaceCastN->getSrcAddressSpace(),
6530 AddrSpaceCastN->getDestAddressSpace(), AddrSpaceCastN->getFlags());
6536 EVT VT =
N->getValueType(0);
6537 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6540 switch (getTypeAction(InVT)) {
6554 SDValue NInOp = GetPromotedInteger(InOp);
6556 if (WidenVT.
bitsEq(NInVT)) {
6559 if (DAG.getDataLayout().isBigEndian()) {
6562 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6580 InOp = GetWidenedVector(InOp);
6582 if (WidenVT.
bitsEq(InVT))
6592 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6597 unsigned NewNumParts = WidenSize / InSize;
6610 EVT OrigInVT =
N->getOperand(0).getValueType();
6615 if (TLI.isTypeLegal(NewInVT)) {
6623 if (WidenSize % InSize == 0) {
6630 DAG.ExtractVectorElements(InOp,
Ops);
6631 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6643 return CreateStackStoreLoad(InOp, WidenVT);
6646SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6648 N->getOpcode(), SDLoc(
N),
6649 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6650 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6656 EVT VT =
N->getValueType(0);
6660 EVT EltVT =
N->getOperand(0).getValueType();
6663 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6667 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6668 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6670 return DAG.getBuildVector(WidenVT, dl, NewOps);
6674 EVT InVT =
N->getOperand(0).getValueType();
6675 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6677 unsigned NumOperands =
N->getNumOperands();
6679 bool InputWidened =
false;
6683 if (WidenNumElts % NumInElts == 0) {
6685 unsigned NumConcat = WidenNumElts / NumInElts;
6686 SDValue UndefVal = DAG.getPOISON(InVT);
6688 for (
unsigned i=0; i < NumOperands; ++i)
6689 Ops[i] =
N->getOperand(i);
6690 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6695 InputWidened =
true;
6696 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6699 for (i=1; i < NumOperands; ++i)
6700 if (!
N->getOperand(i).isUndef())
6703 if (i == NumOperands)
6706 return GetWidenedVector(
N->getOperand(0));
6708 if (NumOperands == 2) {
6710 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6715 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6716 for (
unsigned i = 0; i < NumInElts; ++i) {
6718 MaskOps[i + NumInElts] = i + WidenNumElts;
6720 return DAG.getVectorShuffle(WidenVT, dl,
6721 GetWidenedVector(
N->getOperand(0)),
6722 GetWidenedVector(
N->getOperand(1)),
6729 SDValue WideVec = DAG.getPOISON(WidenVT);
6731 for (
unsigned I = 0;
I < NumOperands; ++
I)
6733 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6744 for (
unsigned i=0; i < NumOperands; ++i) {
6747 InOp = GetWidenedVector(InOp);
6748 for (
unsigned j = 0;
j < NumInElts; ++
j)
6749 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6751 SDValue UndefVal = DAG.getPOISON(EltVT);
6752 for (;
Idx < WidenNumElts; ++
Idx)
6753 Ops[Idx] = UndefVal;
6754 return DAG.getBuildVector(WidenVT, dl,
Ops);
6757SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6758 EVT VT =
N->getValueType(0);
6759 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6760 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6762 SDValue
Idx =
N->getOperand(2);
6767SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6768 EVT VT =
N->getValueType(0);
6770 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6772 SDValue
Idx =
N->getOperand(1);
6775 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6777 InOp = GetWidenedVector(InOp);
6783 if (IdxVal == 0 && InVT == WidenVT)
6790 assert(IdxVal % VTNumElts == 0 &&
6791 "Expected Idx to be a multiple of subvector minimum vector length");
6792 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6805 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6806 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6807 "down type's element count");
6814 for (;
I < VTNumElts / GCD; ++
I)
6816 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6817 for (;
I < WidenNumElts / GCD; ++
I)
6839 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6846 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6847 return DAG.getMaskedLoad(
6848 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6856 for (i = 0; i < VTNumElts; ++i)
6857 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6859 SDValue UndefVal = DAG.getPOISON(EltVT);
6860 for (; i < WidenNumElts; ++i)
6862 return DAG.getBuildVector(WidenVT, dl,
Ops);
6866 SDValue InOp = ModifyToType(
6868 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6873SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6874 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6877 N->getOperand(1),
N->getOperand(2));
6886 "Load width must be less than or equal to first value type width");
6895 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6912 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6923 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6924 EVT LdVT =
LD->getMemoryVT();
6928 SDValue Chain =
LD->getChain();
6933 TypeSize WidthDiff = WidenWidth - LdWidth;
6936 std::optional<EVT> FirstVT =
6937 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6943 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6946 Chain, BasePtr,
LD->getMemOperand());
6950 FirstVTWidth, dl, DAG);
6954 ReplaceValueWith(SDValue(LD, 1), LdOp.
getValue(1));
6968 if (!
LD->getMemoryVT().isByteSized()) {
6969 SDValue
Value, NewChain;
6970 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6971 ReplaceValueWith(SDValue(LD, 0),
Value);
6972 ReplaceValueWith(SDValue(LD, 1), NewChain);
6981 EVT VT =
LD->getValueType(0);
6982 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6983 EVT WideMaskVT = getSetCCResultType(WideVT);
6986 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6987 TLI.isTypeLegal(WideMaskVT)) {
6989 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
6990 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6994 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6995 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6999 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
7007 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
7009 Result = GenWidenVectorLoads(LdChain, LD);
7016 if (LdChain.
size() == 1)
7017 NewChain = LdChain[0];
7023 ReplaceValueWith(SDValue(
N, 1), NewChain);
7034 SDValue NewLoad = DAG.getMaskedLoad(
7035 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
7036 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
7037 LD->getAddressingMode(),
LD->getExtensionType());
7039 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
7047 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7048 SDValue
Mask =
N->getMask();
7049 SDValue EVL =
N->getVectorLength();
7056 "Unable to widen binary VP op");
7057 Mask = GetWidenedVector(Mask);
7058 assert(
Mask.getValueType().getVectorElementCount() ==
7059 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7060 .getVectorElementCount() &&
7061 "Unable to widen vector load");
7064 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
7065 N->getBasePtr(),
N->getOffset(), Mask, EVL,
7066 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
7069 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7074 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7075 SDValue
Mask =
N->getMask();
7076 SDValue EVL =
N->getVectorLength();
7082 "Unable to widen binary VP op");
7083 Mask = GetWidenedVector(Mask);
7084 assert(
Mask.getValueType().getVectorElementCount() ==
7085 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7086 .getVectorElementCount() &&
7087 "Unable to widen vector load");
7089 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
7090 Mask, EVL,
N->getMemOperand());
7091 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7092 ReplaceValueWith(SDValue(
N, 2), Res.
getValue(2));
7100 SDValue
Mask =
N->getMask();
7103 "Unable to widen VP strided load");
7104 Mask = GetWidenedVector(Mask);
7106 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7107 assert(
Mask.getValueType().getVectorElementCount() ==
7109 "Data and mask vectors should have the same number of elements");
7111 SDValue Res = DAG.getStridedLoadVP(
7112 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
7113 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
7114 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
7115 N->isExpandingLoad());
7119 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7123SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
7125 SDValue
Mask =
N->getOperand(1);
7128 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
7130 Mask.getValueType().getVectorElementType(),
7133 SDValue WideVec = ModifyToType(Vec, WideVecVT);
7134 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
7135 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
7137 WideMask, WidePassthru);
7141 EVT VT =
N->getValueType(0);
7142 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7143 SDValue
Mask =
N->getMask();
7144 EVT MaskVT =
Mask.getValueType();
7145 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7154 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7155 TLI.isTypeLegal(WideMaskVT) &&
7161 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7162 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7166 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7167 N->getMemoryVT(),
N->getMemOperand());
7168 SDValue NewVal = NewLoad;
7171 if (!
N->getPassThru()->isUndef()) {
7175 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7176 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7177 DAG.getPOISON(WidenVT), EVL);
7182 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
7188 Mask = ModifyToType(Mask, WideMaskVT,
true);
7190 SDValue Res = DAG.getMaskedLoad(
7191 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7192 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7193 ExtType,
N->isExpandingLoad());
7196 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7202 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7203 SDValue
Mask =
N->getMask();
7204 EVT MaskVT =
Mask.getValueType();
7205 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7206 SDValue Scale =
N->getScale();
7213 Mask = ModifyToType(Mask, WideMaskVT,
true);
7216 SDValue
Index =
N->getIndex();
7218 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7219 Index = ModifyToType(Index, WideIndexVT);
7220 SDValue
Ops[] = {
N->getChain(), PassThru,
Mask,
N->getBasePtr(),
Index,
7225 N->getMemoryVT().getScalarType(), WideEC);
7226 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7227 WideMemVT, dl,
Ops,
N->getMemOperand(),
7228 N->getIndexType(),
N->getExtensionType());
7232 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7237 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7238 SDValue
Mask =
N->getMask();
7239 SDValue Scale =
N->getScale();
7243 SDValue
Index = GetWidenedVector(
N->getIndex());
7245 N->getMemoryVT().getScalarType(), WideEC);
7246 Mask = GetWidenedMask(Mask, WideEC);
7248 SDValue
Ops[] = {
N->getChain(),
N->getBasePtr(),
Index, Scale,
7249 Mask,
N->getVectorLength()};
7250 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7251 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7255 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7260 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7261 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7289 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7290 return N->getOperand(OpNo).getValueType();
7298 N =
N.getOperand(0);
7300 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7301 if (!
N->getOperand(i)->isUndef())
7303 N =
N.getOperand(0);
7307 N =
N.getOperand(0);
7309 N =
N.getOperand(0);
7335 { MaskVT, MVT::Other },
Ops);
7336 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7342 return adjustMaskToType(Mask, ToMaskVT);
7348 LLVMContext &Ctx = *DAG.getContext();
7349 EVT MaskVT =
Mask.getValueType();
7352 if (MaskScalarBits < ToMaskScalBits) {
7356 }
else if (MaskScalarBits > ToMaskScalBits) {
7362 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7364 "Mask should have the right element size by now.");
7367 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7369 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7372 EVT SubVT =
Mask->getValueType(0);
7378 assert((
Mask->getValueType(0) == ToMaskVT) &&
7379 "A mask of ToMaskVT should have been produced by now.");
7386EVT DAGTypeLegalizer::unifyMaskTypes(
SDValue &Op0,
bool IsOpLenient0,
7387 SDValue &Op1,
bool IsOpLenient1,
7391 "unifyMaskTypes only handles scalar width differences");
7403 if (IsOpLenient0 != IsOpLenient1) {
7404 SDValue *LenientOp, *NonLenientOp;
7407 NonLenientOp = &Op1;
7410 NonLenientOp = &Op0;
7413 *LenientOp = adjustMaskToType(*LenientOp, OpVT);
7419 unsigned NarrowBits = std::min(Bits0, Bits1);
7420 unsigned WideBits = std::max(Bits0, Bits1);
7422 unsigned IntBits = NarrowBits == WideBits ? NarrowBits
7423 : ToBits >= WideBits ? WideBits
7424 : ToBits <= NarrowBits ? NarrowBits
7428 Op0 = adjustMaskToType(Op0, OpVT);
7429 Op1 = adjustMaskToType(Op1, OpVT);
7433std::pair<SDValue, bool>
7434DAGTypeLegalizer::convertMaskTreeImpl(
SDValue V,
EVT ToVT,
unsigned Depth) {
7466 if (
Depth >= DAG.MaxRecursionDepth)
7475 unsigned Opcode =
V.getOpcode();
7480 return {convertMask(V, MaskVT, MaskVT),
false};
7488 return {DAG.getConstant(0,
DL, ToVT),
true};
7490 return {DAG.getAllOnesConstant(
DL, ToVT),
true};
7495 auto [Op0, IsLenientOp0] =
7496 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7499 auto [Op1, IsLenientOp1] =
7500 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7503 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7504 return {DAG.getNode(Opcode,
DL, OpVT, Op0, Op1),
7505 IsLenientOp0 && IsLenientOp1};
7510 auto [Inner, IsTypeLenient] =
7511 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7514 return {DAG.getNode(
ISD::FREEZE,
DL, Inner.getValueType(), Inner),
7521 auto [Op0, IsLenientOp0] =
7522 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7525 if (
V.getOperand(1).isUndef()) {
7527 return {DAG.getVectorShuffle(OpVT,
DL, Op0, DAG.getUNDEF(OpVT),
7531 auto [Op1, IsLenientOp1] =
7532 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7535 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7536 return {DAG.getVectorShuffle(OpVT,
DL, Op0, Op1, Shuf->getMask()),
7537 IsLenientOp0 && IsLenientOp1};
7542 auto [Op1, IsLenientOp1] =
7543 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7546 auto [Op2, IsLenientOp2] =
7547 convertMaskTreeImpl(
V.getOperand(2), ToVT,
Depth + 1);
7550 EVT OpVT = unifyMaskTypes(Op1, IsLenientOp1, Op2, IsLenientOp2, ToVT);
7559 SDValue
Cond =
V.getOperand(0);
7560 return {DAG.getNode(Opcode,
DL, OpVT,
Cond, Op1, Op2),
7561 IsLenientOp1 && IsLenientOp2};
7575 *DAG.getContext(),
V.getValueType().getVectorElementCount());
7576 auto [
Result,
_] = convertMaskTreeImpl(V, MaskTreeVT);
7579 return adjustMaskToType(Result, ToVT);
7587 LLVMContext &Ctx = *DAG.getContext();
7588 SDValue
Cond =
N->getOperand(0);
7595 EVT CondVT =
Cond->getValueType(0);
7599 EVT VSelVT =
N->getValueType(0);
7611 EVT FinalVT = VSelVT;
7622 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7623 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7630 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7638 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7641 EVT ToMaskVT = VSelVT;
7646 return convertMaskTree(
Cond, ToMaskVT);
7650 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7653 SDValue Cond1 =
N->getOperand(0);
7655 unsigned Opcode =
N->getOpcode();
7657 if (SDValue WideCond = WidenVSELECTMask(
N)) {
7658 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7659 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7661 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7667 Cond1 = GetWidenedVector(Cond1);
7675 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7676 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7681 Cond1 = ModifyToType(Cond1, CondWidenVT);
7684 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7685 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7687 if (Opcode == ISD::VP_MERGE)
7688 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7690 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7694 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7695 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7698 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7702 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7703 return DAG.getUNDEF(WidenVT);
7707 EVT VT =
N->getValueType(0);
7710 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7714 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7715 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7718 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7719 for (
unsigned i = 0; i != NumElts; ++i) {
7720 int Idx =
N->getMaskElt(i);
7721 if (Idx < (
int)NumElts)
7724 NewMask[i] =
Idx - NumElts + WidenNumElts;
7726 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7730 EVT VT =
N->getValueType(0);
7734 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7735 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7741 unsigned IdxVal = WidenNumElts - VTNumElts;
7754 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7757 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7758 "down type's element count");
7761 for (; i < VTNumElts / GCD; ++i)
7763 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7764 for (; i < WidenNumElts / GCD; ++i)
7772 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7773 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7775 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7779SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7780 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7784void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7785 EVT VT =
N->getValueType(0);
7788 unsigned Factor =
N->getNumOperands();
7791 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7795 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx)
7796 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7799 SDValue Interleaved =
7805 for (
unsigned Idx = 0;
Idx != Factor; ++
Idx)
7806 Slices[Idx] = Interleaved.
getValue(Idx);
7810 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx) {
7811 SDValue Narrow = DAG.getExtractSubvector(
DL, VT, Packed,
7814 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7815 SetWidenedVector(SDValue(
N, Idx), Wide);
7821 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7822 EVT SourceVT =
N->getOperand(0).getValueType();
7827 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7828 N->getOperand(0), 0);
7829 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7830 N->getOperand(2), 0);
7832 N->getOperand(1), WideMask,
N->getFlags());
7835void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7836 EVT VT =
N->getValueType(0);
7839 unsigned Factor =
N->getNumOperands();
7842 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7852 EVT ConcatVT =
EVT::getVectorVT(*DAG.getContext(), EltVT, OrigEC * Factor);
7854 SDValue PackedWidenVec = DAG.getInsertSubvector(
7855 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7859 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx) {
7860 NewOps[
Idx] = DAG.getExtractSubvector(
DL, WidenVT, PackedWidenVec,
7867 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx)
7868 SetWidenedVector(SDValue(
N, Idx), NewRes.
getValue(Idx));
7872 assert(
N->getValueType(0).isVector() &&
7873 N->getOperand(0).getValueType().isVector() &&
7874 "Operands must be vectors");
7875 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7888 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7889 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7896 InOp1 = GetWidenedVector(InOp1);
7897 InOp2 = GetWidenedVector(InOp2);
7899 SDValue
Poison = DAG.getPOISON(WidenInVT);
7900 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7911 "Input not widened to expected type!");
7913 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7918 assert(
N->getValueType(0).isVector() &&
7919 N->getOperand(1).getValueType().isVector() &&
7920 "Operands must be vectors");
7921 EVT VT =
N->getValueType(0);
7922 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7929 SDValue
LHS =
N->getOperand(1);
7930 SDValue
RHS =
N->getOperand(2);
7931 SDValue
CC =
N->getOperand(3);
7932 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7937 for (
unsigned i = 0; i != NumElts; ++i) {
7938 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7939 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7941 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7942 {Chain, LHSElem, RHSElem, CC});
7943 Chains[i] = Scalars[i].getValue(1);
7944 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7945 DAG.getBoolConstant(
true, dl, EltVT, VT),
7946 DAG.getBoolConstant(
false, dl, EltVT, VT));
7950 ReplaceValueWith(SDValue(
N, 1), NewChain);
7952 return DAG.getBuildVector(WidenVT, dl, Scalars);
7955SDValue DAGTypeLegalizer::WidenVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N) {
7957 EVT VT =
N->getValueType(0);
7960 SDValue Expanded = TLI.expandPartialReduceMLA(
N, DAG);
7961 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7962 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WideVT), Expanded, 0);
7968bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7969 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7970 SDValue Res = SDValue();
7973 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7976 switch (
N->getOpcode()) {
7979 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7987 Res = WidenVecOp_FAKE_USE(
N);
7991 Res = WidenVecOp_VECTOR_REPEAT(
N);
7996 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
8000 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
8001 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
8002 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
8007 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
8009 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
8010 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
8012 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
8013 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
8023 Res = WidenVecOp_UnrollVectorOp(
N);
8030 Res = WidenVecOp_EXTEND(
N);
8035 Res = WidenVecOp_CMP(
N);
8053 Res = WidenVecOp_Convert(
N);
8058 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
8078 Res = WidenVecOp_VECREDUCE(
N);
8082 Res = WidenVecOp_VECREDUCE_SEQ(
N);
8084 case ISD::VP_REDUCE_FADD:
8085 case ISD::VP_REDUCE_SEQ_FADD:
8086 case ISD::VP_REDUCE_FMUL:
8087 case ISD::VP_REDUCE_SEQ_FMUL:
8088 case ISD::VP_REDUCE_ADD:
8089 case ISD::VP_REDUCE_MUL:
8090 case ISD::VP_REDUCE_AND:
8091 case ISD::VP_REDUCE_OR:
8092 case ISD::VP_REDUCE_XOR:
8093 case ISD::VP_REDUCE_SMAX:
8094 case ISD::VP_REDUCE_SMIN:
8095 case ISD::VP_REDUCE_UMAX:
8096 case ISD::VP_REDUCE_UMIN:
8097 case ISD::VP_REDUCE_FMAX:
8098 case ISD::VP_REDUCE_FMIN:
8099 case ISD::VP_REDUCE_FMAXIMUM:
8100 case ISD::VP_REDUCE_FMINIMUM:
8101 Res = WidenVecOp_VP_REDUCE(
N);
8105 Res = WidenVecOp_CttzElements(
N);
8107 case ISD::VP_CTTZ_ELTS:
8108 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
8109 Res = WidenVecOp_VP_CttzElements(
N);
8112 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
8115 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
8120 if (!Res.
getNode())
return false;
8128 if (
N->isStrictFPOpcode())
8130 "Invalid operand expansion");
8133 "Invalid operand expansion");
8135 ReplaceValueWith(SDValue(
N, 0), Res);
8141 EVT VT =
N->getValueType(0);
8146 "Unexpected type action");
8147 InOp = GetWidenedVector(InOp);
8150 "Input wasn't widened!");
8158 EVT FixedEltVT = FixedVT.getVectorElementType();
8159 if (TLI.isTypeLegal(FixedVT) &&
8161 FixedEltVT == InEltVT) {
8163 "Not enough elements in the fixed type for the operand!");
8165 "We can't have the same type as we started with!");
8167 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
8169 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
8178 return WidenVecOp_Convert(
N);
8183 switch (
N->getOpcode()) {
8198 EVT OpVT =
N->getOperand(0).getValueType();
8199 EVT ResVT =
N->getValueType(0);
8200 SDValue
LHS = GetWidenedVector(
N->getOperand(0));
8201 SDValue
RHS = GetWidenedVector(
N->getOperand(1));
8206 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
8207 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
8213 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
8214 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
8216 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
8223 return DAG.UnrollVectorOp(
N);
8228 EVT ResultVT =
N->getValueType(0);
8229 SDValue
Test =
N->getOperand(1);
8230 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
8233 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
8239 {WideArg,
Test},
N->getFlags());
8245 SDValue
CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
8247 EVT OpVT =
N->getOperand(0).getValueType();
8250 return DAG.getNode(ExtendCode,
DL, ResultVT,
CC);
8255 EVT VT =
N->getValueType(0);
8258 SDValue InOp =
N->
getOperand(
N->isStrictFPOpcode() ? 1 : 0);
8261 "Unexpected type action");
8262 InOp = GetWidenedVector(InOp);
8264 unsigned Opcode =
N->getOpcode();
8267 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
8269 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
8272 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
8273 return DAG.getNode(Opcode, dl, VT,
Op);
8280 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
8282 if (
N->isStrictFPOpcode()) {
8284 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8287 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8288 {
N->getOperand(0), InOp });
8291 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
8293 Res = MakeConvertNode(WideVT, InOp);
8295 return DAG.getExtractSubvector(dl, VT, Res, 0);
8303 if (
N->isStrictFPOpcode()) {
8306 for (
unsigned i=0; i < NumElts; ++i) {
8307 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8308 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
8312 ReplaceValueWith(SDValue(
N, 1), NewChain);
8314 for (
unsigned i = 0; i < NumElts; ++i) {
8315 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8316 Ops[i] = MakeConvertNode(EltVT, Elt);
8320 return DAG.getBuildVector(VT, dl,
Ops);
8324 EVT DstVT =
N->getValueType(0);
8325 SDValue Src = GetWidenedVector(
N->getOperand(0));
8326 EVT SrcVT = Src.getValueType();
8333 if (TLI.isTypeLegal(WideDstVT)) {
8335 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
8338 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
8342 return DAG.UnrollVectorOp(
N);
8346 EVT VT =
N->getValueType(0);
8347 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8355 if (!VT.
isVector() && VT != MVT::x86mmx &&
8359 if (TLI.isTypeLegal(NewVT)) {
8360 SDValue BitOp = DAG.getNode(
ISD::BITCAST, dl, NewVT, InOp);
8361 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8373 ElementCount NewNumElts =
8375 .divideCoefficientBy(EltSize);
8377 if (TLI.isTypeLegal(NewVT)) {
8379 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8384 return CreateStackStoreLoad(InOp, VT);
8392 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8393 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8398 EVT VT =
N->getValueType(0);
8400 EVT InVT =
N->getOperand(0).getValueType();
8405 unsigned NumOperands =
N->getNumOperands();
8406 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8408 for (i = 1; i < NumOperands; ++i)
8409 if (!
N->getOperand(i).isUndef())
8412 if (i == NumOperands)
8413 return GetWidenedVector(
N->getOperand(0));
8417 SDValue
Result = DAG.getPOISON(VT);
8419 for (
unsigned i = 0; i < NumOperands; ++i) {
8420 SDValue InOp = GetWidenedVector(
N->getOperand(i));
8422 InOp = DAG.getExtractSubvector(dl, InVT, InOp, 0);
8423 Result = DAG.getInsertSubvector(dl, Result, InOp, i * NumInElts);
8435 for (
unsigned i=0; i < NumOperands; ++i) {
8439 "Unexpected type action");
8440 InOp = GetWidenedVector(InOp);
8441 for (
unsigned j = 0;
j < NumInElts; ++
j)
8442 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8444 return DAG.getBuildVector(VT, dl,
Ops);
8449 EVT VT =
N->getValueType(0);
8450 SDValue Src =
N->getOperand(0);
8451 EVT SrcVT = Src.getValueType();
8452 EVT WidenedSrcVT = TLI.getTypeToTransformTo(*DAG.getContext(), SrcVT);
8457 "Cannot widen VECTOR_REPEAT operand to an ElementCount that's not "
8458 "a known scalar multiple of the input ElementCount.");
8462 unsigned NumConcat =
8470 return DAG.getExtractSubvector(
DL, VT, Widened, 0);
8473SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8474 EVT VT =
N->getValueType(0);
8479 SubVec = GetWidenedVector(SubVec);
8484 bool IndicesValid =
false;
8487 IndicesValid =
true;
8491 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8492 Attribute::VScaleRange);
8497 IndicesValid =
true;
8503 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8509 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8516 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8538 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8546 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8547 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8552 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8557 unsigned Idx =
N->getConstantOperandVal(2);
8559 SDValue InsertElt = InVec;
8561 SDValue ExtractElt =
8563 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8569SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8570 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8572 N->getValueType(0), InOp,
N->getOperand(1));
8575SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8576 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8578 N->getValueType(0), InOp,
N->getOperand(1));
8581SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8583 EVT ResVT =
N->getValueType(0);
8586 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8592 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8600 "Widened input size must be a multiple of result element size");
8603 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8605 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8606 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8614 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8615 return TLI.scalarizeVectorStore(ST, DAG);
8617 if (
ST->isTruncatingStore())
8618 return TLI.scalarizeVectorStore(ST, DAG);
8626 SDValue StVal =
ST->getValue();
8628 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8629 EVT WideMaskVT = getSetCCResultType(WideVT);
8631 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8632 TLI.isTypeLegal(WideMaskVT)) {
8635 StVal = GetWidenedVector(StVal);
8636 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
8637 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8639 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8640 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8641 ST->getAddressingMode());
8645 if (GenWidenVectorStores(StChain, ST)) {
8646 if (StChain.
size() == 1)
8655 SDValue WideStVal = GetWidenedVector(StVal);
8659 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8660 ST->getOffset(), Mask,
ST->getMemoryVT(),
8661 ST->getMemOperand(),
ST->getAddressingMode(),
8662 ST->isTruncatingStore());
8669 EVT StVT =
ST->getMemoryVT();
8672 SDValue StVal = GetWidenedVector(
ST->getVal());
8677 TypeSize WidthDiff = WidenWidth - StWidth;
8683 std::optional<EVT> FirstVT =
8684 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8689 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8695 ST->getBasePtr(),
ST->getMemOperand());
8698SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8699 assert((OpNo == 1 || OpNo == 3) &&
8700 "Can widen only data or mask operand of vp_store");
8702 SDValue
Mask =
ST->getMask();
8703 SDValue StVal =
ST->getValue();
8708 StVal = GetWidenedVector(StVal);
8714 "Unable to widen VP store");
8715 Mask = GetWidenedVector(Mask);
8717 Mask = GetWidenedVector(Mask);
8723 "Unable to widen VP store");
8724 StVal = GetWidenedVector(StVal);
8727 assert(
Mask.getValueType().getVectorElementCount() ==
8729 "Mask and data vectors should have the same number of elements");
8730 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8731 ST->getOffset(), Mask,
ST->getVectorLength(),
8732 ST->getMemoryVT(),
ST->getMemOperand(),
8733 ST->getAddressingMode(),
ST->isTruncatingStore(),
8734 ST->isCompressingStore());
8739 assert((OpNo == 1 || OpNo == 4) &&
8740 "Can widen only data or mask operand of vp_strided_store");
8749 "Unable to widen VP strided store");
8753 "Unable to widen VP strided store");
8755 StVal = GetWidenedVector(StVal);
8756 Mask = GetWidenedVector(Mask);
8759 Mask.getValueType().getVectorElementCount() &&
8760 "Data and mask vectors should have the same number of elements");
8762 return DAG.getStridedStoreVP(
8769SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8770 assert((OpNo == 1 || OpNo == 4) &&
8771 "Can widen only data or mask operand of mstore");
8774 EVT MaskVT =
Mask.getValueType();
8779 EVT WideVT, WideMaskVT;
8782 StVal = GetWidenedVector(StVal);
8789 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8796 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8798 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8799 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8808 Mask = ModifyToType(Mask, WideMaskVT,
true);
8811 Mask = ModifyToType(Mask, WideMaskVT,
true);
8813 StVal = ModifyToType(StVal, WideVT);
8816 assert(
Mask.getValueType().getVectorElementCount() ==
8818 "Mask and data vectors should have the same number of elements");
8825SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8826 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8828 SDValue DataOp = MG->getPassThru();
8829 SDValue
Mask = MG->getMask();
8830 SDValue Scale = MG->getScale();
8833 SDValue
Index = GetWidenedVector(MG->getIndex());
8836 SDValue
Ops[] = {MG->getChain(), DataOp,
Mask, MG->getBasePtr(),
Index,
8838 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8839 MG->getMemOperand(), MG->getIndexType(),
8840 MG->getExtensionType());
8841 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
8842 ReplaceValueWith(SDValue(
N, 0), Res.
getValue(0));
8846SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8855 DataOp = GetWidenedVector(DataOp);
8859 EVT IndexVT =
Index.getValueType();
8862 Index = ModifyToType(Index, WideIndexVT);
8865 EVT MaskVT =
Mask.getValueType();
8868 Mask = ModifyToType(Mask, WideMaskVT,
true);
8873 }
else if (OpNo == 4) {
8875 Index = GetWidenedVector(Index);
8881 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8886SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8895 DataOp = GetWidenedVector(DataOp);
8896 Index = GetWidenedVector(Index);
8898 Mask = GetWidenedMask(Mask, WideEC);
8901 }
else if (OpNo == 3) {
8903 Index = GetWidenedVector(Index);
8910 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8915 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8916 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8918 EVT VT =
N->getValueType(0);
8932 SDValue WideSETCC = DAG.getNode(
ISD::SETCC, SDLoc(
N),
8933 SVT, InOp0, InOp1,
N->getOperand(2));
8939 SDValue
CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8941 EVT OpVT =
N->getOperand(0).getValueType();
8944 return DAG.getNode(ExtendCode, dl, VT,
CC);
8949 SDValue
LHS = GetWidenedVector(
N->getOperand(1));
8950 SDValue
RHS = GetWidenedVector(
N->getOperand(2));
8951 SDValue
CC =
N->getOperand(3);
8954 EVT VT =
N->getValueType(0);
8956 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8963 for (
unsigned i = 0; i != NumElts; ++i) {
8964 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8965 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8967 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8968 {Chain, LHSElem, RHSElem, CC});
8969 Chains[i] = Scalars[i].getValue(1);
8970 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8971 DAG.getBoolConstant(
true, dl, EltVT, VT),
8972 DAG.getBoolConstant(
false, dl, EltVT, VT));
8976 ReplaceValueWith(SDValue(
N, 1), NewChain);
8978 return DAG.getBuildVector(VT, dl, Scalars);
9002 SDValue
Op = GetWidenedVector(
N->getOperand(0));
9003 EVT VT =
N->getValueType(0);
9004 EVT OrigVT =
N->getOperand(0).getValueType();
9005 EVT WideVT =
Op.getValueType();
9007 SDNodeFlags
Flags =
N->getFlags();
9009 unsigned Opc =
N->getOpcode();
9011 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
9012 assert(NeutralElem &&
"Neutral element must exist");
9022 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
9023 SDValue
Start = NeutralElem;
9029 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
9030 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
9036 unsigned GCD = std::gcd(OrigElts, WideElts);
9039 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
9040 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx =
Idx + GCD)
9041 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
9042 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
9045 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx++)
9046 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
9048 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
9055 SDValue
Op = GetWidenedVector(VecOp);
9057 EVT VT =
N->getValueType(0);
9059 EVT WideVT =
Op.getValueType();
9061 SDNodeFlags
Flags =
N->getFlags();
9063 unsigned Opc =
N->getOpcode();
9065 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
9075 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
9078 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
9079 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
9085 unsigned GCD = std::gcd(OrigElts, WideElts);
9088 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
9089 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx =
Idx + GCD)
9090 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
9091 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
9094 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx++)
9095 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
9097 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
9101 assert(
N->isVPOpcode() &&
"Expected VP opcode");
9104 SDValue
Op = GetWidenedVector(
N->getOperand(1));
9105 SDValue
Mask = GetWidenedMask(
N->getOperand(2),
9106 Op.getValueType().getVectorElementCount());
9108 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
9109 {N->getOperand(0), Op, Mask, N->getOperand(3)},
9117 EVT VT =
N->getValueType(0);
9120 SDValue
Cond = GetWidenedVector(
N->getOperand(0));
9121 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
9122 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
9127 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
9132 SDValue
Source =
N->getOperand(0);
9133 EVT SourceVT =
Source.getValueType();
9134 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9138 WideSource = GetWidenedVector(Source);
9142 SDValue
AllOnes = DAG.getAllOnesConstant(
DL, WideVT);
9145 WideSource = GetWidenedVector(Source);
9147 SmallVector<int>
Mask(WideElts);
9148 std::iota(
Mask.begin(),
Mask.end(), 0);
9150 Mask[
I] += WideElts;
9151 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
9153 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
9157 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
9163 SDValue
Source = GetWidenedVector(
N->getOperand(0));
9164 EVT SrcVT =
Source.getValueType();
9168 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
9169 {Source, Mask, N->getOperand(2)},
N->getFlags());
9172SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
9174 SDValue
Mask =
N->getOperand(0);
9175 EVT OrigMaskVT =
Mask.getValueType();
9176 SDValue WideMask = GetWidenedVector(Mask);
9182 if (OrigElts != WideElts) {
9183 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
9185 Mask, DAG.getVectorIdxConstant(0,
DL));
9192SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
9195 EVT ResVT =
N->getValueType(0);
9196 EVT SourceVT =
N->getOperand(0).getValueType();
9197 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9202 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
9203 N->getOperand(0), 0);
9204 SDValue WideMask = DAG.getInsertSubvector(
9205 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
9207 N->getOperand(1), WideMask,
N->getFlags());
9208 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
9212 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
9215 SDValue Needle =
N->getOperand(1);
9218 return TLI.expandVectorMatch(
N, DAG);
9220 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
9224 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
9225 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
9228 N->getOperand(0), WideNeedle,
N->getOperand(2),
9246 unsigned WidenEx = 0) {
9251 unsigned AlignInBits =
Align*8;
9253 EVT RetVT = WidenEltVT;
9258 if (Width == WidenEltWidth)
9269 (WidenWidth % MemVTWidth) == 0 &&
9271 (MemVTWidth <= Width ||
9272 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9273 if (MemVTWidth == WidenWidth)
9292 (WidenWidth % MemVTWidth) == 0 &&
9294 (MemVTWidth <= Width ||
9295 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9304 return std::nullopt;
9315 unsigned Start,
unsigned End) {
9316 SDLoc dl(LdOps[Start]);
9317 EVT LdTy = LdOps[Start].getValueType();
9325 for (
unsigned i = Start + 1; i !=
End; ++i) {
9326 EVT NewLdTy = LdOps[i].getValueType();
9327 if (NewLdTy != LdTy) {
9346 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9347 EVT LdVT =
LD->getMemoryVT();
9354 SDValue Chain =
LD->getChain();
9357 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9361 TypeSize WidthDiff = WidenWidth - LdWidth;
9368 std::optional<EVT> FirstVT =
9369 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
9376 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
9381 std::optional<EVT> NewVT = FirstVT;
9382 TypeSize RemainingWidth = LdWidth;
9383 TypeSize NewVTWidth = FirstVTWidth;
9385 RemainingWidth -= NewVTWidth;
9392 NewVTWidth = NewVT->getSizeInBits();
9398 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9412 MachinePointerInfo MPI =
LD->getPointerInfo();
9418 for (EVT MemVT : MemVTs) {
9419 Align NewAlign = ScaledOffset == 0
9420 ?
LD->getBaseAlign()
9422 SDValue
L = DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags,
9442 EVT LdTy = LdOps[i].getValueType();
9445 for (--i; i >= 0; --i) {
9446 LdTy = LdOps[i].getValueType();
9453 ConcatOps[--
Idx] = LdOps[i];
9454 for (--i; i >= 0; --i) {
9455 EVT NewLdTy = LdOps[i].getValueType();
9456 if (NewLdTy != LdTy) {
9467 WidenOps[j] = ConcatOps[Idx+j];
9469 WidenOps[j] = DAG.getPOISON(LdTy);
9476 ConcatOps[--
Idx] = LdOps[i];
9487 SDValue UndefVal = DAG.getPOISON(LdTy);
9490 for (; i !=
End-
Idx; ++i)
9491 WidenOps[i] = ConcatOps[Idx+i];
9493 WidenOps[i] = UndefVal;
9504 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9505 EVT LdVT =
LD->getMemoryVT();
9511 SDValue Chain =
LD->getChain();
9514 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9528 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9529 LdEltVT,
LD->getBaseAlign(), MMOFlags,
Metadata);
9533 SDValue NewBasePtr =
9535 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9536 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9542 SDValue UndefVal = DAG.getPOISON(EltVT);
9543 for (; i != WidenNumElts; ++i)
9546 return DAG.getBuildVector(WidenVT, dl,
Ops);
9554 SDValue Chain =
ST->getChain();
9557 MMOMetadata
Metadata =
ST->getMMOMetadataForSubAccess();
9558 SDValue ValOp = GetWidenedVector(
ST->getValue());
9561 EVT StVT =
ST->getMemoryVT();
9569 "Mismatch between store and value types");
9573 MachinePointerInfo MPI =
ST->getPointerInfo();
9583 std::optional<EVT> NewVT =
9588 TypeSize NewVTWidth = NewVT->getSizeInBits();
9591 StWidth -= NewVTWidth;
9592 MemVTs.
back().second++;
9596 for (
const auto &Pair : MemVTs) {
9597 EVT NewVT = Pair.first;
9598 unsigned Count = Pair.second;
9604 Align NewAlign = ScaledOffset == 0
9605 ?
ST->getBaseAlign()
9607 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9608 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9624 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9626 DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
ST->getBaseAlign(),
9644 bool FillWithZeroes) {
9649 "input and widen element type must match");
9651 "cannot modify scalable vectors in this way");
9664 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9666 for (
unsigned i = 1; i != NumConcat; ++i)
9673 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9679 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9684 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9685 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9687 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9689 unsigned NumResultParts = NewNumElts / CommonFactor;
9690 if (NumResultParts > NumCopiedParts) {
9691 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9692 : DAG.getPOISON(PartVT);
9693 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9700 "Scalable vectors should have been handled already.");
9708 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9710 for (Idx = 0;
Idx < MinNumElts; ++
Idx)
9711 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9713 SDValue UndefVal = DAG.getPOISON(EltVT);
9714 for (;
Idx < WidenNumElts; ++
Idx)
9715 Ops[Idx] = UndefVal;
9717 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9718 if (!FillWithZeroes)
9722 "We expect to never want to FillWithZeroes for non-integral types.");
9725 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9726 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9728 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9729 DAG.getBuildVector(NVT, dl, MaskOps));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT, TypeSize FirstVTWidth, const SDLoc &dl, SelectionDAG &DAG)
Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the widened value so it can b...
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
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)
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
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS*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.
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.