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 SetScalarizedVector(
SDValue(
N, ResNo), R);
315 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
316 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
317 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
323 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
324 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
325 SDValue
Mask =
N->getOperand(2);
326 EVT MaskVT =
Mask.getValueType();
331 Mask = GetScalarizedVector(Mask);
339 SDValue Divisor = DAG.getSelect(
DL,
LHS.getValueType(), Mask,
RHS,
340 DAG.getConstant(1,
DL,
LHS.getValueType()));
342 LHS.getValueType(),
LHS, Divisor);
348 SDValue
LHS =
N->getOperand(0);
349 SDValue
RHS =
N->getOperand(1);
350 if (getTypeAction(
LHS.getValueType()) ==
352 LHS = GetScalarizedVector(
LHS);
353 RHS = GetScalarizedVector(
RHS);
355 EVT VT =
LHS.getValueType().getVectorElementType();
356 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
357 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
360 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
361 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
365 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
366 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
367 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
368 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
373 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
374 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
381DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
383 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
384 "Unexpected vector type!");
385 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
387 EVT VT0 =
N->getValueType(0);
388 EVT VT1 =
N->getValueType(1);
392 DAG.getNode(
N->getOpcode(), dl,
393 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
397 unsigned OtherNo = 1 - ResNo;
398 EVT OtherVT =
N->getValueType(OtherNo);
400 SetScalarizedVector(SDValue(
N, OtherNo), SDValue(ScalarNode, OtherNo));
403 SDValue(ScalarNode, OtherNo));
404 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
407 return SDValue(ScalarNode, ResNo);
412 unsigned NumOpers =
N->getNumOperands();
413 SDValue Chain =
N->getOperand(0);
414 EVT ValueVTs[] = {VT, MVT::Other};
423 for (
unsigned i = 1; i < NumOpers; ++i) {
424 SDValue Oper =
N->getOperand(i);
429 Oper = GetScalarizedVector(Oper);
438 SDValue
Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
439 Opers,
N->getFlags());
443 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
450 EVT ResVT =
N->getValueType(0);
451 EVT OvVT =
N->getValueType(1);
453 SDValue ScalarLHS, ScalarRHS;
455 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
456 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
459 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
460 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
461 ScalarLHS = ElemsLHS[0];
462 ScalarRHS = ElemsRHS[0];
465 SDVTList ScalarVTs = DAG.getVTList(
467 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
468 {ScalarLHS, ScalarRHS},
N->getFlags())
472 unsigned OtherNo = 1 - ResNo;
473 EVT OtherVT =
N->getValueType(OtherNo);
475 SetScalarizedVector(SDValue(
N, OtherNo), SDValue(ScalarNode, OtherNo));
477 SDValue OtherVal = DAG.
getNode(
479 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
482 return SDValue(ScalarNode, ResNo);
487 SDValue
Op = DisintegrateMERGE_VALUES(
N, ResNo);
488 return GetScalarizedVector(
Op);
491SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
494 SDValue
Mask = TLI.expandLoopDependenceMask(
N, DAG);
496 N->getValueType(0).getScalarType(), Mask,
497 DAG.getVectorIdxConstant(0,
DL));
501 SDValue
Op =
N->getOperand(0);
503 Op = GetScalarizedVector(
Op);
504 EVT NewVT =
N->getValueType(0).getVectorElementType();
509SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(
SDNode *
N) {
511 SDValue InOp =
N->getOperand(0);
519SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
521 N->getValueType(0).getVectorElementType(),
522 N->getOperand(0),
N->getOperand(1));
527 SDValue
Op =
N->getOperand(0);
528 EVT OpVT =
Op.getValueType();
532 Op = GetScalarizedVector(
Op);
535 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
538 N->getValueType(0).getVectorElementType(),
Op,
542SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
544 SDValue
Op =
N->getOperand(0);
545 EVT OpVT =
Op.getValueType();
549 Op = GetScalarizedVector(
Op);
552 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
555 N->getValueType(0).getVectorElementType(),
Op,
559SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
561 SDValue
Op =
N->getOperand(0);
562 EVT OpVT =
Op.getValueType();
565 Op = GetScalarizedVector(
Op);
568 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
571 N->getValueType(0).getVectorElementType(),
Op,
572 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
575SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
576 SDValue
Op = GetScalarizedVector(
N->getOperand(0));
577 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
581SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOp_MultiType(
SDNode *
N) {
583 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
584 SDValue
RHS =
N->getOperand(1);
585 EVT RHSVT =
RHS.getValueType();
590 RHS = GetScalarizedVector(
RHS);
594 return DAG.getNode(
N->getOpcode(),
DL,
LHS.getValueType(),
LHS,
RHS,
598SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
601 SDValue
Op =
N->getOperand(1);
603 if (
Op.getValueType() != EltVT)
610 SDValue
Result = DAG.getAtomicLoad(
611 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
612 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
617 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
622 SDValue
Result = DAG.getAtomic(
623 N->getOpcode(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
624 N->getChain(),
N->getBasePtr(), GetScalarizedVector(
N->getVal()),
627 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
632 assert(
N->isUnindexed() &&
"Indexed vector load?");
634 SDValue
Result = DAG.getLoad(
636 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
637 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
638 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
639 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
640 N->getMMOMetadataForSubAccess());
644 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
651 SDValue
Op =
N->getOperand(0);
652 EVT OpVT =
Op.getValueType();
662 Op = GetScalarizedVector(
Op);
665 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
667 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
673 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
674 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
675 LHS, DAG.getValueType(ExtVT));
680 SDValue
Op =
N->getOperand(0);
682 EVT OpVT =
Op.getValueType();
687 Op = GetScalarizedVector(
Op);
689 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
692 switch (
N->getOpcode()) {
704SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
706 SDValue
Op =
N->getOperand(0);
707 EVT OpVT =
Op.getValueType();
717 Op = GetScalarizedVector(
Op);
720 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
723 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
724 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
725 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS,
726 AddrSpaceCastN->getFlags());
729SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
740DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
741 assert(
N->getNumValues() ==
N->getNumOperands() &&
742 "Expected one result per operand");
746 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
747 SetScalarizedVector(SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
752 SDValue
Cond =
N->getOperand(0);
753 EVT OpVT =
Cond.getValueType();
762 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
765 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
767 TLI.getBooleanContents(
false,
false);
774 if (TLI.getBooleanContents(
false,
false) !=
775 TLI.getBooleanContents(
false,
true)) {
779 EVT OpVT =
Cond->getOperand(0).getValueType();
781 VecBool = TLI.getBooleanContents(OpVT);
786 EVT CondVT =
Cond.getValueType();
787 if (ScalarBool != VecBool) {
788 switch (ScalarBool) {
796 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
803 Cond, DAG.getValueType(MVT::i1));
809 auto BoolVT = getSetCCResultType(CondVT);
810 if (BoolVT.bitsLT(CondVT))
813 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
814 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
818 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
819 return DAG.getSelect(SDLoc(
N),
820 LHS.getValueType(),
N->getOperand(0),
LHS,
821 GetScalarizedVector(
N->getOperand(2)));
825 SDValue
LHS = GetScalarizedVector(
N->getOperand(2));
827 N->getOperand(0),
N->getOperand(1),
828 LHS, GetScalarizedVector(
N->getOperand(3)),
833 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
836SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
840 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
842 return GetScalarizedVector(
N->getOperand(
Op));
845SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
846 SDValue Src =
N->getOperand(0);
847 EVT SrcVT = Src.getValueType();
852 Src = GetScalarizedVector(Src);
856 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
858 EVT DstVT =
N->getValueType(0).getVectorElementType();
859 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
863 assert(
N->getValueType(0).isVector() &&
864 N->getOperand(0).getValueType().isVector() &&
865 "Operand types must be vectors");
866 SDValue
LHS =
N->getOperand(0);
867 SDValue
RHS =
N->getOperand(1);
868 EVT OpVT =
LHS.getValueType();
869 EVT NVT =
N->getValueType(0).getVectorElementType();
874 LHS = GetScalarizedVector(
LHS);
875 RHS = GetScalarizedVector(
RHS);
878 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
879 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
889 return DAG.getNode(ExtendCode,
DL, NVT, Res);
900 Arg = GetScalarizedVector(Arg);
903 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
912 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
919bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
922 SDValue Res = SDValue();
925 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
928 switch (
N->getOpcode()) {
931 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
938 Res = ScalarizeVecOp_BITCAST(
N);
941 Res = ScalarizeVecOp_FAKE_USE(
N);
955 Res = ScalarizeVecOp_UnaryOp(
N);
960 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
963 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
964 "Unexpected vector type!");
965 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
966 SDValue
Op = DAG.getNode(
967 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
968 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
976 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
979 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
982 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
985 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
988 Res = ScalarizeVecOp_VSELECT(
N);
991 Res = ScalarizeVecOp_VSETCC(
N);
995 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
1010 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
1013 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
1016 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
1019 Res = ScalarizeVecOp_FP_EXTEND(
N);
1038 Res = ScalarizeVecOp_VECREDUCE(
N);
1042 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
1046 Res = ScalarizeVecOp_CMP(
N);
1049 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
1053 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
1056 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
1062 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
1067 if (!Res.
getNode())
return false;
1075 "Invalid operand expansion");
1077 ReplaceValueWith(SDValue(
N, 0), Res);
1084 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1086 N->getValueType(0), Elt);
1091 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1092 "Fake Use: Unexpected vector type!");
1093 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1094 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1100 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1101 "Unexpected vector type!");
1102 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1103 SDValue
Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1104 N->getValueType(0).getScalarType(), Elt);
1112SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1113 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1114 "Unexpected vector type!");
1115 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1117 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1118 Elt,
N->getOperand(1));
1126SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1127 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1128 "Unexpected vector type!");
1129 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1130 SDValue Res = DAG.
getNode(
N->getOpcode(), SDLoc(
N),
1131 {
N->getValueType(0).getScalarType(), MVT::Other },
1132 {
N->getOperand(0), Elt });
1135 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1142 ReplaceValueWith(SDValue(
N, 0), Res);
1147SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1149 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1150 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1151 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1156SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1160 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1161 SDValue ContainingVec =
N->getOperand(0);
1169SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1170 EVT VT =
N->getValueType(0);
1171 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1183 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1184 EVT VT =
N->getValueType(0);
1186 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1195 assert(
N->getValueType(0).isVector() &&
1196 N->getOperand(0).getValueType().isVector() &&
1197 "Operand types must be vectors");
1198 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1199 "Expected single-element vector type");
1201 EVT VT =
N->getValueType(0);
1202 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
1203 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
1205 EVT OpVT =
N->getOperand(0).getValueType();
1217 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1223SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1225 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1226 assert(
N->getValueType(0).isVector() &&
1227 N->getOperand(1).getValueType().isVector() &&
1228 "Operand types must be vectors");
1229 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1230 "Expected single-element vector type");
1232 EVT VT =
N->getValueType(0);
1233 SDValue Ch =
N->getOperand(0);
1234 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
1235 SDValue
RHS = GetScalarizedVector(
N->getOperand(2));
1236 SDValue CC =
N->getOperand(3);
1238 EVT OpVT =
N->getOperand(1).getValueType();
1241 SDValue Res = DAG.
getNode(
N->getOpcode(),
DL, {MVT::i1, MVT::Other},
1242 {Ch, LHS, RHS, CC});
1246 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1251 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1256 ReplaceValueWith(SDValue(
N, 0), Res);
1263 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1264 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1267 if (
N->isTruncatingStore())
1268 return DAG.getTruncStore(
1269 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1270 N->getBasePtr(),
N->getPointerInfo(),
1271 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1272 N->getMemOperand()->getFlags(),
N->getMMOMetadataForSubAccess());
1274 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1275 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1276 N->getMemOperand()->getFlags(),
1277 N->getMMOMetadataForSubAccess());
1283 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1285 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1286 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1293 assert(OpNo == 3 &&
"Can only scalarize the mask operand!");
1294 EVT DataVT =
N->getValueType(0);
1295 SDValue
Mask = PromoteTargetBoolean(
N->getOperand(OpNo), DataVT);
1297 NewOps[OpNo] =
Mask;
1298 SDNode *Res = DAG.UpdateNodeOperands(
N, NewOps);
1300 return SDValue(Res, 0);
1303 ReplaceValueWith(SDValue(
N, 0), SDValue(Res, 0));
1304 ReplaceValueWith(SDValue(
N, 1), SDValue(Res, 1));
1312 assert(!
N->isCompressingStore() &&
"CompressingStore not expected");
1315 EVT DataVT =
N->getValue().getValueType();
1317 NewOps[OpNo] = PromoteTargetBoolean(
N->getOperand(OpNo), DataVT);
1318 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1323SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1324 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1325 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1327 N->getValueType(0).getVectorElementType(), Elt,
1332SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1334 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1335 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1338 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1342 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1348 ReplaceValueWith(SDValue(
N, 0), Res);
1355 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1357 N->getValueType(0).getVectorElementType(), Elt);
1363SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1364 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1367 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1368 {
N->getOperand(0), Elt});
1371 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1377 ReplaceValueWith(SDValue(
N, 0), Res);
1382 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1389SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1395 SDValue
Op = GetScalarizedVector(VecOp);
1396 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1397 AccOp,
Op,
N->getFlags());
1401 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
1402 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
1405 SDValue
Cmp = DAG.getNode(
N->getOpcode(), SDLoc(
N), ResVT,
LHS,
RHS);
1409SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1417 EVT VT =
N->getValueType(0);
1418 return DAG.getConstant(0, SDLoc(
N), VT);
1425 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1426 SDValue
Op = GetScalarizedVector(
N->getOperand(0));
1428 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1429 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1430 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1433SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1436 SDValue
Mask = TLI.expandVectorMatch(
N, DAG);
1438 N->getValueType(0).getScalarType(), Mask,
1439 DAG.getVectorIdxConstant(0,
DL));
1444 return TLI.expandVectorMatch(
N, DAG);
1447SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1448 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1451 SDValue
LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1452 SDValue
RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1453 SDValue
Mask = GetScalarizedVector(
N->getOperand(2));
1461 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1473void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1478 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1481 switch (
N->getOpcode()) {
1484 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1493 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1496 SplitVecRes_MASK_BEFOREFIRST(
N,
Lo,
Hi);
1503 case ISD::VP_MERGE: SplitRes_Select(
N,
Lo,
Hi);
break;
1519 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1522 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1534 case ISD::VP_LOAD_FF:
1537 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1544 case ISD::VP_GATHER:
1548 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1551 SplitVecRes_SETCC(
N,
Lo,
Hi);
1554 SplitVecRes_VECTOR_REPEAT(
N,
Lo,
Hi);
1557 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1564 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1567 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1570 SplitVecRes_VECTOR_INTERLEAVE(
N);
1573 SplitVecRes_VAARG(
N,
Lo,
Hi);
1579 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1633 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1636 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1642 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1648 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1704 SplitVecRes_BinOp(
N,
Lo,
Hi);
1710 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1715 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1719 SplitVecRes_CMP(
N,
Lo,
Hi);
1722#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1723 case ISD::STRICT_##DAGN:
1724#include "llvm/IR/ConstrainedOps.def"
1725 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1730 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1739 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1749 SplitVecRes_FIX(
N,
Lo,
Hi);
1751 case ISD::EXPERIMENTAL_VP_SPLICE:
1752 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1754 case ISD::EXPERIMENTAL_VP_REVERSE:
1755 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1761 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1764 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1767 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1773 SetSplitVector(SDValue(
N, ResNo),
Lo,
Hi);
1776void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1783 SDValue BytesIncrement = DAG.getVScale(
1786 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1788 *ScaledOffset += IncrementSize;
1798std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1799 return SplitMask(Mask, SDLoc(Mask));
1802std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1804 SDValue MaskLo, MaskHi;
1805 EVT MaskVT =
Mask.getValueType();
1807 GetSplitVector(Mask, MaskLo, MaskHi);
1809 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1810 return std::make_pair(MaskLo, MaskHi);
1814 SDValue LHSLo, LHSHi;
1815 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1816 SDValue RHSLo, RHSHi;
1817 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1820 const SDNodeFlags
Flags =
N->getFlags();
1821 unsigned Opcode =
N->getOpcode();
1822 if (
N->getNumOperands() == 2) {
1823 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1824 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1828 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1829 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
1830 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
1831 "Expected VP opcode");
1833 SDValue MaskLo, MaskHi;
1834 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1836 SDValue EVLLo, EVLHi;
1837 std::tie(EVLLo, EVLHi) =
1838 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1841 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1843 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1848 SDValue LHSLo, LHSHi;
1849 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1850 SDValue RHSLo, RHSHi;
1851 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1853 SDValue MaskLo, MaskHi,
Mask =
N->getOperand(2);
1855 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1857 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1861 const SDNodeFlags
Flags =
N->getFlags();
1862 unsigned Opcode =
N->getOpcode();
1863 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1865 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1871 SDValue Op0Lo, Op0Hi;
1872 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1873 SDValue Op1Lo, Op1Hi;
1874 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1875 SDValue Op2Lo, Op2Hi;
1876 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1879 const SDNodeFlags
Flags =
N->getFlags();
1880 unsigned Opcode =
N->getOpcode();
1882 DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1884 DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1888 LLVMContext &Ctxt = *DAG.getContext();
1891 SDValue
LHS =
N->getOperand(0);
1892 SDValue
RHS =
N->getOperand(1);
1894 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1896 GetSplitVector(
LHS, LHSLo, LHSHi);
1897 GetSplitVector(
RHS, RHSLo, RHSHi);
1899 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1900 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1904 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1905 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1909 SDValue LHSLo, LHSHi;
1910 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1911 SDValue RHSLo, RHSHi;
1912 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1916 unsigned Opcode =
N->getOpcode();
1917 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1919 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1928 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1935 switch (getTypeAction(InVT)) {
1949 GetExpandedOp(InOp,
Lo,
Hi);
1950 if (DAG.getDataLayout().isBigEndian())
1960 GetSplitVector(InOp,
Lo,
Hi);
1969 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1978 if (DAG.getDataLayout().isBigEndian())
1981 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1983 if (DAG.getDataLayout().isBigEndian())
1989void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1993 SDValue PtrA =
N->getOperand(0);
1994 SDValue PtrB =
N->getOperand(1);
1995 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1998 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
2003 unsigned LaneOffset =
2006 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
2008 DAG.getConstant(LaneOffset,
DL, MVT::i64));
2015 GetSplitVector(
N->getOperand(0), InLo, InHi);
2021 SDValue
Cond = DAG.getBoolExtOrTrunc(AnyLoActive,
DL,
2022 getSetCCResultType(MVT::i1), MVT::i1);
2031 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2034 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
2037 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
2042 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
2044 unsigned NumSubvectors =
N->getNumOperands() / 2;
2045 if (NumSubvectors == 1) {
2046 Lo =
N->getOperand(0);
2047 Hi =
N->getOperand(1);
2052 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2061void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
2063 SDValue Vec =
N->getOperand(0);
2064 SDValue
Idx =
N->getOperand(1);
2068 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2081 SDValue
Idx =
N->getOperand(2);
2083 GetSplitVector(Vec,
Lo,
Hi);
2086 EVT LoVT =
Lo.getValueType();
2095 unsigned IdxVal =
Idx->getAsZExtVal();
2096 if (IdxVal + SubElems <= LoElems) {
2104 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
2106 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
2112 SDValue WideSubVec = GetWidenedVector(SubVec);
2114 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2122 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2124 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2125 auto &MF = DAG.getMachineFunction();
2129 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2134 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2135 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2139 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2144 MachinePointerInfo MPI =
Load->getPointerInfo();
2145 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2148 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2156 SDValue LHSLo, LHSHi;
2157 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2160 SDValue RHSLo, RHSHi;
2161 SDValue
RHS =
N->getOperand(1);
2162 EVT RHSVT =
RHS.getValueType();
2165 GetSplitVector(
RHS, RHSLo, RHSHi);
2167 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2180 SDValue ArgLo, ArgHi;
2181 SDValue
Test =
N->getOperand(1);
2182 SDValue FpValue =
N->getOperand(0);
2184 GetSplitVector(FpValue, ArgLo, ArgHi);
2186 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2188 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2196 SDValue LHSLo, LHSHi;
2197 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2201 std::tie(LoVT, HiVT) =
2205 DAG.getValueType(LoVT));
2207 DAG.getValueType(HiVT));
2212 unsigned Opcode =
N->getOpcode();
2213 SDValue N0 =
N->getOperand(0);
2219 GetSplitVector(N0, InLo, InHi);
2221 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2226 EVT OutLoVT, OutHiVT;
2227 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2229 assert((2 * OutNumElements) <= InNumElements &&
2230 "Illegal extend vector in reg split");
2239 SmallVector<int, 8> SplitHi(InNumElements, -1);
2240 for (
unsigned i = 0; i != OutNumElements; ++i)
2241 SplitHi[i] = i + OutNumElements;
2242 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2244 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2245 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2250 unsigned NumOps =
N->getNumOperands();
2254 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2264 for (
unsigned i = 1; i <
NumOps; ++i) {
2265 SDValue
Op =
N->getOperand(i);
2269 EVT InVT =
Op.getValueType();
2274 GetSplitVector(
Op, OpLo, OpHi);
2276 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2283 EVT LoValueVTs[] = {LoVT, MVT::Other};
2284 EVT HiValueVTs[] = {HiVT, MVT::Other};
2285 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2287 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2293 Lo.getValue(1),
Hi.getValue(1));
2297 ReplaceValueWith(SDValue(
N, 1), Chain);
2300SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2302 EVT VT =
N->getValueType(0);
2313 else if (NE > ResNE)
2317 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2321 for (i = 0; i !=
NE; ++i) {
2323 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2324 SDValue Operand =
N->getOperand(j);
2328 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2334 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2342 for (; i < ResNE; ++i)
2343 Scalars.
push_back(DAG.getPOISON(EltVT));
2347 ReplaceValueWith(SDValue(
N, 1), Chain);
2351 return DAG.getBuildVector(VecVT, dl, Scalars);
2354void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2357 EVT ResVT =
N->getValueType(0);
2358 EVT OvVT =
N->getValueType(1);
2359 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2360 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2361 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2363 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2365 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2366 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2368 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2369 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2372 unsigned Opcode =
N->getOpcode();
2373 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2374 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2376 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2378 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2380 Lo = SDValue(LoNode, ResNo);
2381 Hi = SDValue(HiNode, ResNo);
2384 unsigned OtherNo = 1 - ResNo;
2385 EVT OtherVT =
N->getValueType(OtherNo);
2387 SetSplitVector(SDValue(
N, OtherNo),
2388 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2390 SDValue OtherVal = DAG.
getNode(
2392 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2393 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
2397void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2401 SDValue
Idx =
N->getOperand(2);
2403 GetSplitVector(Vec,
Lo,
Hi);
2406 unsigned IdxVal = CIdx->getZExtValue();
2407 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2408 if (IdxVal < LoNumElts) {
2410 Lo.getValueType(),
Lo, Elt, Idx);
2413 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2433 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2435 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2436 auto &MF = DAG.getMachineFunction();
2440 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2445 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2446 Store = DAG.getTruncStore(
2452 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2455 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2459 MachinePointerInfo MPI =
Load->getPointerInfo();
2460 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2462 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2465 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2466 if (LoVT !=
Lo.getValueType())
2468 if (HiVT !=
Hi.getValueType())
2476 assert(
N->getValueType(0).isScalableVector() &&
2477 "Only scalable vectors are supported for STEP_VECTOR");
2478 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2479 SDValue Step =
N->getOperand(0);
2499 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2500 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2502 Hi = DAG.getPOISON(HiVT);
2512 "Extended load during type legalization!");
2514 EVT VT =
LD->getValueType(0);
2516 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2518 SDValue Ch =
LD->getChain();
2519 SDValue Ptr =
LD->getBasePtr();
2524 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2525 Ch, Ptr,
LD->getMemOperand());
2529 SDValue ExtractLo, ExtractHi;
2530 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2532 Lo = DAG.getBitcast(LoVT, ExtractLo);
2533 Hi = DAG.getBitcast(HiVT, ExtractHi);
2537 ReplaceValueWith(SDValue(LD, 1), ALD.
getValue(1));
2545 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2548 SDValue Ch =
LD->getChain();
2549 SDValue Ptr =
LD->getBasePtr();
2551 EVT MemoryVT =
LD->getMemoryVT();
2553 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
2555 EVT LoMemVT, HiMemVT;
2556 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2559 SDValue
Value, NewChain;
2560 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2561 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2562 ReplaceValueWith(SDValue(LD, 1), NewChain);
2567 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2570 MachinePointerInfo MPI;
2571 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2574 HiMemVT,
LD->getBaseAlign(), MMOFlags,
Metadata);
2583 ReplaceValueWith(SDValue(LD, 1), Ch);
2588 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2591 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2594 SDValue Ch =
LD->getChain();
2595 SDValue Ptr =
LD->getBasePtr();
2597 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2599 SDValue
Mask =
LD->getMask();
2600 SDValue EVL =
LD->getVectorLength();
2601 EVT MemoryVT =
LD->getMemoryVT();
2603 EVT LoMemVT, HiMemVT;
2604 bool HiIsEmpty =
false;
2605 std::tie(LoMemVT, HiMemVT) =
2606 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2609 SDValue MaskLo, MaskHi;
2611 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2614 GetSplitVector(Mask, MaskLo, MaskHi);
2616 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2620 SDValue EVLLo, EVLHi;
2621 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2623 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2626 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2629 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2630 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2638 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2639 LD->isExpandingLoad());
2641 MachinePointerInfo MPI;
2643 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2645 MPI =
LD->getPointerInfo().getWithOffset(
2648 MMO = DAG.getMachineFunction().getMachineMemOperand(
2650 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2652 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2653 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2654 LD->isExpandingLoad());
2664 ReplaceValueWith(SDValue(LD, 1), Ch);
2670 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2672 SDValue Ch =
LD->getChain();
2673 SDValue Ptr =
LD->getBasePtr();
2675 SDValue
Mask =
LD->getMask();
2676 SDValue EVL =
LD->getVectorLength();
2679 SDValue MaskLo, MaskHi;
2681 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2684 GetSplitVector(Mask, MaskLo, MaskHi);
2686 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2690 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2692 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2695 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2697 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2700 Hi = DAG.getPOISON(HiVT);
2702 ReplaceValueWith(SDValue(LD, 1),
Lo.getValue(1));
2703 ReplaceValueWith(SDValue(LD, 2),
Lo.getValue(2));
2709 "Indexed VP strided load during type legalization!");
2711 "Unexpected indexed variable-length load offset");
2716 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2718 EVT LoMemVT, HiMemVT;
2719 bool HiIsEmpty =
false;
2720 std::tie(LoMemVT, HiMemVT) =
2721 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2724 SDValue LoMask, HiMask;
2726 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2729 GetSplitVector(Mask, LoMask, HiMask);
2731 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2734 SDValue LoEVL, HiEVL;
2735 std::tie(LoEVL, HiEVL) =
2739 Lo = DAG.getStridedLoadVP(
2766 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2773 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2784 ReplaceValueWith(SDValue(SLD, 1), Ch);
2792 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2797 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2805 SDValue MaskLo, MaskHi;
2807 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2810 GetSplitVector(Mask, MaskLo, MaskHi);
2812 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2816 EVT LoMemVT, HiMemVT;
2817 bool HiIsEmpty =
false;
2818 std::tie(LoMemVT, HiMemVT) =
2819 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2821 SDValue PassThruLo, PassThruHi;
2823 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2825 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2827 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2832 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2842 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2845 MachinePointerInfo MPI;
2852 MMO = DAG.getMachineFunction().getMachineMemOperand(
2857 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2869 ReplaceValueWith(SDValue(MLD, 1), Ch);
2877 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2879 SDValue Ch =
N->getChain();
2880 SDValue Ptr =
N->getBasePtr();
2887 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2890 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2893 EVT MemoryVT =
N->getMemoryVT();
2897 SDValue MaskLo, MaskHi;
2899 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2901 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2904 EVT LoMemVT, HiMemVT;
2906 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2908 SDValue IndexHi, IndexLo;
2909 if (getTypeAction(
Ops.Index.getValueType()) ==
2911 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2913 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2916 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2918 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2921 SDValue PassThru = MGT->getPassThru();
2922 SDValue PassThruLo, PassThruHi;
2925 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2927 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2932 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2933 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2934 OpsLo, MMO, IndexTy, ExtType);
2936 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2937 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2938 OpsHi, MMO, IndexTy, ExtType);
2941 SDValue EVLLo, EVLHi;
2942 std::tie(EVLLo, EVLHi) =
2943 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2945 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2946 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2947 MMO, VPGT->getIndexType());
2949 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2950 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2951 MMO, VPGT->getIndexType());
2961 ReplaceValueWith(SDValue(
N, 1), Ch);
2975 EVT VecVT =
N->getValueType(0);
2977 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2978 bool HasCustomLowering =
false;
2985 HasCustomLowering =
true;
2991 SDValue Passthru =
N->getOperand(2);
2992 if (!HasCustomLowering) {
2993 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2994 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2999 SDValue
Mask =
N->getOperand(1);
3000 SDValue LoMask, HiMask;
3001 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3002 std::tie(LoMask, HiMask) = SplitMask(Mask);
3004 SDValue UndefPassthru = DAG.getPOISON(LoVT);
3008 SDValue
StackPtr = DAG.CreateStackTemporary(
3009 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
3022 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
3024 SDValue Chain = DAG.getEntryNode();
3025 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
3029 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
3033 EVT MaskVT =
Mask.getValueType();
3037 SDValue NumActiveElts =
3040 SDValue StepVector = DAG.getStepVector(
DL, WideMaskVT);
3041 SDValue SplatNumActiveElts = DAG.getSplat(WideMaskVT,
DL, NumActiveElts);
3042 SDValue CompressedMask =
3043 DAG.getSetCC(
DL, MaskVT, StepVector, SplatNumActiveElts,
ISD::SETULT);
3046 Compressed, Passthru);
3048 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
3052 assert(
N->getValueType(0).isVector() &&
3053 N->getOperand(0).getValueType().isVector() &&
3054 "Operand types must be vectors");
3058 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3061 SDValue LL, LH, RL, RH;
3062 if (getTypeAction(
N->getOperand(0).getValueType()) ==
3064 GetSplitVector(
N->getOperand(0), LL, LH);
3066 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
3068 if (getTypeAction(
N->getOperand(1).getValueType()) ==
3070 GetSplitVector(
N->getOperand(1), RL, RH);
3072 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
3074 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
3075 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
3083 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3087 EVT InVT =
N->getOperand(0).getValueType();
3089 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3091 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3093 const SDNodeFlags
Flags =
N->getFlags();
3094 unsigned Opcode =
N->getOpcode();
3096 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
3097 N->getOperand(3), Flags);
3098 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
3099 N->getOperand(3), Flags);
3105 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
3106 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
3108 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
3109 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
3116 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3120 EVT InVT =
N->getOperand(0).getValueType();
3122 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3124 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3127 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3128 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3129 SDNodeFlags
Flags = AddrSpaceCastN->getFlags();
3130 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS, Flags);
3131 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS, Flags);
3134void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3139 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3140 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3144 EVT InVT =
N->getOperand(0).getValueType();
3146 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3148 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3150 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3151 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3153 SDNode *HiNode =
Hi.getNode();
3154 SDNode *LoNode =
Lo.getNode();
3157 unsigned OtherNo = 1 - ResNo;
3158 EVT OtherVT =
N->getValueType(OtherNo);
3160 SetSplitVector(SDValue(
N, OtherNo), SDValue(LoNode, OtherNo),
3161 SDValue(HiNode, OtherNo));
3165 SDValue(HiNode, OtherNo));
3166 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
3173 EVT SrcVT =
N->getOperand(0).getValueType();
3174 EVT DestVT =
N->getValueType(0);
3176 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3193 LLVMContext &Ctx = *DAG.getContext();
3197 EVT SplitLoVT, SplitHiVT;
3198 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3199 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3200 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3201 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3202 N->dump(&DAG);
dbgs() <<
"\n");
3205 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3207 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3209 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3210 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3215 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3223 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3224 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3230 return N.getResNo() == 0 &&
3234 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](SDValue &Input1,
3236 ArrayRef<int>
Mask) {
3239 "Expected build vector node.");
3242 for (
unsigned I = 0;
I < NewElts; ++
I) {
3247 Ops[
I] = Input2.getOperand(Idx - NewElts);
3249 Ops[
I] = Input1.getOperand(Idx);
3254 return DAG.getBuildVector(NewVT,
DL,
Ops);
3260 SmallVector<int> OrigMask(
N->getMask());
3262 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3263 &
DL](SmallVectorImpl<int> &
Mask) {
3265 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3266 for (
unsigned Idx = 0;
Idx < std::size(Inputs); ++
Idx) {
3267 SDValue Input = Inputs[
Idx];
3277 for (
auto &
P : ShufflesIdxs) {
3278 if (
P.second.size() < 2)
3282 for (
int &Idx : Mask) {
3285 unsigned SrcRegIdx =
Idx / NewElts;
3286 if (Inputs[SrcRegIdx].
isUndef()) {
3294 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3299 Idx = MaskElt % NewElts +
3300 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3306 Inputs[
P.second[0]] =
P.first.first;
3307 Inputs[
P.second[1]] =
P.first.second;
3310 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3313 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3314 for (
int &Idx : Mask) {
3317 unsigned SrcRegIdx =
Idx / NewElts;
3318 if (Inputs[SrcRegIdx].
isUndef()) {
3325 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3326 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3329 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3331 if (UsedSubVector.count() > 1) {
3333 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3334 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3336 if (Pairs.
empty() || Pairs.
back().size() == 2)
3338 if (UsedSubVector.test(2 *
I)) {
3339 Pairs.
back().emplace_back(
I, 0);
3341 assert(UsedSubVector.test(2 *
I + 1) &&
3342 "Expected to be used one of the subvectors.");
3343 Pairs.
back().emplace_back(
I, 1);
3346 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3348 for (
int &Idx : Mask) {
3351 unsigned SrcRegIdx =
Idx / NewElts;
3353 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3354 return Idxs.front().first == SrcRegIdx ||
3355 Idxs.back().first == SrcRegIdx;
3357 if (It == Pairs.
end())
3359 Idx = It->front().first * NewElts + (
Idx % NewElts) % (NewElts / 2) +
3360 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3363 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3364 Inputs[Idxs.front().first] = DAG.
getNode(
3366 Inputs[Idxs.front().first].getValueType(),
3367 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3368 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3377 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3381 if (Shuffle->getOperand(0).getValueType() != NewVT)
3384 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3385 !Shuffle->isSplat()) {
3387 }
else if (!Inputs[
I].hasOneUse() &&
3388 !Shuffle->getOperand(1).isUndef()) {
3390 for (
int &Idx : Mask) {
3393 unsigned SrcRegIdx =
Idx / NewElts;
3396 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3401 int OpIdx = MaskElt / NewElts;
3414 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3415 if (Shuffle->getOperand(OpIdx).isUndef())
3417 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3418 if (It == std::end(Inputs))
3420 int FoundOp = std::distance(std::begin(Inputs), It);
3423 for (
int &Idx : Mask) {
3426 unsigned SrcRegIdx =
Idx / NewElts;
3429 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3434 int MaskIdx = MaskElt / NewElts;
3435 if (OpIdx == MaskIdx)
3436 Idx = MaskElt % NewElts + FoundOp * NewElts;
3439 Op = (OpIdx + 1) % 2;
3447 for (
int &Idx : Mask) {
3450 unsigned SrcRegIdx =
Idx / NewElts;
3453 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3454 int OpIdx = MaskElt / NewElts;
3457 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3463 TryPeekThroughShufflesInputs(OrigMask);
3465 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3466 NewElts](SmallVectorImpl<int> &
Mask) {
3467 SetVector<SDValue> UniqueInputs;
3468 SetVector<SDValue> UniqueConstantInputs;
3469 for (
const auto &
I : Inputs) {
3471 UniqueConstantInputs.
insert(
I);
3472 else if (!
I.isUndef())
3477 if (UniqueInputs.
size() != std::size(Inputs)) {
3478 auto &&UniqueVec = UniqueInputs.
takeVector();
3479 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3480 unsigned ConstNum = UniqueConstantVec.size();
3481 for (
int &Idx : Mask) {
3484 unsigned SrcRegIdx =
Idx / NewElts;
3485 if (Inputs[SrcRegIdx].
isUndef()) {
3489 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3490 if (It != UniqueConstantVec.end()) {
3492 NewElts * std::distance(UniqueConstantVec.begin(), It);
3493 assert(Idx >= 0 &&
"Expected defined mask idx.");
3496 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3497 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3499 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3500 assert(Idx >= 0 &&
"Expected defined mask idx.");
3502 copy(UniqueConstantVec, std::begin(Inputs));
3503 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3506 MakeUniqueInputs(OrigMask);
3507 SDValue OrigInputs[4];
3508 copy(Inputs, std::begin(OrigInputs));
3514 unsigned FirstMaskIdx =
High * NewElts;
3517 assert(!Output &&
"Expected default initialized initial value.");
3518 TryPeekThroughShufflesInputs(Mask);
3519 MakeUniqueInputs(Mask);
3520 SDValue TmpInputs[4];
3521 copy(Inputs, std::begin(TmpInputs));
3524 bool SecondIteration =
false;
3525 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3530 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3531 SecondIteration =
true;
3532 return SecondIteration;
3535 Mask, std::size(Inputs), std::size(Inputs),
3537 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3538 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3539 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3541 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3543 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3544 DAG.getPOISON(NewVT), Mask);
3545 Inputs[
Idx] = Output;
3547 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3548 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3549 unsigned Idx2,
bool ) {
3550 if (AccumulateResults(Idx1)) {
3553 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3555 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3556 Inputs[Idx2], Mask);
3560 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3562 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3563 TmpInputs[Idx2], Mask);
3565 Inputs[Idx1] = Output;
3567 copy(OrigInputs, std::begin(Inputs));
3572 EVT OVT =
N->getValueType(0);
3576 SDValue
SV =
N->getOperand(2);
3580 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3582 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV,
Alignment.value());
3583 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV,
Alignment.value());
3588 ReplaceValueWith(SDValue(
N, 1), Chain);
3593 EVT DstVTLo, DstVTHi;
3594 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3597 SDValue SrcLo, SrcHi;
3598 EVT SrcVT =
N->getOperand(0).getValueType();
3600 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3602 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3604 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3605 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3610 EVT VT =
N->getValueType(0);
3611 SDValue Src =
N->getOperand(0);
3612 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VT);
3613 assert(LoVT == HiVT &&
"Expected equal split types");
3618 auto [SrcLo, SrcHi] = DAG.SplitVector(Src,
DL);
3620 SDValue Deinterleaved =
3622 DAG.getVTList(SplitSrcVT, SplitSrcVT), SrcLo, SrcHi);
3628 DAG.getVTList(LoVT, LoVT), Even, Odd);
3636 GetSplitVector(
N->getOperand(0), InLo, InHi);
3647 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3648 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3653 EVT VT =
N->getValueType(0);
3654 SDValue Val =
N->getOperand(0);
3655 SDValue
Mask =
N->getOperand(1);
3676 EVT PtrVT =
StackPtr.getValueType();
3677 auto &MF = DAG.getMachineFunction();
3681 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3684 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3689 SDValue NumElemMinus1 =
3690 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3691 DAG.getConstant(1,
DL, PtrVT));
3692 SDValue StartOffset = DAG.getNode(
ISD::MUL,
DL, PtrVT, NumElemMinus1,
3693 DAG.getConstant(EltWidth,
DL, PtrVT));
3694 SDValue StorePtr = DAG.getNode(
ISD::ADD,
DL, PtrVT, StackPtr, StartOffset);
3695 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3697 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3698 SDValue
Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3699 DAG.getPOISON(PtrVT), Stride, TrueMask,
3702 SDValue
Load = DAG.getLoadVP(VT,
DL,
Store, StackPtr, Mask, EVL, LoadMMO);
3708 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3713 EVT VT =
N->getValueType(0);
3714 SDValue
V1 =
N->getOperand(0);
3715 SDValue V2 =
N->getOperand(1);
3717 SDValue
Mask =
N->getOperand(3);
3718 SDValue EVL1 =
N->getOperand(4);
3719 SDValue EVL2 =
N->getOperand(5);
3725 EVL1 = ZExtPromotedInteger(EVL1);
3744 EVT PtrVT =
StackPtr.getValueType();
3745 auto &MF = DAG.getMachineFunction();
3749 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3752 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3756 SDValue EltByteSize =
3758 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3759 SDValue EVL1Bytes = DAG.getNode(
ISD::MUL,
DL, PtrVT, EVL1Ptr, EltByteSize);
3763 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3764 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3766 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3768 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3772 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3777 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3778 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3782 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3785 SDValue OffsetToV2 = DAG.getNode(
ISD::SUB,
DL, PtrVT, StackPtr2, StackPtr);
3791 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3799 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3801 DAG.getVectorIdxConstant(0,
DL));
3807void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3810 SDValue Acc =
N->getOperand(0);
3811 SDValue Input1 =
N->getOperand(1);
3812 SDValue Input2 =
N->getOperand(2);
3814 SDValue AccLo, AccHi;
3815 GetSplitVector(Acc, AccLo, AccHi);
3816 unsigned Opcode =
N->getOpcode();
3826 SDValue Input1Lo, Input1Hi;
3827 SDValue Input2Lo, Input2Hi;
3828 GetSplitVector(Input1, Input1Lo, Input1Hi);
3829 GetSplitVector(Input2, Input2Lo, Input2Hi);
3832 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3833 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3836void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3844 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3848 SDValue HiStartVal = DAG.getNode(
ISD::UADDSAT,
DL, OpVT, Op0, LoElts);
3854 SDValue SourceLo, SourceHi;
3855 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3856 SDValue MaskLo, MaskHi;
3857 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3861 N->getOperand(1), MaskLo,
N->getFlags());
3863 N->getOperand(1), MaskHi,
N->getFlags());
3866void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3867 unsigned Factor =
N->getNumOperands();
3870 for (
unsigned i = 0; i != Factor; ++i) {
3872 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3874 Ops[i * 2 + 1] = OpHi;
3885 for (
unsigned i = 0; i != Factor; ++i)
3889void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3890 unsigned Factor =
N->getNumOperands();
3893 for (
unsigned i = 0; i != Factor; ++i) {
3895 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3897 Ops[i + Factor] = OpHi;
3908 for (
unsigned i = 0; i != Factor; ++i) {
3909 unsigned IdxLo = 2 * i;
3910 unsigned IdxHi = 2 * i + 1;
3911 SetSplitVector(SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3912 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3924bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3926 SDValue Res = SDValue();
3929 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3932 switch (
N->getOpcode()) {
3935 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3944 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3951 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3954 Res = SplitVecOp_TruncateHelper(
N);
3960 Res = SplitVecOp_FP_ROUND(
N);
3972 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3979 case ISD::VP_SCATTER:
3983 case ISD::VP_GATHER:
3987 Res = SplitVecOp_VSELECT(
N, OpNo);
3993 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3996 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
4002 if (
N->getValueType(0).bitsLT(
4003 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
4004 Res = SplitVecOp_TruncateHelper(
N);
4006 Res = SplitVecOp_UnaryOp(
N);
4010 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
4026 Res = SplitVecOp_UnaryOp(
N);
4029 Res = SplitVecOp_FPOpDifferentTypes(
N);
4034 Res = SplitVecOp_CMP(
N);
4038 Res = SplitVecOp_FAKE_USE(
N);
4043 Res = SplitVecOp_ExtVecInRegOp(
N);
4063 Res = SplitVecOp_VECREDUCE(
N, OpNo);
4067 Res = SplitVecOp_VECREDUCE_SEQ(
N);
4069 case ISD::VP_REDUCE_FADD:
4070 case ISD::VP_REDUCE_SEQ_FADD:
4071 case ISD::VP_REDUCE_FMUL:
4072 case ISD::VP_REDUCE_SEQ_FMUL:
4073 case ISD::VP_REDUCE_ADD:
4074 case ISD::VP_REDUCE_MUL:
4075 case ISD::VP_REDUCE_AND:
4076 case ISD::VP_REDUCE_OR:
4077 case ISD::VP_REDUCE_XOR:
4078 case ISD::VP_REDUCE_SMAX:
4079 case ISD::VP_REDUCE_SMIN:
4080 case ISD::VP_REDUCE_UMAX:
4081 case ISD::VP_REDUCE_UMIN:
4082 case ISD::VP_REDUCE_FMAX:
4083 case ISD::VP_REDUCE_FMIN:
4084 case ISD::VP_REDUCE_FMAXIMUM:
4085 case ISD::VP_REDUCE_FMINIMUM:
4086 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
4090 Res = SplitVecOp_CttzElts(
N);
4092 case ISD::VP_CTTZ_ELTS:
4093 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
4094 Res = SplitVecOp_VP_CttzElements(
N);
4097 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
4103 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
4106 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
4111 if (!Res.
getNode())
return false;
4118 if (
N->isStrictFPOpcode())
4120 "Invalid operand expansion");
4123 "Invalid operand expansion");
4125 ReplaceValueWith(SDValue(
N, 0), Res);
4129SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4132 SDValue LoMask, HiMask;
4133 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4135 EVT VT =
N->getValueType(0);
4147 SDValue
Cond = DAG.getBoolExtOrTrunc(AnyHiActive,
DL,
4148 getSetCCResultType(MVT::i1), MVT::i1);
4153 DAG.getElementCount(
DL, VT, SplitEC)),
4157SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4160 assert(OpNo == 0 &&
"Illegal operand must be mask");
4162 SDValue
Mask =
N->getOperand(0);
4163 SDValue
Src0 =
N->getOperand(1);
4164 SDValue
Src1 =
N->getOperand(2);
4165 EVT Src0VT =
Src0.getValueType();
4167 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4170 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4171 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4172 "Lo and Hi have differing types");
4175 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4176 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4178 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4179 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4180 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4181 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4191SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4192 assert(OpNo == 2 &&
"Illegal operand must be mask");
4195 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4196 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4197 SDValue MaskLo, MaskHi;
4198 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4201 RHSLo, MaskLo,
N->getFlags());
4203 RHSHi, MaskHi,
N->getFlags());
4207SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4210 assert(OpNo == 1 &&
"Illegal operand must be mask");
4215 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4217 EVT VecVT =
N->getValueType(0);
4221SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4222 EVT ResVT =
N->getValueType(0);
4228 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4229 GetSplitVector(VecOp,
Lo,
Hi);
4231 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4236 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4237 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4241 EVT ResVT =
N->getValueType(0);
4247 SDNodeFlags
Flags =
N->getFlags();
4250 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4251 GetSplitVector(VecOp,
Lo,
Hi);
4253 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4256 SDValue Partial = DAG.
getNode(
N->getOpcode(), dl, ResVT, AccOp,
Lo, Flags);
4259 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4262SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4263 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4264 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4266 unsigned Opc =
N->getOpcode();
4267 EVT ResVT =
N->getValueType(0);
4273 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4274 GetSplitVector(VecOp,
Lo,
Hi);
4276 SDValue MaskLo, MaskHi;
4277 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4279 SDValue EVLLo, EVLHi;
4280 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4282 const SDNodeFlags
Flags =
N->getFlags();
4286 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4291 EVT ResVT =
N->getValueType(0);
4294 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4295 EVT InVT =
Lo.getValueType();
4300 if (
N->isStrictFPOpcode()) {
4301 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4302 {N->getOperand(0), Lo});
4303 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4304 {N->getOperand(0), Hi});
4313 ReplaceValueWith(SDValue(
N, 1), Ch);
4315 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4316 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4325 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4335 EVT ResVT =
N->getValueType(0);
4337 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4341 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4347 Lo = BitConvertToInteger(
Lo);
4348 Hi = BitConvertToInteger(
Hi);
4350 if (DAG.getDataLayout().isBigEndian())
4358 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4360 EVT ResVT =
N->getValueType(0);
4364 SDValue
Idx =
N->getOperand(2);
4368 GetSplitVector(SubVec,
Lo,
Hi);
4373 SDValue FirstInsertion =
4375 SDValue SecondInsertion =
4377 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4379 return SecondInsertion;
4382SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4385 SDValue
Idx =
N->getOperand(1);
4389 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4391 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4393 ElementCount IdxVal =
4397 EVT SrcVT =
N->getOperand(0).getValueType();
4416 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4417 LoEltsMin - IdxValMin);
4418 DAG.ExtractVectorElements(
Hi, Elts, 0,
4421 return DAG.getBuildVector(SubVT, dl, Elts);
4425 ElementCount ExtractIdx = IdxVal - LoElts;
4427 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4430 EVT HiVT =
Hi.getValueType();
4432 "Only fixed-vector extracts are supported in this case");
4442 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4443 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4449 "Extracting scalable subvector from fixed-width unsupported");
4457 "subvector from a scalable predicate vector");
4463 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4465 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4466 auto &MF = DAG.getMachineFunction();
4470 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4474 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4477 SubVT, dl,
Store, StackPtr,
4481SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4483 SDValue
Idx =
N->getOperand(1);
4490 GetSplitVector(Vec,
Lo,
Hi);
4492 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4494 if (IdxVal < LoElts)
4495 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4497 return SDValue(DAG.UpdateNodeOperands(
N,
Hi,
4498 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4499 Idx.getValueType())), 0);
4503 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4513 SDValue NewExtract =
4515 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4521 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4523 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4524 auto &MF = DAG.getMachineFunction();
4527 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4531 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4535 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4537 return DAG.getExtLoad(
4548 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4556 SplitVecRes_Gather(
N,
Lo,
Hi);
4559 ReplaceValueWith(SDValue(
N, 0), Res);
4564 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4565 SDValue Ch =
N->getChain();
4566 SDValue Ptr =
N->getBasePtr();
4567 SDValue
Offset =
N->getOffset();
4568 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4569 SDValue
Mask =
N->getMask();
4570 SDValue EVL =
N->getVectorLength();
4571 SDValue
Data =
N->getValue();
4575 SDValue DataLo, DataHi;
4578 GetSplitVector(
Data, DataLo, DataHi);
4580 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4583 SDValue MaskLo, MaskHi;
4585 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4588 GetSplitVector(Mask, MaskLo, MaskHi);
4590 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4593 EVT MemoryVT =
N->getMemoryVT();
4594 EVT LoMemVT, HiMemVT;
4595 bool HiIsEmpty =
false;
4596 std::tie(LoMemVT, HiMemVT) =
4597 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4600 SDValue EVLLo, EVLHi;
4601 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4604 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4607 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4609 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4610 N->getAddressingMode(),
N->isTruncatingStore(),
4611 N->isCompressingStore());
4617 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4618 N->isCompressingStore());
4620 MachinePointerInfo MPI;
4624 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4629 MMO = DAG.getMachineFunction().getMachineMemOperand(
4631 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4633 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4634 N->getAddressingMode(),
N->isTruncatingStore(),
4635 N->isCompressingStore());
4644 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4645 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4649 SDValue
Data =
N->getValue();
4650 SDValue LoData, HiData;
4652 GetSplitVector(
Data, LoData, HiData);
4654 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4656 EVT LoMemVT, HiMemVT;
4657 bool HiIsEmpty =
false;
4658 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4661 SDValue
Mask =
N->getMask();
4662 SDValue LoMask, HiMask;
4664 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4665 else if (getTypeAction(
Mask.getValueType()) ==
4667 GetSplitVector(Mask, LoMask, HiMask);
4669 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4671 SDValue LoEVL, HiEVL;
4672 std::tie(LoEVL, HiEVL) =
4673 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4676 SDValue
Lo = DAG.getStridedStoreVP(
4677 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4678 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4679 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4690 EVT PtrVT =
N->getBasePtr().getValueType();
4693 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4701 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4702 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4704 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4706 SDValue
Hi = DAG.getStridedStoreVP(
4707 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4708 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4709 N->isCompressingStore());
4718 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4719 SDValue Ch =
N->getChain();
4720 SDValue Ptr =
N->getBasePtr();
4721 SDValue
Offset =
N->getOffset();
4722 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4723 SDValue
Mask =
N->getMask();
4724 SDValue
Data =
N->getValue();
4728 SDValue DataLo, DataHi;
4731 GetSplitVector(
Data, DataLo, DataHi);
4733 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4736 SDValue MaskLo, MaskHi;
4738 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4741 GetSplitVector(Mask, MaskLo, MaskHi);
4743 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4746 EVT MemoryVT =
N->getMemoryVT();
4747 EVT LoMemVT, HiMemVT;
4748 bool HiIsEmpty =
false;
4749 std::tie(LoMemVT, HiMemVT) =
4750 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4752 SDValue
Lo,
Hi, Res;
4753 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4756 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4758 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4759 N->getAddressingMode(),
N->isTruncatingStore(),
4760 N->isCompressingStore());
4768 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4769 N->isCompressingStore());
4771 MachinePointerInfo MPI;
4775 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4780 MMO = DAG.getMachineFunction().getMachineMemOperand(
4783 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4785 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4786 N->getAddressingMode(),
N->isTruncatingStore(),
4787 N->isCompressingStore());
4798 SDValue Ch =
N->getChain();
4799 SDValue Ptr =
N->getBasePtr();
4800 EVT MemoryVT =
N->getMemoryVT();
4810 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4814 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4819 EVT LoMemVT, HiMemVT;
4820 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4822 SDValue DataLo, DataHi;
4825 GetSplitVector(
Ops.Data, DataLo, DataHi);
4827 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4830 SDValue MaskLo, MaskHi;
4832 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4834 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4837 SDValue IndexHi, IndexLo;
4838 if (getTypeAction(
Ops.Index.getValueType()) ==
4840 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4842 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4846 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4848 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4851 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4853 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4854 MSC->getIndexType(), MSC->isTruncatingStore());
4859 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4860 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4861 MMO, MSC->getIndexType(),
4862 MSC->isTruncatingStore());
4865 SDValue EVLLo, EVLHi;
4866 std::tie(EVLLo, EVLHi) =
4867 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4869 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4870 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4871 VPSC->getIndexType());
4876 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4877 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4878 VPSC->getIndexType());
4882 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4883 assert(OpNo == 1 &&
"Can only split the stored value");
4886 bool isTruncating =
N->isTruncatingStore();
4887 SDValue Ch =
N->getChain();
4888 SDValue Ptr =
N->getBasePtr();
4889 EVT MemoryVT =
N->getMemoryVT();
4892 MMOMetadata
Metadata =
N->getMMOMetadataForSubAccess();
4894 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4896 EVT LoMemVT, HiMemVT;
4897 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4901 return TLI.scalarizeVectorStore(
N, DAG);
4904 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4907 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4910 MachinePointerInfo MPI;
4911 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4914 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI, HiMemVT, Alignment, MMOFlags,
4917 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags,
Metadata);
4924 LLVMContext &Ctx = *DAG.getContext();
4925 SDValue StVal =
N->getVal();
4942 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4943 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4947 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4950 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4951 DAG.getBitcast(MemVecVT, Wide), 0);
4953 N->getBasePtr(),
N->getMemOperand());
4961 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4963 N->getBasePtr(),
N->getMemOperand());
4976 for (
const SDValue &
Op :
N->op_values()) {
4977 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4983 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
5004 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
5005 SDValue InVec =
N->getOperand(OpNo);
5007 EVT OutVT =
N->getValueType(0);
5015 EVT LoOutVT, HiOutVT;
5016 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
5017 assert(LoOutVT == HiOutVT &&
"Unequal split?");
5022 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
5024 return SplitVecOp_UnaryOp(
N);
5033 return SplitVecOp_UnaryOp(
N);
5036 SDValue InLoVec, InHiVec;
5037 GetSplitVector(InVec, InLoVec, InHiVec);
5043 EVT HalfElementVT = IsFloat ?
5045 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
5052 if (
N->isStrictFPOpcode()) {
5053 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
5054 {N->getOperand(0), InLoVec});
5055 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
5056 {N->getOperand(0), InHiVec});
5062 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
5063 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
5067 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
5075 if (
N->isStrictFPOpcode()) {
5079 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
5081 ReplaceValueWith(SDValue(
N, 1), SDValue(Res.
getNode(), 1));
5087 DAG.getTargetConstant(
5088 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
5095 assert(
N->getValueType(0).isVector() &&
5096 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
5097 "Operand types must be vectors");
5099 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
5101 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
5102 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
5104 EVT VT =
N->getValueType(0);
5105 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
5111 assert(isStrict &&
"unexpected node");
5112 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5113 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
5114 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5115 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
5118 ReplaceValueWith(SDValue(
N, 1), NewChain);
5126 EVT OpVT =
N->getOperand(0).getValueType();
5129 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5135 EVT ResVT =
N->getValueType(0);
5138 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5139 EVT InVT =
Lo.getValueType();
5144 if (
N->isStrictFPOpcode()) {
5145 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5146 {N->getOperand(0), Lo, N->getOperand(2)});
5147 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5148 {N->getOperand(0), Hi, N->getOperand(2)});
5152 Lo.getValue(1),
Hi.getValue(1));
5153 ReplaceValueWith(SDValue(
N, 1), NewChain);
5155 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5156 N->getOperand(2),
N->getOperand(3));
5157 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5158 N->getOperand(2),
N->getOperand(3));
5160 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5161 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5172SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5175 EVT LHSLoVT, LHSHiVT;
5176 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5178 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5179 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5181 SDValue LHSLo, LHSHi;
5182 std::tie(LHSLo, LHSHi) =
5183 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5185 SDValue RHSLo, RHSHi;
5186 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5188 SDValue
Lo = DAG.
getNode(
N->getOpcode(),
DL, LHSLoVT, LHSLo, RHSLo);
5189 SDValue
Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5195 LLVMContext &Ctxt = *DAG.getContext();
5198 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5199 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5200 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5202 EVT ResVT =
N->getValueType(0);
5207 SDValue
Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5208 SDValue
Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5214 EVT ResVT =
N->getValueType(0);
5217 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5218 EVT InVT =
Lo.getValueType();
5224 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5225 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5232 EVT ResVT =
N->getValueType(0);
5236 GetSplitVector(VecOp,
Lo,
Hi);
5242 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5243 SDValue ResLoNotVL =
5244 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5245 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi);
5246 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5247 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5252 EVT ResVT =
N->getValueType(0);
5256 GetSplitVector(VecOp,
Lo,
Hi);
5258 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5259 auto [EVLLo, EVLHi] =
5261 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5265 SDValue ResLo = DAG.
getNode(ISD::VP_CTTZ_ELTS,
DL, ResVT,
Lo, MaskLo, EVLLo);
5266 SDValue ResLoNotEVL =
5267 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5268 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi, MaskHi, EVLHi);
5269 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5270 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5273SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5276 SDValue Inc = HG->
getInc();
5284 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5285 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5286 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5287 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5288 SDValue
Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5289 OpsLo, MMO, IndexType);
5290 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5291 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5295SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5299 EVT LoResVT, HiResVT;
5300 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5301 SDValue SourceLo, SourceHi;
5302 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5303 SDValue MaskLo, MaskHi;
5304 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5307 N->getOperand(1), MaskLo,
N->getFlags());
5309 N->getOperand(1), MaskHi,
N->getFlags());
5315 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5317 SDValue NeedleLo, NeedleHi;
5318 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5322 NeedleLo,
N->getOperand(2),
N->getFlags());
5325 NeedleHi,
N->getOperand(2),
N->getFlags());
5326 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5329SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5332 "Accumulator should already be a legal type, and shouldn't need "
5333 "further splitting");
5336 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5337 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5338 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5339 unsigned Opcode =
N->getOpcode();
5342 SDValue
Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5343 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5350void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5351 unsigned WidenResNo) {
5352 unsigned NumResults =
N->getNumValues();
5353 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5354 if (ResNo == WidenResNo)
5356 EVT ResVT =
N->getValueType(ResNo);
5358 SetWidenedVector(SDValue(
N, ResNo), SDValue(WidenNode, ResNo));
5362 DAG.getExtractSubvector(
DL, ResVT, SDValue(WidenNode, ResNo), 0);
5363 ReplaceValueWith(SDValue(
N, ResNo), ResVal);
5368void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5369 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5372 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5375 SDValue Res = SDValue();
5377 auto unrollExpandedOp = [&]() {
5382 EVT ResVT =
N->getValueType(ResNo);
5383 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5384 EVT VT0 =
N->getValueType(0);
5385 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5386 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT0.
getScalarType())) {
5390 if (
N->getNumValues() > 1)
5391 ReplaceOtherWidenResults(
N, Unrolled.
getNode(), ResNo);
5397 switch (
N->getOpcode()) {
5400 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5408 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5412 Res = WidenVecRes_ADDRSPACECAST(
N);
5419 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5426 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5430 Res = WidenVecRes_ScalarOp(
N);
5436 Res = WidenVecRes_Select(
N);
5439 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5441 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5448 case ISD::VP_LOAD_FF:
5451 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5455 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5463 case ISD::VP_GATHER:
5467 Res = WidenVecRes_VECTOR_REVERSE(
N);
5470 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5473 WidenVecRes_VECTOR_INTERLEAVE(
N);
5476 Res = WidenVecRes_VECTOR_MATCH(
N);
5479 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5535 Res = WidenVecRes_Binary(
N);
5542 Res = WidenVecRes_MaskedBinary(
N);
5547 Res = WidenVecRes_CMP(
N);
5553 if (unrollExpandedOp())
5568 Res = WidenVecRes_BinaryCanTrap(
N);
5577 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5580#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5581 case ISD::STRICT_##DAGN:
5582#include "llvm/IR/ConstrainedOps.def"
5583 Res = WidenVecRes_StrictFP(
N);
5592 Res = WidenVecRes_OverflowOp(
N, ResNo);
5596 Res = WidenVecRes_FCOPYSIGN(
N);
5601 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5606 if (!unrollExpandedOp())
5607 Res = WidenVecRes_ExpOp(
N);
5613 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5628 Res = WidenVecRes_Convert(
N);
5633 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5640 Res = WidenVecRes_XROUND(
N);
5666 if (unrollExpandedOp())
5689 Res = WidenVecRes_Unary(
N);
5694 Res = WidenVecRes_Ternary(
N);
5700 if (!unrollExpandedOp())
5701 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5708 Res = WidenVecRes_PARTIAL_REDUCE_MLA(
N);
5714 SetWidenedVector(SDValue(
N, ResNo), Res);
5720 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5721 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5722 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5723 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5724 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5730 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5731 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5732 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5733 if (
N->getNumOperands() == 2)
5734 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5737 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5738 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5739 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5740 "Expected VP opcode");
5744 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5745 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5750 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5751 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5752 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5753 SDValue
Mask =
N->getOperand(2);
5755 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5756 Mask = ModifyToType(Mask, WideMaskVT,
true);
5757 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5762 LLVMContext &Ctxt = *DAG.getContext();
5765 SDValue
LHS =
N->getOperand(0);
5766 SDValue
RHS =
N->getOperand(1);
5767 EVT OpVT =
LHS.getValueType();
5769 LHS = GetWidenedVector(
LHS);
5770 RHS = GetWidenedVector(
RHS);
5771 OpVT =
LHS.getValueType();
5774 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5777 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5783SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5786 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5787 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5788 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5790 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5799 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5802 if (ConcatEnd == 1) {
5803 VT = ConcatOps[0].getValueType();
5805 return ConcatOps[0];
5808 SDLoc dl(ConcatOps[0]);
5815 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
5816 int Idx = ConcatEnd - 1;
5817 VT = ConcatOps[Idx--].getValueType();
5818 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
5831 unsigned NumToInsert = ConcatEnd - Idx - 1;
5832 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5834 ConcatOps[Idx+1] = VecOp;
5835 ConcatEnd = Idx + 2;
5841 unsigned RealVals = ConcatEnd - Idx - 1;
5842 unsigned SubConcatEnd = 0;
5843 unsigned SubConcatIdx = Idx + 1;
5844 while (SubConcatEnd < RealVals)
5845 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5846 while (SubConcatEnd < OpsToConcat)
5847 SubConcatOps[SubConcatEnd++] = undefVec;
5849 NextVT, SubConcatOps);
5850 ConcatEnd = SubConcatIdx + 1;
5855 if (ConcatEnd == 1) {
5856 VT = ConcatOps[0].getValueType();
5858 return ConcatOps[0];
5863 if (
NumOps != ConcatEnd ) {
5865 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5866 ConcatOps[j] = UndefVal;
5874 unsigned Opcode =
N->getOpcode();
5876 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5880 const SDNodeFlags
Flags =
N->getFlags();
5881 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5882 NumElts = NumElts / 2;
5886 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5888 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5889 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5890 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5898 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5901 TLI.isTypeLegal(WideMaskVT)) {
5902 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5903 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5904 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5906 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5907 N->getValueType(0).getVectorElementCount());
5908 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5922 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5923 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5924 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5927 unsigned ConcatEnd = 0;
5935 while (CurNumElts != 0) {
5936 while (CurNumElts >= NumElts) {
5937 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5938 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5939 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5941 CurNumElts -= NumElts;
5944 NumElts = NumElts / 2;
5946 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5949 for (
unsigned i = 0; i != CurNumElts; ++i, ++
Idx) {
5950 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5951 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5952 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5963 switch (
N->getOpcode()) {
5966 return WidenVecRes_STRICT_FSETCC(
N);
5973 return WidenVecRes_Convert_StrictFP(
N);
5980 unsigned Opcode =
N->getOpcode();
5982 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5986 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5987 NumElts = NumElts / 2;
5998 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
6002 unsigned ConcatEnd = 0;
6009 for (
unsigned i = 1; i < NumOpers; ++i) {
6015 Oper = GetWidenedVector(Oper);
6021 DAG.getPOISON(WideOpVT), Oper,
6022 DAG.getVectorIdxConstant(0, dl));
6034 while (CurNumElts != 0) {
6035 while (CurNumElts >= NumElts) {
6038 for (
unsigned i = 0; i < NumOpers; ++i) {
6039 SDValue
Op = InOps[i];
6041 EVT OpVT =
Op.getValueType();
6046 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
6052 EVT OperVT[] = {VT, MVT::Other};
6053 SDValue Oper = DAG.
getNode(Opcode, dl, OperVT, EOps);
6054 ConcatOps[ConcatEnd++] = Oper;
6057 CurNumElts -= NumElts;
6060 NumElts = NumElts / 2;
6062 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
6065 for (
unsigned i = 0; i != CurNumElts; ++i, ++
Idx) {
6068 for (
unsigned i = 0; i < NumOpers; ++i) {
6069 SDValue
Op = InOps[i];
6071 EVT OpVT =
Op.getValueType();
6079 EVT WidenVT[] = {WidenEltVT, MVT::Other};
6080 SDValue Oper = DAG.
getNode(Opcode, dl, WidenVT, EOps);
6081 ConcatOps[ConcatEnd++] = Oper;
6090 if (Chains.
size() == 1)
6091 NewChain = Chains[0];
6094 ReplaceValueWith(SDValue(
N, 1), NewChain);
6099SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
6101 EVT ResVT =
N->getValueType(0);
6102 EVT OvVT =
N->getValueType(1);
6103 EVT WideResVT, WideOvVT;
6104 SDValue WideLHS, WideRHS;
6108 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6113 WideLHS = GetWidenedVector(
N->getOperand(0));
6114 WideRHS = GetWidenedVector(
N->getOperand(1));
6116 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6121 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
6122 SDValue
Poison = DAG.getPOISON(WideResVT);
6125 N->getOperand(0), Zero);
6127 N->getOperand(1), Zero);
6130 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6131 SDNode *WideNode = DAG.getNode(
6132 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6135 unsigned OtherNo = 1 - ResNo;
6136 EVT OtherVT =
N->getValueType(OtherNo);
6138 SetWidenedVector(SDValue(
N, OtherNo), SDValue(WideNode, OtherNo));
6140 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
6141 SDValue OtherVal = DAG.
getNode(
6143 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
6146 return SDValue(WideNode, ResNo);
6150 LLVMContext &Ctx = *DAG.getContext();
6154 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6159 unsigned Opcode =
N->getOpcode();
6160 const SDNodeFlags
Flags =
N->getFlags();
6166 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6168 InOp = ZExtPromotedInteger(InOp);
6179 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
6180 if (
N->getNumOperands() == 1)
6181 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6183 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6184 N->getOperand(3), Flags);
6185 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6189 InOp = GetWidenedVector(
N->getOperand(0));
6192 if (InVTEC == WidenEC)
6193 return MakeConvertNode(WidenVT, InOp);
6217 SDValue MidRes = DAG.getNode(
ISD::TRUNCATE,
DL, MidResVT, InOp, Flags);
6218 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6222 if (TLI.isTypeLegal(InWidenVT)) {
6230 unsigned NumConcat =
6235 return MakeConvertNode(WidenVT, InVec);
6239 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6241 return MakeConvertNode(WidenVT, InVal);
6250 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6251 for (
unsigned i=0; i < MinElts; ++i) {
6252 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6253 Ops[i] = MakeConvertNode(EltVT, Val);
6256 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6261 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6264 SDValue Src =
N->getOperand(0);
6265 EVT SrcVT = Src.getValueType();
6269 Src = GetWidenedVector(Src);
6270 SrcVT = Src.getValueType();
6277 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6282 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6285 SDValue Src =
N->getOperand(0);
6286 EVT SrcVT = Src.getValueType();
6290 Src = GetWidenedVector(Src);
6291 SrcVT = Src.getValueType();
6298 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6301SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6306 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6312 unsigned Opcode =
N->getOpcode();
6318 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6323 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6324 for (
unsigned i=0; i < MinElts; ++i) {
6325 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6326 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6330 ReplaceValueWith(SDValue(
N, 1), NewChain);
6332 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6335SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6336 unsigned Opcode =
N->getOpcode();
6340 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6349 InOp = GetWidenedVector(InOp);
6356 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6363 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6364 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6381 while (
Ops.size() != WidenNumElts)
6382 Ops.push_back(DAG.getPOISON(WidenSVT));
6384 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6390 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6391 return WidenVecRes_BinaryCanTrap(
N);
6394 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6401SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6403 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6406 SDValue Arg = GetWidenedVector(FpValue);
6407 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6412 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6413 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6414 SDValue
RHS =
N->getOperand(1);
6415 EVT ExpVT =
RHS.getValueType();
6416 SDValue ExpOp =
RHS;
6420 ExpOp = ModifyToType(
RHS, WideExpVT);
6423 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6428 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6429 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6430 if (
N->getNumOperands() == 1)
6431 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6433 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6438 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6443 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6444 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6445 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6448SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6450 EVT VT0 =
N->getValueType(0);
6451 EVT VT1 =
N->getValueType(1);
6455 "expected both results to be vectors of matching element count");
6457 LLVMContext &Ctx = *DAG.getContext();
6458 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6460 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6467 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6470 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6471 return SDValue(WidenNode, ResNo);
6474SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6475 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6476 return GetWidenedVector(WidenVec);
6481 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6493 InOp = GetWidenedVector(InOp);
6497 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6500 return DAG.getAddrSpaceCast(
6501 DL, WidenVT, InOp, AddrSpaceCastN->getSrcAddressSpace(),
6502 AddrSpaceCastN->getDestAddressSpace(), AddrSpaceCastN->getFlags());
6508 EVT VT =
N->getValueType(0);
6509 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6512 switch (getTypeAction(InVT)) {
6526 SDValue NInOp = GetPromotedInteger(InOp);
6528 if (WidenVT.
bitsEq(NInVT)) {
6531 if (DAG.getDataLayout().isBigEndian()) {
6534 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6552 InOp = GetWidenedVector(InOp);
6554 if (WidenVT.
bitsEq(InVT))
6564 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6569 unsigned NewNumParts = WidenSize / InSize;
6582 EVT OrigInVT =
N->getOperand(0).getValueType();
6587 if (TLI.isTypeLegal(NewInVT)) {
6595 if (WidenSize % InSize == 0) {
6602 DAG.ExtractVectorElements(InOp,
Ops);
6603 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6615 return CreateStackStoreLoad(InOp, WidenVT);
6618SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6620 N->getOpcode(), SDLoc(
N),
6621 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6622 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6628 EVT VT =
N->getValueType(0);
6632 EVT EltVT =
N->getOperand(0).getValueType();
6635 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6639 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6640 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6642 return DAG.getBuildVector(WidenVT, dl, NewOps);
6646 EVT InVT =
N->getOperand(0).getValueType();
6647 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6649 unsigned NumOperands =
N->getNumOperands();
6651 bool InputWidened =
false;
6655 if (WidenNumElts % NumInElts == 0) {
6657 unsigned NumConcat = WidenNumElts / NumInElts;
6658 SDValue UndefVal = DAG.getPOISON(InVT);
6660 for (
unsigned i=0; i < NumOperands; ++i)
6661 Ops[i] =
N->getOperand(i);
6662 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6667 InputWidened =
true;
6668 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6671 for (i=1; i < NumOperands; ++i)
6672 if (!
N->getOperand(i).isUndef())
6675 if (i == NumOperands)
6678 return GetWidenedVector(
N->getOperand(0));
6680 if (NumOperands == 2) {
6682 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6687 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6688 for (
unsigned i = 0; i < NumInElts; ++i) {
6690 MaskOps[i + NumInElts] = i + WidenNumElts;
6692 return DAG.getVectorShuffle(WidenVT, dl,
6693 GetWidenedVector(
N->getOperand(0)),
6694 GetWidenedVector(
N->getOperand(1)),
6701 SDValue WideVec = DAG.getPOISON(WidenVT);
6703 for (
unsigned I = 0;
I < NumOperands; ++
I)
6705 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6716 for (
unsigned i=0; i < NumOperands; ++i) {
6719 InOp = GetWidenedVector(InOp);
6720 for (
unsigned j = 0;
j < NumInElts; ++
j)
6721 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6723 SDValue UndefVal = DAG.getPOISON(EltVT);
6724 for (;
Idx < WidenNumElts; ++
Idx)
6725 Ops[Idx] = UndefVal;
6726 return DAG.getBuildVector(WidenVT, dl,
Ops);
6729SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6730 EVT VT =
N->getValueType(0);
6731 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6732 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6734 SDValue
Idx =
N->getOperand(2);
6739SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6740 EVT VT =
N->getValueType(0);
6742 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6744 SDValue
Idx =
N->getOperand(1);
6747 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6749 InOp = GetWidenedVector(InOp);
6755 if (IdxVal == 0 && InVT == WidenVT)
6762 assert(IdxVal % VTNumElts == 0 &&
6763 "Expected Idx to be a multiple of subvector minimum vector length");
6764 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6777 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6778 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6779 "down type's element count");
6786 for (;
I < VTNumElts / GCD; ++
I)
6788 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6789 for (;
I < WidenNumElts / GCD; ++
I)
6811 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6818 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6819 return DAG.getMaskedLoad(
6820 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6828 for (i = 0; i < VTNumElts; ++i)
6829 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6831 SDValue UndefVal = DAG.getPOISON(EltVT);
6832 for (; i < WidenNumElts; ++i)
6834 return DAG.getBuildVector(WidenVT, dl,
Ops);
6838 SDValue InOp = ModifyToType(
6840 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6845SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6846 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6849 N->getOperand(1),
N->getOperand(2));
6858 "Load width must be less than or equal to first value type width");
6867 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6884 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6895 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6896 EVT LdVT =
LD->getMemoryVT();
6900 SDValue Chain =
LD->getChain();
6905 TypeSize WidthDiff = WidenWidth - LdWidth;
6908 std::optional<EVT> FirstVT =
6909 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6916 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6919 Chain, BasePtr,
LD->getMemOperand());
6923 FirstVTWidth, dl, DAG);
6927 ReplaceValueWith(SDValue(LD, 1), LdOp.
getValue(1));
6941 if (!
LD->getMemoryVT().isByteSized()) {
6942 SDValue
Value, NewChain;
6943 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6944 ReplaceValueWith(SDValue(LD, 0),
Value);
6945 ReplaceValueWith(SDValue(LD, 1), NewChain);
6954 EVT VT =
LD->getValueType(0);
6955 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6956 EVT WideMaskVT = getSetCCResultType(WideVT);
6959 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6960 TLI.isTypeLegal(WideMaskVT)) {
6962 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
6963 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6967 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6968 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6972 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
6980 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6982 Result = GenWidenVectorLoads(LdChain, LD);
6989 if (LdChain.
size() == 1)
6990 NewChain = LdChain[0];
6996 ReplaceValueWith(SDValue(
N, 1), NewChain);
7007 SDValue NewLoad = DAG.getMaskedLoad(
7008 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
7009 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
7010 LD->getAddressingMode(),
LD->getExtensionType());
7012 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
7020 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7021 SDValue
Mask =
N->getMask();
7022 SDValue EVL =
N->getVectorLength();
7029 "Unable to widen binary VP op");
7030 Mask = GetWidenedVector(Mask);
7031 assert(
Mask.getValueType().getVectorElementCount() ==
7032 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7033 .getVectorElementCount() &&
7034 "Unable to widen vector load");
7037 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
7038 N->getBasePtr(),
N->getOffset(), Mask, EVL,
7039 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
7042 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7047 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7048 SDValue
Mask =
N->getMask();
7049 SDValue EVL =
N->getVectorLength();
7055 "Unable to widen binary VP op");
7056 Mask = GetWidenedVector(Mask);
7057 assert(
Mask.getValueType().getVectorElementCount() ==
7058 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7059 .getVectorElementCount() &&
7060 "Unable to widen vector load");
7062 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
7063 Mask, EVL,
N->getMemOperand());
7064 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7065 ReplaceValueWith(SDValue(
N, 2), Res.
getValue(2));
7073 SDValue
Mask =
N->getMask();
7076 "Unable to widen VP strided load");
7077 Mask = GetWidenedVector(Mask);
7079 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7080 assert(
Mask.getValueType().getVectorElementCount() ==
7082 "Data and mask vectors should have the same number of elements");
7084 SDValue Res = DAG.getStridedLoadVP(
7085 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
7086 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
7087 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
7088 N->isExpandingLoad());
7092 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7096SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
7098 SDValue
Mask =
N->getOperand(1);
7101 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
7103 Mask.getValueType().getVectorElementType(),
7106 SDValue WideVec = ModifyToType(Vec, WideVecVT);
7107 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
7108 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
7110 WideMask, WidePassthru);
7114 EVT VT =
N->getValueType(0);
7115 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7116 SDValue
Mask =
N->getMask();
7117 EVT MaskVT =
Mask.getValueType();
7118 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7127 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7128 TLI.isTypeLegal(WideMaskVT) &&
7134 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7135 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7139 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7140 N->getMemoryVT(),
N->getMemOperand());
7141 SDValue NewVal = NewLoad;
7144 if (!
N->getPassThru()->isUndef()) {
7148 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7149 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7150 DAG.getPOISON(WidenVT), EVL);
7155 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
7161 Mask = ModifyToType(Mask, WideMaskVT,
true);
7163 SDValue Res = DAG.getMaskedLoad(
7164 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7165 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7166 ExtType,
N->isExpandingLoad());
7169 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7175 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7176 SDValue
Mask =
N->getMask();
7177 EVT MaskVT =
Mask.getValueType();
7178 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7179 SDValue Scale =
N->getScale();
7186 Mask = ModifyToType(Mask, WideMaskVT,
true);
7189 SDValue
Index =
N->getIndex();
7191 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7192 Index = ModifyToType(Index, WideIndexVT);
7193 SDValue
Ops[] = {
N->getChain(), PassThru,
Mask,
N->getBasePtr(),
Index,
7198 N->getMemoryVT().getScalarType(), WideEC);
7199 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7200 WideMemVT, dl,
Ops,
N->getMemOperand(),
7201 N->getIndexType(),
N->getExtensionType());
7205 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7210 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7211 SDValue
Mask =
N->getMask();
7212 SDValue Scale =
N->getScale();
7216 SDValue
Index = GetWidenedVector(
N->getIndex());
7218 N->getMemoryVT().getScalarType(), WideEC);
7219 Mask = GetWidenedMask(Mask, WideEC);
7221 SDValue
Ops[] = {
N->getChain(),
N->getBasePtr(),
Index, Scale,
7222 Mask,
N->getVectorLength()};
7223 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7224 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7228 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7233 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7234 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7262 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7263 return N->getOperand(OpNo).getValueType();
7271 N =
N.getOperand(0);
7273 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7274 if (!
N->getOperand(i)->isUndef())
7276 N =
N.getOperand(0);
7280 N =
N.getOperand(0);
7282 N =
N.getOperand(0);
7308 { MaskVT, MVT::Other },
Ops);
7309 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7315 return adjustMaskToType(Mask, ToMaskVT);
7321 LLVMContext &Ctx = *DAG.getContext();
7322 EVT MaskVT =
Mask.getValueType();
7325 if (MaskScalarBits < ToMaskScalBits) {
7329 }
else if (MaskScalarBits > ToMaskScalBits) {
7335 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7337 "Mask should have the right element size by now.");
7340 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7342 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7345 EVT SubVT =
Mask->getValueType(0);
7351 assert((
Mask->getValueType(0) == ToMaskVT) &&
7352 "A mask of ToMaskVT should have been produced by now.");
7359EVT DAGTypeLegalizer::unifyMaskTypes(
SDValue &Op0,
bool IsOpLenient0,
7360 SDValue &Op1,
bool IsOpLenient1,
7364 "unifyMaskTypes only handles scalar width differences");
7376 if (IsOpLenient0 != IsOpLenient1) {
7377 SDValue *LenientOp, *NonLenientOp;
7380 NonLenientOp = &Op1;
7383 NonLenientOp = &Op0;
7386 *LenientOp = adjustMaskToType(*LenientOp, OpVT);
7392 unsigned NarrowBits = std::min(Bits0, Bits1);
7393 unsigned WideBits = std::max(Bits0, Bits1);
7395 unsigned IntBits = NarrowBits == WideBits ? NarrowBits
7396 : ToBits >= WideBits ? WideBits
7397 : ToBits <= NarrowBits ? NarrowBits
7401 Op0 = adjustMaskToType(Op0, OpVT);
7402 Op1 = adjustMaskToType(Op1, OpVT);
7406std::pair<SDValue, bool>
7407DAGTypeLegalizer::convertMaskTreeImpl(
SDValue V,
EVT ToVT,
unsigned Depth) {
7439 if (
Depth >= DAG.MaxRecursionDepth)
7448 unsigned Opcode =
V.getOpcode();
7453 return {convertMask(V, MaskVT, MaskVT),
false};
7461 return {DAG.getConstant(0,
DL, ToVT),
true};
7463 return {DAG.getAllOnesConstant(
DL, ToVT),
true};
7468 auto [Op0, IsLenientOp0] =
7469 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7472 auto [Op1, IsLenientOp1] =
7473 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7476 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7477 return {DAG.getNode(Opcode,
DL, OpVT, Op0, Op1),
7478 IsLenientOp0 && IsLenientOp1};
7483 auto [Inner, IsTypeLenient] =
7484 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7487 return {DAG.getNode(
ISD::FREEZE,
DL, Inner.getValueType(), Inner),
7494 auto [Op0, IsLenientOp0] =
7495 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7498 if (
V.getOperand(1).isUndef()) {
7500 return {DAG.getVectorShuffle(OpVT,
DL, Op0, DAG.getUNDEF(OpVT),
7504 auto [Op1, IsLenientOp1] =
7505 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7508 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7509 return {DAG.getVectorShuffle(OpVT,
DL, Op0, Op1, Shuf->getMask()),
7510 IsLenientOp0 && IsLenientOp1};
7515 auto [Op1, IsLenientOp1] =
7516 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7519 auto [Op2, IsLenientOp2] =
7520 convertMaskTreeImpl(
V.getOperand(2), ToVT,
Depth + 1);
7523 EVT OpVT = unifyMaskTypes(Op1, IsLenientOp1, Op2, IsLenientOp2, ToVT);
7532 SDValue
Cond =
V.getOperand(0);
7533 return {DAG.getNode(Opcode,
DL, OpVT,
Cond, Op1, Op2),
7534 IsLenientOp1 && IsLenientOp2};
7548 *DAG.getContext(),
V.getValueType().getVectorElementCount());
7549 auto [
Result,
_] = convertMaskTreeImpl(V, MaskTreeVT);
7552 return adjustMaskToType(Result, ToVT);
7560 LLVMContext &Ctx = *DAG.getContext();
7561 SDValue
Cond =
N->getOperand(0);
7568 EVT CondVT =
Cond->getValueType(0);
7572 EVT VSelVT =
N->getValueType(0);
7584 EVT FinalVT = VSelVT;
7595 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7596 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7603 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7611 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7614 EVT ToMaskVT = VSelVT;
7619 return convertMaskTree(
Cond, ToMaskVT);
7623 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7626 SDValue Cond1 =
N->getOperand(0);
7628 unsigned Opcode =
N->getOpcode();
7630 if (SDValue WideCond = WidenVSELECTMask(
N)) {
7631 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7632 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7634 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7640 Cond1 = GetWidenedVector(Cond1);
7648 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7649 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7654 Cond1 = ModifyToType(Cond1, CondWidenVT);
7657 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7658 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7660 if (Opcode == ISD::VP_MERGE)
7661 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7663 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7667 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7668 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7671 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7675 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7676 return DAG.getUNDEF(WidenVT);
7680 EVT VT =
N->getValueType(0);
7683 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7687 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7688 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7691 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7692 for (
unsigned i = 0; i != NumElts; ++i) {
7693 int Idx =
N->getMaskElt(i);
7694 if (Idx < (
int)NumElts)
7697 NewMask[i] =
Idx - NumElts + WidenNumElts;
7699 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7703 EVT VT =
N->getValueType(0);
7707 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7708 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7714 unsigned IdxVal = WidenNumElts - VTNumElts;
7727 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7730 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7731 "down type's element count");
7734 for (; i < VTNumElts / GCD; ++i)
7736 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7737 for (; i < WidenNumElts / GCD; ++i)
7745 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7746 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7748 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7752SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7753 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7757void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7758 EVT VT =
N->getValueType(0);
7761 unsigned Factor =
N->getNumOperands();
7764 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7768 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx)
7769 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7772 SDValue Interleaved =
7778 for (
unsigned Idx = 0;
Idx != Factor; ++
Idx)
7779 Slices[Idx] = Interleaved.
getValue(Idx);
7783 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx) {
7784 SDValue Narrow = DAG.getExtractSubvector(
DL, VT, Packed,
7787 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7788 SetWidenedVector(SDValue(
N, Idx), Wide);
7794 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7795 EVT SourceVT =
N->getOperand(0).getValueType();
7800 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7801 N->getOperand(0), 0);
7802 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7803 N->getOperand(2), 0);
7805 N->getOperand(1), WideMask,
N->getFlags());
7808void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7809 EVT VT =
N->getValueType(0);
7812 unsigned Factor =
N->getNumOperands();
7815 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7825 EVT ConcatVT =
EVT::getVectorVT(*DAG.getContext(), EltVT, OrigEC * Factor);
7827 SDValue PackedWidenVec = DAG.getInsertSubvector(
7828 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7832 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx) {
7833 NewOps[
Idx] = DAG.getExtractSubvector(
DL, WidenVT, PackedWidenVec,
7840 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx)
7841 SetWidenedVector(SDValue(
N, Idx), NewRes.
getValue(Idx));
7845 assert(
N->getValueType(0).isVector() &&
7846 N->getOperand(0).getValueType().isVector() &&
7847 "Operands must be vectors");
7848 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7861 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7862 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7869 InOp1 = GetWidenedVector(InOp1);
7870 InOp2 = GetWidenedVector(InOp2);
7872 SDValue
Poison = DAG.getPOISON(WidenInVT);
7873 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7884 "Input not widened to expected type!");
7886 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7891 assert(
N->getValueType(0).isVector() &&
7892 N->getOperand(1).getValueType().isVector() &&
7893 "Operands must be vectors");
7894 EVT VT =
N->getValueType(0);
7895 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7902 SDValue
LHS =
N->getOperand(1);
7903 SDValue
RHS =
N->getOperand(2);
7905 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7910 for (
unsigned i = 0; i != NumElts; ++i) {
7911 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7912 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7914 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7915 {Chain, LHSElem, RHSElem, CC});
7916 Chains[i] = Scalars[i].getValue(1);
7917 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7918 DAG.getBoolConstant(
true, dl, EltVT, VT),
7919 DAG.getBoolConstant(
false, dl, EltVT, VT));
7923 ReplaceValueWith(SDValue(
N, 1), NewChain);
7925 return DAG.getBuildVector(WidenVT, dl, Scalars);
7928SDValue DAGTypeLegalizer::WidenVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N) {
7930 EVT VT =
N->getValueType(0);
7933 SDValue Expanded = TLI.expandPartialReduceMLA(
N, DAG);
7934 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7935 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WideVT), Expanded, 0);
7941bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7942 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7943 SDValue Res = SDValue();
7946 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7949 switch (
N->getOpcode()) {
7952 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7960 Res = WidenVecOp_FAKE_USE(
N);
7964 Res = WidenVecOp_VECTOR_REPEAT(
N);
7969 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7973 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7974 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7975 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7980 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7982 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7983 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7985 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7986 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7996 Res = WidenVecOp_UnrollVectorOp(
N);
8003 Res = WidenVecOp_EXTEND(
N);
8008 Res = WidenVecOp_CMP(
N);
8026 Res = WidenVecOp_Convert(
N);
8031 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
8051 Res = WidenVecOp_VECREDUCE(
N);
8055 Res = WidenVecOp_VECREDUCE_SEQ(
N);
8057 case ISD::VP_REDUCE_FADD:
8058 case ISD::VP_REDUCE_SEQ_FADD:
8059 case ISD::VP_REDUCE_FMUL:
8060 case ISD::VP_REDUCE_SEQ_FMUL:
8061 case ISD::VP_REDUCE_ADD:
8062 case ISD::VP_REDUCE_MUL:
8063 case ISD::VP_REDUCE_AND:
8064 case ISD::VP_REDUCE_OR:
8065 case ISD::VP_REDUCE_XOR:
8066 case ISD::VP_REDUCE_SMAX:
8067 case ISD::VP_REDUCE_SMIN:
8068 case ISD::VP_REDUCE_UMAX:
8069 case ISD::VP_REDUCE_UMIN:
8070 case ISD::VP_REDUCE_FMAX:
8071 case ISD::VP_REDUCE_FMIN:
8072 case ISD::VP_REDUCE_FMAXIMUM:
8073 case ISD::VP_REDUCE_FMINIMUM:
8074 Res = WidenVecOp_VP_REDUCE(
N);
8078 Res = WidenVecOp_CttzElements(
N);
8080 case ISD::VP_CTTZ_ELTS:
8081 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
8082 Res = WidenVecOp_VP_CttzElements(
N);
8085 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
8088 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
8093 if (!Res.
getNode())
return false;
8101 if (
N->isStrictFPOpcode())
8103 "Invalid operand expansion");
8106 "Invalid operand expansion");
8108 ReplaceValueWith(SDValue(
N, 0), Res);
8114 EVT VT =
N->getValueType(0);
8119 "Unexpected type action");
8120 InOp = GetWidenedVector(InOp);
8123 "Input wasn't widened!");
8131 EVT FixedEltVT = FixedVT.getVectorElementType();
8132 if (TLI.isTypeLegal(FixedVT) &&
8134 FixedEltVT == InEltVT) {
8136 "Not enough elements in the fixed type for the operand!");
8138 "We can't have the same type as we started with!");
8140 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
8142 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
8151 return WidenVecOp_Convert(
N);
8156 switch (
N->getOpcode()) {
8171 EVT OpVT =
N->getOperand(0).getValueType();
8172 EVT ResVT =
N->getValueType(0);
8173 SDValue
LHS = GetWidenedVector(
N->getOperand(0));
8174 SDValue
RHS = GetWidenedVector(
N->getOperand(1));
8179 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
8180 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
8186 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
8187 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
8189 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
8196 return DAG.UnrollVectorOp(
N);
8201 EVT ResultVT =
N->getValueType(0);
8202 SDValue
Test =
N->getOperand(1);
8203 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
8206 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
8212 {WideArg,
Test},
N->getFlags());
8218 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
8220 EVT OpVT =
N->getOperand(0).getValueType();
8223 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
8228 EVT VT =
N->getValueType(0);
8231 SDValue InOp =
N->
getOperand(
N->isStrictFPOpcode() ? 1 : 0);
8234 "Unexpected type action");
8235 InOp = GetWidenedVector(InOp);
8237 unsigned Opcode =
N->getOpcode();
8240 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
8242 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
8245 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
8246 return DAG.getNode(Opcode, dl, VT,
Op);
8253 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
8255 if (
N->isStrictFPOpcode()) {
8257 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8260 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8261 {
N->getOperand(0), InOp });
8264 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
8266 Res = MakeConvertNode(WideVT, InOp);
8268 return DAG.getExtractSubvector(dl, VT, Res, 0);
8276 if (
N->isStrictFPOpcode()) {
8279 for (
unsigned i=0; i < NumElts; ++i) {
8280 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8281 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
8285 ReplaceValueWith(SDValue(
N, 1), NewChain);
8287 for (
unsigned i = 0; i < NumElts; ++i) {
8288 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8289 Ops[i] = MakeConvertNode(EltVT, Elt);
8293 return DAG.getBuildVector(VT, dl,
Ops);
8297 EVT DstVT =
N->getValueType(0);
8298 SDValue Src = GetWidenedVector(
N->getOperand(0));
8299 EVT SrcVT = Src.getValueType();
8306 if (TLI.isTypeLegal(WideDstVT)) {
8308 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
8311 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
8315 return DAG.UnrollVectorOp(
N);
8319 EVT VT =
N->getValueType(0);
8320 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8328 if (!VT.
isVector() && VT != MVT::x86mmx &&
8332 if (TLI.isTypeLegal(NewVT)) {
8333 SDValue BitOp = DAG.getNode(
ISD::BITCAST, dl, NewVT, InOp);
8334 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8346 ElementCount NewNumElts =
8348 .divideCoefficientBy(EltSize);
8350 if (TLI.isTypeLegal(NewVT)) {
8352 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8357 return CreateStackStoreLoad(InOp, VT);
8365 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8366 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8371 EVT VT =
N->getValueType(0);
8373 EVT InVT =
N->getOperand(0).getValueType();
8378 unsigned NumOperands =
N->getNumOperands();
8379 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8381 for (i = 1; i < NumOperands; ++i)
8382 if (!
N->getOperand(i).isUndef())
8385 if (i == NumOperands)
8386 return GetWidenedVector(
N->getOperand(0));
8390 SDValue
Result = DAG.getPOISON(VT);
8392 for (
unsigned i = 0; i < NumOperands; ++i) {
8393 SDValue InOp = GetWidenedVector(
N->getOperand(i));
8395 InOp = DAG.getExtractSubvector(dl, InVT, InOp, 0);
8396 Result = DAG.getInsertSubvector(dl, Result, InOp, i * NumInElts);
8408 for (
unsigned i=0; i < NumOperands; ++i) {
8412 "Unexpected type action");
8413 InOp = GetWidenedVector(InOp);
8414 for (
unsigned j = 0;
j < NumInElts; ++
j)
8415 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8417 return DAG.getBuildVector(VT, dl,
Ops);
8422 EVT VT =
N->getValueType(0);
8423 SDValue Src =
N->getOperand(0);
8424 EVT SrcVT = Src.getValueType();
8425 EVT WidenedSrcVT = TLI.getTypeToTransformTo(*DAG.getContext(), SrcVT);
8430 "Cannot widen VECTOR_REPEAT operand to an ElementCount that's not "
8431 "a known scalar multiple of the input ElementCount.");
8435 unsigned NumConcat =
8443 return DAG.getExtractSubvector(
DL, VT, Widened, 0);
8446SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8447 EVT VT =
N->getValueType(0);
8452 SubVec = GetWidenedVector(SubVec);
8457 bool IndicesValid =
false;
8460 IndicesValid =
true;
8464 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8465 Attribute::VScaleRange);
8470 IndicesValid =
true;
8476 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8482 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8489 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8511 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8519 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8520 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8525 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8530 unsigned Idx =
N->getConstantOperandVal(2);
8532 SDValue InsertElt = InVec;
8534 SDValue ExtractElt =
8536 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8542SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8543 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8545 N->getValueType(0), InOp,
N->getOperand(1));
8548SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8549 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8551 N->getValueType(0), InOp,
N->getOperand(1));
8554SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8556 EVT ResVT =
N->getValueType(0);
8559 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8565 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8573 "Widened input size must be a multiple of result element size");
8576 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8578 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8579 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8587 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8588 return TLI.scalarizeVectorStore(ST, DAG);
8590 if (
ST->isTruncatingStore())
8591 return TLI.scalarizeVectorStore(ST, DAG);
8599 SDValue StVal =
ST->getValue();
8601 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8602 EVT WideMaskVT = getSetCCResultType(WideVT);
8604 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8605 TLI.isTypeLegal(WideMaskVT)) {
8608 StVal = GetWidenedVector(StVal);
8609 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
8610 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8612 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8613 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8614 ST->getAddressingMode());
8618 if (GenWidenVectorStores(StChain, ST)) {
8619 if (StChain.
size() == 1)
8628 SDValue WideStVal = GetWidenedVector(StVal);
8632 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8633 ST->getOffset(), Mask,
ST->getMemoryVT(),
8634 ST->getMemOperand(),
ST->getAddressingMode(),
8635 ST->isTruncatingStore());
8642 EVT StVT =
ST->getMemoryVT();
8645 SDValue StVal = GetWidenedVector(
ST->getVal());
8650 TypeSize WidthDiff = WidenWidth - StWidth;
8656 std::optional<EVT> FirstVT =
8657 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8662 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8668 ST->getBasePtr(),
ST->getMemOperand());
8671SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8672 assert((OpNo == 1 || OpNo == 3) &&
8673 "Can widen only data or mask operand of vp_store");
8675 SDValue
Mask =
ST->getMask();
8676 SDValue StVal =
ST->getValue();
8681 StVal = GetWidenedVector(StVal);
8687 "Unable to widen VP store");
8688 Mask = GetWidenedVector(Mask);
8690 Mask = GetWidenedVector(Mask);
8696 "Unable to widen VP store");
8697 StVal = GetWidenedVector(StVal);
8700 assert(
Mask.getValueType().getVectorElementCount() ==
8702 "Mask and data vectors should have the same number of elements");
8703 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8704 ST->getOffset(), Mask,
ST->getVectorLength(),
8705 ST->getMemoryVT(),
ST->getMemOperand(),
8706 ST->getAddressingMode(),
ST->isTruncatingStore(),
8707 ST->isCompressingStore());
8712 assert((OpNo == 1 || OpNo == 4) &&
8713 "Can widen only data or mask operand of vp_strided_store");
8722 "Unable to widen VP strided store");
8726 "Unable to widen VP strided store");
8728 StVal = GetWidenedVector(StVal);
8729 Mask = GetWidenedVector(Mask);
8732 Mask.getValueType().getVectorElementCount() &&
8733 "Data and mask vectors should have the same number of elements");
8735 return DAG.getStridedStoreVP(
8742SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8743 assert((OpNo == 1 || OpNo == 4) &&
8744 "Can widen only data or mask operand of mstore");
8747 EVT MaskVT =
Mask.getValueType();
8752 EVT WideVT, WideMaskVT;
8755 StVal = GetWidenedVector(StVal);
8762 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8769 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8771 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8772 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8781 Mask = ModifyToType(Mask, WideMaskVT,
true);
8784 Mask = ModifyToType(Mask, WideMaskVT,
true);
8786 StVal = ModifyToType(StVal, WideVT);
8789 assert(
Mask.getValueType().getVectorElementCount() ==
8791 "Mask and data vectors should have the same number of elements");
8798SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8799 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8801 SDValue DataOp = MG->getPassThru();
8802 SDValue
Mask = MG->getMask();
8803 SDValue Scale = MG->getScale();
8806 SDValue
Index = GetWidenedVector(MG->getIndex());
8809 SDValue
Ops[] = {MG->getChain(), DataOp,
Mask, MG->getBasePtr(),
Index,
8811 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8812 MG->getMemOperand(), MG->getIndexType(),
8813 MG->getExtensionType());
8814 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
8815 ReplaceValueWith(SDValue(
N, 0), Res.
getValue(0));
8819SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8828 DataOp = GetWidenedVector(DataOp);
8832 EVT IndexVT =
Index.getValueType();
8835 Index = ModifyToType(Index, WideIndexVT);
8838 EVT MaskVT =
Mask.getValueType();
8841 Mask = ModifyToType(Mask, WideMaskVT,
true);
8846 }
else if (OpNo == 4) {
8848 Index = GetWidenedVector(Index);
8854 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8859SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8868 DataOp = GetWidenedVector(DataOp);
8869 Index = GetWidenedVector(Index);
8871 Mask = GetWidenedMask(Mask, WideEC);
8874 }
else if (OpNo == 3) {
8876 Index = GetWidenedVector(Index);
8883 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8888 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8889 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8891 EVT VT =
N->getValueType(0);
8905 SDValue WideSETCC = DAG.getNode(
ISD::SETCC, SDLoc(
N),
8906 SVT, InOp0, InOp1,
N->getOperand(2));
8912 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8914 EVT OpVT =
N->getOperand(0).getValueType();
8917 return DAG.getNode(ExtendCode, dl, VT, CC);
8922 SDValue
LHS = GetWidenedVector(
N->getOperand(1));
8923 SDValue
RHS = GetWidenedVector(
N->getOperand(2));
8927 EVT VT =
N->getValueType(0);
8929 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8936 for (
unsigned i = 0; i != NumElts; ++i) {
8937 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8938 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8940 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8941 {Chain, LHSElem, RHSElem, CC});
8942 Chains[i] = Scalars[i].getValue(1);
8943 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8944 DAG.getBoolConstant(
true, dl, EltVT, VT),
8945 DAG.getBoolConstant(
false, dl, EltVT, VT));
8949 ReplaceValueWith(SDValue(
N, 1), NewChain);
8951 return DAG.getBuildVector(VT, dl, Scalars);
8975 SDValue
Op = GetWidenedVector(
N->getOperand(0));
8976 EVT VT =
N->getValueType(0);
8977 EVT OrigVT =
N->getOperand(0).getValueType();
8978 EVT WideVT =
Op.getValueType();
8980 SDNodeFlags
Flags =
N->getFlags();
8982 unsigned Opc =
N->getOpcode();
8984 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8985 assert(NeutralElem &&
"Neutral element must exist");
8995 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8996 SDValue
Start = NeutralElem;
9002 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
9003 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
9009 unsigned GCD = std::gcd(OrigElts, WideElts);
9012 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
9013 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx =
Idx + GCD)
9014 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
9015 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
9018 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx++)
9019 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
9021 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
9028 SDValue
Op = GetWidenedVector(VecOp);
9030 EVT VT =
N->getValueType(0);
9032 EVT WideVT =
Op.getValueType();
9034 SDNodeFlags
Flags =
N->getFlags();
9036 unsigned Opc =
N->getOpcode();
9038 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
9048 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
9051 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
9052 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
9058 unsigned GCD = std::gcd(OrigElts, WideElts);
9061 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
9062 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx =
Idx + GCD)
9063 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
9064 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
9067 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx++)
9068 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
9070 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
9074 assert(
N->isVPOpcode() &&
"Expected VP opcode");
9077 SDValue
Op = GetWidenedVector(
N->getOperand(1));
9078 SDValue
Mask = GetWidenedMask(
N->getOperand(2),
9079 Op.getValueType().getVectorElementCount());
9081 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
9082 {N->getOperand(0), Op, Mask, N->getOperand(3)},
9090 EVT VT =
N->getValueType(0);
9093 SDValue
Cond = GetWidenedVector(
N->getOperand(0));
9094 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
9095 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
9100 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
9105 SDValue
Source =
N->getOperand(0);
9106 EVT SourceVT =
Source.getValueType();
9107 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9111 WideSource = GetWidenedVector(Source);
9115 SDValue
AllOnes = DAG.getAllOnesConstant(
DL, WideVT);
9118 WideSource = GetWidenedVector(Source);
9120 SmallVector<int>
Mask(WideElts);
9121 std::iota(
Mask.begin(),
Mask.end(), 0);
9123 Mask[
I] += WideElts;
9124 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
9126 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
9130 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
9136 SDValue
Source = GetWidenedVector(
N->getOperand(0));
9137 EVT SrcVT =
Source.getValueType();
9141 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
9142 {Source, Mask, N->getOperand(2)},
N->getFlags());
9145SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
9147 SDValue
Mask =
N->getOperand(0);
9148 EVT OrigMaskVT =
Mask.getValueType();
9149 SDValue WideMask = GetWidenedVector(Mask);
9155 if (OrigElts != WideElts) {
9156 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
9158 Mask, DAG.getVectorIdxConstant(0,
DL));
9165SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
9168 EVT ResVT =
N->getValueType(0);
9169 EVT SourceVT =
N->getOperand(0).getValueType();
9170 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9175 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
9176 N->getOperand(0), 0);
9177 SDValue WideMask = DAG.getInsertSubvector(
9178 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
9180 N->getOperand(1), WideMask,
N->getFlags());
9181 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
9185 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
9188 SDValue Needle =
N->getOperand(1);
9191 return TLI.expandVectorMatch(
N, DAG);
9193 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
9197 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
9198 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
9201 N->getOperand(0), WideNeedle,
N->getOperand(2),
9219 unsigned WidenEx = 0) {
9224 unsigned AlignInBits =
Align*8;
9226 EVT RetVT = WidenEltVT;
9231 if (Width == WidenEltWidth)
9242 (WidenWidth % MemVTWidth) == 0 &&
9244 (MemVTWidth <= Width ||
9245 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9246 if (MemVTWidth == WidenWidth)
9265 (WidenWidth % MemVTWidth) == 0 &&
9267 (MemVTWidth <= Width ||
9268 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9277 return std::nullopt;
9288 unsigned Start,
unsigned End) {
9289 SDLoc dl(LdOps[Start]);
9290 EVT LdTy = LdOps[Start].getValueType();
9298 for (
unsigned i = Start + 1; i !=
End; ++i) {
9299 EVT NewLdTy = LdOps[i].getValueType();
9300 if (NewLdTy != LdTy) {
9319 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9320 EVT LdVT =
LD->getMemoryVT();
9327 SDValue Chain =
LD->getChain();
9330 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9334 TypeSize WidthDiff = WidenWidth - LdWidth;
9341 std::optional<EVT> FirstVT =
9342 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
9349 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
9354 std::optional<EVT> NewVT = FirstVT;
9355 TypeSize RemainingWidth = LdWidth;
9356 TypeSize NewVTWidth = FirstVTWidth;
9358 RemainingWidth -= NewVTWidth;
9365 NewVTWidth = NewVT->getSizeInBits();
9371 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9385 MachinePointerInfo MPI =
LD->getPointerInfo();
9391 for (EVT MemVT : MemVTs) {
9392 Align NewAlign = ScaledOffset == 0
9393 ?
LD->getBaseAlign()
9395 SDValue
L = DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags,
9415 EVT LdTy = LdOps[i].getValueType();
9418 for (--i; i >= 0; --i) {
9419 LdTy = LdOps[i].getValueType();
9426 ConcatOps[--
Idx] = LdOps[i];
9427 for (--i; i >= 0; --i) {
9428 EVT NewLdTy = LdOps[i].getValueType();
9429 if (NewLdTy != LdTy) {
9440 WidenOps[j] = ConcatOps[Idx+j];
9442 WidenOps[j] = DAG.getPOISON(LdTy);
9449 ConcatOps[--
Idx] = LdOps[i];
9460 SDValue UndefVal = DAG.getPOISON(LdTy);
9463 for (; i !=
End-
Idx; ++i)
9464 WidenOps[i] = ConcatOps[Idx+i];
9466 WidenOps[i] = UndefVal;
9477 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9478 EVT LdVT =
LD->getMemoryVT();
9484 SDValue Chain =
LD->getChain();
9487 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9501 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9502 LdEltVT,
LD->getBaseAlign(), MMOFlags,
Metadata);
9506 SDValue NewBasePtr =
9508 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9509 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9515 SDValue UndefVal = DAG.getPOISON(EltVT);
9516 for (; i != WidenNumElts; ++i)
9519 return DAG.getBuildVector(WidenVT, dl,
Ops);
9527 SDValue Chain =
ST->getChain();
9530 MMOMetadata
Metadata =
ST->getMMOMetadataForSubAccess();
9531 SDValue ValOp = GetWidenedVector(
ST->getValue());
9534 EVT StVT =
ST->getMemoryVT();
9542 "Mismatch between store and value types");
9546 MachinePointerInfo MPI =
ST->getPointerInfo();
9556 std::optional<EVT> NewVT =
9561 TypeSize NewVTWidth = NewVT->getSizeInBits();
9564 StWidth -= NewVTWidth;
9565 MemVTs.
back().second++;
9569 for (
const auto &Pair : MemVTs) {
9570 EVT NewVT = Pair.first;
9571 unsigned Count = Pair.second;
9577 Align NewAlign = ScaledOffset == 0
9578 ?
ST->getBaseAlign()
9580 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9581 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9597 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9599 DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
ST->getBaseAlign(),
9617 bool FillWithZeroes) {
9622 "input and widen element type must match");
9624 "cannot modify scalable vectors in this way");
9637 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9639 for (
unsigned i = 1; i != NumConcat; ++i)
9646 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9652 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9657 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9658 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9660 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9662 unsigned NumResultParts = NewNumElts / CommonFactor;
9663 if (NumResultParts > NumCopiedParts) {
9664 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9665 : DAG.getPOISON(PartVT);
9666 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9673 "Scalable vectors should have been handled already.");
9681 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9683 for (Idx = 0;
Idx < MinNumElts; ++
Idx)
9684 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9686 SDValue UndefVal = DAG.getPOISON(EltVT);
9687 for (;
Idx < WidenNumElts; ++
Idx)
9688 Ops[Idx] = UndefVal;
9690 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9691 if (!FillWithZeroes)
9695 "We expect to never want to FillWithZeroes for non-integral types.");
9698 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9699 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9701 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9702 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.
const SmallVectorImpl< MachineOperand > & Cond
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
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.