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);
92 R = ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
N);
98 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
100 R = ScalarizeVecRes_VECTOR_MATCH(
N);
103 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
109 R = ScalarizeVecRes_VecInregOp(
N);
161 R = ScalarizeVecRes_UnaryOp(
N);
164 R = ScalarizeVecRes_ADDRSPACECAST(
N);
170 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
228 R = ScalarizeVecRes_BinOp(
N);
235 R = ScalarizeVecRes_MaskedBinOp(
N);
239 R = ScalarizeVecRes_FPOp_MultiType(
N);
244 R = ScalarizeVecRes_CMP(
N);
250 R = ScalarizeVecRes_TernaryOp(
N);
253#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
254 case ISD::STRICT_##DAGN:
255#include "llvm/IR/ConstrainedOps.def"
256 R = ScalarizeVecRes_StrictFPOp(
N);
261 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
270 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
280 R = ScalarizeVecRes_FIX(
N);
286 SetScalarizedVector(
SDValue(
N, ResNo), R);
290 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
291 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
292 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
298 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
299 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
300 SDValue
Mask =
N->getOperand(2);
301 EVT MaskVT =
Mask.getValueType();
306 Mask = GetScalarizedVector(Mask);
314 SDValue Divisor = DAG.getSelect(
DL,
LHS.getValueType(), Mask,
RHS,
315 DAG.getConstant(1,
DL,
LHS.getValueType()));
317 LHS.getValueType(),
LHS, Divisor);
323 SDValue
LHS =
N->getOperand(0);
324 SDValue
RHS =
N->getOperand(1);
325 if (getTypeAction(
LHS.getValueType()) ==
327 LHS = GetScalarizedVector(
LHS);
328 RHS = GetScalarizedVector(
RHS);
330 EVT VT =
LHS.getValueType().getVectorElementType();
331 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
332 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
335 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
336 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
340 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
341 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
342 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
343 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
348 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
349 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
356DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
358 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
359 "Unexpected vector type!");
360 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
362 EVT VT0 =
N->getValueType(0);
363 EVT VT1 =
N->getValueType(1);
367 DAG.getNode(
N->getOpcode(), dl,
368 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
372 unsigned OtherNo = 1 - ResNo;
373 EVT OtherVT =
N->getValueType(OtherNo);
375 SetScalarizedVector(SDValue(
N, OtherNo), SDValue(ScalarNode, OtherNo));
378 SDValue(ScalarNode, OtherNo));
379 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
382 return SDValue(ScalarNode, ResNo);
387 unsigned NumOpers =
N->getNumOperands();
388 SDValue Chain =
N->getOperand(0);
389 EVT ValueVTs[] = {VT, MVT::Other};
398 for (
unsigned i = 1; i < NumOpers; ++i) {
399 SDValue Oper =
N->getOperand(i);
404 Oper = GetScalarizedVector(Oper);
413 SDValue
Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
414 Opers,
N->getFlags());
418 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
425 EVT ResVT =
N->getValueType(0);
426 EVT OvVT =
N->getValueType(1);
428 SDValue ScalarLHS, ScalarRHS;
430 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
431 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
434 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
435 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
436 ScalarLHS = ElemsLHS[0];
437 ScalarRHS = ElemsRHS[0];
440 SDVTList ScalarVTs = DAG.getVTList(
442 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
443 {ScalarLHS, ScalarRHS},
N->getFlags())
447 unsigned OtherNo = 1 - ResNo;
448 EVT OtherVT =
N->getValueType(OtherNo);
450 SetScalarizedVector(SDValue(
N, OtherNo), SDValue(ScalarNode, OtherNo));
452 SDValue OtherVal = DAG.
getNode(
454 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
457 return SDValue(ScalarNode, ResNo);
462 SDValue
Op = DisintegrateMERGE_VALUES(
N, ResNo);
463 return GetScalarizedVector(
Op);
466SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
469 SDValue
Mask = TLI.expandLoopDependenceMask(
N, DAG);
471 N->getValueType(0).getScalarType(), Mask,
472 DAG.getVectorIdxConstant(0,
DL));
476 SDValue
Op =
N->getOperand(0);
478 Op = GetScalarizedVector(
Op);
479 EVT NewVT =
N->getValueType(0).getVectorElementType();
484SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(
SDNode *
N) {
486 SDValue InOp =
N->getOperand(0);
494SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
496 N->getValueType(0).getVectorElementType(),
497 N->getOperand(0),
N->getOperand(1));
502 SDValue
Op =
N->getOperand(0);
503 EVT OpVT =
Op.getValueType();
507 Op = GetScalarizedVector(
Op);
510 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
513 N->getValueType(0).getVectorElementType(),
Op,
517SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
519 SDValue
Op =
N->getOperand(0);
520 EVT OpVT =
Op.getValueType();
524 Op = GetScalarizedVector(
Op);
527 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
530 N->getValueType(0).getVectorElementType(),
Op,
534SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
536 SDValue
Op =
N->getOperand(0);
537 EVT OpVT =
Op.getValueType();
540 Op = GetScalarizedVector(
Op);
543 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
546 N->getValueType(0).getVectorElementType(),
Op,
547 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
550SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
551 SDValue
Op = GetScalarizedVector(
N->getOperand(0));
552 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
556SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOp_MultiType(
SDNode *
N) {
558 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
559 SDValue
RHS =
N->getOperand(1);
560 EVT RHSVT =
RHS.getValueType();
565 RHS = GetScalarizedVector(
RHS);
569 return DAG.getNode(
N->getOpcode(),
DL,
LHS.getValueType(),
LHS,
RHS,
573SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
576 SDValue
Op =
N->getOperand(1);
578 if (
Op.getValueType() != EltVT)
585 SDValue
Result = DAG.getAtomicLoad(
586 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
587 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
592 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
597 assert(
N->isUnindexed() &&
"Indexed vector load?");
599 SDValue
Result = DAG.getLoad(
601 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
602 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
603 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
604 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
608 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
615 SDValue
Op =
N->getOperand(0);
616 EVT OpVT =
Op.getValueType();
626 Op = GetScalarizedVector(
Op);
629 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
631 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
637 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
638 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
639 LHS, DAG.getValueType(ExtVT));
644 SDValue
Op =
N->getOperand(0);
646 EVT OpVT =
Op.getValueType();
651 Op = GetScalarizedVector(
Op);
653 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
656 switch (
N->getOpcode()) {
668SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
670 SDValue
Op =
N->getOperand(0);
671 EVT OpVT =
Op.getValueType();
681 Op = GetScalarizedVector(
Op);
684 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
687 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
688 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
689 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS,
690 AddrSpaceCastN->getFlags());
693SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
704DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
705 assert(
N->getNumValues() ==
N->getNumOperands() &&
706 "Expected one result per operand");
710 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
711 SetScalarizedVector(SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
716 SDValue
Cond =
N->getOperand(0);
717 EVT OpVT =
Cond.getValueType();
726 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
729 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
731 TLI.getBooleanContents(
false,
false);
738 if (TLI.getBooleanContents(
false,
false) !=
739 TLI.getBooleanContents(
false,
true)) {
743 EVT OpVT =
Cond->getOperand(0).getValueType();
745 VecBool = TLI.getBooleanContents(OpVT);
750 EVT CondVT =
Cond.getValueType();
751 if (ScalarBool != VecBool) {
752 switch (ScalarBool) {
760 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
767 Cond, DAG.getValueType(MVT::i1));
773 auto BoolVT = getSetCCResultType(CondVT);
774 if (BoolVT.bitsLT(CondVT))
777 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
778 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
782 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
783 return DAG.getSelect(SDLoc(
N),
784 LHS.getValueType(),
N->getOperand(0),
LHS,
785 GetScalarizedVector(
N->getOperand(2)));
789 SDValue
LHS = GetScalarizedVector(
N->getOperand(2));
791 N->getOperand(0),
N->getOperand(1),
792 LHS, GetScalarizedVector(
N->getOperand(3)),
797 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
800SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
804 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
806 return GetScalarizedVector(
N->getOperand(
Op));
809SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
810 SDValue Src =
N->getOperand(0);
811 EVT SrcVT = Src.getValueType();
816 Src = GetScalarizedVector(Src);
820 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
822 EVT DstVT =
N->getValueType(0).getVectorElementType();
823 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
827 assert(
N->getValueType(0).isVector() &&
828 N->getOperand(0).getValueType().isVector() &&
829 "Operand types must be vectors");
830 SDValue
LHS =
N->getOperand(0);
831 SDValue
RHS =
N->getOperand(1);
832 EVT OpVT =
LHS.getValueType();
833 EVT NVT =
N->getValueType(0).getVectorElementType();
838 LHS = GetScalarizedVector(
LHS);
839 RHS = GetScalarizedVector(
RHS);
842 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
843 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
853 return DAG.getNode(ExtendCode,
DL, NVT, Res);
864 Arg = GetScalarizedVector(Arg);
867 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
876 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
883bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
886 SDValue Res = SDValue();
889 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
892 switch (
N->getOpcode()) {
895 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
902 Res = ScalarizeVecOp_BITCAST(
N);
905 Res = ScalarizeVecOp_FAKE_USE(
N);
919 Res = ScalarizeVecOp_UnaryOp(
N);
924 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
927 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
928 "Unexpected vector type!");
929 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
930 SDValue
Op = DAG.getNode(
931 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
932 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
940 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
943 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
946 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
949 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
952 Res = ScalarizeVecOp_VSELECT(
N);
955 Res = ScalarizeVecOp_VSETCC(
N);
959 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
968 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
971 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
974 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
977 Res = ScalarizeVecOp_FP_EXTEND(
N);
996 Res = ScalarizeVecOp_VECREDUCE(
N);
1000 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
1004 Res = ScalarizeVecOp_CMP(
N);
1007 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
1011 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
1014 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
1020 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
1025 if (!Res.
getNode())
return false;
1033 "Invalid operand expansion");
1035 ReplaceValueWith(SDValue(
N, 0), Res);
1042 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1044 N->getValueType(0), Elt);
1049 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1050 "Fake Use: Unexpected vector type!");
1051 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1052 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1058 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1059 "Unexpected vector type!");
1060 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1061 SDValue
Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1062 N->getValueType(0).getScalarType(), Elt);
1070SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1071 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1072 "Unexpected vector type!");
1073 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1075 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1076 Elt,
N->getOperand(1));
1084SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1085 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1086 "Unexpected vector type!");
1087 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1088 SDValue Res = DAG.
getNode(
N->getOpcode(), SDLoc(
N),
1089 {
N->getValueType(0).getScalarType(), MVT::Other },
1090 {
N->getOperand(0), Elt });
1093 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1100 ReplaceValueWith(SDValue(
N, 0), Res);
1105SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1107 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1108 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1109 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1114SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1118 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1119 SDValue ContainingVec =
N->getOperand(0);
1127SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1128 EVT VT =
N->getValueType(0);
1129 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1141 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1142 EVT VT =
N->getValueType(0);
1144 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1153 assert(
N->getValueType(0).isVector() &&
1154 N->getOperand(0).getValueType().isVector() &&
1155 "Operand types must be vectors");
1156 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1157 "Expected single-element vector type");
1159 EVT VT =
N->getValueType(0);
1160 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
1161 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
1163 EVT OpVT =
N->getOperand(0).getValueType();
1175 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1181SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1183 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1184 assert(
N->getValueType(0).isVector() &&
1185 N->getOperand(1).getValueType().isVector() &&
1186 "Operand types must be vectors");
1187 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1188 "Expected single-element vector type");
1190 EVT VT =
N->getValueType(0);
1191 SDValue Ch =
N->getOperand(0);
1192 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
1193 SDValue
RHS = GetScalarizedVector(
N->getOperand(2));
1194 SDValue CC =
N->getOperand(3);
1196 EVT OpVT =
N->getOperand(1).getValueType();
1199 SDValue Res = DAG.
getNode(
N->getOpcode(),
DL, {MVT::i1, MVT::Other},
1200 {Ch, LHS, RHS, CC});
1204 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1209 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1214 ReplaceValueWith(SDValue(
N, 0), Res);
1221 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1222 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1225 if (
N->isTruncatingStore())
1226 return DAG.getTruncStore(
1227 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1228 N->getBasePtr(),
N->getPointerInfo(),
1229 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1230 N->getMemOperand()->getFlags(),
N->getAAInfo());
1232 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1233 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1234 N->getMemOperand()->getFlags(),
N->getAAInfo());
1240 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1242 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1243 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1248SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1249 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1250 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1252 N->getValueType(0).getVectorElementType(), Elt,
1257SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1259 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1260 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1263 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1267 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1273 ReplaceValueWith(SDValue(
N, 0), Res);
1280 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1282 N->getValueType(0).getVectorElementType(), Elt);
1288SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1289 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1292 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1293 {
N->getOperand(0), Elt});
1296 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1302 ReplaceValueWith(SDValue(
N, 0), Res);
1307 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1314SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1320 SDValue
Op = GetScalarizedVector(VecOp);
1321 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1322 AccOp,
Op,
N->getFlags());
1326 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
1327 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
1330 SDValue
Cmp = DAG.getNode(
N->getOpcode(), SDLoc(
N), ResVT,
LHS,
RHS);
1334SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1342 EVT VT =
N->getValueType(0);
1343 return DAG.getConstant(0, SDLoc(
N), VT);
1350 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1351 SDValue
Op = GetScalarizedVector(
N->getOperand(0));
1353 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1354 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1355 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1358SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1361 SDValue
Mask = TLI.expandVectorMatch(
N, DAG);
1363 N->getValueType(0).getScalarType(), Mask,
1364 DAG.getVectorIdxConstant(0,
DL));
1369 return TLI.expandVectorMatch(
N, DAG);
1372SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1373 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1376 SDValue
LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1377 SDValue
RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1378 SDValue
Mask = GetScalarizedVector(
N->getOperand(2));
1386 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1398void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1403 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1406 switch (
N->getOpcode()) {
1409 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1418 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1425 case ISD::VP_MERGE: SplitRes_Select(
N,
Lo,
Hi);
break;
1441 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1444 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1456 case ISD::VP_LOAD_FF:
1459 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1466 case ISD::VP_GATHER:
1470 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1473 SplitVecRes_SETCC(
N,
Lo,
Hi);
1476 SplitVecRes_VECTOR_REPEAT(
N,
Lo,
Hi);
1479 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1486 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1489 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1492 SplitVecRes_VECTOR_INTERLEAVE(
N);
1495 SplitVecRes_VAARG(
N,
Lo,
Hi);
1501 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1555 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1558 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1564 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1570 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1626 SplitVecRes_BinOp(
N,
Lo,
Hi);
1632 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1637 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1641 SplitVecRes_CMP(
N,
Lo,
Hi);
1644#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1645 case ISD::STRICT_##DAGN:
1646#include "llvm/IR/ConstrainedOps.def"
1647 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1652 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1661 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1671 SplitVecRes_FIX(
N,
Lo,
Hi);
1673 case ISD::EXPERIMENTAL_VP_SPLICE:
1674 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1676 case ISD::EXPERIMENTAL_VP_REVERSE:
1677 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1683 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1686 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1689 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1695 SetSplitVector(SDValue(
N, ResNo),
Lo,
Hi);
1698void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1705 SDValue BytesIncrement = DAG.getVScale(
1708 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1710 *ScaledOffset += IncrementSize;
1720std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1721 return SplitMask(Mask, SDLoc(Mask));
1724std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1726 SDValue MaskLo, MaskHi;
1727 EVT MaskVT =
Mask.getValueType();
1729 GetSplitVector(Mask, MaskLo, MaskHi);
1731 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1732 return std::make_pair(MaskLo, MaskHi);
1736 SDValue LHSLo, LHSHi;
1737 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1738 SDValue RHSLo, RHSHi;
1739 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1742 const SDNodeFlags
Flags =
N->getFlags();
1743 unsigned Opcode =
N->getOpcode();
1744 if (
N->getNumOperands() == 2) {
1745 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1746 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1750 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1751 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
1752 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
1753 "Expected VP opcode");
1755 SDValue MaskLo, MaskHi;
1756 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1758 SDValue EVLLo, EVLHi;
1759 std::tie(EVLLo, EVLHi) =
1760 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1763 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1765 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1770 SDValue LHSLo, LHSHi;
1771 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1772 SDValue RHSLo, RHSHi;
1773 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1775 SDValue MaskLo, MaskHi,
Mask =
N->getOperand(2);
1777 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1779 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1783 const SDNodeFlags
Flags =
N->getFlags();
1784 unsigned Opcode =
N->getOpcode();
1785 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1787 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1793 SDValue Op0Lo, Op0Hi;
1794 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1795 SDValue Op1Lo, Op1Hi;
1796 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1797 SDValue Op2Lo, Op2Hi;
1798 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1801 const SDNodeFlags
Flags =
N->getFlags();
1802 unsigned Opcode =
N->getOpcode();
1804 DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1806 DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1810 LLVMContext &Ctxt = *DAG.getContext();
1813 SDValue
LHS =
N->getOperand(0);
1814 SDValue
RHS =
N->getOperand(1);
1816 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1818 GetSplitVector(
LHS, LHSLo, LHSHi);
1819 GetSplitVector(
RHS, RHSLo, RHSHi);
1821 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1822 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1826 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1827 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1831 SDValue LHSLo, LHSHi;
1832 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1833 SDValue RHSLo, RHSHi;
1834 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1838 unsigned Opcode =
N->getOpcode();
1839 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1841 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1850 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1857 switch (getTypeAction(InVT)) {
1871 GetExpandedOp(InOp,
Lo,
Hi);
1872 if (DAG.getDataLayout().isBigEndian())
1882 GetSplitVector(InOp,
Lo,
Hi);
1891 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1900 if (DAG.getDataLayout().isBigEndian())
1903 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1905 if (DAG.getDataLayout().isBigEndian())
1911void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1915 SDValue PtrA =
N->getOperand(0);
1916 SDValue PtrB =
N->getOperand(1);
1917 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1920 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1925 unsigned LaneOffset =
1928 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1930 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1937 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1940 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1943 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1948 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1950 unsigned NumSubvectors =
N->getNumOperands() / 2;
1951 if (NumSubvectors == 1) {
1952 Lo =
N->getOperand(0);
1953 Hi =
N->getOperand(1);
1958 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1967void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1969 SDValue Vec =
N->getOperand(0);
1970 SDValue Idx =
N->getOperand(1);
1974 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1989 GetSplitVector(Vec,
Lo,
Hi);
1992 EVT LoVT =
Lo.getValueType();
2002 if (IdxVal + SubElems <= LoElems) {
2010 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
2012 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
2018 SDValue WideSubVec = GetWidenedVector(SubVec);
2020 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2028 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2030 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2031 auto &MF = DAG.getMachineFunction();
2035 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2040 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2041 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2045 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2050 MachinePointerInfo MPI =
Load->getPointerInfo();
2051 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2054 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2062 SDValue LHSLo, LHSHi;
2063 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2066 SDValue RHSLo, RHSHi;
2067 SDValue
RHS =
N->getOperand(1);
2068 EVT RHSVT =
RHS.getValueType();
2071 GetSplitVector(
RHS, RHSLo, RHSHi);
2073 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2086 SDValue ArgLo, ArgHi;
2087 SDValue
Test =
N->getOperand(1);
2088 SDValue FpValue =
N->getOperand(0);
2090 GetSplitVector(FpValue, ArgLo, ArgHi);
2092 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2094 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2102 SDValue LHSLo, LHSHi;
2103 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2107 std::tie(LoVT, HiVT) =
2111 DAG.getValueType(LoVT));
2113 DAG.getValueType(HiVT));
2118 unsigned Opcode =
N->getOpcode();
2119 SDValue N0 =
N->getOperand(0);
2125 GetSplitVector(N0, InLo, InHi);
2127 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2132 EVT OutLoVT, OutHiVT;
2133 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2135 assert((2 * OutNumElements) <= InNumElements &&
2136 "Illegal extend vector in reg split");
2145 SmallVector<int, 8> SplitHi(InNumElements, -1);
2146 for (
unsigned i = 0; i != OutNumElements; ++i)
2147 SplitHi[i] = i + OutNumElements;
2148 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2150 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2151 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2156 unsigned NumOps =
N->getNumOperands();
2160 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2170 for (
unsigned i = 1; i <
NumOps; ++i) {
2171 SDValue
Op =
N->getOperand(i);
2175 EVT InVT =
Op.getValueType();
2180 GetSplitVector(
Op, OpLo, OpHi);
2182 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2189 EVT LoValueVTs[] = {LoVT, MVT::Other};
2190 EVT HiValueVTs[] = {HiVT, MVT::Other};
2191 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2193 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2199 Lo.getValue(1),
Hi.getValue(1));
2203 ReplaceValueWith(SDValue(
N, 1), Chain);
2206SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2208 EVT VT =
N->getValueType(0);
2219 else if (NE > ResNE)
2223 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2227 for (i = 0; i !=
NE; ++i) {
2229 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2230 SDValue Operand =
N->getOperand(j);
2234 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2240 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2248 for (; i < ResNE; ++i)
2249 Scalars.
push_back(DAG.getPOISON(EltVT));
2253 ReplaceValueWith(SDValue(
N, 1), Chain);
2257 return DAG.getBuildVector(VecVT, dl, Scalars);
2260void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2263 EVT ResVT =
N->getValueType(0);
2264 EVT OvVT =
N->getValueType(1);
2265 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2266 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2267 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2269 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2271 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2272 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2274 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2275 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2278 unsigned Opcode =
N->getOpcode();
2279 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2280 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2282 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2284 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2286 Lo = SDValue(LoNode, ResNo);
2287 Hi = SDValue(HiNode, ResNo);
2290 unsigned OtherNo = 1 - ResNo;
2291 EVT OtherVT =
N->getValueType(OtherNo);
2293 SetSplitVector(SDValue(
N, OtherNo),
2294 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2296 SDValue OtherVal = DAG.
getNode(
2298 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2299 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
2303void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2309 GetSplitVector(Vec,
Lo,
Hi);
2312 unsigned IdxVal = CIdx->getZExtValue();
2313 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2314 if (IdxVal < LoNumElts) {
2316 Lo.getValueType(),
Lo, Elt, Idx);
2319 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2339 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2341 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2342 auto &MF = DAG.getMachineFunction();
2346 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2351 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2352 Store = DAG.getTruncStore(
2358 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2361 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2365 MachinePointerInfo MPI =
Load->getPointerInfo();
2366 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2368 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2371 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2372 if (LoVT !=
Lo.getValueType())
2374 if (HiVT !=
Hi.getValueType())
2382 assert(
N->getValueType(0).isScalableVector() &&
2383 "Only scalable vectors are supported for STEP_VECTOR");
2384 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2385 SDValue Step =
N->getOperand(0);
2405 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2406 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2408 Hi = DAG.getPOISON(HiVT);
2418 "Extended load during type legalization!");
2420 EVT VT =
LD->getValueType(0);
2422 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2424 SDValue Ch =
LD->getChain();
2425 SDValue Ptr =
LD->getBasePtr();
2430 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2431 Ch, Ptr,
LD->getMemOperand());
2435 SDValue ExtractLo, ExtractHi;
2436 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2438 Lo = DAG.getBitcast(LoVT, ExtractLo);
2439 Hi = DAG.getBitcast(HiVT, ExtractHi);
2443 ReplaceValueWith(SDValue(LD, 1), ALD.
getValue(1));
2451 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2454 SDValue Ch =
LD->getChain();
2455 SDValue Ptr =
LD->getBasePtr();
2457 EVT MemoryVT =
LD->getMemoryVT();
2459 AAMDNodes AAInfo =
LD->getAAInfo();
2461 EVT LoMemVT, HiMemVT;
2462 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2465 SDValue
Value, NewChain;
2466 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2467 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2468 ReplaceValueWith(SDValue(LD, 1), NewChain);
2473 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2476 MachinePointerInfo MPI;
2477 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2480 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2489 ReplaceValueWith(SDValue(LD, 1), Ch);
2494 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2497 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2500 SDValue Ch =
LD->getChain();
2501 SDValue Ptr =
LD->getBasePtr();
2503 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2505 SDValue
Mask =
LD->getMask();
2506 SDValue EVL =
LD->getVectorLength();
2507 EVT MemoryVT =
LD->getMemoryVT();
2509 EVT LoMemVT, HiMemVT;
2510 bool HiIsEmpty =
false;
2511 std::tie(LoMemVT, HiMemVT) =
2512 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2515 SDValue MaskLo, MaskHi;
2517 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2520 GetSplitVector(Mask, MaskLo, MaskHi);
2522 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2526 SDValue EVLLo, EVLHi;
2527 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2529 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2532 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2535 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2536 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2544 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2545 LD->isExpandingLoad());
2547 MachinePointerInfo MPI;
2549 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2551 MPI =
LD->getPointerInfo().getWithOffset(
2554 MMO = DAG.getMachineFunction().getMachineMemOperand(
2556 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2558 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2559 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2560 LD->isExpandingLoad());
2570 ReplaceValueWith(SDValue(LD, 1), Ch);
2576 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2578 SDValue Ch =
LD->getChain();
2579 SDValue Ptr =
LD->getBasePtr();
2581 SDValue
Mask =
LD->getMask();
2582 SDValue EVL =
LD->getVectorLength();
2585 SDValue MaskLo, MaskHi;
2587 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2590 GetSplitVector(Mask, MaskLo, MaskHi);
2592 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2596 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2598 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2601 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2603 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2606 Hi = DAG.getPOISON(HiVT);
2608 ReplaceValueWith(SDValue(LD, 1),
Lo.getValue(1));
2609 ReplaceValueWith(SDValue(LD, 2),
Lo.getValue(2));
2615 "Indexed VP strided load during type legalization!");
2617 "Unexpected indexed variable-length load offset");
2622 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2624 EVT LoMemVT, HiMemVT;
2625 bool HiIsEmpty =
false;
2626 std::tie(LoMemVT, HiMemVT) =
2627 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2630 SDValue LoMask, HiMask;
2632 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2635 GetSplitVector(Mask, LoMask, HiMask);
2637 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2640 SDValue LoEVL, HiEVL;
2641 std::tie(LoEVL, HiEVL) =
2645 Lo = DAG.getStridedLoadVP(
2672 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2679 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2690 ReplaceValueWith(SDValue(SLD, 1), Ch);
2698 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2703 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2711 SDValue MaskLo, MaskHi;
2713 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2716 GetSplitVector(Mask, MaskLo, MaskHi);
2718 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2722 EVT LoMemVT, HiMemVT;
2723 bool HiIsEmpty =
false;
2724 std::tie(LoMemVT, HiMemVT) =
2725 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2727 SDValue PassThruLo, PassThruHi;
2729 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2731 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2733 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2738 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2748 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2751 MachinePointerInfo MPI;
2758 MMO = DAG.getMachineFunction().getMachineMemOperand(
2763 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2775 ReplaceValueWith(SDValue(MLD, 1), Ch);
2783 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2785 SDValue Ch =
N->getChain();
2786 SDValue Ptr =
N->getBasePtr();
2793 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2796 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2799 EVT MemoryVT =
N->getMemoryVT();
2803 SDValue MaskLo, MaskHi;
2805 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2807 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2810 EVT LoMemVT, HiMemVT;
2812 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2814 SDValue IndexHi, IndexLo;
2815 if (getTypeAction(
Ops.Index.getValueType()) ==
2817 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2819 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2822 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2824 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2827 SDValue PassThru = MGT->getPassThru();
2828 SDValue PassThruLo, PassThruHi;
2831 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2833 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2838 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2839 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2840 OpsLo, MMO, IndexTy, ExtType);
2842 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2843 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2844 OpsHi, MMO, IndexTy, ExtType);
2847 SDValue EVLLo, EVLHi;
2848 std::tie(EVLLo, EVLHi) =
2849 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2851 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2852 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2853 MMO, VPGT->getIndexType());
2855 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2856 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2857 MMO, VPGT->getIndexType());
2867 ReplaceValueWith(SDValue(
N, 1), Ch);
2881 EVT VecVT =
N->getValueType(0);
2883 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2884 bool HasCustomLowering =
false;
2891 HasCustomLowering =
true;
2897 SDValue Passthru =
N->getOperand(2);
2898 if (!HasCustomLowering) {
2899 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2900 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2905 SDValue
Mask =
N->getOperand(1);
2906 SDValue LoMask, HiMask;
2907 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2908 std::tie(LoMask, HiMask) = SplitMask(Mask);
2910 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2914 SDValue
StackPtr = DAG.CreateStackTemporary(
2915 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2928 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2930 SDValue Chain = DAG.getEntryNode();
2931 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2935 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2939 EVT MaskVT =
Mask.getValueType();
2943 SDValue NumActiveElts =
2946 SDValue StepVector = DAG.getStepVector(
DL, WideMaskVT);
2947 SDValue SplatNumActiveElts = DAG.getSplat(WideMaskVT,
DL, NumActiveElts);
2948 SDValue CompressedMask =
2949 DAG.getSetCC(
DL, MaskVT, StepVector, SplatNumActiveElts,
ISD::SETULT);
2952 Compressed, Passthru);
2954 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2958 assert(
N->getValueType(0).isVector() &&
2959 N->getOperand(0).getValueType().isVector() &&
2960 "Operand types must be vectors");
2964 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2967 SDValue LL, LH, RL, RH;
2968 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2970 GetSplitVector(
N->getOperand(0), LL, LH);
2972 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2974 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2976 GetSplitVector(
N->getOperand(1), RL, RH);
2978 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2980 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2981 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2989 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2993 EVT InVT =
N->getOperand(0).getValueType();
2995 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2997 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2999 const SDNodeFlags
Flags =
N->getFlags();
3000 unsigned Opcode =
N->getOpcode();
3002 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
3003 N->getOperand(3), Flags);
3004 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
3005 N->getOperand(3), Flags);
3011 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
3012 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
3014 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
3015 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
3022 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3026 EVT InVT =
N->getOperand(0).getValueType();
3028 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3030 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3033 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3034 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3035 SDNodeFlags
Flags = AddrSpaceCastN->getFlags();
3036 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS, Flags);
3037 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS, Flags);
3040void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3045 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3046 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3050 EVT InVT =
N->getOperand(0).getValueType();
3052 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3054 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3056 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3057 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3059 SDNode *HiNode =
Hi.getNode();
3060 SDNode *LoNode =
Lo.getNode();
3063 unsigned OtherNo = 1 - ResNo;
3064 EVT OtherVT =
N->getValueType(OtherNo);
3066 SetSplitVector(SDValue(
N, OtherNo), SDValue(LoNode, OtherNo),
3067 SDValue(HiNode, OtherNo));
3071 SDValue(HiNode, OtherNo));
3072 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
3079 EVT SrcVT =
N->getOperand(0).getValueType();
3080 EVT DestVT =
N->getValueType(0);
3082 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3099 LLVMContext &Ctx = *DAG.getContext();
3103 EVT SplitLoVT, SplitHiVT;
3104 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3105 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3106 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3107 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3108 N->dump(&DAG);
dbgs() <<
"\n");
3111 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3113 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3115 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3116 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3121 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3129 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3130 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3136 return N.getResNo() == 0 &&
3140 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](SDValue &Input1,
3142 ArrayRef<int>
Mask) {
3145 "Expected build vector node.");
3148 for (
unsigned I = 0;
I < NewElts; ++
I) {
3151 unsigned Idx =
Mask[
I];
3153 Ops[
I] = Input2.getOperand(Idx - NewElts);
3155 Ops[
I] = Input1.getOperand(Idx);
3160 return DAG.getBuildVector(NewVT,
DL,
Ops);
3166 SmallVector<int> OrigMask(
N->getMask());
3168 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3169 &
DL](SmallVectorImpl<int> &
Mask) {
3171 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3172 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3173 SDValue Input = Inputs[Idx];
3183 for (
auto &
P : ShufflesIdxs) {
3184 if (
P.second.size() < 2)
3188 for (
int &Idx : Mask) {
3191 unsigned SrcRegIdx = Idx / NewElts;
3192 if (Inputs[SrcRegIdx].
isUndef()) {
3200 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3205 Idx = MaskElt % NewElts +
3206 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3212 Inputs[
P.second[0]] =
P.first.first;
3213 Inputs[
P.second[1]] =
P.first.second;
3216 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3219 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3220 for (
int &Idx : Mask) {
3223 unsigned SrcRegIdx = Idx / NewElts;
3224 if (Inputs[SrcRegIdx].
isUndef()) {
3231 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3232 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3235 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3237 if (UsedSubVector.count() > 1) {
3239 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3240 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3242 if (Pairs.
empty() || Pairs.
back().size() == 2)
3244 if (UsedSubVector.test(2 *
I)) {
3245 Pairs.
back().emplace_back(
I, 0);
3247 assert(UsedSubVector.test(2 *
I + 1) &&
3248 "Expected to be used one of the subvectors.");
3249 Pairs.
back().emplace_back(
I, 1);
3252 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3254 for (
int &Idx : Mask) {
3257 unsigned SrcRegIdx = Idx / NewElts;
3259 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3260 return Idxs.front().first == SrcRegIdx ||
3261 Idxs.back().first == SrcRegIdx;
3263 if (It == Pairs.
end())
3265 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3266 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3269 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3270 Inputs[Idxs.front().first] = DAG.
getNode(
3272 Inputs[Idxs.front().first].getValueType(),
3273 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3274 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3283 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3287 if (Shuffle->getOperand(0).getValueType() != NewVT)
3290 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3291 !Shuffle->isSplat()) {
3293 }
else if (!Inputs[
I].hasOneUse() &&
3294 !Shuffle->getOperand(1).isUndef()) {
3296 for (
int &Idx : Mask) {
3299 unsigned SrcRegIdx = Idx / NewElts;
3302 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3307 int OpIdx = MaskElt / NewElts;
3320 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3321 if (Shuffle->getOperand(OpIdx).isUndef())
3323 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3324 if (It == std::end(Inputs))
3326 int FoundOp = std::distance(std::begin(Inputs), It);
3329 for (
int &Idx : Mask) {
3332 unsigned SrcRegIdx = Idx / NewElts;
3335 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3340 int MaskIdx = MaskElt / NewElts;
3341 if (OpIdx == MaskIdx)
3342 Idx = MaskElt % NewElts + FoundOp * NewElts;
3345 Op = (OpIdx + 1) % 2;
3353 for (
int &Idx : Mask) {
3356 unsigned SrcRegIdx = Idx / NewElts;
3359 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3360 int OpIdx = MaskElt / NewElts;
3363 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3369 TryPeekThroughShufflesInputs(OrigMask);
3371 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3372 NewElts](SmallVectorImpl<int> &
Mask) {
3373 SetVector<SDValue> UniqueInputs;
3374 SetVector<SDValue> UniqueConstantInputs;
3375 for (
const auto &
I : Inputs) {
3377 UniqueConstantInputs.
insert(
I);
3378 else if (!
I.isUndef())
3383 if (UniqueInputs.
size() != std::size(Inputs)) {
3384 auto &&UniqueVec = UniqueInputs.
takeVector();
3385 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3386 unsigned ConstNum = UniqueConstantVec.size();
3387 for (
int &Idx : Mask) {
3390 unsigned SrcRegIdx = Idx / NewElts;
3391 if (Inputs[SrcRegIdx].
isUndef()) {
3395 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3396 if (It != UniqueConstantVec.end()) {
3397 Idx = (Idx % NewElts) +
3398 NewElts * std::distance(UniqueConstantVec.begin(), It);
3399 assert(Idx >= 0 &&
"Expected defined mask idx.");
3402 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3403 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3404 Idx = (Idx % NewElts) +
3405 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3406 assert(Idx >= 0 &&
"Expected defined mask idx.");
3408 copy(UniqueConstantVec, std::begin(Inputs));
3409 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3412 MakeUniqueInputs(OrigMask);
3413 SDValue OrigInputs[4];
3414 copy(Inputs, std::begin(OrigInputs));
3420 unsigned FirstMaskIdx =
High * NewElts;
3423 assert(!Output &&
"Expected default initialized initial value.");
3424 TryPeekThroughShufflesInputs(Mask);
3425 MakeUniqueInputs(Mask);
3426 SDValue TmpInputs[4];
3427 copy(Inputs, std::begin(TmpInputs));
3430 bool SecondIteration =
false;
3431 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3436 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3437 SecondIteration =
true;
3438 return SecondIteration;
3441 Mask, std::size(Inputs), std::size(Inputs),
3443 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3444 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3445 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3447 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3449 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3450 DAG.getPOISON(NewVT), Mask);
3451 Inputs[Idx] = Output;
3453 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3454 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3455 unsigned Idx2,
bool ) {
3456 if (AccumulateResults(Idx1)) {
3459 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3461 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3462 Inputs[Idx2], Mask);
3466 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3468 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3469 TmpInputs[Idx2], Mask);
3471 Inputs[Idx1] = Output;
3473 copy(OrigInputs, std::begin(Inputs));
3478 EVT OVT =
N->getValueType(0);
3482 SDValue
SV =
N->getOperand(2);
3486 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3488 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV,
Alignment.value());
3489 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV,
Alignment.value());
3494 ReplaceValueWith(SDValue(
N, 1), Chain);
3499 EVT DstVTLo, DstVTHi;
3500 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3503 SDValue SrcLo, SrcHi;
3504 EVT SrcVT =
N->getOperand(0).getValueType();
3506 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3508 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3510 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3511 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3516 EVT VT =
N->getValueType(0);
3517 SDValue Src =
N->getOperand(0);
3518 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VT);
3519 assert(LoVT == HiVT &&
"Expected equal split types");
3524 auto [SrcLo, SrcHi] = DAG.SplitVector(Src,
DL);
3526 SDValue Deinterleaved =
3528 DAG.getVTList(SplitSrcVT, SplitSrcVT), SrcLo, SrcHi);
3534 DAG.getVTList(LoVT, LoVT), Even, Odd);
3542 GetSplitVector(
N->getOperand(0), InLo, InHi);
3553 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3554 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3559 EVT VT =
N->getValueType(0);
3560 SDValue Val =
N->getOperand(0);
3561 SDValue
Mask =
N->getOperand(1);
3582 EVT PtrVT =
StackPtr.getValueType();
3583 auto &MF = DAG.getMachineFunction();
3587 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3590 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3595 SDValue NumElemMinus1 =
3596 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3597 DAG.getConstant(1,
DL, PtrVT));
3598 SDValue StartOffset = DAG.getNode(
ISD::MUL,
DL, PtrVT, NumElemMinus1,
3599 DAG.getConstant(EltWidth,
DL, PtrVT));
3600 SDValue StorePtr = DAG.getNode(
ISD::ADD,
DL, PtrVT, StackPtr, StartOffset);
3601 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3603 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3604 SDValue
Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3605 DAG.getPOISON(PtrVT), Stride, TrueMask,
3608 SDValue
Load = DAG.getLoadVP(VT,
DL,
Store, StackPtr, Mask, EVL, LoadMMO);
3614 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3619 EVT VT =
N->getValueType(0);
3620 SDValue
V1 =
N->getOperand(0);
3621 SDValue V2 =
N->getOperand(1);
3623 SDValue
Mask =
N->getOperand(3);
3624 SDValue EVL1 =
N->getOperand(4);
3625 SDValue EVL2 =
N->getOperand(5);
3631 EVL1 = ZExtPromotedInteger(EVL1);
3650 EVT PtrVT =
StackPtr.getValueType();
3651 auto &MF = DAG.getMachineFunction();
3655 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3658 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3662 SDValue EltByteSize =
3664 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3665 SDValue EVL1Bytes = DAG.getNode(
ISD::MUL,
DL, PtrVT, EVL1Ptr, EltByteSize);
3669 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3670 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3672 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3674 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3678 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3683 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3684 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3688 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3691 SDValue OffsetToV2 = DAG.getNode(
ISD::SUB,
DL, PtrVT, StackPtr2, StackPtr);
3697 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3705 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3707 DAG.getVectorIdxConstant(0,
DL));
3713void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3716 SDValue Acc =
N->getOperand(0);
3717 SDValue Input1 =
N->getOperand(1);
3718 SDValue Input2 =
N->getOperand(2);
3720 SDValue AccLo, AccHi;
3721 GetSplitVector(Acc, AccLo, AccHi);
3722 unsigned Opcode =
N->getOpcode();
3732 SDValue Input1Lo, Input1Hi;
3733 SDValue Input2Lo, Input2Hi;
3734 GetSplitVector(Input1, Input1Lo, Input1Hi);
3735 GetSplitVector(Input2, Input2Lo, Input2Hi);
3738 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3739 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3742void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3750 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3754 SDValue HiStartVal = DAG.getNode(
ISD::UADDSAT,
DL, OpVT, Op0, LoElts);
3760 SDValue SourceLo, SourceHi;
3761 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3762 SDValue MaskLo, MaskHi;
3763 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3767 N->getOperand(1), MaskLo,
N->getFlags());
3769 N->getOperand(1), MaskHi,
N->getFlags());
3772void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3773 unsigned Factor =
N->getNumOperands();
3776 for (
unsigned i = 0; i != Factor; ++i) {
3778 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3780 Ops[i * 2 + 1] = OpHi;
3791 for (
unsigned i = 0; i != Factor; ++i)
3795void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3796 unsigned Factor =
N->getNumOperands();
3799 for (
unsigned i = 0; i != Factor; ++i) {
3801 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3803 Ops[i + Factor] = OpHi;
3814 for (
unsigned i = 0; i != Factor; ++i) {
3815 unsigned IdxLo = 2 * i;
3816 unsigned IdxHi = 2 * i + 1;
3817 SetSplitVector(SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3818 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3830bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3832 SDValue Res = SDValue();
3835 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3838 switch (
N->getOpcode()) {
3841 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3850 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3857 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3860 Res = SplitVecOp_TruncateHelper(
N);
3866 Res = SplitVecOp_FP_ROUND(
N);
3878 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3885 case ISD::VP_SCATTER:
3889 case ISD::VP_GATHER:
3893 Res = SplitVecOp_VSELECT(
N, OpNo);
3899 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3902 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3908 if (
N->getValueType(0).bitsLT(
3909 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3910 Res = SplitVecOp_TruncateHelper(
N);
3912 Res = SplitVecOp_UnaryOp(
N);
3916 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3932 Res = SplitVecOp_UnaryOp(
N);
3935 Res = SplitVecOp_FPOpDifferentTypes(
N);
3940 Res = SplitVecOp_CMP(
N);
3944 Res = SplitVecOp_FAKE_USE(
N);
3949 Res = SplitVecOp_ExtVecInRegOp(
N);
3969 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3973 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3975 case ISD::VP_REDUCE_FADD:
3976 case ISD::VP_REDUCE_SEQ_FADD:
3977 case ISD::VP_REDUCE_FMUL:
3978 case ISD::VP_REDUCE_SEQ_FMUL:
3979 case ISD::VP_REDUCE_ADD:
3980 case ISD::VP_REDUCE_MUL:
3981 case ISD::VP_REDUCE_AND:
3982 case ISD::VP_REDUCE_OR:
3983 case ISD::VP_REDUCE_XOR:
3984 case ISD::VP_REDUCE_SMAX:
3985 case ISD::VP_REDUCE_SMIN:
3986 case ISD::VP_REDUCE_UMAX:
3987 case ISD::VP_REDUCE_UMIN:
3988 case ISD::VP_REDUCE_FMAX:
3989 case ISD::VP_REDUCE_FMIN:
3990 case ISD::VP_REDUCE_FMAXIMUM:
3991 case ISD::VP_REDUCE_FMINIMUM:
3992 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3996 Res = SplitVecOp_CttzElts(
N);
3998 case ISD::VP_CTTZ_ELTS:
3999 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
4000 Res = SplitVecOp_VP_CttzElements(
N);
4003 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
4009 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
4012 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
4017 if (!Res.
getNode())
return false;
4024 if (
N->isStrictFPOpcode())
4026 "Invalid operand expansion");
4029 "Invalid operand expansion");
4031 ReplaceValueWith(SDValue(
N, 0), Res);
4035SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4038 SDValue LoMask, HiMask;
4039 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4041 EVT VT =
N->getValueType(0);
4053 SDValue
Cond = DAG.getBoolExtOrTrunc(AnyHiActive,
DL,
4054 getSetCCResultType(MVT::i1), MVT::i1);
4059 DAG.getElementCount(
DL, VT, SplitEC)),
4063SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4066 assert(OpNo == 0 &&
"Illegal operand must be mask");
4068 SDValue
Mask =
N->getOperand(0);
4069 SDValue Src0 =
N->getOperand(1);
4070 SDValue Src1 =
N->getOperand(2);
4073 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4076 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4077 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4078 "Lo and Hi have differing types");
4081 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4082 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4084 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4085 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4086 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4087 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4097SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4098 assert(OpNo == 2 &&
"Illegal operand must be mask");
4101 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4102 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4103 SDValue MaskLo, MaskHi;
4104 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4107 RHSLo, MaskLo,
N->getFlags());
4109 RHSHi, MaskHi,
N->getFlags());
4113SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4116 assert(OpNo == 1 &&
"Illegal operand must be mask");
4121 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4123 EVT VecVT =
N->getValueType(0);
4127SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4128 EVT ResVT =
N->getValueType(0);
4134 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4135 GetSplitVector(VecOp,
Lo,
Hi);
4137 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4142 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4143 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4147 EVT ResVT =
N->getValueType(0);
4153 SDNodeFlags
Flags =
N->getFlags();
4156 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4157 GetSplitVector(VecOp,
Lo,
Hi);
4159 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4162 SDValue Partial = DAG.
getNode(
N->getOpcode(), dl, ResVT, AccOp,
Lo, Flags);
4165 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4168SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4169 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4170 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4172 unsigned Opc =
N->getOpcode();
4173 EVT ResVT =
N->getValueType(0);
4179 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4180 GetSplitVector(VecOp,
Lo,
Hi);
4182 SDValue MaskLo, MaskHi;
4183 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4185 SDValue EVLLo, EVLHi;
4186 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4188 const SDNodeFlags
Flags =
N->getFlags();
4192 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4197 EVT ResVT =
N->getValueType(0);
4200 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4201 EVT InVT =
Lo.getValueType();
4206 if (
N->isStrictFPOpcode()) {
4207 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4208 {N->getOperand(0), Lo});
4209 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4210 {N->getOperand(0), Hi});
4219 ReplaceValueWith(SDValue(
N, 1), Ch);
4221 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4222 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4231 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4241 EVT ResVT =
N->getValueType(0);
4243 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4247 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4253 Lo = BitConvertToInteger(
Lo);
4254 Hi = BitConvertToInteger(
Hi);
4256 if (DAG.getDataLayout().isBigEndian())
4264 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4266 EVT ResVT =
N->getValueType(0);
4274 GetSplitVector(SubVec,
Lo,
Hi);
4279 SDValue FirstInsertion =
4281 SDValue SecondInsertion =
4283 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4285 return SecondInsertion;
4288SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4295 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4297 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4299 ElementCount IdxVal =
4303 EVT SrcVT =
N->getOperand(0).getValueType();
4322 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4323 LoEltsMin - IdxValMin);
4324 DAG.ExtractVectorElements(
Hi, Elts, 0,
4327 return DAG.getBuildVector(SubVT, dl, Elts);
4331 ElementCount ExtractIdx = IdxVal - LoElts;
4333 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4336 EVT HiVT =
Hi.getValueType();
4338 "Only fixed-vector extracts are supported in this case");
4348 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4349 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4355 "Extracting scalable subvector from fixed-width unsupported");
4363 "subvector from a scalable predicate vector");
4369 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4371 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4372 auto &MF = DAG.getMachineFunction();
4376 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4380 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4383 SubVT, dl,
Store, StackPtr,
4387SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4396 GetSplitVector(Vec,
Lo,
Hi);
4398 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4400 if (IdxVal < LoElts)
4401 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4403 return SDValue(DAG.UpdateNodeOperands(
N,
Hi,
4404 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4409 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4419 SDValue NewExtract =
4421 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4427 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4429 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4430 auto &MF = DAG.getMachineFunction();
4433 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4437 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4441 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4443 return DAG.getExtLoad(
4454 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4462 SplitVecRes_Gather(
N,
Lo,
Hi);
4465 ReplaceValueWith(SDValue(
N, 0), Res);
4470 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4471 SDValue Ch =
N->getChain();
4472 SDValue Ptr =
N->getBasePtr();
4473 SDValue
Offset =
N->getOffset();
4474 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4475 SDValue
Mask =
N->getMask();
4476 SDValue EVL =
N->getVectorLength();
4477 SDValue
Data =
N->getValue();
4481 SDValue DataLo, DataHi;
4484 GetSplitVector(
Data, DataLo, DataHi);
4486 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4489 SDValue MaskLo, MaskHi;
4491 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4494 GetSplitVector(Mask, MaskLo, MaskHi);
4496 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4499 EVT MemoryVT =
N->getMemoryVT();
4500 EVT LoMemVT, HiMemVT;
4501 bool HiIsEmpty =
false;
4502 std::tie(LoMemVT, HiMemVT) =
4503 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4506 SDValue EVLLo, EVLHi;
4507 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4510 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4513 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4515 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4516 N->getAddressingMode(),
N->isTruncatingStore(),
4517 N->isCompressingStore());
4523 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4524 N->isCompressingStore());
4526 MachinePointerInfo MPI;
4530 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4535 MMO = DAG.getMachineFunction().getMachineMemOperand(
4537 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4539 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4540 N->getAddressingMode(),
N->isTruncatingStore(),
4541 N->isCompressingStore());
4550 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4551 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4555 SDValue
Data =
N->getValue();
4556 SDValue LoData, HiData;
4558 GetSplitVector(
Data, LoData, HiData);
4560 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4562 EVT LoMemVT, HiMemVT;
4563 bool HiIsEmpty =
false;
4564 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4567 SDValue
Mask =
N->getMask();
4568 SDValue LoMask, HiMask;
4570 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4571 else if (getTypeAction(
Mask.getValueType()) ==
4573 GetSplitVector(Mask, LoMask, HiMask);
4575 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4577 SDValue LoEVL, HiEVL;
4578 std::tie(LoEVL, HiEVL) =
4579 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4582 SDValue
Lo = DAG.getStridedStoreVP(
4583 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4584 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4585 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4596 EVT PtrVT =
N->getBasePtr().getValueType();
4599 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4607 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4608 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4610 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4612 SDValue
Hi = DAG.getStridedStoreVP(
4613 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4614 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4615 N->isCompressingStore());
4624 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4625 SDValue Ch =
N->getChain();
4626 SDValue Ptr =
N->getBasePtr();
4627 SDValue
Offset =
N->getOffset();
4628 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4629 SDValue
Mask =
N->getMask();
4630 SDValue
Data =
N->getValue();
4634 SDValue DataLo, DataHi;
4637 GetSplitVector(
Data, DataLo, DataHi);
4639 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4642 SDValue MaskLo, MaskHi;
4644 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4647 GetSplitVector(Mask, MaskLo, MaskHi);
4649 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4652 EVT MemoryVT =
N->getMemoryVT();
4653 EVT LoMemVT, HiMemVT;
4654 bool HiIsEmpty =
false;
4655 std::tie(LoMemVT, HiMemVT) =
4656 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4658 SDValue
Lo,
Hi, Res;
4659 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4662 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4664 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4665 N->getAddressingMode(),
N->isTruncatingStore(),
4666 N->isCompressingStore());
4674 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4675 N->isCompressingStore());
4677 MachinePointerInfo MPI;
4681 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4686 MMO = DAG.getMachineFunction().getMachineMemOperand(
4689 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4691 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4692 N->getAddressingMode(),
N->isTruncatingStore(),
4693 N->isCompressingStore());
4704 SDValue Ch =
N->getChain();
4705 SDValue Ptr =
N->getBasePtr();
4706 EVT MemoryVT =
N->getMemoryVT();
4716 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4720 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4725 EVT LoMemVT, HiMemVT;
4726 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4728 SDValue DataLo, DataHi;
4731 GetSplitVector(
Ops.Data, DataLo, DataHi);
4733 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4736 SDValue MaskLo, MaskHi;
4738 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4740 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4743 SDValue IndexHi, IndexLo;
4744 if (getTypeAction(
Ops.Index.getValueType()) ==
4746 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4748 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4752 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4754 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4757 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4759 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4760 MSC->getIndexType(), MSC->isTruncatingStore());
4765 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4766 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4767 MMO, MSC->getIndexType(),
4768 MSC->isTruncatingStore());
4771 SDValue EVLLo, EVLHi;
4772 std::tie(EVLLo, EVLHi) =
4773 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4775 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4776 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4777 VPSC->getIndexType());
4782 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4783 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4784 VPSC->getIndexType());
4788 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4789 assert(OpNo == 1 &&
"Can only split the stored value");
4792 bool isTruncating =
N->isTruncatingStore();
4793 SDValue Ch =
N->getChain();
4794 SDValue Ptr =
N->getBasePtr();
4795 EVT MemoryVT =
N->getMemoryVT();
4798 AAMDNodes AAInfo =
N->getAAInfo();
4800 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4802 EVT LoMemVT, HiMemVT;
4803 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4807 return TLI.scalarizeVectorStore(
N, DAG);
4810 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4811 Alignment, MMOFlags, AAInfo);
4813 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4816 MachinePointerInfo MPI;
4817 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4820 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4821 HiMemVT, Alignment, MMOFlags, AAInfo);
4823 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4830 LLVMContext &Ctx = *DAG.getContext();
4831 SDValue StVal =
N->getVal();
4848 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4849 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4853 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4856 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4857 DAG.getBitcast(MemVecVT, Wide), 0);
4859 N->getBasePtr(),
N->getMemOperand());
4867 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4869 N->getBasePtr(),
N->getMemOperand());
4882 for (
const SDValue &
Op :
N->op_values()) {
4883 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4889 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4910 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4911 SDValue InVec =
N->getOperand(OpNo);
4913 EVT OutVT =
N->getValueType(0);
4921 EVT LoOutVT, HiOutVT;
4922 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4923 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4928 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4930 return SplitVecOp_UnaryOp(
N);
4939 return SplitVecOp_UnaryOp(
N);
4942 SDValue InLoVec, InHiVec;
4943 GetSplitVector(InVec, InLoVec, InHiVec);
4949 EVT HalfElementVT = IsFloat ?
4951 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4958 if (
N->isStrictFPOpcode()) {
4959 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4960 {N->getOperand(0), InLoVec});
4961 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4962 {N->getOperand(0), InHiVec});
4968 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4969 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4973 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4981 if (
N->isStrictFPOpcode()) {
4985 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4987 ReplaceValueWith(SDValue(
N, 1), SDValue(Res.
getNode(), 1));
4993 DAG.getTargetConstant(
4994 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
5001 assert(
N->getValueType(0).isVector() &&
5002 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
5003 "Operand types must be vectors");
5005 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
5007 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
5008 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
5010 EVT VT =
N->getValueType(0);
5011 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
5017 assert(isStrict &&
"unexpected node");
5018 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5019 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
5020 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5021 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
5024 ReplaceValueWith(SDValue(
N, 1), NewChain);
5032 EVT OpVT =
N->getOperand(0).getValueType();
5035 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5041 EVT ResVT =
N->getValueType(0);
5044 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5045 EVT InVT =
Lo.getValueType();
5050 if (
N->isStrictFPOpcode()) {
5051 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5052 {N->getOperand(0), Lo, N->getOperand(2)});
5053 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5054 {N->getOperand(0), Hi, N->getOperand(2)});
5058 Lo.getValue(1),
Hi.getValue(1));
5059 ReplaceValueWith(SDValue(
N, 1), NewChain);
5061 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5062 N->getOperand(2),
N->getOperand(3));
5063 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5064 N->getOperand(2),
N->getOperand(3));
5066 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5067 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5078SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5081 EVT LHSLoVT, LHSHiVT;
5082 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5084 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5085 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5087 SDValue LHSLo, LHSHi;
5088 std::tie(LHSLo, LHSHi) =
5089 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5091 SDValue RHSLo, RHSHi;
5092 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5094 SDValue
Lo = DAG.
getNode(
N->getOpcode(),
DL, LHSLoVT, LHSLo, RHSLo);
5095 SDValue
Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5101 LLVMContext &Ctxt = *DAG.getContext();
5104 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5105 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5106 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5108 EVT ResVT =
N->getValueType(0);
5113 SDValue
Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5114 SDValue
Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5120 EVT ResVT =
N->getValueType(0);
5123 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5124 EVT InVT =
Lo.getValueType();
5130 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5131 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5138 EVT ResVT =
N->getValueType(0);
5142 GetSplitVector(VecOp,
Lo,
Hi);
5148 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5149 SDValue ResLoNotVL =
5150 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5151 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi);
5152 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5153 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5158 EVT ResVT =
N->getValueType(0);
5162 GetSplitVector(VecOp,
Lo,
Hi);
5164 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5165 auto [EVLLo, EVLHi] =
5167 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5171 SDValue ResLo = DAG.
getNode(ISD::VP_CTTZ_ELTS,
DL, ResVT,
Lo, MaskLo, EVLLo);
5172 SDValue ResLoNotEVL =
5173 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5174 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi, MaskHi, EVLHi);
5175 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5176 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5179SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5182 SDValue Inc = HG->
getInc();
5190 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5191 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5192 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5193 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5194 SDValue
Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5195 OpsLo, MMO, IndexType);
5196 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5197 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5201SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5205 EVT LoResVT, HiResVT;
5206 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5207 SDValue SourceLo, SourceHi;
5208 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5209 SDValue MaskLo, MaskHi;
5210 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5213 N->getOperand(1), MaskLo,
N->getFlags());
5215 N->getOperand(1), MaskHi,
N->getFlags());
5221 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5223 SDValue NeedleLo, NeedleHi;
5224 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5228 NeedleLo,
N->getOperand(2),
N->getFlags());
5231 NeedleHi,
N->getOperand(2),
N->getFlags());
5232 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5235SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5238 "Accumulator should already be a legal type, and shouldn't need "
5239 "further splitting");
5242 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5243 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5244 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5245 unsigned Opcode =
N->getOpcode();
5248 SDValue
Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5249 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5256void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5257 unsigned WidenResNo) {
5258 unsigned NumResults =
N->getNumValues();
5259 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5260 if (ResNo == WidenResNo)
5262 EVT ResVT =
N->getValueType(ResNo);
5264 SetWidenedVector(SDValue(
N, ResNo), SDValue(WidenNode, ResNo));
5268 DAG.getExtractSubvector(
DL, ResVT, SDValue(WidenNode, ResNo), 0);
5269 ReplaceValueWith(SDValue(
N, ResNo), ResVal);
5274void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5275 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5278 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5281 SDValue Res = SDValue();
5283 auto unrollExpandedOp = [&]() {
5288 EVT ResVT =
N->getValueType(ResNo);
5289 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5290 EVT VT0 =
N->getValueType(0);
5291 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5292 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT0.
getScalarType())) {
5296 if (
N->getNumValues() > 1)
5297 ReplaceOtherWidenResults(
N, Unrolled.
getNode(), ResNo);
5303 switch (
N->getOpcode()) {
5306 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5314 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5318 Res = WidenVecRes_ADDRSPACECAST(
N);
5325 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5332 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5336 Res = WidenVecRes_ScalarOp(
N);
5342 Res = WidenVecRes_Select(
N);
5345 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5347 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5354 case ISD::VP_LOAD_FF:
5357 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5361 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5369 case ISD::VP_GATHER:
5373 Res = WidenVecRes_VECTOR_REVERSE(
N);
5376 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5379 WidenVecRes_VECTOR_INTERLEAVE(
N);
5382 Res = WidenVecRes_VECTOR_MATCH(
N);
5385 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5439 Res = WidenVecRes_Binary(
N);
5446 Res = WidenVecRes_MaskedBinary(
N);
5451 Res = WidenVecRes_CMP(
N);
5457 if (unrollExpandedOp())
5472 Res = WidenVecRes_BinaryCanTrap(
N);
5481 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5484#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5485 case ISD::STRICT_##DAGN:
5486#include "llvm/IR/ConstrainedOps.def"
5487 Res = WidenVecRes_StrictFP(
N);
5496 Res = WidenVecRes_OverflowOp(
N, ResNo);
5500 Res = WidenVecRes_FCOPYSIGN(
N);
5505 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5510 if (!unrollExpandedOp())
5511 Res = WidenVecRes_ExpOp(
N);
5517 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5532 Res = WidenVecRes_Convert(
N);
5537 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5544 Res = WidenVecRes_XROUND(
N);
5570 if (unrollExpandedOp())
5592 Res = WidenVecRes_Unary(
N);
5597 Res = WidenVecRes_Ternary(
N);
5603 if (!unrollExpandedOp())
5604 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5611 Res = WidenVecRes_PARTIAL_REDUCE_MLA(
N);
5617 SetWidenedVector(SDValue(
N, ResNo), Res);
5623 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5624 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5625 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5626 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5627 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5633 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5634 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5635 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5636 if (
N->getNumOperands() == 2)
5637 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5640 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5641 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5642 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5643 "Expected VP opcode");
5647 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5648 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5653 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5654 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5655 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5656 SDValue
Mask =
N->getOperand(2);
5658 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5659 Mask = ModifyToType(Mask, WideMaskVT,
true);
5660 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5665 LLVMContext &Ctxt = *DAG.getContext();
5668 SDValue
LHS =
N->getOperand(0);
5669 SDValue
RHS =
N->getOperand(1);
5670 EVT OpVT =
LHS.getValueType();
5672 LHS = GetWidenedVector(
LHS);
5673 RHS = GetWidenedVector(
RHS);
5674 OpVT =
LHS.getValueType();
5677 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5680 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5686SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5689 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5690 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5691 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5693 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5702 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5705 if (ConcatEnd == 1) {
5706 VT = ConcatOps[0].getValueType();
5708 return ConcatOps[0];
5711 SDLoc dl(ConcatOps[0]);
5718 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
5719 int Idx = ConcatEnd - 1;
5720 VT = ConcatOps[Idx--].getValueType();
5721 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
5734 unsigned NumToInsert = ConcatEnd - Idx - 1;
5735 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5737 ConcatOps[Idx+1] = VecOp;
5738 ConcatEnd = Idx + 2;
5744 unsigned RealVals = ConcatEnd - Idx - 1;
5745 unsigned SubConcatEnd = 0;
5746 unsigned SubConcatIdx = Idx + 1;
5747 while (SubConcatEnd < RealVals)
5748 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5749 while (SubConcatEnd < OpsToConcat)
5750 SubConcatOps[SubConcatEnd++] = undefVec;
5752 NextVT, SubConcatOps);
5753 ConcatEnd = SubConcatIdx + 1;
5758 if (ConcatEnd == 1) {
5759 VT = ConcatOps[0].getValueType();
5761 return ConcatOps[0];
5766 if (
NumOps != ConcatEnd ) {
5768 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5769 ConcatOps[j] = UndefVal;
5777 unsigned Opcode =
N->getOpcode();
5779 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5783 const SDNodeFlags
Flags =
N->getFlags();
5784 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5785 NumElts = NumElts / 2;
5789 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5791 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5792 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5793 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5801 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5804 TLI.isTypeLegal(WideMaskVT)) {
5805 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5806 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5807 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5809 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5810 N->getValueType(0).getVectorElementCount());
5811 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5825 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5826 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5827 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5830 unsigned ConcatEnd = 0;
5838 while (CurNumElts != 0) {
5839 while (CurNumElts >= NumElts) {
5840 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5841 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5842 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5844 CurNumElts -= NumElts;
5847 NumElts = NumElts / 2;
5849 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5852 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5853 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5854 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5855 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5866 switch (
N->getOpcode()) {
5869 return WidenVecRes_STRICT_FSETCC(
N);
5876 return WidenVecRes_Convert_StrictFP(
N);
5883 unsigned Opcode =
N->getOpcode();
5885 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5889 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5890 NumElts = NumElts / 2;
5901 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5905 unsigned ConcatEnd = 0;
5912 for (
unsigned i = 1; i < NumOpers; ++i) {
5918 Oper = GetWidenedVector(Oper);
5924 DAG.getPOISON(WideOpVT), Oper,
5925 DAG.getVectorIdxConstant(0, dl));
5937 while (CurNumElts != 0) {
5938 while (CurNumElts >= NumElts) {
5941 for (
unsigned i = 0; i < NumOpers; ++i) {
5942 SDValue
Op = InOps[i];
5944 EVT OpVT =
Op.getValueType();
5949 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5955 EVT OperVT[] = {VT, MVT::Other};
5956 SDValue Oper = DAG.
getNode(Opcode, dl, OperVT, EOps);
5957 ConcatOps[ConcatEnd++] = Oper;
5960 CurNumElts -= NumElts;
5963 NumElts = NumElts / 2;
5965 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5968 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5971 for (
unsigned i = 0; i < NumOpers; ++i) {
5972 SDValue
Op = InOps[i];
5974 EVT OpVT =
Op.getValueType();
5982 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5983 SDValue Oper = DAG.
getNode(Opcode, dl, WidenVT, EOps);
5984 ConcatOps[ConcatEnd++] = Oper;
5993 if (Chains.
size() == 1)
5994 NewChain = Chains[0];
5997 ReplaceValueWith(SDValue(
N, 1), NewChain);
6002SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
6004 EVT ResVT =
N->getValueType(0);
6005 EVT OvVT =
N->getValueType(1);
6006 EVT WideResVT, WideOvVT;
6007 SDValue WideLHS, WideRHS;
6011 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6016 WideLHS = GetWidenedVector(
N->getOperand(0));
6017 WideRHS = GetWidenedVector(
N->getOperand(1));
6019 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6024 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
6025 SDValue
Poison = DAG.getPOISON(WideResVT);
6028 N->getOperand(0), Zero);
6030 N->getOperand(1), Zero);
6033 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6034 SDNode *WideNode = DAG.getNode(
6035 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6038 unsigned OtherNo = 1 - ResNo;
6039 EVT OtherVT =
N->getValueType(OtherNo);
6041 SetWidenedVector(SDValue(
N, OtherNo), SDValue(WideNode, OtherNo));
6043 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
6044 SDValue OtherVal = DAG.
getNode(
6046 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
6049 return SDValue(WideNode, ResNo);
6053 LLVMContext &Ctx = *DAG.getContext();
6057 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6062 unsigned Opcode =
N->getOpcode();
6063 const SDNodeFlags
Flags =
N->getFlags();
6069 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6071 InOp = ZExtPromotedInteger(InOp);
6082 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
6083 if (
N->getNumOperands() == 1)
6084 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6086 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6087 N->getOperand(3), Flags);
6088 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6092 InOp = GetWidenedVector(
N->getOperand(0));
6095 if (InVTEC == WidenEC)
6096 return MakeConvertNode(WidenVT, InOp);
6120 SDValue MidRes = DAG.getNode(
ISD::TRUNCATE,
DL, MidResVT, InOp, Flags);
6121 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6125 if (TLI.isTypeLegal(InWidenVT)) {
6133 unsigned NumConcat =
6138 return MakeConvertNode(WidenVT, InVec);
6142 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6144 return MakeConvertNode(WidenVT, InVal);
6153 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6154 for (
unsigned i=0; i < MinElts; ++i) {
6155 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6156 Ops[i] = MakeConvertNode(EltVT, Val);
6159 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6164 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6167 SDValue Src =
N->getOperand(0);
6168 EVT SrcVT = Src.getValueType();
6172 Src = GetWidenedVector(Src);
6173 SrcVT = Src.getValueType();
6180 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6185 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6188 SDValue Src =
N->getOperand(0);
6189 EVT SrcVT = Src.getValueType();
6193 Src = GetWidenedVector(Src);
6194 SrcVT = Src.getValueType();
6201 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6204SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6209 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6215 unsigned Opcode =
N->getOpcode();
6221 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6226 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6227 for (
unsigned i=0; i < MinElts; ++i) {
6228 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6229 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6233 ReplaceValueWith(SDValue(
N, 1), NewChain);
6235 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6238SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6239 unsigned Opcode =
N->getOpcode();
6243 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6252 InOp = GetWidenedVector(InOp);
6259 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6266 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6267 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6284 while (
Ops.size() != WidenNumElts)
6285 Ops.push_back(DAG.getPOISON(WidenSVT));
6287 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6293 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6294 return WidenVecRes_BinaryCanTrap(
N);
6297 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6304SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6306 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6309 SDValue Arg = GetWidenedVector(FpValue);
6310 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6315 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6316 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6317 SDValue
RHS =
N->getOperand(1);
6318 EVT ExpVT =
RHS.getValueType();
6319 SDValue ExpOp =
RHS;
6323 ExpOp = ModifyToType(
RHS, WideExpVT);
6326 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6331 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6332 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6333 if (
N->getNumOperands() == 1)
6334 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6336 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6341 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6346 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6347 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6348 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6351SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6353 EVT VT0 =
N->getValueType(0);
6354 EVT VT1 =
N->getValueType(1);
6358 "expected both results to be vectors of matching element count");
6360 LLVMContext &Ctx = *DAG.getContext();
6361 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6363 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6370 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6373 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6374 return SDValue(WidenNode, ResNo);
6377SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6378 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6379 return GetWidenedVector(WidenVec);
6384 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6396 InOp = GetWidenedVector(InOp);
6400 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6403 return DAG.getAddrSpaceCast(
6404 DL, WidenVT, InOp, AddrSpaceCastN->getSrcAddressSpace(),
6405 AddrSpaceCastN->getDestAddressSpace(), AddrSpaceCastN->getFlags());
6411 EVT VT =
N->getValueType(0);
6412 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6415 switch (getTypeAction(InVT)) {
6429 SDValue NInOp = GetPromotedInteger(InOp);
6431 if (WidenVT.
bitsEq(NInVT)) {
6434 if (DAG.getDataLayout().isBigEndian()) {
6437 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6455 InOp = GetWidenedVector(InOp);
6457 if (WidenVT.
bitsEq(InVT))
6467 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6472 unsigned NewNumParts = WidenSize / InSize;
6485 EVT OrigInVT =
N->getOperand(0).getValueType();
6490 if (TLI.isTypeLegal(NewInVT)) {
6498 if (WidenSize % InSize == 0) {
6505 DAG.ExtractVectorElements(InOp,
Ops);
6506 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6518 return CreateStackStoreLoad(InOp, WidenVT);
6521SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6523 N->getOpcode(), SDLoc(
N),
6524 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6525 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6531 EVT VT =
N->getValueType(0);
6535 EVT EltVT =
N->getOperand(0).getValueType();
6538 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6542 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6543 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6545 return DAG.getBuildVector(WidenVT, dl, NewOps);
6549 EVT InVT =
N->getOperand(0).getValueType();
6550 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6552 unsigned NumOperands =
N->getNumOperands();
6554 bool InputWidened =
false;
6558 if (WidenNumElts % NumInElts == 0) {
6560 unsigned NumConcat = WidenNumElts / NumInElts;
6561 SDValue UndefVal = DAG.getPOISON(InVT);
6563 for (
unsigned i=0; i < NumOperands; ++i)
6564 Ops[i] =
N->getOperand(i);
6565 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6570 InputWidened =
true;
6571 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6574 for (i=1; i < NumOperands; ++i)
6575 if (!
N->getOperand(i).isUndef())
6578 if (i == NumOperands)
6581 return GetWidenedVector(
N->getOperand(0));
6583 if (NumOperands == 2) {
6585 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6590 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6591 for (
unsigned i = 0; i < NumInElts; ++i) {
6593 MaskOps[i + NumInElts] = i + WidenNumElts;
6595 return DAG.getVectorShuffle(WidenVT, dl,
6596 GetWidenedVector(
N->getOperand(0)),
6597 GetWidenedVector(
N->getOperand(1)),
6604 SDValue WideVec = DAG.getPOISON(WidenVT);
6606 for (
unsigned I = 0;
I < NumOperands; ++
I)
6608 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6619 for (
unsigned i=0; i < NumOperands; ++i) {
6622 InOp = GetWidenedVector(InOp);
6623 for (
unsigned j = 0;
j < NumInElts; ++
j)
6624 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6626 SDValue UndefVal = DAG.getPOISON(EltVT);
6627 for (; Idx < WidenNumElts; ++Idx)
6628 Ops[Idx] = UndefVal;
6629 return DAG.getBuildVector(WidenVT, dl,
Ops);
6632SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6633 EVT VT =
N->getValueType(0);
6634 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6635 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6637 SDValue Idx =
N->getOperand(2);
6642SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6643 EVT VT =
N->getValueType(0);
6645 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6650 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6652 InOp = GetWidenedVector(InOp);
6658 if (IdxVal == 0 && InVT == WidenVT)
6665 assert(IdxVal % VTNumElts == 0 &&
6666 "Expected Idx to be a multiple of subvector minimum vector length");
6667 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6680 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6681 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6682 "down type's element count");
6689 for (;
I < VTNumElts / GCD; ++
I)
6691 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6692 for (;
I < WidenNumElts / GCD; ++
I)
6714 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6721 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6722 return DAG.getMaskedLoad(
6723 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6731 for (i = 0; i < VTNumElts; ++i)
6732 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6734 SDValue UndefVal = DAG.getPOISON(EltVT);
6735 for (; i < WidenNumElts; ++i)
6737 return DAG.getBuildVector(WidenVT, dl,
Ops);
6741 SDValue InOp = ModifyToType(
6743 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6748SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6749 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6752 N->getOperand(1),
N->getOperand(2));
6761 "Load width must be less than or equal to first value type width");
6770 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6787 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6798 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6799 EVT LdVT =
LD->getMemoryVT();
6803 SDValue Chain =
LD->getChain();
6808 TypeSize WidthDiff = WidenWidth - LdWidth;
6811 std::optional<EVT> FirstVT =
6812 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6819 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6822 Chain, BasePtr,
LD->getMemOperand());
6826 FirstVTWidth, dl, DAG);
6830 ReplaceValueWith(SDValue(LD, 1), LdOp.
getValue(1));
6844 if (!
LD->getMemoryVT().isByteSized()) {
6845 SDValue
Value, NewChain;
6846 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6847 ReplaceValueWith(SDValue(LD, 0),
Value);
6848 ReplaceValueWith(SDValue(LD, 1), NewChain);
6857 EVT VT =
LD->getValueType(0);
6858 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6859 EVT WideMaskVT = getSetCCResultType(WideVT);
6862 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6863 TLI.isTypeLegal(WideMaskVT)) {
6865 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
6866 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6870 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6871 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6875 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
6883 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6885 Result = GenWidenVectorLoads(LdChain, LD);
6892 if (LdChain.
size() == 1)
6893 NewChain = LdChain[0];
6899 ReplaceValueWith(SDValue(
N, 1), NewChain);
6910 SDValue NewLoad = DAG.getMaskedLoad(
6911 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6912 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6913 LD->getAddressingMode(),
LD->getExtensionType());
6915 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
6923 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6924 SDValue
Mask =
N->getMask();
6925 SDValue EVL =
N->getVectorLength();
6932 "Unable to widen binary VP op");
6933 Mask = GetWidenedVector(Mask);
6934 assert(
Mask.getValueType().getVectorElementCount() ==
6935 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6936 .getVectorElementCount() &&
6937 "Unable to widen vector load");
6940 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6941 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6942 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6945 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
6950 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6951 SDValue
Mask =
N->getMask();
6952 SDValue EVL =
N->getVectorLength();
6958 "Unable to widen binary VP op");
6959 Mask = GetWidenedVector(Mask);
6960 assert(
Mask.getValueType().getVectorElementCount() ==
6961 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6962 .getVectorElementCount() &&
6963 "Unable to widen vector load");
6965 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6966 Mask, EVL,
N->getMemOperand());
6967 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
6968 ReplaceValueWith(SDValue(
N, 2), Res.
getValue(2));
6976 SDValue
Mask =
N->getMask();
6979 "Unable to widen VP strided load");
6980 Mask = GetWidenedVector(Mask);
6982 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6983 assert(
Mask.getValueType().getVectorElementCount() ==
6985 "Data and mask vectors should have the same number of elements");
6987 SDValue Res = DAG.getStridedLoadVP(
6988 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6989 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6990 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6991 N->isExpandingLoad());
6995 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
6999SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
7001 SDValue
Mask =
N->getOperand(1);
7004 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
7006 Mask.getValueType().getVectorElementType(),
7009 SDValue WideVec = ModifyToType(Vec, WideVecVT);
7010 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
7011 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
7013 WideMask, WidePassthru);
7017 EVT VT =
N->getValueType(0);
7018 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7019 SDValue
Mask =
N->getMask();
7020 EVT MaskVT =
Mask.getValueType();
7021 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7030 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7031 TLI.isTypeLegal(WideMaskVT) &&
7037 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7038 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7042 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7043 N->getMemoryVT(),
N->getMemOperand());
7044 SDValue NewVal = NewLoad;
7047 if (!
N->getPassThru()->isUndef()) {
7051 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7052 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7053 DAG.getPOISON(WidenVT), EVL);
7058 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
7064 Mask = ModifyToType(Mask, WideMaskVT,
true);
7066 SDValue Res = DAG.getMaskedLoad(
7067 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7068 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7069 ExtType,
N->isExpandingLoad());
7072 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7078 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7079 SDValue
Mask =
N->getMask();
7080 EVT MaskVT =
Mask.getValueType();
7081 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7082 SDValue Scale =
N->getScale();
7089 Mask = ModifyToType(Mask, WideMaskVT,
true);
7092 SDValue
Index =
N->getIndex();
7094 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7095 Index = ModifyToType(Index, WideIndexVT);
7096 SDValue
Ops[] = {
N->getChain(), PassThru,
Mask,
N->getBasePtr(),
Index,
7101 N->getMemoryVT().getScalarType(), WideEC);
7102 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7103 WideMemVT, dl,
Ops,
N->getMemOperand(),
7104 N->getIndexType(),
N->getExtensionType());
7108 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7113 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7114 SDValue
Mask =
N->getMask();
7115 SDValue Scale =
N->getScale();
7119 SDValue
Index = GetWidenedVector(
N->getIndex());
7121 N->getMemoryVT().getScalarType(), WideEC);
7122 Mask = GetWidenedMask(Mask, WideEC);
7124 SDValue
Ops[] = {
N->getChain(),
N->getBasePtr(),
Index, Scale,
7125 Mask,
N->getVectorLength()};
7126 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7127 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7131 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7136 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7137 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7165 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7166 return N->getOperand(OpNo).getValueType();
7174 N =
N.getOperand(0);
7176 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7177 if (!
N->getOperand(i)->isUndef())
7179 N =
N.getOperand(0);
7183 N =
N.getOperand(0);
7185 N =
N.getOperand(0);
7211 { MaskVT, MVT::Other },
Ops);
7212 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7218 return adjustMaskToType(Mask, ToMaskVT);
7224 LLVMContext &Ctx = *DAG.getContext();
7225 EVT MaskVT =
Mask.getValueType();
7228 if (MaskScalarBits < ToMaskScalBits) {
7232 }
else if (MaskScalarBits > ToMaskScalBits) {
7238 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7240 "Mask should have the right element size by now.");
7243 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7245 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7248 EVT SubVT =
Mask->getValueType(0);
7254 assert((
Mask->getValueType(0) == ToMaskVT) &&
7255 "A mask of ToMaskVT should have been produced by now.");
7262EVT DAGTypeLegalizer::unifyMaskTypes(
SDValue &Op0,
bool IsOpLenient0,
7263 SDValue &Op1,
bool IsOpLenient1,
7267 "unifyMaskTypes only handles scalar width differences");
7279 if (IsOpLenient0 != IsOpLenient1) {
7280 SDValue *LenientOp, *NonLenientOp;
7283 NonLenientOp = &Op1;
7286 NonLenientOp = &Op0;
7289 *LenientOp = adjustMaskToType(*LenientOp, OpVT);
7295 unsigned NarrowBits = std::min(Bits0, Bits1);
7296 unsigned WideBits = std::max(Bits0, Bits1);
7298 unsigned IntBits = NarrowBits == WideBits ? NarrowBits
7299 : ToBits >= WideBits ? WideBits
7300 : ToBits <= NarrowBits ? NarrowBits
7304 Op0 = adjustMaskToType(Op0, OpVT);
7305 Op1 = adjustMaskToType(Op1, OpVT);
7309std::pair<SDValue, bool>
7310DAGTypeLegalizer::convertMaskTreeImpl(
SDValue V,
EVT ToVT,
unsigned Depth) {
7342 if (
Depth >= DAG.MaxRecursionDepth)
7351 unsigned Opcode =
V.getOpcode();
7356 return {convertMask(V, MaskVT, MaskVT),
false};
7364 return {DAG.getConstant(0,
DL, ToVT),
true};
7366 return {DAG.getAllOnesConstant(
DL, ToVT),
true};
7371 auto [Op0, IsLenientOp0] =
7372 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7375 auto [Op1, IsLenientOp1] =
7376 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7379 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7380 return {DAG.getNode(Opcode,
DL, OpVT, Op0, Op1),
7381 IsLenientOp0 && IsLenientOp1};
7386 auto [Inner, IsTypeLenient] =
7387 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7390 return {DAG.getNode(
ISD::FREEZE,
DL, Inner.getValueType(), Inner),
7397 auto [Op0, IsLenientOp0] =
7398 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7401 if (
V.getOperand(1).isUndef()) {
7403 return {DAG.getVectorShuffle(OpVT,
DL, Op0, DAG.getUNDEF(OpVT),
7407 auto [Op1, IsLenientOp1] =
7408 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7411 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7412 return {DAG.getVectorShuffle(OpVT,
DL, Op0, Op1, Shuf->getMask()),
7413 IsLenientOp0 && IsLenientOp1};
7418 auto [Op1, IsLenientOp1] =
7419 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7422 auto [Op2, IsLenientOp2] =
7423 convertMaskTreeImpl(
V.getOperand(2), ToVT,
Depth + 1);
7426 EVT OpVT = unifyMaskTypes(Op1, IsLenientOp1, Op2, IsLenientOp2, ToVT);
7435 SDValue
Cond =
V.getOperand(0);
7436 return {DAG.getNode(Opcode,
DL, OpVT,
Cond, Op1, Op2),
7437 IsLenientOp1 && IsLenientOp2};
7451 *DAG.getContext(),
V.getValueType().getVectorElementCount());
7452 auto [
Result,
_] = convertMaskTreeImpl(V, MaskTreeVT);
7455 return adjustMaskToType(Result, ToVT);
7463 LLVMContext &Ctx = *DAG.getContext();
7464 SDValue
Cond =
N->getOperand(0);
7471 EVT CondVT =
Cond->getValueType(0);
7475 EVT VSelVT =
N->getValueType(0);
7487 EVT FinalVT = VSelVT;
7498 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7499 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7506 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7514 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7517 EVT ToMaskVT = VSelVT;
7522 return convertMaskTree(
Cond, ToMaskVT);
7526 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7529 SDValue Cond1 =
N->getOperand(0);
7531 unsigned Opcode =
N->getOpcode();
7533 if (SDValue WideCond = WidenVSELECTMask(
N)) {
7534 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7535 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7537 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7543 Cond1 = GetWidenedVector(Cond1);
7551 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7552 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7557 Cond1 = ModifyToType(Cond1, CondWidenVT);
7560 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7561 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7563 if (Opcode == ISD::VP_MERGE)
7564 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7566 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7570 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7571 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7574 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7578 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7579 return DAG.getUNDEF(WidenVT);
7583 EVT VT =
N->getValueType(0);
7586 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7590 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7591 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7594 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7595 for (
unsigned i = 0; i != NumElts; ++i) {
7596 int Idx =
N->getMaskElt(i);
7597 if (Idx < (
int)NumElts)
7600 NewMask[i] = Idx - NumElts + WidenNumElts;
7602 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7606 EVT VT =
N->getValueType(0);
7610 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7611 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7617 unsigned IdxVal = WidenNumElts - VTNumElts;
7630 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7633 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7634 "down type's element count");
7637 for (; i < VTNumElts / GCD; ++i)
7639 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7640 for (; i < WidenNumElts / GCD; ++i)
7648 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7649 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7651 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7655SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7656 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7660void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7661 EVT VT =
N->getValueType(0);
7664 unsigned Factor =
N->getNumOperands();
7667 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7671 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7672 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7675 SDValue Interleaved =
7681 for (
unsigned Idx = 0; Idx != Factor; ++Idx)
7682 Slices[Idx] = Interleaved.
getValue(Idx);
7686 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7687 SDValue Narrow = DAG.getExtractSubvector(
DL, VT, Packed,
7690 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7691 SetWidenedVector(SDValue(
N, Idx), Wide);
7697 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7698 EVT SourceVT =
N->getOperand(0).getValueType();
7703 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7704 N->getOperand(0), 0);
7705 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7706 N->getOperand(2), 0);
7708 N->getOperand(1), WideMask,
N->getFlags());
7711void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7712 EVT VT =
N->getValueType(0);
7715 unsigned Factor =
N->getNumOperands();
7718 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7728 EVT ConcatVT =
EVT::getVectorVT(*DAG.getContext(), EltVT, OrigEC * Factor);
7730 SDValue PackedWidenVec = DAG.getInsertSubvector(
7731 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7735 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7736 NewOps[Idx] = DAG.getExtractSubvector(
DL, WidenVT, PackedWidenVec,
7743 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7744 SetWidenedVector(SDValue(
N, Idx), NewRes.
getValue(Idx));
7748 assert(
N->getValueType(0).isVector() &&
7749 N->getOperand(0).getValueType().isVector() &&
7750 "Operands must be vectors");
7751 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7764 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7765 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7772 InOp1 = GetWidenedVector(InOp1);
7773 InOp2 = GetWidenedVector(InOp2);
7775 SDValue
Poison = DAG.getPOISON(WidenInVT);
7776 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7787 "Input not widened to expected type!");
7789 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7794 assert(
N->getValueType(0).isVector() &&
7795 N->getOperand(1).getValueType().isVector() &&
7796 "Operands must be vectors");
7797 EVT VT =
N->getValueType(0);
7798 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7805 SDValue
LHS =
N->getOperand(1);
7806 SDValue
RHS =
N->getOperand(2);
7808 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7813 for (
unsigned i = 0; i != NumElts; ++i) {
7814 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7815 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7817 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7818 {Chain, LHSElem, RHSElem, CC});
7819 Chains[i] = Scalars[i].getValue(1);
7820 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7821 DAG.getBoolConstant(
true, dl, EltVT, VT),
7822 DAG.getBoolConstant(
false, dl, EltVT, VT));
7826 ReplaceValueWith(SDValue(
N, 1), NewChain);
7828 return DAG.getBuildVector(WidenVT, dl, Scalars);
7831SDValue DAGTypeLegalizer::WidenVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N) {
7833 EVT VT =
N->getValueType(0);
7836 SDValue Expanded = TLI.expandPartialReduceMLA(
N, DAG);
7837 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7838 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WideVT), Expanded, 0);
7844bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7845 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7846 SDValue Res = SDValue();
7849 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7852 switch (
N->getOpcode()) {
7855 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7863 Res = WidenVecOp_FAKE_USE(
N);
7867 Res = WidenVecOp_VECTOR_REPEAT(
N);
7872 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7876 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7877 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7878 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7883 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7885 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7886 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7888 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7889 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7899 Res = WidenVecOp_UnrollVectorOp(
N);
7906 Res = WidenVecOp_EXTEND(
N);
7911 Res = WidenVecOp_CMP(
N);
7929 Res = WidenVecOp_Convert(
N);
7934 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7954 Res = WidenVecOp_VECREDUCE(
N);
7958 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7960 case ISD::VP_REDUCE_FADD:
7961 case ISD::VP_REDUCE_SEQ_FADD:
7962 case ISD::VP_REDUCE_FMUL:
7963 case ISD::VP_REDUCE_SEQ_FMUL:
7964 case ISD::VP_REDUCE_ADD:
7965 case ISD::VP_REDUCE_MUL:
7966 case ISD::VP_REDUCE_AND:
7967 case ISD::VP_REDUCE_OR:
7968 case ISD::VP_REDUCE_XOR:
7969 case ISD::VP_REDUCE_SMAX:
7970 case ISD::VP_REDUCE_SMIN:
7971 case ISD::VP_REDUCE_UMAX:
7972 case ISD::VP_REDUCE_UMIN:
7973 case ISD::VP_REDUCE_FMAX:
7974 case ISD::VP_REDUCE_FMIN:
7975 case ISD::VP_REDUCE_FMAXIMUM:
7976 case ISD::VP_REDUCE_FMINIMUM:
7977 Res = WidenVecOp_VP_REDUCE(
N);
7981 Res = WidenVecOp_CttzElements(
N);
7983 case ISD::VP_CTTZ_ELTS:
7984 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7985 Res = WidenVecOp_VP_CttzElements(
N);
7988 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7991 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
7996 if (!Res.
getNode())
return false;
8004 if (
N->isStrictFPOpcode())
8006 "Invalid operand expansion");
8009 "Invalid operand expansion");
8011 ReplaceValueWith(SDValue(
N, 0), Res);
8017 EVT VT =
N->getValueType(0);
8022 "Unexpected type action");
8023 InOp = GetWidenedVector(InOp);
8026 "Input wasn't widened!");
8034 EVT FixedEltVT = FixedVT.getVectorElementType();
8035 if (TLI.isTypeLegal(FixedVT) &&
8037 FixedEltVT == InEltVT) {
8039 "Not enough elements in the fixed type for the operand!");
8041 "We can't have the same type as we started with!");
8043 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
8045 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
8054 return WidenVecOp_Convert(
N);
8059 switch (
N->getOpcode()) {
8074 EVT OpVT =
N->getOperand(0).getValueType();
8075 EVT ResVT =
N->getValueType(0);
8076 SDValue
LHS = GetWidenedVector(
N->getOperand(0));
8077 SDValue
RHS = GetWidenedVector(
N->getOperand(1));
8082 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
8083 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
8089 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
8090 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
8092 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
8099 return DAG.UnrollVectorOp(
N);
8104 EVT ResultVT =
N->getValueType(0);
8105 SDValue
Test =
N->getOperand(1);
8106 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
8109 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
8115 {WideArg,
Test},
N->getFlags());
8121 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
8123 EVT OpVT =
N->getOperand(0).getValueType();
8126 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
8131 EVT VT =
N->getValueType(0);
8134 SDValue InOp =
N->
getOperand(
N->isStrictFPOpcode() ? 1 : 0);
8137 "Unexpected type action");
8138 InOp = GetWidenedVector(InOp);
8140 unsigned Opcode =
N->getOpcode();
8143 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
8145 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
8148 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
8149 return DAG.getNode(Opcode, dl, VT,
Op);
8156 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
8158 if (
N->isStrictFPOpcode()) {
8160 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8163 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8164 {
N->getOperand(0), InOp });
8167 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
8169 Res = MakeConvertNode(WideVT, InOp);
8171 return DAG.getExtractSubvector(dl, VT, Res, 0);
8179 if (
N->isStrictFPOpcode()) {
8182 for (
unsigned i=0; i < NumElts; ++i) {
8183 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8184 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
8188 ReplaceValueWith(SDValue(
N, 1), NewChain);
8190 for (
unsigned i = 0; i < NumElts; ++i) {
8191 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8192 Ops[i] = MakeConvertNode(EltVT, Elt);
8196 return DAG.getBuildVector(VT, dl,
Ops);
8200 EVT DstVT =
N->getValueType(0);
8201 SDValue Src = GetWidenedVector(
N->getOperand(0));
8202 EVT SrcVT = Src.getValueType();
8209 if (TLI.isTypeLegal(WideDstVT)) {
8211 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
8214 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
8218 return DAG.UnrollVectorOp(
N);
8222 EVT VT =
N->getValueType(0);
8223 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8231 if (!VT.
isVector() && VT != MVT::x86mmx &&
8235 if (TLI.isTypeLegal(NewVT)) {
8236 SDValue BitOp = DAG.getNode(
ISD::BITCAST, dl, NewVT, InOp);
8237 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8249 ElementCount NewNumElts =
8251 .divideCoefficientBy(EltSize);
8253 if (TLI.isTypeLegal(NewVT)) {
8255 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8260 return CreateStackStoreLoad(InOp, VT);
8268 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8269 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8274 EVT VT =
N->getValueType(0);
8276 EVT InVT =
N->getOperand(0).getValueType();
8281 unsigned NumOperands =
N->getNumOperands();
8282 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8284 for (i = 1; i < NumOperands; ++i)
8285 if (!
N->getOperand(i).isUndef())
8288 if (i == NumOperands)
8289 return GetWidenedVector(
N->getOperand(0));
8293 SDValue
Result = DAG.getPOISON(VT);
8295 for (
unsigned i = 0; i < NumOperands; ++i) {
8296 SDValue InOp = GetWidenedVector(
N->getOperand(i));
8298 InOp = DAG.getExtractSubvector(dl, InVT, InOp, 0);
8299 Result = DAG.getInsertSubvector(dl, Result, InOp, i * NumInElts);
8311 for (
unsigned i=0; i < NumOperands; ++i) {
8315 "Unexpected type action");
8316 InOp = GetWidenedVector(InOp);
8317 for (
unsigned j = 0;
j < NumInElts; ++
j)
8318 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8320 return DAG.getBuildVector(VT, dl,
Ops);
8325 EVT VT =
N->getValueType(0);
8326 SDValue Src =
N->getOperand(0);
8327 EVT SrcVT = Src.getValueType();
8328 EVT WidenedSrcVT = TLI.getTypeToTransformTo(*DAG.getContext(), SrcVT);
8333 "Cannot widen VECTOR_REPEAT operand to an ElementCount that's not "
8334 "a known scalar multiple of the input ElementCount.");
8338 unsigned NumConcat =
8346 return DAG.getExtractSubvector(
DL, VT, Widened, 0);
8349SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8350 EVT VT =
N->getValueType(0);
8355 SubVec = GetWidenedVector(SubVec);
8360 bool IndicesValid =
false;
8363 IndicesValid =
true;
8367 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8368 Attribute::VScaleRange);
8373 IndicesValid =
true;
8379 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8385 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8392 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8414 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8422 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8423 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8428 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8433 unsigned Idx =
N->getConstantOperandVal(2);
8435 SDValue InsertElt = InVec;
8437 SDValue ExtractElt =
8439 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8445SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8446 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8448 N->getValueType(0), InOp,
N->getOperand(1));
8451SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8452 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8454 N->getValueType(0), InOp,
N->getOperand(1));
8457SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8459 EVT ResVT =
N->getValueType(0);
8462 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8468 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8476 "Widened input size must be a multiple of result element size");
8479 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8481 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8482 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8490 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8491 return TLI.scalarizeVectorStore(ST, DAG);
8493 if (
ST->isTruncatingStore())
8494 return TLI.scalarizeVectorStore(ST, DAG);
8502 SDValue StVal =
ST->getValue();
8504 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8505 EVT WideMaskVT = getSetCCResultType(WideVT);
8507 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8508 TLI.isTypeLegal(WideMaskVT)) {
8511 StVal = GetWidenedVector(StVal);
8512 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
8513 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8515 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8516 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8517 ST->getAddressingMode());
8521 if (GenWidenVectorStores(StChain, ST)) {
8522 if (StChain.
size() == 1)
8531 SDValue WideStVal = GetWidenedVector(StVal);
8535 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8536 ST->getOffset(), Mask,
ST->getMemoryVT(),
8537 ST->getMemOperand(),
ST->getAddressingMode(),
8538 ST->isTruncatingStore());
8545 EVT StVT =
ST->getMemoryVT();
8548 SDValue StVal = GetWidenedVector(
ST->getVal());
8553 TypeSize WidthDiff = WidenWidth - StWidth;
8559 std::optional<EVT> FirstVT =
8560 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8565 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8571 ST->getBasePtr(),
ST->getMemOperand());
8574SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8575 assert((OpNo == 1 || OpNo == 3) &&
8576 "Can widen only data or mask operand of vp_store");
8578 SDValue
Mask =
ST->getMask();
8579 SDValue StVal =
ST->getValue();
8584 StVal = GetWidenedVector(StVal);
8590 "Unable to widen VP store");
8591 Mask = GetWidenedVector(Mask);
8593 Mask = GetWidenedVector(Mask);
8599 "Unable to widen VP store");
8600 StVal = GetWidenedVector(StVal);
8603 assert(
Mask.getValueType().getVectorElementCount() ==
8605 "Mask and data vectors should have the same number of elements");
8606 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8607 ST->getOffset(), Mask,
ST->getVectorLength(),
8608 ST->getMemoryVT(),
ST->getMemOperand(),
8609 ST->getAddressingMode(),
ST->isTruncatingStore(),
8610 ST->isCompressingStore());
8615 assert((OpNo == 1 || OpNo == 4) &&
8616 "Can widen only data or mask operand of vp_strided_store");
8625 "Unable to widen VP strided store");
8629 "Unable to widen VP strided store");
8631 StVal = GetWidenedVector(StVal);
8632 Mask = GetWidenedVector(Mask);
8635 Mask.getValueType().getVectorElementCount() &&
8636 "Data and mask vectors should have the same number of elements");
8638 return DAG.getStridedStoreVP(
8645SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8646 assert((OpNo == 1 || OpNo == 4) &&
8647 "Can widen only data or mask operand of mstore");
8650 EVT MaskVT =
Mask.getValueType();
8655 EVT WideVT, WideMaskVT;
8658 StVal = GetWidenedVector(StVal);
8665 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8672 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8674 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8675 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8684 Mask = ModifyToType(Mask, WideMaskVT,
true);
8687 Mask = ModifyToType(Mask, WideMaskVT,
true);
8689 StVal = ModifyToType(StVal, WideVT);
8692 assert(
Mask.getValueType().getVectorElementCount() ==
8694 "Mask and data vectors should have the same number of elements");
8701SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8702 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8704 SDValue DataOp = MG->getPassThru();
8705 SDValue
Mask = MG->getMask();
8706 SDValue Scale = MG->getScale();
8709 SDValue
Index = GetWidenedVector(MG->getIndex());
8712 SDValue
Ops[] = {MG->getChain(), DataOp,
Mask, MG->getBasePtr(),
Index,
8714 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8715 MG->getMemOperand(), MG->getIndexType(),
8716 MG->getExtensionType());
8717 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
8718 ReplaceValueWith(SDValue(
N, 0), Res.
getValue(0));
8722SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8731 DataOp = GetWidenedVector(DataOp);
8735 EVT IndexVT =
Index.getValueType();
8738 Index = ModifyToType(Index, WideIndexVT);
8741 EVT MaskVT =
Mask.getValueType();
8744 Mask = ModifyToType(Mask, WideMaskVT,
true);
8749 }
else if (OpNo == 4) {
8751 Index = GetWidenedVector(Index);
8757 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8762SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8771 DataOp = GetWidenedVector(DataOp);
8772 Index = GetWidenedVector(Index);
8774 Mask = GetWidenedMask(Mask, WideEC);
8777 }
else if (OpNo == 3) {
8779 Index = GetWidenedVector(Index);
8786 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8791 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8792 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8794 EVT VT =
N->getValueType(0);
8808 SDValue WideSETCC = DAG.getNode(
ISD::SETCC, SDLoc(
N),
8809 SVT, InOp0, InOp1,
N->getOperand(2));
8815 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8817 EVT OpVT =
N->getOperand(0).getValueType();
8820 return DAG.getNode(ExtendCode, dl, VT, CC);
8825 SDValue
LHS = GetWidenedVector(
N->getOperand(1));
8826 SDValue
RHS = GetWidenedVector(
N->getOperand(2));
8830 EVT VT =
N->getValueType(0);
8832 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8839 for (
unsigned i = 0; i != NumElts; ++i) {
8840 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8841 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8843 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8844 {Chain, LHSElem, RHSElem, CC});
8845 Chains[i] = Scalars[i].getValue(1);
8846 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8847 DAG.getBoolConstant(
true, dl, EltVT, VT),
8848 DAG.getBoolConstant(
false, dl, EltVT, VT));
8852 ReplaceValueWith(SDValue(
N, 1), NewChain);
8854 return DAG.getBuildVector(VT, dl, Scalars);
8878 SDValue
Op = GetWidenedVector(
N->getOperand(0));
8879 EVT VT =
N->getValueType(0);
8880 EVT OrigVT =
N->getOperand(0).getValueType();
8881 EVT WideVT =
Op.getValueType();
8883 SDNodeFlags
Flags =
N->getFlags();
8885 unsigned Opc =
N->getOpcode();
8887 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8888 assert(NeutralElem &&
"Neutral element must exist");
8898 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8899 SDValue
Start = NeutralElem;
8905 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8906 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8912 unsigned GCD = std::gcd(OrigElts, WideElts);
8915 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8916 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8917 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8918 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8921 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8922 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8924 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8931 SDValue
Op = GetWidenedVector(VecOp);
8933 EVT VT =
N->getValueType(0);
8935 EVT WideVT =
Op.getValueType();
8937 SDNodeFlags
Flags =
N->getFlags();
8939 unsigned Opc =
N->getOpcode();
8941 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8951 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8954 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8955 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8961 unsigned GCD = std::gcd(OrigElts, WideElts);
8964 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8965 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8966 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8967 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8970 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8971 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8973 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8977 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8980 SDValue
Op = GetWidenedVector(
N->getOperand(1));
8981 SDValue
Mask = GetWidenedMask(
N->getOperand(2),
8982 Op.getValueType().getVectorElementCount());
8984 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8985 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8993 EVT VT =
N->getValueType(0);
8996 SDValue
Cond = GetWidenedVector(
N->getOperand(0));
8997 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8998 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
9003 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
9008 SDValue
Source =
N->getOperand(0);
9009 EVT SourceVT =
Source.getValueType();
9010 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9014 WideSource = GetWidenedVector(Source);
9018 SDValue
AllOnes = DAG.getAllOnesConstant(
DL, WideVT);
9021 WideSource = GetWidenedVector(Source);
9023 SmallVector<int>
Mask(WideElts);
9024 std::iota(
Mask.begin(),
Mask.end(), 0);
9026 Mask[
I] += WideElts;
9027 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
9029 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
9033 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
9039 SDValue
Source = GetWidenedVector(
N->getOperand(0));
9040 EVT SrcVT =
Source.getValueType();
9044 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
9045 {Source, Mask, N->getOperand(2)},
N->getFlags());
9048SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
9050 SDValue
Mask =
N->getOperand(0);
9051 EVT OrigMaskVT =
Mask.getValueType();
9052 SDValue WideMask = GetWidenedVector(Mask);
9058 if (OrigElts != WideElts) {
9059 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
9061 Mask, DAG.getVectorIdxConstant(0,
DL));
9068SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
9071 EVT ResVT =
N->getValueType(0);
9072 EVT SourceVT =
N->getOperand(0).getValueType();
9073 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9078 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
9079 N->getOperand(0), 0);
9080 SDValue WideMask = DAG.getInsertSubvector(
9081 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
9083 N->getOperand(1), WideMask,
N->getFlags());
9084 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
9088 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
9091 SDValue Needle =
N->getOperand(1);
9094 return TLI.expandVectorMatch(
N, DAG);
9096 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
9100 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
9101 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
9104 N->getOperand(0), WideNeedle,
N->getOperand(2),
9122 unsigned WidenEx = 0) {
9127 unsigned AlignInBits =
Align*8;
9129 EVT RetVT = WidenEltVT;
9134 if (Width == WidenEltWidth)
9145 (WidenWidth % MemVTWidth) == 0 &&
9147 (MemVTWidth <= Width ||
9148 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9149 if (MemVTWidth == WidenWidth)
9168 (WidenWidth % MemVTWidth) == 0 &&
9170 (MemVTWidth <= Width ||
9171 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9180 return std::nullopt;
9191 unsigned Start,
unsigned End) {
9192 SDLoc dl(LdOps[Start]);
9193 EVT LdTy = LdOps[Start].getValueType();
9201 for (
unsigned i = Start + 1; i != End; ++i) {
9202 EVT NewLdTy = LdOps[i].getValueType();
9203 if (NewLdTy != LdTy) {
9222 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9223 EVT LdVT =
LD->getMemoryVT();
9230 SDValue Chain =
LD->getChain();
9233 AAMDNodes AAInfo =
LD->getAAInfo();
9237 TypeSize WidthDiff = WidenWidth - LdWidth;
9244 std::optional<EVT> FirstVT =
9245 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
9252 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
9257 std::optional<EVT> NewVT = FirstVT;
9258 TypeSize RemainingWidth = LdWidth;
9259 TypeSize NewVTWidth = FirstVTWidth;
9261 RemainingWidth -= NewVTWidth;
9268 NewVTWidth = NewVT->getSizeInBits();
9274 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9275 LD->getBaseAlign(), MMOFlags, AAInfo);
9288 MachinePointerInfo MPI =
LD->getPointerInfo();
9294 for (EVT MemVT : MemVTs) {
9295 Align NewAlign = ScaledOffset == 0
9296 ?
LD->getBaseAlign()
9299 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
9307 unsigned End = LdOps.
size();
9318 EVT LdTy = LdOps[i].getValueType();
9321 for (--i; i >= 0; --i) {
9322 LdTy = LdOps[i].getValueType();
9329 ConcatOps[--Idx] = LdOps[i];
9330 for (--i; i >= 0; --i) {
9331 EVT NewLdTy = LdOps[i].getValueType();
9332 if (NewLdTy != LdTy) {
9342 for (;
j != End-Idx; ++
j)
9343 WidenOps[j] = ConcatOps[Idx+j];
9345 WidenOps[j] = DAG.getPOISON(LdTy);
9352 ConcatOps[--Idx] = LdOps[i];
9357 ArrayRef(&ConcatOps[Idx], End - Idx));
9363 SDValue UndefVal = DAG.getPOISON(LdTy);
9366 for (; i != End-Idx; ++i)
9367 WidenOps[i] = ConcatOps[Idx+i];
9369 WidenOps[i] = UndefVal;
9380 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9381 EVT LdVT =
LD->getMemoryVT();
9387 SDValue Chain =
LD->getChain();
9390 AAMDNodes AAInfo =
LD->getAAInfo();
9404 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9405 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9409 SDValue NewBasePtr =
9411 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9412 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9413 LD->getBaseAlign(), MMOFlags, AAInfo);
9418 SDValue UndefVal = DAG.getPOISON(EltVT);
9419 for (; i != WidenNumElts; ++i)
9422 return DAG.getBuildVector(WidenVT, dl,
Ops);
9430 SDValue Chain =
ST->getChain();
9433 AAMDNodes AAInfo =
ST->getAAInfo();
9434 SDValue ValOp = GetWidenedVector(
ST->getValue());
9437 EVT StVT =
ST->getMemoryVT();
9445 "Mismatch between store and value types");
9449 MachinePointerInfo MPI =
ST->getPointerInfo();
9459 std::optional<EVT> NewVT =
9464 TypeSize NewVTWidth = NewVT->getSizeInBits();
9467 StWidth -= NewVTWidth;
9468 MemVTs.
back().second++;
9472 for (
const auto &Pair : MemVTs) {
9473 EVT NewVT = Pair.first;
9474 unsigned Count = Pair.second;
9480 Align NewAlign = ScaledOffset == 0
9481 ?
ST->getBaseAlign()
9483 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9484 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9500 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9501 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9502 ST->getBaseAlign(), MMOFlags, AAInfo);
9519 bool FillWithZeroes) {
9524 "input and widen element type must match");
9526 "cannot modify scalable vectors in this way");
9539 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9541 for (
unsigned i = 1; i != NumConcat; ++i)
9548 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9554 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9559 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9560 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9562 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9564 unsigned NumResultParts = NewNumElts / CommonFactor;
9565 if (NumResultParts > NumCopiedParts) {
9566 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9567 : DAG.getPOISON(PartVT);
9568 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9575 "Scalable vectors should have been handled already.");
9583 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9585 for (Idx = 0; Idx < MinNumElts; ++Idx)
9586 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9588 SDValue UndefVal = DAG.getPOISON(EltVT);
9589 for (; Idx < WidenNumElts; ++Idx)
9590 Ops[Idx] = UndefVal;
9592 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9593 if (!FillWithZeroes)
9597 "We expect to never want to FillWithZeroes for non-integral types.");
9600 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9601 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9603 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9604 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
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
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 ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ 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 - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by OFFSET elements an...
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ MASKED_UDIV
Masked vector arithmetic that returns poison on disabled lanes.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_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.
@ 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 - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool 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.)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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.