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);
70 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
73 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
79 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
89 R = ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
N);
95 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
97 R = ScalarizeVecRes_VECTOR_MATCH(
N);
100 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
106 R = ScalarizeVecRes_VecInregOp(
N);
158 R = ScalarizeVecRes_UnaryOp(
N);
161 R = ScalarizeVecRes_ADDRSPACECAST(
N);
167 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
226 R = ScalarizeVecRes_BinOp(
N);
233 R = ScalarizeVecRes_MaskedBinOp(
N);
238 R = ScalarizeVecRes_CMP(
N);
244 R = ScalarizeVecRes_TernaryOp(
N);
247#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
248 case ISD::STRICT_##DAGN:
249#include "llvm/IR/ConstrainedOps.def"
250 R = ScalarizeVecRes_StrictFPOp(
N);
255 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
264 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
274 R = ScalarizeVecRes_FIX(
N);
280 SetScalarizedVector(
SDValue(
N, ResNo), R);
284 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
285 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
286 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
292 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
293 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
295 EVT MaskVT =
Mask.getValueType();
300 Mask = GetScalarizedVector(Mask);
309 DAG.getConstant(1,
DL,
LHS.getValueType()));
311 LHS.getValueType(),
LHS, Divisor);
319 if (getTypeAction(
LHS.getValueType()) ==
321 LHS = GetScalarizedVector(
LHS);
322 RHS = GetScalarizedVector(
RHS);
324 EVT VT =
LHS.getValueType().getVectorElementType();
325 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
326 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
329 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
330 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
334 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
335 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
336 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
337 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
342 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
343 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
350DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
352 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
353 "Unexpected vector type!");
354 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
356 EVT VT0 =
N->getValueType(0);
357 EVT VT1 =
N->getValueType(1);
361 DAG.getNode(
N->getOpcode(), dl,
362 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
366 unsigned OtherNo = 1 - ResNo;
367 EVT OtherVT =
N->getValueType(OtherNo);
369 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
373 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
376 return SDValue(ScalarNode, ResNo);
381 unsigned NumOpers =
N->getNumOperands();
383 EVT ValueVTs[] = {VT, MVT::Other};
392 for (
unsigned i = 1; i < NumOpers; ++i) {
398 Oper = GetScalarizedVector(Oper);
407 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
408 Opers,
N->getFlags());
419 EVT ResVT =
N->getValueType(0);
420 EVT OvVT =
N->getValueType(1);
424 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
425 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
428 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
429 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
430 ScalarLHS = ElemsLHS[0];
431 ScalarRHS = ElemsRHS[0];
434 SDVTList ScalarVTs = DAG.getVTList(
436 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
437 {ScalarLHS, ScalarRHS},
N->getFlags())
441 unsigned OtherNo = 1 - ResNo;
442 EVT OtherVT =
N->getValueType(OtherNo);
444 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
448 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
451 return SDValue(ScalarNode, ResNo);
456 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
457 return GetScalarizedVector(
Op);
460SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
465 N->getValueType(0).getScalarType(), Mask,
466 DAG.getVectorIdxConstant(0,
DL));
472 Op = GetScalarizedVector(
Op);
473 EVT NewVT =
N->getValueType(0).getVectorElementType();
478SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
488SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
490 N->getValueType(0).getVectorElementType(),
491 N->getOperand(0),
N->getOperand(1));
497 EVT OpVT =
Op.getValueType();
501 Op = GetScalarizedVector(
Op);
504 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
507 N->getValueType(0).getVectorElementType(),
Op,
511SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
514 EVT OpVT =
Op.getValueType();
518 Op = GetScalarizedVector(
Op);
521 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
524 N->getValueType(0).getVectorElementType(),
Op,
528SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
531 EVT OpVT =
Op.getValueType();
534 Op = GetScalarizedVector(
Op);
537 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
540 N->getValueType(0).getVectorElementType(),
Op,
541 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
544SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
545 SDValue Op = GetScalarizedVector(
N->getOperand(0));
546 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
550SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
555 if (
Op.getValueType() != EltVT)
563 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
564 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
574 assert(
N->isUnindexed() &&
"Indexed vector load?");
578 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
579 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
580 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
581 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
593 EVT OpVT =
Op.getValueType();
603 Op = GetScalarizedVector(
Op);
606 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
608 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
614 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
615 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
616 LHS, DAG.getValueType(ExtVT));
623 EVT OpVT =
Op.getValueType();
628 Op = GetScalarizedVector(
Op);
630 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
633 switch (
N->getOpcode()) {
645SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
648 EVT OpVT =
Op.getValueType();
658 Op = GetScalarizedVector(
Op);
661 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
664 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
665 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
666 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
669SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
680DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
681 assert(
N->getNumValues() ==
N->getNumOperands() &&
682 "Expected one result per operand");
686 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
687 SetScalarizedVector(
SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
693 EVT OpVT =
Cond.getValueType();
702 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
705 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
707 TLI.getBooleanContents(
false,
false);
714 if (TLI.getBooleanContents(
false,
false) !=
715 TLI.getBooleanContents(
false,
true)) {
719 EVT OpVT =
Cond->getOperand(0).getValueType();
721 VecBool = TLI.getBooleanContents(OpVT);
726 EVT CondVT =
Cond.getValueType();
727 if (ScalarBool != VecBool) {
728 switch (ScalarBool) {
736 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
743 Cond, DAG.getValueType(MVT::i1));
749 auto BoolVT = getSetCCResultType(CondVT);
750 if (BoolVT.bitsLT(CondVT))
753 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
754 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
758 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
759 return DAG.getSelect(SDLoc(
N),
760 LHS.getValueType(),
N->getOperand(0),
LHS,
761 GetScalarizedVector(
N->getOperand(2)));
765 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
767 N->getOperand(0),
N->getOperand(1),
768 LHS, GetScalarizedVector(
N->getOperand(3)),
773 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
776SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
780 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
782 return GetScalarizedVector(
N->getOperand(
Op));
785SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
787 EVT SrcVT = Src.getValueType();
792 Src = GetScalarizedVector(Src);
796 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
798 EVT DstVT =
N->getValueType(0).getVectorElementType();
799 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
803 assert(
N->getValueType(0).isVector() &&
804 N->getOperand(0).getValueType().isVector() &&
805 "Operand types must be vectors");
808 EVT OpVT =
LHS.getValueType();
809 EVT NVT =
N->getValueType(0).getVectorElementType();
814 LHS = GetScalarizedVector(
LHS);
815 RHS = GetScalarizedVector(
RHS);
818 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
819 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
829 return DAG.getNode(ExtendCode,
DL, NVT, Res);
840 Arg = GetScalarizedVector(Arg);
843 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
852 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
859bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
865 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
868 switch (
N->getOpcode()) {
871 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
878 Res = ScalarizeVecOp_BITCAST(
N);
881 Res = ScalarizeVecOp_FAKE_USE(
N);
895 Res = ScalarizeVecOp_UnaryOp(
N);
900 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
903 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
904 "Unexpected vector type!");
905 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
907 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
908 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
916 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
919 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
922 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
925 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
928 Res = ScalarizeVecOp_VSELECT(
N);
931 Res = ScalarizeVecOp_VSETCC(
N);
935 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
944 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
947 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
950 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
953 Res = ScalarizeVecOp_FP_EXTEND(
N);
972 Res = ScalarizeVecOp_VECREDUCE(
N);
976 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
980 Res = ScalarizeVecOp_CMP(
N);
983 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
987 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
990 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
996 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
1001 if (!Res.
getNode())
return false;
1009 "Invalid operand expansion");
1011 ReplaceValueWith(
SDValue(
N, 0), Res);
1018 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1020 N->getValueType(0), Elt);
1025 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1026 "Fake Use: Unexpected vector type!");
1027 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1028 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1034 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1035 "Unexpected vector type!");
1036 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1037 SDValue Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1038 N->getValueType(0).getScalarType(), Elt);
1046SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1047 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1048 "Unexpected vector type!");
1049 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1051 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1052 Elt,
N->getOperand(1));
1060SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1061 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1062 "Unexpected vector type!");
1063 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1065 {
N->getValueType(0).getScalarType(), MVT::Other },
1066 {
N->getOperand(0), Elt });
1076 ReplaceValueWith(
SDValue(
N, 0), Res);
1081SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1083 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1084 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1085 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1090SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1094 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1095 SDValue ContainingVec =
N->getOperand(0);
1103SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1104 EVT VT =
N->getValueType(0);
1105 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1117 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1118 EVT VT =
N->getValueType(0);
1120 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1129 assert(
N->getValueType(0).isVector() &&
1130 N->getOperand(0).getValueType().isVector() &&
1131 "Operand types must be vectors");
1132 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1133 "Expected single-element vector type");
1135 EVT VT =
N->getValueType(0);
1136 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1137 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1139 EVT OpVT =
N->getOperand(0).getValueType();
1151 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1157SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1159 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1160 assert(
N->getValueType(0).isVector() &&
1161 N->getOperand(1).getValueType().isVector() &&
1162 "Operand types must be vectors");
1163 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1164 "Expected single-element vector type");
1166 EVT VT =
N->getValueType(0);
1168 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1169 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1172 EVT OpVT =
N->getOperand(1).getValueType();
1176 {Ch, LHS, RHS, CC});
1185 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1190 ReplaceValueWith(
SDValue(
N, 0), Res);
1197 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1198 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1201 if (
N->isTruncatingStore())
1202 return DAG.getTruncStore(
1203 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1204 N->getBasePtr(),
N->getPointerInfo(),
1205 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1206 N->getMemOperand()->getFlags(),
N->getAAInfo());
1208 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1209 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1210 N->getMemOperand()->getFlags(),
N->getAAInfo());
1216 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1218 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1219 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1224SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1225 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1226 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1228 N->getValueType(0).getVectorElementType(), Elt,
1233SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1235 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1236 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1239 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1249 ReplaceValueWith(
SDValue(
N, 0), Res);
1256 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1258 N->getValueType(0).getVectorElementType(), Elt);
1264SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1265 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1268 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1269 {
N->getOperand(0), Elt});
1278 ReplaceValueWith(
SDValue(
N, 0), Res);
1283 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1290SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1296 SDValue Op = GetScalarizedVector(VecOp);
1297 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1298 AccOp,
Op,
N->getFlags());
1302 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1303 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1310SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1318 EVT VT =
N->getValueType(0);
1319 return DAG.getConstant(0, SDLoc(
N), VT);
1326 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1327 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1329 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1330 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1331 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1334SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1339 N->getValueType(0).getScalarType(), Mask,
1340 DAG.getVectorIdxConstant(0,
DL));
1345 return TLI.expandVectorMatch(
N, DAG);
1348SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1349 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1352 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1353 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1362 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1374void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1379 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1382 switch (
N->getOpcode()) {
1385 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1394 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1401 case ISD::VP_MERGE: SplitRes_Select(
N,
Lo,
Hi);
break;
1417 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1420 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1432 case ISD::VP_LOAD_FF:
1435 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1442 case ISD::VP_GATHER:
1446 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1449 SplitVecRes_SETCC(
N,
Lo,
Hi);
1452 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1459 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1462 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1465 SplitVecRes_VECTOR_INTERLEAVE(
N);
1468 SplitVecRes_VAARG(
N,
Lo,
Hi);
1474 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1528 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1531 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1537 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1543 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1599 SplitVecRes_BinOp(
N,
Lo,
Hi);
1605 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1610 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1614 SplitVecRes_CMP(
N,
Lo,
Hi);
1617#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1618 case ISD::STRICT_##DAGN:
1619#include "llvm/IR/ConstrainedOps.def"
1620 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1625 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1634 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1644 SplitVecRes_FIX(
N,
Lo,
Hi);
1646 case ISD::EXPERIMENTAL_VP_SPLICE:
1647 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1649 case ISD::EXPERIMENTAL_VP_REVERSE:
1650 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1656 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1659 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1662 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1671void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1678 SDValue BytesIncrement = DAG.getVScale(
1681 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1683 *ScaledOffset += IncrementSize;
1693std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1694 return SplitMask(Mask, SDLoc(Mask));
1697std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1700 EVT MaskVT =
Mask.getValueType();
1702 GetSplitVector(Mask, MaskLo, MaskHi);
1704 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1705 return std::make_pair(MaskLo, MaskHi);
1710 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1712 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1715 const SDNodeFlags
Flags =
N->getFlags();
1716 unsigned Opcode =
N->getOpcode();
1717 if (
N->getNumOperands() == 2) {
1718 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1719 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1723 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1724 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
1725 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
1726 "Expected VP opcode");
1729 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1732 std::tie(EVLLo, EVLHi) =
1733 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1736 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1738 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1744 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1746 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1750 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1752 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1756 const SDNodeFlags
Flags =
N->getFlags();
1757 unsigned Opcode =
N->getOpcode();
1758 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1760 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1767 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1769 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1771 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1774 const SDNodeFlags
Flags =
N->getFlags();
1775 unsigned Opcode =
N->getOpcode();
1777 DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1779 DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1783 LLVMContext &Ctxt = *DAG.getContext();
1789 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1791 GetSplitVector(
LHS, LHSLo, LHSHi);
1792 GetSplitVector(
RHS, RHSLo, RHSHi);
1794 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1795 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1799 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1800 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1805 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1807 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1811 unsigned Opcode =
N->getOpcode();
1812 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1814 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1823 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1830 switch (getTypeAction(InVT)) {
1844 GetExpandedOp(InOp,
Lo,
Hi);
1845 if (DAG.getDataLayout().isBigEndian())
1855 GetSplitVector(InOp,
Lo,
Hi);
1864 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1873 if (DAG.getDataLayout().isBigEndian())
1876 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1878 if (DAG.getDataLayout().isBigEndian())
1884void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1890 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1893 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1898 unsigned LaneOffset =
1901 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1903 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1910 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1913 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1916 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1921 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1923 unsigned NumSubvectors =
N->getNumOperands() / 2;
1924 if (NumSubvectors == 1) {
1925 Lo =
N->getOperand(0);
1926 Hi =
N->getOperand(1);
1931 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1940void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1947 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1962 GetSplitVector(Vec,
Lo,
Hi);
1965 EVT LoVT =
Lo.getValueType();
1975 if (IdxVal + SubElems <= LoElems) {
1983 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1985 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1991 SDValue WideSubVec = GetWidenedVector(SubVec);
1993 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2001 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2003 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2004 auto &MF = DAG.getMachineFunction();
2008 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2013 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2014 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2018 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2023 MachinePointerInfo MPI =
Load->getPointerInfo();
2024 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2027 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2036 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2041 EVT RHSVT =
RHS.getValueType();
2044 GetSplitVector(
RHS, RHSLo, RHSHi);
2046 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2061 SDValue FpValue =
N->getOperand(0);
2063 GetSplitVector(FpValue, ArgLo, ArgHi);
2065 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2067 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2076 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2080 std::tie(LoVT, HiVT) =
2084 DAG.getValueType(LoVT));
2086 DAG.getValueType(HiVT));
2091 unsigned Opcode =
N->getOpcode();
2098 GetSplitVector(N0, InLo, InHi);
2100 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2105 EVT OutLoVT, OutHiVT;
2106 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2108 assert((2 * OutNumElements) <= InNumElements &&
2109 "Illegal extend vector in reg split");
2118 SmallVector<int, 8> SplitHi(InNumElements, -1);
2119 for (
unsigned i = 0; i != OutNumElements; ++i)
2120 SplitHi[i] = i + OutNumElements;
2121 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2123 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2124 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2129 unsigned NumOps =
N->getNumOperands();
2133 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2143 for (
unsigned i = 1; i <
NumOps; ++i) {
2148 EVT InVT =
Op.getValueType();
2153 GetSplitVector(
Op, OpLo, OpHi);
2155 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2162 EVT LoValueVTs[] = {LoVT, MVT::Other};
2163 EVT HiValueVTs[] = {HiVT, MVT::Other};
2164 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2166 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2172 Lo.getValue(1),
Hi.getValue(1));
2176 ReplaceValueWith(
SDValue(
N, 1), Chain);
2179SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2181 EVT VT =
N->getValueType(0);
2192 else if (NE > ResNE)
2196 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2200 for (i = 0; i !=
NE; ++i) {
2202 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2203 SDValue Operand =
N->getOperand(j);
2207 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2213 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2221 for (; i < ResNE; ++i)
2222 Scalars.
push_back(DAG.getPOISON(EltVT));
2226 ReplaceValueWith(
SDValue(
N, 1), Chain);
2230 return DAG.getBuildVector(VecVT, dl, Scalars);
2233void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2236 EVT ResVT =
N->getValueType(0);
2237 EVT OvVT =
N->getValueType(1);
2238 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2239 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2240 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2242 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2244 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2245 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2247 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2248 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2251 unsigned Opcode =
N->getOpcode();
2252 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2253 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2255 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2257 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2263 unsigned OtherNo = 1 - ResNo;
2264 EVT OtherVT =
N->getValueType(OtherNo);
2266 SetSplitVector(
SDValue(
N, OtherNo),
2272 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2276void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2282 GetSplitVector(Vec,
Lo,
Hi);
2285 unsigned IdxVal = CIdx->getZExtValue();
2286 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2287 if (IdxVal < LoNumElts) {
2289 Lo.getValueType(),
Lo, Elt, Idx);
2292 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2312 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2314 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2315 auto &MF = DAG.getMachineFunction();
2319 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2324 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2325 Store = DAG.getTruncStore(
2331 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2334 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2338 MachinePointerInfo MPI =
Load->getPointerInfo();
2339 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2341 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2344 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2345 if (LoVT !=
Lo.getValueType())
2347 if (HiVT !=
Hi.getValueType())
2355 assert(
N->getValueType(0).isScalableVector() &&
2356 "Only scalable vectors are supported for STEP_VECTOR");
2357 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2378 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2379 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2381 Hi = DAG.getPOISON(HiVT);
2391 "Extended load during type legalization!");
2393 EVT VT =
LD->getValueType(0);
2395 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2403 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2404 Ch, Ptr,
LD->getMemOperand());
2409 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2411 Lo = DAG.getBitcast(LoVT, ExtractLo);
2412 Hi = DAG.getBitcast(HiVT, ExtractHi);
2424 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2430 EVT MemoryVT =
LD->getMemoryVT();
2432 AAMDNodes AAInfo =
LD->getAAInfo();
2434 EVT LoMemVT, HiMemVT;
2435 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2439 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2440 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2441 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2446 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2449 MachinePointerInfo MPI;
2450 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2453 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2462 ReplaceValueWith(
SDValue(LD, 1), Ch);
2467 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2470 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2476 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2480 EVT MemoryVT =
LD->getMemoryVT();
2482 EVT LoMemVT, HiMemVT;
2483 bool HiIsEmpty =
false;
2484 std::tie(LoMemVT, HiMemVT) =
2485 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2490 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2493 GetSplitVector(Mask, MaskLo, MaskHi);
2495 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2500 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2502 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2505 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2508 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2509 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2517 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2518 LD->isExpandingLoad());
2520 MachinePointerInfo MPI;
2522 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2524 MPI =
LD->getPointerInfo().getWithOffset(
2527 MMO = DAG.getMachineFunction().getMachineMemOperand(
2529 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2531 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2532 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2533 LD->isExpandingLoad());
2543 ReplaceValueWith(
SDValue(LD, 1), Ch);
2549 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2560 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2563 GetSplitVector(Mask, MaskLo, MaskHi);
2565 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2569 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2571 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2574 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2576 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2579 Hi = DAG.getPOISON(HiVT);
2581 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2582 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2588 "Indexed VP strided load during type legalization!");
2590 "Unexpected indexed variable-length load offset");
2595 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2597 EVT LoMemVT, HiMemVT;
2598 bool HiIsEmpty =
false;
2599 std::tie(LoMemVT, HiMemVT) =
2600 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2605 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2608 GetSplitVector(Mask, LoMask, HiMask);
2610 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2614 std::tie(LoEVL, HiEVL) =
2618 Lo = DAG.getStridedLoadVP(
2645 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2652 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2663 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2671 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2676 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2686 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2689 GetSplitVector(Mask, MaskLo, MaskHi);
2691 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2695 EVT LoMemVT, HiMemVT;
2696 bool HiIsEmpty =
false;
2697 std::tie(LoMemVT, HiMemVT) =
2698 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2700 SDValue PassThruLo, PassThruHi;
2702 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2704 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2706 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2711 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2721 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2724 MachinePointerInfo MPI;
2731 MMO = DAG.getMachineFunction().getMachineMemOperand(
2736 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2748 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2756 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2766 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2769 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2772 EVT MemoryVT =
N->getMemoryVT();
2778 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2780 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2783 EVT LoMemVT, HiMemVT;
2785 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2788 if (getTypeAction(
Ops.Index.getValueType()) ==
2790 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2792 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2795 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2797 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2800 SDValue PassThru = MGT->getPassThru();
2801 SDValue PassThruLo, PassThruHi;
2804 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2806 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2811 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2812 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2813 OpsLo, MMO, IndexTy, ExtType);
2815 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2816 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2817 OpsHi, MMO, IndexTy, ExtType);
2821 std::tie(EVLLo, EVLHi) =
2822 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2824 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2825 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2826 MMO, VPGT->getIndexType());
2828 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2829 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2830 MMO, VPGT->getIndexType());
2840 ReplaceValueWith(
SDValue(
N, 1), Ch);
2854 EVT VecVT =
N->getValueType(0);
2856 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2857 bool HasCustomLowering =
false;
2864 HasCustomLowering =
true;
2870 SDValue Passthru =
N->getOperand(2);
2871 if (!HasCustomLowering) {
2872 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2873 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2880 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2881 std::tie(LoMask, HiMask) = SplitMask(Mask);
2883 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2888 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2901 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2903 SDValue Chain = DAG.getEntryNode();
2904 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2908 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2913 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2917 assert(
N->getValueType(0).isVector() &&
2918 N->getOperand(0).getValueType().isVector() &&
2919 "Operand types must be vectors");
2923 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2927 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2929 GetSplitVector(
N->getOperand(0), LL, LH);
2931 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2933 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2935 GetSplitVector(
N->getOperand(1), RL, RH);
2937 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2939 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2940 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2948 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2952 EVT InVT =
N->getOperand(0).getValueType();
2954 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2956 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2958 const SDNodeFlags
Flags =
N->getFlags();
2959 unsigned Opcode =
N->getOpcode();
2961 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
2962 N->getOperand(3), Flags);
2963 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
2964 N->getOperand(3), Flags);
2970 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2971 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2973 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2974 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2981 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2985 EVT InVT =
N->getOperand(0).getValueType();
2987 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2989 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2992 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2993 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2994 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2995 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2998void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3003 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3004 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3008 EVT InVT =
N->getOperand(0).getValueType();
3010 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3012 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3014 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3015 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3017 SDNode *HiNode =
Hi.getNode();
3018 SDNode *LoNode =
Lo.getNode();
3021 unsigned OtherNo = 1 - ResNo;
3022 EVT OtherVT =
N->getValueType(OtherNo);
3030 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3037 EVT SrcVT =
N->getOperand(0).getValueType();
3038 EVT DestVT =
N->getValueType(0);
3040 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3057 LLVMContext &Ctx = *DAG.getContext();
3061 EVT SplitLoVT, SplitHiVT;
3062 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3063 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3064 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3065 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3066 N->dump(&DAG);
dbgs() <<
"\n");
3069 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3071 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3073 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3074 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3079 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3087 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3088 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3094 return N.getResNo() == 0 &&
3098 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3100 ArrayRef<int>
Mask) {
3103 "Expected build vector node.");
3106 for (
unsigned I = 0;
I < NewElts; ++
I) {
3109 unsigned Idx =
Mask[
I];
3111 Ops[
I] = Input2.getOperand(Idx - NewElts);
3113 Ops[
I] = Input1.getOperand(Idx);
3118 return DAG.getBuildVector(NewVT,
DL,
Ops);
3124 SmallVector<int> OrigMask(
N->getMask());
3126 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3127 &
DL](SmallVectorImpl<int> &
Mask) {
3129 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3130 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3141 for (
auto &
P : ShufflesIdxs) {
3142 if (
P.second.size() < 2)
3146 for (
int &Idx : Mask) {
3149 unsigned SrcRegIdx = Idx / NewElts;
3150 if (Inputs[SrcRegIdx].
isUndef()) {
3158 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3163 Idx = MaskElt % NewElts +
3164 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3170 Inputs[
P.second[0]] =
P.first.first;
3171 Inputs[
P.second[1]] =
P.first.second;
3174 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3177 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3178 for (
int &Idx : Mask) {
3181 unsigned SrcRegIdx = Idx / NewElts;
3182 if (Inputs[SrcRegIdx].
isUndef()) {
3189 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3190 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3193 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3195 if (UsedSubVector.count() > 1) {
3197 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3198 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3200 if (Pairs.
empty() || Pairs.
back().size() == 2)
3202 if (UsedSubVector.test(2 *
I)) {
3203 Pairs.
back().emplace_back(
I, 0);
3205 assert(UsedSubVector.test(2 *
I + 1) &&
3206 "Expected to be used one of the subvectors.");
3207 Pairs.
back().emplace_back(
I, 1);
3210 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3212 for (
int &Idx : Mask) {
3215 unsigned SrcRegIdx = Idx / NewElts;
3217 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3218 return Idxs.front().first == SrcRegIdx ||
3219 Idxs.back().first == SrcRegIdx;
3221 if (It == Pairs.
end())
3223 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3224 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3227 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3228 Inputs[Idxs.front().first] = DAG.
getNode(
3230 Inputs[Idxs.front().first].getValueType(),
3231 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3232 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3241 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3245 if (Shuffle->getOperand(0).getValueType() != NewVT)
3248 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3249 !Shuffle->isSplat()) {
3251 }
else if (!Inputs[
I].hasOneUse() &&
3252 !Shuffle->getOperand(1).isUndef()) {
3254 for (
int &Idx : Mask) {
3257 unsigned SrcRegIdx = Idx / NewElts;
3260 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3265 int OpIdx = MaskElt / NewElts;
3278 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3279 if (Shuffle->getOperand(OpIdx).isUndef())
3281 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3282 if (It == std::end(Inputs))
3284 int FoundOp = std::distance(std::begin(Inputs), It);
3287 for (
int &Idx : Mask) {
3290 unsigned SrcRegIdx = Idx / NewElts;
3293 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3298 int MaskIdx = MaskElt / NewElts;
3299 if (OpIdx == MaskIdx)
3300 Idx = MaskElt % NewElts + FoundOp * NewElts;
3303 Op = (OpIdx + 1) % 2;
3311 for (
int &Idx : Mask) {
3314 unsigned SrcRegIdx = Idx / NewElts;
3317 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3318 int OpIdx = MaskElt / NewElts;
3321 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3327 TryPeekThroughShufflesInputs(OrigMask);
3329 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3330 NewElts](SmallVectorImpl<int> &
Mask) {
3331 SetVector<SDValue> UniqueInputs;
3332 SetVector<SDValue> UniqueConstantInputs;
3333 for (
const auto &
I : Inputs) {
3335 UniqueConstantInputs.
insert(
I);
3336 else if (!
I.isUndef())
3341 if (UniqueInputs.
size() != std::size(Inputs)) {
3342 auto &&UniqueVec = UniqueInputs.
takeVector();
3343 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3344 unsigned ConstNum = UniqueConstantVec.size();
3345 for (
int &Idx : Mask) {
3348 unsigned SrcRegIdx = Idx / NewElts;
3349 if (Inputs[SrcRegIdx].
isUndef()) {
3353 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3354 if (It != UniqueConstantVec.end()) {
3355 Idx = (Idx % NewElts) +
3356 NewElts * std::distance(UniqueConstantVec.begin(), It);
3357 assert(Idx >= 0 &&
"Expected defined mask idx.");
3360 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3361 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3362 Idx = (Idx % NewElts) +
3363 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3364 assert(Idx >= 0 &&
"Expected defined mask idx.");
3366 copy(UniqueConstantVec, std::begin(Inputs));
3367 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3370 MakeUniqueInputs(OrigMask);
3372 copy(Inputs, std::begin(OrigInputs));
3378 unsigned FirstMaskIdx =
High * NewElts;
3381 assert(!Output &&
"Expected default initialized initial value.");
3382 TryPeekThroughShufflesInputs(Mask);
3383 MakeUniqueInputs(Mask);
3385 copy(Inputs, std::begin(TmpInputs));
3388 bool SecondIteration =
false;
3389 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3394 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3395 SecondIteration =
true;
3396 return SecondIteration;
3399 Mask, std::size(Inputs), std::size(Inputs),
3401 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3402 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3403 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3405 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3407 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3408 DAG.getPOISON(NewVT), Mask);
3409 Inputs[Idx] = Output;
3411 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3412 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3413 unsigned Idx2,
bool ) {
3414 if (AccumulateResults(Idx1)) {
3417 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3419 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3420 Inputs[Idx2], Mask);
3424 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3426 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3427 TmpInputs[Idx2], Mask);
3429 Inputs[Idx1] = Output;
3431 copy(OrigInputs, std::begin(Inputs));
3436 EVT OVT =
N->getValueType(0);
3444 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3446 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV,
Alignment.value());
3447 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV,
Alignment.value());
3452 ReplaceValueWith(
SDValue(
N, 1), Chain);
3457 EVT DstVTLo, DstVTHi;
3458 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3462 EVT SrcVT =
N->getOperand(0).getValueType();
3464 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3466 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3468 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3469 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3475 GetSplitVector(
N->getOperand(0), InLo, InHi);
3486 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3487 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3492 EVT VT =
N->getValueType(0);
3515 EVT PtrVT =
StackPtr.getValueType();
3516 auto &MF = DAG.getMachineFunction();
3520 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3523 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3529 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3530 DAG.getConstant(1,
DL, PtrVT));
3532 DAG.getConstant(EltWidth,
DL, PtrVT));
3534 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3536 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3537 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3538 DAG.getPOISON(PtrVT), Stride, TrueMask,
3547 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3552 EVT VT =
N->getValueType(0);
3564 EVL1 = ZExtPromotedInteger(EVL1);
3583 EVT PtrVT =
StackPtr.getValueType();
3584 auto &MF = DAG.getMachineFunction();
3588 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3591 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3597 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3602 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3603 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3605 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3607 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3611 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3616 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3617 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3621 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3630 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3638 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3640 DAG.getVectorIdxConstant(0,
DL));
3646void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3654 GetSplitVector(Acc, AccLo, AccHi);
3655 unsigned Opcode =
N->getOpcode();
3667 GetSplitVector(Input1, Input1Lo, Input1Hi);
3668 GetSplitVector(Input2, Input2Lo, Input2Hi);
3671 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3672 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3675void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3683 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3694 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3696 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3700 N->getOperand(1), MaskLo,
N->getFlags());
3702 N->getOperand(1), MaskHi,
N->getFlags());
3705void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3706 unsigned Factor =
N->getNumOperands();
3709 for (
unsigned i = 0; i != Factor; ++i) {
3711 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3713 Ops[i * 2 + 1] = OpHi;
3724 for (
unsigned i = 0; i != Factor; ++i)
3728void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3729 unsigned Factor =
N->getNumOperands();
3732 for (
unsigned i = 0; i != Factor; ++i) {
3734 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3736 Ops[i + Factor] = OpHi;
3747 for (
unsigned i = 0; i != Factor; ++i) {
3748 unsigned IdxLo = 2 * i;
3749 unsigned IdxHi = 2 * i + 1;
3750 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3751 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3763bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3768 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3771 switch (
N->getOpcode()) {
3774 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3783 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3790 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3793 Res = SplitVecOp_TruncateHelper(
N);
3799 Res = SplitVecOp_FP_ROUND(
N);
3811 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3818 case ISD::VP_SCATTER:
3822 case ISD::VP_GATHER:
3826 Res = SplitVecOp_VSELECT(
N, OpNo);
3832 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3835 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3841 if (
N->getValueType(0).bitsLT(
3842 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3843 Res = SplitVecOp_TruncateHelper(
N);
3845 Res = SplitVecOp_UnaryOp(
N);
3849 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3865 Res = SplitVecOp_UnaryOp(
N);
3868 Res = SplitVecOp_FPOpDifferentTypes(
N);
3873 Res = SplitVecOp_CMP(
N);
3877 Res = SplitVecOp_FAKE_USE(
N);
3882 Res = SplitVecOp_ExtVecInRegOp(
N);
3902 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3906 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3908 case ISD::VP_REDUCE_FADD:
3909 case ISD::VP_REDUCE_SEQ_FADD:
3910 case ISD::VP_REDUCE_FMUL:
3911 case ISD::VP_REDUCE_SEQ_FMUL:
3912 case ISD::VP_REDUCE_ADD:
3913 case ISD::VP_REDUCE_MUL:
3914 case ISD::VP_REDUCE_AND:
3915 case ISD::VP_REDUCE_OR:
3916 case ISD::VP_REDUCE_XOR:
3917 case ISD::VP_REDUCE_SMAX:
3918 case ISD::VP_REDUCE_SMIN:
3919 case ISD::VP_REDUCE_UMAX:
3920 case ISD::VP_REDUCE_UMIN:
3921 case ISD::VP_REDUCE_FMAX:
3922 case ISD::VP_REDUCE_FMIN:
3923 case ISD::VP_REDUCE_FMAXIMUM:
3924 case ISD::VP_REDUCE_FMINIMUM:
3925 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3929 Res = SplitVecOp_CttzElts(
N);
3931 case ISD::VP_CTTZ_ELTS:
3932 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3933 Res = SplitVecOp_VP_CttzElements(
N);
3936 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3942 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3945 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
3950 if (!Res.
getNode())
return false;
3957 if (
N->isStrictFPOpcode())
3959 "Invalid operand expansion");
3962 "Invalid operand expansion");
3964 ReplaceValueWith(
SDValue(
N, 0), Res);
3968SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3972 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3974 EVT VT =
N->getValueType(0);
3987 getSetCCResultType(MVT::i1), MVT::i1);
3992 DAG.getElementCount(
DL, VT, SplitEC)),
3996SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3999 assert(OpNo == 0 &&
"Illegal operand must be mask");
4006 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4009 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4010 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4011 "Lo and Hi have differing types");
4014 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4015 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4017 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4018 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4019 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4020 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4030SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4031 assert(OpNo == 2 &&
"Illegal operand must be mask");
4034 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4035 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4037 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4040 RHSLo, MaskLo,
N->getFlags());
4042 RHSHi, MaskHi,
N->getFlags());
4046SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4049 assert(OpNo == 1 &&
"Illegal operand must be mask");
4054 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4056 EVT VecVT =
N->getValueType(0);
4060SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4061 EVT ResVT =
N->getValueType(0);
4067 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4068 GetSplitVector(VecOp,
Lo,
Hi);
4070 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4075 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4076 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4080 EVT ResVT =
N->getValueType(0);
4086 SDNodeFlags
Flags =
N->getFlags();
4089 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4090 GetSplitVector(VecOp,
Lo,
Hi);
4092 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4098 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4101SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4102 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4103 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4105 unsigned Opc =
N->getOpcode();
4106 EVT ResVT =
N->getValueType(0);
4112 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4113 GetSplitVector(VecOp,
Lo,
Hi);
4116 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4119 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4121 const SDNodeFlags
Flags =
N->getFlags();
4125 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4130 EVT ResVT =
N->getValueType(0);
4133 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4134 EVT InVT =
Lo.getValueType();
4139 if (
N->isStrictFPOpcode()) {
4140 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4141 {N->getOperand(0), Lo});
4142 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4143 {N->getOperand(0), Hi});
4152 ReplaceValueWith(
SDValue(
N, 1), Ch);
4154 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4155 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4164 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4174 EVT ResVT =
N->getValueType(0);
4176 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4180 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4186 Lo = BitConvertToInteger(
Lo);
4187 Hi = BitConvertToInteger(
Hi);
4189 if (DAG.getDataLayout().isBigEndian())
4197 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4199 EVT ResVT =
N->getValueType(0);
4207 GetSplitVector(SubVec,
Lo,
Hi);
4216 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4218 return SecondInsertion;
4221SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4228 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4230 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4232 ElementCount IdxVal =
4236 EVT SrcVT =
N->getOperand(0).getValueType();
4255 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4256 LoEltsMin - IdxValMin);
4257 DAG.ExtractVectorElements(
Hi, Elts, 0,
4260 return DAG.getBuildVector(SubVT, dl, Elts);
4264 ElementCount ExtractIdx = IdxVal - LoElts;
4266 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4269 EVT HiVT =
Hi.getValueType();
4271 "Only fixed-vector extracts are supported in this case");
4281 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4282 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4288 "Extracting scalable subvector from fixed-width unsupported");
4296 "subvector from a scalable predicate vector");
4302 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4304 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4305 auto &MF = DAG.getMachineFunction();
4309 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4313 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4316 SubVT, dl,
Store, StackPtr,
4320SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4329 GetSplitVector(Vec,
Lo,
Hi);
4331 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4333 if (IdxVal < LoElts)
4334 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4337 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4342 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4354 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4360 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4362 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4363 auto &MF = DAG.getMachineFunction();
4366 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4370 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4374 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4376 return DAG.getExtLoad(
4387 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4395 SplitVecRes_Gather(
N,
Lo,
Hi);
4398 ReplaceValueWith(
SDValue(
N, 0), Res);
4403 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4407 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4409 SDValue EVL =
N->getVectorLength();
4417 GetSplitVector(
Data, DataLo, DataHi);
4419 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4424 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4427 GetSplitVector(Mask, MaskLo, MaskHi);
4429 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4432 EVT MemoryVT =
N->getMemoryVT();
4433 EVT LoMemVT, HiMemVT;
4434 bool HiIsEmpty =
false;
4435 std::tie(LoMemVT, HiMemVT) =
4436 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4440 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4443 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4446 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4448 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4449 N->getAddressingMode(),
N->isTruncatingStore(),
4450 N->isCompressingStore());
4456 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4457 N->isCompressingStore());
4459 MachinePointerInfo MPI;
4463 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4468 MMO = DAG.getMachineFunction().getMachineMemOperand(
4470 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4472 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4473 N->getAddressingMode(),
N->isTruncatingStore(),
4474 N->isCompressingStore());
4483 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4484 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4491 GetSplitVector(
Data, LoData, HiData);
4493 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4495 EVT LoMemVT, HiMemVT;
4496 bool HiIsEmpty =
false;
4497 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4503 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4504 else if (getTypeAction(
Mask.getValueType()) ==
4506 GetSplitVector(Mask, LoMask, HiMask);
4508 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4511 std::tie(LoEVL, HiEVL) =
4512 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4516 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4517 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4518 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4529 EVT PtrVT =
N->getBasePtr().getValueType();
4532 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4540 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4541 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4543 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4546 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4547 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4548 N->isCompressingStore());
4557 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4561 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4570 GetSplitVector(
Data, DataLo, DataHi);
4572 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4577 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4580 GetSplitVector(Mask, MaskLo, MaskHi);
4582 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4585 EVT MemoryVT =
N->getMemoryVT();
4586 EVT LoMemVT, HiMemVT;
4587 bool HiIsEmpty =
false;
4588 std::tie(LoMemVT, HiMemVT) =
4589 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4592 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4595 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4597 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4598 N->getAddressingMode(),
N->isTruncatingStore(),
4599 N->isCompressingStore());
4607 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4608 N->isCompressingStore());
4610 MachinePointerInfo MPI;
4614 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4619 MMO = DAG.getMachineFunction().getMachineMemOperand(
4622 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4624 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4625 N->getAddressingMode(),
N->isTruncatingStore(),
4626 N->isCompressingStore());
4639 EVT MemoryVT =
N->getMemoryVT();
4649 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4653 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4658 EVT LoMemVT, HiMemVT;
4659 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4664 GetSplitVector(
Ops.Data, DataLo, DataHi);
4666 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4671 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4673 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4677 if (getTypeAction(
Ops.Index.getValueType()) ==
4679 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4681 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4685 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4687 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4690 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4692 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4693 MSC->getIndexType(), MSC->isTruncatingStore());
4698 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4699 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4700 MMO, MSC->getIndexType(),
4701 MSC->isTruncatingStore());
4705 std::tie(EVLLo, EVLHi) =
4706 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4708 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4709 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4710 VPSC->getIndexType());
4715 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4716 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4717 VPSC->getIndexType());
4721 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4722 assert(OpNo == 1 &&
"Can only split the stored value");
4725 bool isTruncating =
N->isTruncatingStore();
4728 EVT MemoryVT =
N->getMemoryVT();
4731 AAMDNodes AAInfo =
N->getAAInfo();
4733 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4735 EVT LoMemVT, HiMemVT;
4736 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4740 return TLI.scalarizeVectorStore(
N, DAG);
4743 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4744 Alignment, MMOFlags, AAInfo);
4746 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4749 MachinePointerInfo MPI;
4750 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4753 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4754 HiMemVT, Alignment, MMOFlags, AAInfo);
4756 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4763 LLVMContext &Ctx = *DAG.getContext();
4781 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4782 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4786 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4789 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4790 DAG.getBitcast(MemVecVT, Wide), 0);
4792 N->getBasePtr(),
N->getMemOperand());
4800 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4802 N->getBasePtr(),
N->getMemOperand());
4816 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4822 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4843 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4844 SDValue InVec =
N->getOperand(OpNo);
4846 EVT OutVT =
N->getValueType(0);
4854 EVT LoOutVT, HiOutVT;
4855 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4856 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4861 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4863 return SplitVecOp_UnaryOp(
N);
4872 return SplitVecOp_UnaryOp(
N);
4876 GetSplitVector(InVec, InLoVec, InHiVec);
4882 EVT HalfElementVT = IsFloat ?
4884 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4891 if (
N->isStrictFPOpcode()) {
4892 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4893 {N->getOperand(0), InLoVec});
4894 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4895 {N->getOperand(0), InHiVec});
4901 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4902 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4906 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4914 if (
N->isStrictFPOpcode()) {
4918 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4926 DAG.getTargetConstant(
4927 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4934 assert(
N->getValueType(0).isVector() &&
4935 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4936 "Operand types must be vectors");
4938 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4940 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4941 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4943 EVT VT =
N->getValueType(0);
4944 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4950 assert(isStrict &&
"unexpected node");
4951 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4952 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4953 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4954 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4957 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4965 EVT OpVT =
N->getOperand(0).getValueType();
4968 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4974 EVT ResVT =
N->getValueType(0);
4977 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4978 EVT InVT =
Lo.getValueType();
4983 if (
N->isStrictFPOpcode()) {
4984 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4985 {N->getOperand(0), Lo, N->getOperand(2)});
4986 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4987 {N->getOperand(0), Hi, N->getOperand(2)});
4991 Lo.getValue(1),
Hi.getValue(1));
4992 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4994 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
4995 N->getOperand(2),
N->getOperand(3));
4996 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
4997 N->getOperand(2),
N->getOperand(3));
4999 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5000 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5011SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5014 EVT LHSLoVT, LHSHiVT;
5015 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5017 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5018 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5021 std::tie(LHSLo, LHSHi) =
5022 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5025 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5028 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5034 LLVMContext &Ctxt = *DAG.getContext();
5037 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5038 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5039 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5041 EVT ResVT =
N->getValueType(0);
5046 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5047 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5053 EVT ResVT =
N->getValueType(0);
5056 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5057 EVT InVT =
Lo.getValueType();
5063 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5064 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5071 EVT ResVT =
N->getValueType(0);
5075 GetSplitVector(VecOp,
Lo,
Hi);
5081 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5083 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5085 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5086 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5091 EVT ResVT =
N->getValueType(0);
5095 GetSplitVector(VecOp,
Lo,
Hi);
5097 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5098 auto [EVLLo, EVLHi] =
5100 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5106 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5108 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5109 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5112SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5123 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5124 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5125 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5126 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5127 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5128 OpsLo, MMO, IndexType);
5129 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5130 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5134SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5138 EVT LoResVT, HiResVT;
5139 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5141 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5143 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5146 N->getOperand(1), MaskLo,
N->getFlags());
5148 N->getOperand(1), MaskHi,
N->getFlags());
5154 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5157 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5161 NeedleLo,
N->getOperand(2),
N->getFlags());
5164 NeedleHi,
N->getOperand(2),
N->getFlags());
5165 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5168SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5171 "Accumulator should already be a legal type, and shouldn't need "
5172 "further splitting");
5175 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5176 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5177 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5178 unsigned Opcode =
N->getOpcode();
5181 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5182 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5189void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5190 unsigned WidenResNo) {
5191 unsigned NumResults =
N->getNumValues();
5192 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5193 if (ResNo == WidenResNo)
5195 EVT ResVT =
N->getValueType(ResNo);
5201 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5202 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5207void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5208 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5211 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5216 auto unrollExpandedOp = [&]() {
5221 EVT VT =
N->getValueType(0);
5222 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5223 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5224 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5226 if (
N->getNumValues() > 1)
5227 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5233 switch (
N->getOpcode()) {
5236 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5244 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5248 Res = WidenVecRes_ADDRSPACECAST(
N);
5255 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5262 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5266 Res = WidenVecRes_ScalarOp(
N);
5272 Res = WidenVecRes_Select(
N);
5275 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5277 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5284 case ISD::VP_LOAD_FF:
5287 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5291 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5299 case ISD::VP_GATHER:
5303 Res = WidenVecRes_VECTOR_REVERSE(
N);
5306 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5309 WidenVecRes_VECTOR_INTERLEAVE(
N);
5312 Res = WidenVecRes_VECTOR_MATCH(
N);
5315 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5369 Res = WidenVecRes_Binary(
N);
5376 Res = WidenVecRes_MaskedBinary(
N);
5381 Res = WidenVecRes_CMP(
N);
5387 if (unrollExpandedOp())
5402 Res = WidenVecRes_BinaryCanTrap(
N);
5411 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5414#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5415 case ISD::STRICT_##DAGN:
5416#include "llvm/IR/ConstrainedOps.def"
5417 Res = WidenVecRes_StrictFP(
N);
5426 Res = WidenVecRes_OverflowOp(
N, ResNo);
5430 Res = WidenVecRes_FCOPYSIGN(
N);
5435 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5440 if (!unrollExpandedOp())
5441 Res = WidenVecRes_ExpOp(
N);
5447 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5462 Res = WidenVecRes_Convert(
N);
5467 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5474 Res = WidenVecRes_XROUND(
N);
5500 if (unrollExpandedOp())
5522 Res = WidenVecRes_Unary(
N);
5527 Res = WidenVecRes_Ternary(
N);
5533 if (!unrollExpandedOp())
5534 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5538 Res = WidenVecRes_PARTIAL_REDUCE_MLA(
N);
5544 SetWidenedVector(
SDValue(
N, ResNo), Res);
5550 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5551 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5552 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5553 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5554 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5560 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5561 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5562 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5563 if (
N->getNumOperands() == 2)
5564 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5567 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5568 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5569 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5570 "Expected VP opcode");
5574 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5575 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5580 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5581 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5582 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5585 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5586 Mask = ModifyToType(Mask, WideMaskVT,
true);
5587 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5592 LLVMContext &Ctxt = *DAG.getContext();
5597 EVT OpVT =
LHS.getValueType();
5599 LHS = GetWidenedVector(
LHS);
5600 RHS = GetWidenedVector(
RHS);
5601 OpVT =
LHS.getValueType();
5604 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5607 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5613SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5616 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5617 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5618 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5620 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5629 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5632 if (ConcatEnd == 1) {
5633 VT = ConcatOps[0].getValueType();
5635 return ConcatOps[0];
5638 SDLoc dl(ConcatOps[0]);
5645 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
5646 int Idx = ConcatEnd - 1;
5647 VT = ConcatOps[Idx--].getValueType();
5648 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
5661 unsigned NumToInsert = ConcatEnd - Idx - 1;
5662 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5664 ConcatOps[Idx+1] = VecOp;
5665 ConcatEnd = Idx + 2;
5671 unsigned RealVals = ConcatEnd - Idx - 1;
5672 unsigned SubConcatEnd = 0;
5673 unsigned SubConcatIdx = Idx + 1;
5674 while (SubConcatEnd < RealVals)
5675 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5676 while (SubConcatEnd < OpsToConcat)
5677 SubConcatOps[SubConcatEnd++] = undefVec;
5679 NextVT, SubConcatOps);
5680 ConcatEnd = SubConcatIdx + 1;
5685 if (ConcatEnd == 1) {
5686 VT = ConcatOps[0].getValueType();
5688 return ConcatOps[0];
5693 if (
NumOps != ConcatEnd ) {
5695 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5696 ConcatOps[j] = UndefVal;
5704 unsigned Opcode =
N->getOpcode();
5706 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5710 const SDNodeFlags
Flags =
N->getFlags();
5711 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5712 NumElts = NumElts / 2;
5716 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5718 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5719 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5720 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5728 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5731 TLI.isTypeLegal(WideMaskVT)) {
5732 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5733 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5734 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5736 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5737 N->getValueType(0).getVectorElementCount());
5738 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5752 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5753 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5754 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5757 unsigned ConcatEnd = 0;
5765 while (CurNumElts != 0) {
5766 while (CurNumElts >= NumElts) {
5767 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5768 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5769 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5771 CurNumElts -= NumElts;
5774 NumElts = NumElts / 2;
5776 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5779 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5780 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5781 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5782 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5793 switch (
N->getOpcode()) {
5796 return WidenVecRes_STRICT_FSETCC(
N);
5803 return WidenVecRes_Convert_StrictFP(
N);
5810 unsigned Opcode =
N->getOpcode();
5812 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5816 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5817 NumElts = NumElts / 2;
5828 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5832 unsigned ConcatEnd = 0;
5839 for (
unsigned i = 1; i < NumOpers; ++i) {
5845 Oper = GetWidenedVector(Oper);
5851 DAG.getPOISON(WideOpVT), Oper,
5852 DAG.getVectorIdxConstant(0, dl));
5864 while (CurNumElts != 0) {
5865 while (CurNumElts >= NumElts) {
5868 for (
unsigned i = 0; i < NumOpers; ++i) {
5871 EVT OpVT =
Op.getValueType();
5876 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5882 EVT OperVT[] = {VT, MVT::Other};
5884 ConcatOps[ConcatEnd++] = Oper;
5887 CurNumElts -= NumElts;
5890 NumElts = NumElts / 2;
5892 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5895 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5898 for (
unsigned i = 0; i < NumOpers; ++i) {
5901 EVT OpVT =
Op.getValueType();
5909 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5911 ConcatOps[ConcatEnd++] = Oper;
5920 if (Chains.
size() == 1)
5921 NewChain = Chains[0];
5924 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5929SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5931 EVT ResVT =
N->getValueType(0);
5932 EVT OvVT =
N->getValueType(1);
5933 EVT WideResVT, WideOvVT;
5938 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5943 WideLHS = GetWidenedVector(
N->getOperand(0));
5944 WideRHS = GetWidenedVector(
N->getOperand(1));
5946 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5955 N->getOperand(0), Zero);
5957 N->getOperand(1), Zero);
5960 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5961 SDNode *WideNode = DAG.getNode(
5962 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5965 unsigned OtherNo = 1 - ResNo;
5966 EVT OtherVT =
N->getValueType(OtherNo);
5973 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5976 return SDValue(WideNode, ResNo);
5980 LLVMContext &Ctx = *DAG.getContext();
5984 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5989 unsigned Opcode =
N->getOpcode();
5990 const SDNodeFlags
Flags =
N->getFlags();
5996 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5998 InOp = ZExtPromotedInteger(InOp);
6010 if (
N->getNumOperands() == 1)
6011 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6013 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6014 N->getOperand(3), Flags);
6015 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6019 InOp = GetWidenedVector(
N->getOperand(0));
6022 if (InVTEC == WidenEC)
6023 return MakeConvertNode(WidenVT, InOp);
6048 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6052 if (TLI.isTypeLegal(InWidenVT)) {
6060 unsigned NumConcat =
6065 return MakeConvertNode(WidenVT, InVec);
6069 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6071 return MakeConvertNode(WidenVT, InVal);
6080 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6081 for (
unsigned i=0; i < MinElts; ++i) {
6082 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6083 Ops[i] = MakeConvertNode(EltVT, Val);
6086 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6091 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6095 EVT SrcVT = Src.getValueType();
6099 Src = GetWidenedVector(Src);
6100 SrcVT = Src.getValueType();
6107 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6112 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6116 EVT SrcVT = Src.getValueType();
6120 Src = GetWidenedVector(Src);
6121 SrcVT = Src.getValueType();
6128 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6131SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6136 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6142 unsigned Opcode =
N->getOpcode();
6148 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6153 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6154 for (
unsigned i=0; i < MinElts; ++i) {
6155 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6156 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6160 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6162 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6165SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6166 unsigned Opcode =
N->getOpcode();
6170 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6179 InOp = GetWidenedVector(InOp);
6186 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6193 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6194 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6211 while (
Ops.size() != WidenNumElts)
6212 Ops.push_back(DAG.getPOISON(WidenSVT));
6214 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6220 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6221 return WidenVecRes_BinaryCanTrap(
N);
6224 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6231SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6233 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6236 SDValue Arg = GetWidenedVector(FpValue);
6237 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6242 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6243 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6245 EVT ExpVT =
RHS.getValueType();
6250 ExpOp = ModifyToType(
RHS, WideExpVT);
6253 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6258 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6259 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6260 if (
N->getNumOperands() == 1)
6261 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6263 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6268 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6273 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6274 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6275 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6278SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6280 EVT VT0 =
N->getValueType(0);
6281 EVT VT1 =
N->getValueType(1);
6285 "expected both results to be vectors of matching element count");
6287 LLVMContext &Ctx = *DAG.getContext();
6288 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6290 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6297 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6300 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6301 return SDValue(WidenNode, ResNo);
6304SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6305 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6306 return GetWidenedVector(WidenVec);
6311 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6321 InOp = GetWidenedVector(InOp);
6325 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6328 return DAG.getAddrSpaceCast(
DL, WidenVT, InOp,
6329 AddrSpaceCastN->getSrcAddressSpace(),
6330 AddrSpaceCastN->getDestAddressSpace());
6336 EVT VT =
N->getValueType(0);
6337 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6340 switch (getTypeAction(InVT)) {
6354 SDValue NInOp = GetPromotedInteger(InOp);
6356 if (WidenVT.
bitsEq(NInVT)) {
6359 if (DAG.getDataLayout().isBigEndian()) {
6362 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6380 InOp = GetWidenedVector(InOp);
6382 if (WidenVT.
bitsEq(InVT))
6392 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6397 unsigned NewNumParts = WidenSize / InSize;
6410 EVT OrigInVT =
N->getOperand(0).getValueType();
6415 if (TLI.isTypeLegal(NewInVT)) {
6423 if (WidenSize % InSize == 0) {
6430 DAG.ExtractVectorElements(InOp,
Ops);
6431 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6443 return CreateStackStoreLoad(InOp, WidenVT);
6446SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6448 N->getOpcode(), SDLoc(
N),
6449 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6450 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6456 EVT VT =
N->getValueType(0);
6460 EVT EltVT =
N->getOperand(0).getValueType();
6463 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6467 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6468 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6470 return DAG.getBuildVector(WidenVT, dl, NewOps);
6474 EVT InVT =
N->getOperand(0).getValueType();
6475 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6477 unsigned NumOperands =
N->getNumOperands();
6479 bool InputWidened =
false;
6483 if (WidenNumElts % NumInElts == 0) {
6485 unsigned NumConcat = WidenNumElts / NumInElts;
6486 SDValue UndefVal = DAG.getPOISON(InVT);
6488 for (
unsigned i=0; i < NumOperands; ++i)
6489 Ops[i] =
N->getOperand(i);
6490 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6495 InputWidened =
true;
6496 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6499 for (i=1; i < NumOperands; ++i)
6500 if (!
N->getOperand(i).isUndef())
6503 if (i == NumOperands)
6506 return GetWidenedVector(
N->getOperand(0));
6508 if (NumOperands == 2) {
6510 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6515 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6516 for (
unsigned i = 0; i < NumInElts; ++i) {
6518 MaskOps[i + NumInElts] = i + WidenNumElts;
6520 return DAG.getVectorShuffle(WidenVT, dl,
6521 GetWidenedVector(
N->getOperand(0)),
6522 GetWidenedVector(
N->getOperand(1)),
6529 SDValue WideVec = DAG.getPOISON(WidenVT);
6531 for (
unsigned I = 0;
I < NumOperands; ++
I)
6533 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6544 for (
unsigned i=0; i < NumOperands; ++i) {
6547 InOp = GetWidenedVector(InOp);
6548 for (
unsigned j = 0;
j < NumInElts; ++
j)
6549 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6551 SDValue UndefVal = DAG.getPOISON(EltVT);
6552 for (; Idx < WidenNumElts; ++Idx)
6553 Ops[Idx] = UndefVal;
6554 return DAG.getBuildVector(WidenVT, dl,
Ops);
6557SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6558 EVT VT =
N->getValueType(0);
6559 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6560 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6567SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6568 EVT VT =
N->getValueType(0);
6570 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6575 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6577 InOp = GetWidenedVector(InOp);
6583 if (IdxVal == 0 && InVT == WidenVT)
6590 assert(IdxVal % VTNumElts == 0 &&
6591 "Expected Idx to be a multiple of subvector minimum vector length");
6592 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6605 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6606 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6607 "down type's element count");
6614 for (;
I < VTNumElts / GCD; ++
I)
6616 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6617 for (;
I < WidenNumElts / GCD; ++
I)
6639 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6646 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6647 return DAG.getMaskedLoad(
6648 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6656 for (i = 0; i < VTNumElts; ++i)
6657 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6659 SDValue UndefVal = DAG.getPOISON(EltVT);
6660 for (; i < WidenNumElts; ++i)
6662 return DAG.getBuildVector(WidenVT, dl,
Ops);
6668 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6673SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6674 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6677 N->getOperand(1),
N->getOperand(2));
6686 "Load width must be less than or equal to first value type width");
6695 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6712 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6723 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6724 EVT LdVT =
LD->getMemoryVT();
6733 TypeSize WidthDiff = WidenWidth - LdWidth;
6736 std::optional<EVT> FirstVT =
6737 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6744 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6747 Chain, BasePtr,
LD->getMemOperand());
6751 FirstVTWidth, dl, DAG);
6769 if (!
LD->getMemoryVT().isByteSized()) {
6771 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6773 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6782 EVT VT =
LD->getValueType(0);
6783 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6784 EVT WideMaskVT = getSetCCResultType(WideVT);
6787 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6788 TLI.isTypeLegal(WideMaskVT)) {
6791 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6795 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6796 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6808 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6810 Result = GenWidenVectorLoads(LdChain, LD);
6817 if (LdChain.
size() == 1)
6818 NewChain = LdChain[0];
6824 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6835 SDValue NewLoad = DAG.getMaskedLoad(
6836 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6837 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6838 LD->getAddressingMode(),
LD->getExtensionType());
6848 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6850 SDValue EVL =
N->getVectorLength();
6857 "Unable to widen binary VP op");
6858 Mask = GetWidenedVector(Mask);
6859 assert(
Mask.getValueType().getVectorElementCount() ==
6860 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6861 .getVectorElementCount() &&
6862 "Unable to widen vector load");
6865 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6866 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6867 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6875 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6877 SDValue EVL =
N->getVectorLength();
6883 "Unable to widen binary VP op");
6884 Mask = GetWidenedVector(Mask);
6885 assert(
Mask.getValueType().getVectorElementCount() ==
6886 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6887 .getVectorElementCount() &&
6888 "Unable to widen vector load");
6890 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6891 Mask, EVL,
N->getMemOperand());
6904 "Unable to widen VP strided load");
6905 Mask = GetWidenedVector(Mask);
6907 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6908 assert(
Mask.getValueType().getVectorElementCount() ==
6910 "Data and mask vectors should have the same number of elements");
6912 SDValue Res = DAG.getStridedLoadVP(
6913 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6914 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6915 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6916 N->isExpandingLoad());
6924SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6929 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6931 Mask.getValueType().getVectorElementType(),
6934 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6935 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6936 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6938 WideMask, WidePassthru);
6942 EVT VT =
N->getValueType(0);
6943 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6945 EVT MaskVT =
Mask.getValueType();
6946 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6955 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6956 TLI.isTypeLegal(WideMaskVT) &&
6962 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6963 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6967 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6968 N->getMemoryVT(),
N->getMemOperand());
6972 if (!
N->getPassThru()->isUndef()) {
6976 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6977 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6978 DAG.getPOISON(WidenVT), EVL);
6989 Mask = ModifyToType(Mask, WideMaskVT,
true);
6991 SDValue Res = DAG.getMaskedLoad(
6992 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6993 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6994 ExtType,
N->isExpandingLoad());
7003 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7005 EVT MaskVT =
Mask.getValueType();
7006 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7014 Mask = ModifyToType(Mask, WideMaskVT,
true);
7019 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7020 Index = ModifyToType(Index, WideIndexVT);
7026 N->getMemoryVT().getScalarType(), WideEC);
7027 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7028 WideMemVT, dl,
Ops,
N->getMemOperand(),
7029 N->getIndexType(),
N->getExtensionType());
7038 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7046 N->getMemoryVT().getScalarType(), WideEC);
7047 Mask = GetWidenedMask(Mask, WideEC);
7050 Mask,
N->getVectorLength()};
7051 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7052 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7061 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7062 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7090 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7091 return N->getOperand(OpNo).getValueType();
7099 N =
N.getOperand(0);
7101 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7102 if (!
N->getOperand(i)->isUndef())
7104 N =
N.getOperand(0);
7108 N =
N.getOperand(0);
7110 N =
N.getOperand(0);
7137 { MaskVT, MVT::Other },
Ops);
7138 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7146 LLVMContext &Ctx = *DAG.getContext();
7149 if (MaskScalarBits < ToMaskScalBits) {
7153 }
else if (MaskScalarBits > ToMaskScalBits) {
7159 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7161 "Mask should have the right element size by now.");
7164 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7166 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7169 EVT SubVT =
Mask->getValueType(0);
7175 assert((
Mask->getValueType(0) == ToMaskVT) &&
7176 "A mask of ToMaskVT should have been produced by now.");
7186 LLVMContext &Ctx = *DAG.getContext();
7197 EVT CondVT =
Cond->getValueType(0);
7201 EVT VSelVT =
N->getValueType(0);
7213 EVT FinalVT = VSelVT;
7224 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7225 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7232 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7240 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7243 EVT ToMaskVT = VSelVT;
7250 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7266 if (ScalarBits0 != ScalarBits1) {
7267 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7268 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7280 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7281 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7282 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7285 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7293 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7298 unsigned Opcode =
N->getOpcode();
7300 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7301 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7302 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7304 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7310 Cond1 = GetWidenedVector(Cond1);
7318 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7319 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7324 Cond1 = ModifyToType(Cond1, CondWidenVT);
7327 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7328 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7330 if (Opcode == ISD::VP_MERGE)
7331 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7333 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7337 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7338 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7341 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7345 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7346 return DAG.getUNDEF(WidenVT);
7350 EVT VT =
N->getValueType(0);
7353 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7357 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7358 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7361 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7362 for (
unsigned i = 0; i != NumElts; ++i) {
7363 int Idx =
N->getMaskElt(i);
7364 if (Idx < (
int)NumElts)
7367 NewMask[i] = Idx - NumElts + WidenNumElts;
7369 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7373 EVT VT =
N->getValueType(0);
7377 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7378 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7384 unsigned IdxVal = WidenNumElts - VTNumElts;
7397 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7400 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7401 "down type's element count");
7404 for (; i < VTNumElts / GCD; ++i)
7406 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7407 for (; i < WidenNumElts / GCD; ++i)
7415 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7416 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7418 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7422SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7423 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7427void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7428 EVT VT =
N->getValueType(0);
7431 unsigned Factor =
N->getNumOperands();
7434 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7438 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7439 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7448 for (
unsigned Idx = 0; Idx != Factor; ++Idx)
7449 Slices[Idx] = Interleaved.
getValue(Idx);
7453 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7454 SDValue Narrow = DAG.getExtractSubvector(
7457 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7458 SetWidenedVector(
SDValue(
N, Idx), Wide);
7464 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7465 EVT SourceVT =
N->getOperand(0).getValueType();
7470 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7471 N->getOperand(0), 0);
7472 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7473 N->getOperand(2), 0);
7475 N->getOperand(1), WideMask,
N->getFlags());
7478void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7479 EVT VT =
N->getValueType(0);
7482 unsigned Factor =
N->getNumOperands();
7485 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7498 SDValue PackedWidenVec = DAG.getInsertSubvector(
7499 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7503 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7504 NewOps[Idx] = DAG.getExtractSubvector(
7505 DL, WidenVT, PackedWidenVec,
7512 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7517 assert(
N->getValueType(0).isVector() &&
7518 N->getOperand(0).getValueType().isVector() &&
7519 "Operands must be vectors");
7520 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7533 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7534 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7541 InOp1 = GetWidenedVector(InOp1);
7542 InOp2 = GetWidenedVector(InOp2);
7545 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7556 "Input not widened to expected type!");
7558 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7563 assert(
N->getValueType(0).isVector() &&
7564 N->getOperand(1).getValueType().isVector() &&
7565 "Operands must be vectors");
7566 EVT VT =
N->getValueType(0);
7567 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7577 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7582 for (
unsigned i = 0; i != NumElts; ++i) {
7583 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7584 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7586 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7587 {Chain, LHSElem, RHSElem, CC});
7588 Chains[i] = Scalars[i].getValue(1);
7589 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7590 DAG.getBoolConstant(
true, dl, EltVT, VT),
7591 DAG.getBoolConstant(
false, dl, EltVT, VT));
7595 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7597 return DAG.getBuildVector(WidenVT, dl, Scalars);
7600SDValue DAGTypeLegalizer::WidenVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N) {
7602 EVT VT =
N->getValueType(0);
7605 SDValue Expanded = TLI.expandPartialReduceMLA(
N, DAG);
7606 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7607 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WideVT), Expanded, 0);
7613bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7614 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7618 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7621 switch (
N->getOpcode()) {
7624 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7632 Res = WidenVecOp_FAKE_USE(
N);
7638 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7642 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7643 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7644 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7649 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7651 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7652 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7654 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7655 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7665 Res = WidenVecOp_UnrollVectorOp(
N);
7672 Res = WidenVecOp_EXTEND(
N);
7677 Res = WidenVecOp_CMP(
N);
7695 Res = WidenVecOp_Convert(
N);
7700 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7720 Res = WidenVecOp_VECREDUCE(
N);
7724 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7726 case ISD::VP_REDUCE_FADD:
7727 case ISD::VP_REDUCE_SEQ_FADD:
7728 case ISD::VP_REDUCE_FMUL:
7729 case ISD::VP_REDUCE_SEQ_FMUL:
7730 case ISD::VP_REDUCE_ADD:
7731 case ISD::VP_REDUCE_MUL:
7732 case ISD::VP_REDUCE_AND:
7733 case ISD::VP_REDUCE_OR:
7734 case ISD::VP_REDUCE_XOR:
7735 case ISD::VP_REDUCE_SMAX:
7736 case ISD::VP_REDUCE_SMIN:
7737 case ISD::VP_REDUCE_UMAX:
7738 case ISD::VP_REDUCE_UMIN:
7739 case ISD::VP_REDUCE_FMAX:
7740 case ISD::VP_REDUCE_FMIN:
7741 case ISD::VP_REDUCE_FMAXIMUM:
7742 case ISD::VP_REDUCE_FMINIMUM:
7743 Res = WidenVecOp_VP_REDUCE(
N);
7747 Res = WidenVecOp_CttzElements(
N);
7749 case ISD::VP_CTTZ_ELTS:
7750 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7751 Res = WidenVecOp_VP_CttzElements(
N);
7754 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7757 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
7762 if (!Res.
getNode())
return false;
7770 if (
N->isStrictFPOpcode())
7772 "Invalid operand expansion");
7775 "Invalid operand expansion");
7777 ReplaceValueWith(
SDValue(
N, 0), Res);
7783 EVT VT =
N->getValueType(0);
7788 "Unexpected type action");
7789 InOp = GetWidenedVector(InOp);
7792 "Input wasn't widened!");
7800 EVT FixedEltVT = FixedVT.getVectorElementType();
7801 if (TLI.isTypeLegal(FixedVT) &&
7803 FixedEltVT == InEltVT) {
7805 "Not enough elements in the fixed type for the operand!");
7807 "We can't have the same type as we started with!");
7809 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7811 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7820 return WidenVecOp_Convert(
N);
7825 switch (
N->getOpcode()) {
7840 EVT OpVT =
N->getOperand(0).getValueType();
7841 EVT ResVT =
N->getValueType(0);
7848 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7849 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7855 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7856 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7858 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7865 return DAG.UnrollVectorOp(
N);
7870 EVT ResultVT =
N->getValueType(0);
7872 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7875 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7881 {WideArg,
Test},
N->getFlags());
7887 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7889 EVT OpVT =
N->getOperand(0).getValueType();
7892 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7897 EVT VT =
N->getValueType(0);
7903 "Unexpected type action");
7904 InOp = GetWidenedVector(InOp);
7906 unsigned Opcode =
N->getOpcode();
7911 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7914 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7915 return DAG.getNode(Opcode, dl, VT,
Op);
7922 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7924 if (
N->isStrictFPOpcode()) {
7926 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7929 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7930 {
N->getOperand(0), InOp });
7935 Res = MakeConvertNode(WideVT, InOp);
7937 return DAG.getExtractSubvector(dl, VT, Res, 0);
7945 if (
N->isStrictFPOpcode()) {
7948 for (
unsigned i=0; i < NumElts; ++i) {
7949 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7950 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7954 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7956 for (
unsigned i = 0; i < NumElts; ++i) {
7957 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7958 Ops[i] = MakeConvertNode(EltVT, Elt);
7962 return DAG.getBuildVector(VT, dl,
Ops);
7966 EVT DstVT =
N->getValueType(0);
7967 SDValue Src = GetWidenedVector(
N->getOperand(0));
7968 EVT SrcVT = Src.getValueType();
7975 if (TLI.isTypeLegal(WideDstVT)) {
7977 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7980 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7984 return DAG.UnrollVectorOp(
N);
7988 EVT VT =
N->getValueType(0);
7989 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7997 if (!VT.
isVector() && VT != MVT::x86mmx &&
8001 if (TLI.isTypeLegal(NewVT)) {
8003 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8015 ElementCount NewNumElts =
8017 .divideCoefficientBy(EltSize);
8019 if (TLI.isTypeLegal(NewVT)) {
8021 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8026 return CreateStackStoreLoad(InOp, VT);
8034 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8035 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8040 EVT VT =
N->getValueType(0);
8042 EVT InVT =
N->getOperand(0).getValueType();
8047 unsigned NumOperands =
N->getNumOperands();
8048 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8050 for (i = 1; i < NumOperands; ++i)
8051 if (!
N->getOperand(i).isUndef())
8054 if (i == NumOperands)
8055 return GetWidenedVector(
N->getOperand(0));
8065 for (
unsigned i=0; i < NumOperands; ++i) {
8069 "Unexpected type action");
8070 InOp = GetWidenedVector(InOp);
8071 for (
unsigned j = 0;
j < NumInElts; ++
j)
8072 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8074 return DAG.getBuildVector(VT, dl,
Ops);
8077SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8078 EVT VT =
N->getValueType(0);
8083 SubVec = GetWidenedVector(SubVec);
8088 bool IndicesValid =
false;
8091 IndicesValid =
true;
8095 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8096 Attribute::VScaleRange);
8101 IndicesValid =
true;
8107 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8113 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8120 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8142 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8150 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8151 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8156 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8161 unsigned Idx =
N->getConstantOperandVal(2);
8167 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8173SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8174 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8176 N->getValueType(0), InOp,
N->getOperand(1));
8179SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8180 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8182 N->getValueType(0), InOp,
N->getOperand(1));
8185SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8187 EVT ResVT =
N->getValueType(0);
8190 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8196 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8204 "Widened input size must be a multiple of result element size");
8207 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8209 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8210 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8218 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8219 return TLI.scalarizeVectorStore(ST, DAG);
8221 if (
ST->isTruncatingStore())
8222 return TLI.scalarizeVectorStore(ST, DAG);
8232 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8233 EVT WideMaskVT = getSetCCResultType(WideVT);
8235 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8236 TLI.isTypeLegal(WideMaskVT)) {
8239 StVal = GetWidenedVector(StVal);
8241 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8243 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8244 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8245 ST->getAddressingMode());
8249 if (GenWidenVectorStores(StChain, ST)) {
8250 if (StChain.
size() == 1)
8259 SDValue WideStVal = GetWidenedVector(StVal);
8263 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8264 ST->getOffset(), Mask,
ST->getMemoryVT(),
8265 ST->getMemOperand(),
ST->getAddressingMode(),
8266 ST->isTruncatingStore());
8273 EVT StVT =
ST->getMemoryVT();
8276 SDValue StVal = GetWidenedVector(
ST->getVal());
8281 TypeSize WidthDiff = WidenWidth - StWidth;
8287 std::optional<EVT> FirstVT =
8288 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8293 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8299 ST->getBasePtr(),
ST->getMemOperand());
8302SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8303 assert((OpNo == 1 || OpNo == 3) &&
8304 "Can widen only data or mask operand of vp_store");
8312 StVal = GetWidenedVector(StVal);
8318 "Unable to widen VP store");
8319 Mask = GetWidenedVector(Mask);
8321 Mask = GetWidenedVector(Mask);
8327 "Unable to widen VP store");
8328 StVal = GetWidenedVector(StVal);
8331 assert(
Mask.getValueType().getVectorElementCount() ==
8333 "Mask and data vectors should have the same number of elements");
8334 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8335 ST->getOffset(), Mask,
ST->getVectorLength(),
8336 ST->getMemoryVT(),
ST->getMemOperand(),
8337 ST->getAddressingMode(),
ST->isTruncatingStore(),
8338 ST->isCompressingStore());
8343 assert((OpNo == 1 || OpNo == 4) &&
8344 "Can widen only data or mask operand of vp_strided_store");
8353 "Unable to widen VP strided store");
8357 "Unable to widen VP strided store");
8359 StVal = GetWidenedVector(StVal);
8360 Mask = GetWidenedVector(Mask);
8363 Mask.getValueType().getVectorElementCount() &&
8364 "Data and mask vectors should have the same number of elements");
8366 return DAG.getStridedStoreVP(
8373SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8374 assert((OpNo == 1 || OpNo == 4) &&
8375 "Can widen only data or mask operand of mstore");
8378 EVT MaskVT =
Mask.getValueType();
8383 EVT WideVT, WideMaskVT;
8386 StVal = GetWidenedVector(StVal);
8393 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8400 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8402 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8403 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8412 Mask = ModifyToType(Mask, WideMaskVT,
true);
8415 Mask = ModifyToType(Mask, WideMaskVT,
true);
8417 StVal = ModifyToType(StVal, WideVT);
8420 assert(
Mask.getValueType().getVectorElementCount() ==
8422 "Mask and data vectors should have the same number of elements");
8429SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8430 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8432 SDValue DataOp = MG->getPassThru();
8434 SDValue Scale = MG->getScale();
8442 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8443 MG->getMemOperand(), MG->getIndexType(),
8444 MG->getExtensionType());
8450SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8459 DataOp = GetWidenedVector(DataOp);
8463 EVT IndexVT =
Index.getValueType();
8466 Index = ModifyToType(Index, WideIndexVT);
8469 EVT MaskVT =
Mask.getValueType();
8472 Mask = ModifyToType(Mask, WideMaskVT,
true);
8477 }
else if (OpNo == 4) {
8479 Index = GetWidenedVector(Index);
8485 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8490SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8499 DataOp = GetWidenedVector(DataOp);
8500 Index = GetWidenedVector(Index);
8502 Mask = GetWidenedMask(Mask, WideEC);
8505 }
else if (OpNo == 3) {
8507 Index = GetWidenedVector(Index);
8514 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8519 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8520 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8522 EVT VT =
N->getValueType(0);
8537 SVT, InOp0, InOp1,
N->getOperand(2));
8543 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8545 EVT OpVT =
N->getOperand(0).getValueType();
8548 return DAG.getNode(ExtendCode, dl, VT, CC);
8558 EVT VT =
N->getValueType(0);
8560 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8567 for (
unsigned i = 0; i != NumElts; ++i) {
8568 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8569 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8571 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8572 {Chain, LHSElem, RHSElem, CC});
8573 Chains[i] = Scalars[i].getValue(1);
8574 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8575 DAG.getBoolConstant(
true, dl, EltVT, VT),
8576 DAG.getBoolConstant(
false, dl, EltVT, VT));
8580 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8582 return DAG.getBuildVector(VT, dl, Scalars);
8606 SDValue Op = GetWidenedVector(
N->getOperand(0));
8607 EVT VT =
N->getValueType(0);
8608 EVT OrigVT =
N->getOperand(0).getValueType();
8609 EVT WideVT =
Op.getValueType();
8611 SDNodeFlags
Flags =
N->getFlags();
8613 unsigned Opc =
N->getOpcode();
8615 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8616 assert(NeutralElem &&
"Neutral element must exist");
8626 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8633 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8634 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8640 unsigned GCD = std::gcd(OrigElts, WideElts);
8643 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8644 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8645 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8646 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8649 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8650 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8652 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8661 EVT VT =
N->getValueType(0);
8663 EVT WideVT =
Op.getValueType();
8665 SDNodeFlags
Flags =
N->getFlags();
8667 unsigned Opc =
N->getOpcode();
8669 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8679 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8682 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8683 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8689 unsigned GCD = std::gcd(OrigElts, WideElts);
8692 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8693 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8694 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8695 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8698 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8699 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8701 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8705 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8708 SDValue Op = GetWidenedVector(
N->getOperand(1));
8710 Op.getValueType().getVectorElementCount());
8712 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8713 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8721 EVT VT =
N->getValueType(0);
8725 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8726 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8731 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8737 EVT SourceVT =
Source.getValueType();
8738 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8742 WideSource = GetWidenedVector(Source);
8749 WideSource = GetWidenedVector(Source);
8751 SmallVector<int>
Mask(WideElts);
8752 std::iota(
Mask.begin(),
Mask.end(), 0);
8754 Mask[
I] += WideElts;
8755 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
8757 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8761 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8768 EVT SrcVT =
Source.getValueType();
8772 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8773 {Source, Mask, N->getOperand(2)},
N->getFlags());
8776SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8779 EVT OrigMaskVT =
Mask.getValueType();
8780 SDValue WideMask = GetWidenedVector(Mask);
8786 if (OrigElts != WideElts) {
8787 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8789 Mask, DAG.getVectorIdxConstant(0,
DL));
8796SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
8799 EVT ResVT =
N->getValueType(0);
8800 EVT SourceVT =
N->getOperand(0).getValueType();
8801 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8806 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
8807 N->getOperand(0), 0);
8808 SDValue WideMask = DAG.getInsertSubvector(
8809 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
8811 N->getOperand(1), WideMask,
N->getFlags());
8812 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
8816 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
8822 return TLI.expandVectorMatch(
N, DAG);
8824 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
8828 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
8829 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
8832 N->getOperand(0), WideNeedle,
N->getOperand(2),
8850 unsigned WidenEx = 0) {
8855 unsigned AlignInBits =
Align*8;
8857 EVT RetVT = WidenEltVT;
8862 if (Width == WidenEltWidth)
8873 (WidenWidth % MemVTWidth) == 0 &&
8875 (MemVTWidth <= Width ||
8876 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8877 if (MemVTWidth == WidenWidth)
8896 (WidenWidth % MemVTWidth) == 0 &&
8898 (MemVTWidth <= Width ||
8899 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8908 return std::nullopt;
8919 unsigned Start,
unsigned End) {
8920 SDLoc dl(LdOps[Start]);
8921 EVT LdTy = LdOps[Start].getValueType();
8929 for (
unsigned i = Start + 1; i != End; ++i) {
8930 EVT NewLdTy = LdOps[i].getValueType();
8931 if (NewLdTy != LdTy) {
8950 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8951 EVT LdVT =
LD->getMemoryVT();
8961 AAMDNodes AAInfo =
LD->getAAInfo();
8965 TypeSize WidthDiff = WidenWidth - LdWidth;
8972 std::optional<EVT> FirstVT =
8973 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8980 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8985 std::optional<EVT> NewVT = FirstVT;
8986 TypeSize RemainingWidth = LdWidth;
8987 TypeSize NewVTWidth = FirstVTWidth;
8989 RemainingWidth -= NewVTWidth;
8996 NewVTWidth = NewVT->getSizeInBits();
9002 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9003 LD->getBaseAlign(), MMOFlags, AAInfo);
9016 MachinePointerInfo MPI =
LD->getPointerInfo();
9022 for (EVT MemVT : MemVTs) {
9023 Align NewAlign = ScaledOffset == 0
9024 ?
LD->getBaseAlign()
9027 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
9035 unsigned End = LdOps.
size();
9046 EVT LdTy = LdOps[i].getValueType();
9049 for (--i; i >= 0; --i) {
9050 LdTy = LdOps[i].getValueType();
9057 ConcatOps[--Idx] = LdOps[i];
9058 for (--i; i >= 0; --i) {
9059 EVT NewLdTy = LdOps[i].getValueType();
9060 if (NewLdTy != LdTy) {
9070 for (;
j != End-Idx; ++
j)
9071 WidenOps[j] = ConcatOps[Idx+j];
9073 WidenOps[j] = DAG.getPOISON(LdTy);
9080 ConcatOps[--Idx] = LdOps[i];
9085 ArrayRef(&ConcatOps[Idx], End - Idx));
9091 SDValue UndefVal = DAG.getPOISON(LdTy);
9094 for (; i != End-Idx; ++i)
9095 WidenOps[i] = ConcatOps[Idx+i];
9097 WidenOps[i] = UndefVal;
9108 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9109 EVT LdVT =
LD->getMemoryVT();
9118 AAMDNodes AAInfo =
LD->getAAInfo();
9132 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9133 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9139 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9140 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9141 LD->getBaseAlign(), MMOFlags, AAInfo);
9146 SDValue UndefVal = DAG.getPOISON(EltVT);
9147 for (; i != WidenNumElts; ++i)
9150 return DAG.getBuildVector(WidenVT, dl,
Ops);
9161 AAMDNodes AAInfo =
ST->getAAInfo();
9162 SDValue ValOp = GetWidenedVector(
ST->getValue());
9165 EVT StVT =
ST->getMemoryVT();
9173 "Mismatch between store and value types");
9177 MachinePointerInfo MPI =
ST->getPointerInfo();
9187 std::optional<EVT> NewVT =
9192 TypeSize NewVTWidth = NewVT->getSizeInBits();
9195 StWidth -= NewVTWidth;
9196 MemVTs.
back().second++;
9200 for (
const auto &Pair : MemVTs) {
9201 EVT NewVT = Pair.first;
9202 unsigned Count = Pair.second;
9208 Align NewAlign = ScaledOffset == 0
9209 ?
ST->getBaseAlign()
9211 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9212 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9228 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9229 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9230 ST->getBaseAlign(), MMOFlags, AAInfo);
9247 bool FillWithZeroes) {
9252 "input and widen element type must match");
9254 "cannot modify scalable vectors in this way");
9267 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9269 for (
unsigned i = 1; i != NumConcat; ++i)
9276 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9282 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9287 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9288 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9290 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9292 unsigned NumResultParts = NewNumElts / CommonFactor;
9293 if (NumResultParts > NumCopiedParts) {
9294 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9295 : DAG.getPOISON(PartVT);
9296 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9303 "Scalable vectors should have been handled already.");
9311 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9313 for (Idx = 0; Idx < MinNumElts; ++Idx)
9314 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9316 SDValue UndefVal = DAG.getPOISON(EltVT);
9317 for (; Idx < WidenNumElts; ++Idx)
9318 Ops[Idx] = UndefVal;
9320 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9321 if (!FillWithZeroes)
9325 "We expect to never want to FillWithZeroes for non-integral types.");
9328 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9329 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9331 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9332 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
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtractVectorElt(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Extract element at Idx from Vec.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr LeafTy multiplyCoefficientBy(ScalarTy RHS) const
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_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
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.
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.