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(
2710 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2720 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2723 MachinePointerInfo MPI;
2730 MMO = DAG.getMachineFunction().getMachineMemOperand(
2734 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2746 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2754 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2764 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2767 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2770 EVT MemoryVT =
N->getMemoryVT();
2776 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2778 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2781 EVT LoMemVT, HiMemVT;
2783 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2786 if (getTypeAction(
Ops.Index.getValueType()) ==
2788 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2790 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2793 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2795 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2798 SDValue PassThru = MGT->getPassThru();
2799 SDValue PassThruLo, PassThruHi;
2802 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2804 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2809 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2810 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2811 OpsLo, MMO, IndexTy, ExtType);
2813 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2814 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2815 OpsHi, MMO, IndexTy, ExtType);
2819 std::tie(EVLLo, EVLHi) =
2820 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2822 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2823 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2824 MMO, VPGT->getIndexType());
2826 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2827 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2828 MMO, VPGT->getIndexType());
2838 ReplaceValueWith(
SDValue(
N, 1), Ch);
2852 EVT VecVT =
N->getValueType(0);
2854 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2855 bool HasCustomLowering =
false;
2862 HasCustomLowering =
true;
2868 SDValue Passthru =
N->getOperand(2);
2869 if (!HasCustomLowering) {
2870 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2871 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2878 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2879 std::tie(LoMask, HiMask) = SplitMask(Mask);
2881 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2886 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2899 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2901 SDValue Chain = DAG.getEntryNode();
2902 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2906 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2911 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2915 assert(
N->getValueType(0).isVector() &&
2916 N->getOperand(0).getValueType().isVector() &&
2917 "Operand types must be vectors");
2921 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2925 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2927 GetSplitVector(
N->getOperand(0), LL, LH);
2929 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2931 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2933 GetSplitVector(
N->getOperand(1), RL, RH);
2935 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2937 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2938 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2946 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2950 EVT InVT =
N->getOperand(0).getValueType();
2952 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2954 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2956 const SDNodeFlags
Flags =
N->getFlags();
2957 unsigned Opcode =
N->getOpcode();
2959 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
2960 N->getOperand(3), Flags);
2961 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
2962 N->getOperand(3), Flags);
2968 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2969 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2971 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2972 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2979 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2983 EVT InVT =
N->getOperand(0).getValueType();
2985 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2987 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2990 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2991 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2992 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2993 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2996void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3001 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3002 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3006 EVT InVT =
N->getOperand(0).getValueType();
3008 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3010 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3012 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3013 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3015 SDNode *HiNode =
Hi.getNode();
3016 SDNode *LoNode =
Lo.getNode();
3019 unsigned OtherNo = 1 - ResNo;
3020 EVT OtherVT =
N->getValueType(OtherNo);
3028 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3035 EVT SrcVT =
N->getOperand(0).getValueType();
3036 EVT DestVT =
N->getValueType(0);
3038 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3055 LLVMContext &Ctx = *DAG.getContext();
3059 EVT SplitLoVT, SplitHiVT;
3060 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3061 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3062 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3063 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3064 N->dump(&DAG);
dbgs() <<
"\n");
3067 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3069 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3071 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3072 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3077 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3085 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3086 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3092 return N.getResNo() == 0 &&
3096 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3098 ArrayRef<int>
Mask) {
3101 "Expected build vector node.");
3104 for (
unsigned I = 0;
I < NewElts; ++
I) {
3107 unsigned Idx =
Mask[
I];
3109 Ops[
I] = Input2.getOperand(Idx - NewElts);
3111 Ops[
I] = Input1.getOperand(Idx);
3116 return DAG.getBuildVector(NewVT,
DL,
Ops);
3122 SmallVector<int> OrigMask(
N->getMask());
3124 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3125 &
DL](SmallVectorImpl<int> &
Mask) {
3127 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3128 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3139 for (
auto &
P : ShufflesIdxs) {
3140 if (
P.second.size() < 2)
3144 for (
int &Idx : Mask) {
3147 unsigned SrcRegIdx = Idx / NewElts;
3148 if (Inputs[SrcRegIdx].
isUndef()) {
3156 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3161 Idx = MaskElt % NewElts +
3162 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3168 Inputs[
P.second[0]] =
P.first.first;
3169 Inputs[
P.second[1]] =
P.first.second;
3172 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3175 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3176 for (
int &Idx : Mask) {
3179 unsigned SrcRegIdx = Idx / NewElts;
3180 if (Inputs[SrcRegIdx].
isUndef()) {
3187 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3188 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3191 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3193 if (UsedSubVector.count() > 1) {
3195 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3196 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3198 if (Pairs.
empty() || Pairs.
back().size() == 2)
3200 if (UsedSubVector.test(2 *
I)) {
3201 Pairs.
back().emplace_back(
I, 0);
3203 assert(UsedSubVector.test(2 *
I + 1) &&
3204 "Expected to be used one of the subvectors.");
3205 Pairs.
back().emplace_back(
I, 1);
3208 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3210 for (
int &Idx : Mask) {
3213 unsigned SrcRegIdx = Idx / NewElts;
3215 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3216 return Idxs.front().first == SrcRegIdx ||
3217 Idxs.back().first == SrcRegIdx;
3219 if (It == Pairs.
end())
3221 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3222 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3225 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3226 Inputs[Idxs.front().first] = DAG.
getNode(
3228 Inputs[Idxs.front().first].getValueType(),
3229 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3230 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3239 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3243 if (Shuffle->getOperand(0).getValueType() != NewVT)
3246 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3247 !Shuffle->isSplat()) {
3249 }
else if (!Inputs[
I].hasOneUse() &&
3250 !Shuffle->getOperand(1).isUndef()) {
3252 for (
int &Idx : Mask) {
3255 unsigned SrcRegIdx = Idx / NewElts;
3258 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3263 int OpIdx = MaskElt / NewElts;
3276 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3277 if (Shuffle->getOperand(OpIdx).isUndef())
3279 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3280 if (It == std::end(Inputs))
3282 int FoundOp = std::distance(std::begin(Inputs), It);
3285 for (
int &Idx : Mask) {
3288 unsigned SrcRegIdx = Idx / NewElts;
3291 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3296 int MaskIdx = MaskElt / NewElts;
3297 if (OpIdx == MaskIdx)
3298 Idx = MaskElt % NewElts + FoundOp * NewElts;
3301 Op = (OpIdx + 1) % 2;
3309 for (
int &Idx : Mask) {
3312 unsigned SrcRegIdx = Idx / NewElts;
3315 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3316 int OpIdx = MaskElt / NewElts;
3319 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3325 TryPeekThroughShufflesInputs(OrigMask);
3327 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3328 NewElts](SmallVectorImpl<int> &
Mask) {
3329 SetVector<SDValue> UniqueInputs;
3330 SetVector<SDValue> UniqueConstantInputs;
3331 for (
const auto &
I : Inputs) {
3333 UniqueConstantInputs.
insert(
I);
3334 else if (!
I.isUndef())
3339 if (UniqueInputs.
size() != std::size(Inputs)) {
3340 auto &&UniqueVec = UniqueInputs.
takeVector();
3341 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3342 unsigned ConstNum = UniqueConstantVec.size();
3343 for (
int &Idx : Mask) {
3346 unsigned SrcRegIdx = Idx / NewElts;
3347 if (Inputs[SrcRegIdx].
isUndef()) {
3351 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3352 if (It != UniqueConstantVec.end()) {
3353 Idx = (Idx % NewElts) +
3354 NewElts * std::distance(UniqueConstantVec.begin(), It);
3355 assert(Idx >= 0 &&
"Expected defined mask idx.");
3358 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3359 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3360 Idx = (Idx % NewElts) +
3361 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3362 assert(Idx >= 0 &&
"Expected defined mask idx.");
3364 copy(UniqueConstantVec, std::begin(Inputs));
3365 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3368 MakeUniqueInputs(OrigMask);
3370 copy(Inputs, std::begin(OrigInputs));
3376 unsigned FirstMaskIdx =
High * NewElts;
3379 assert(!Output &&
"Expected default initialized initial value.");
3380 TryPeekThroughShufflesInputs(Mask);
3381 MakeUniqueInputs(Mask);
3383 copy(Inputs, std::begin(TmpInputs));
3386 bool SecondIteration =
false;
3387 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3392 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3393 SecondIteration =
true;
3394 return SecondIteration;
3397 Mask, std::size(Inputs), std::size(Inputs),
3399 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3400 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3401 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3403 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3405 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3406 DAG.getPOISON(NewVT), Mask);
3407 Inputs[Idx] = Output;
3409 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3410 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3411 unsigned Idx2,
bool ) {
3412 if (AccumulateResults(Idx1)) {
3415 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3417 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3418 Inputs[Idx2], Mask);
3422 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3424 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3425 TmpInputs[Idx2], Mask);
3427 Inputs[Idx1] = Output;
3429 copy(OrigInputs, std::begin(Inputs));
3434 EVT OVT =
N->getValueType(0);
3442 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3444 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV,
Alignment.value());
3445 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV,
Alignment.value());
3450 ReplaceValueWith(
SDValue(
N, 1), Chain);
3455 EVT DstVTLo, DstVTHi;
3456 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3460 EVT SrcVT =
N->getOperand(0).getValueType();
3462 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3464 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3466 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3467 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3473 GetSplitVector(
N->getOperand(0), InLo, InHi);
3484 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3485 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3490 EVT VT =
N->getValueType(0);
3513 EVT PtrVT =
StackPtr.getValueType();
3514 auto &MF = DAG.getMachineFunction();
3518 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3521 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3527 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3528 DAG.getConstant(1,
DL, PtrVT));
3530 DAG.getConstant(EltWidth,
DL, PtrVT));
3532 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3534 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3535 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3536 DAG.getPOISON(PtrVT), Stride, TrueMask,
3545 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3550 EVT VT =
N->getValueType(0);
3562 EVL1 = ZExtPromotedInteger(EVL1);
3581 EVT PtrVT =
StackPtr.getValueType();
3582 auto &MF = DAG.getMachineFunction();
3586 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3589 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3595 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3600 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3601 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3603 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3605 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3609 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3614 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3615 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3619 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3628 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3636 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3638 DAG.getVectorIdxConstant(0,
DL));
3644void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3652 GetSplitVector(Acc, AccLo, AccHi);
3653 unsigned Opcode =
N->getOpcode();
3665 GetSplitVector(Input1, Input1Lo, Input1Hi);
3666 GetSplitVector(Input2, Input2Lo, Input2Hi);
3669 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3670 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3673void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3681 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3692 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3694 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3698 N->getOperand(1), MaskLo,
N->getFlags());
3700 N->getOperand(1), MaskHi,
N->getFlags());
3703void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3704 unsigned Factor =
N->getNumOperands();
3707 for (
unsigned i = 0; i != Factor; ++i) {
3709 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3711 Ops[i * 2 + 1] = OpHi;
3722 for (
unsigned i = 0; i != Factor; ++i)
3726void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3727 unsigned Factor =
N->getNumOperands();
3730 for (
unsigned i = 0; i != Factor; ++i) {
3732 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3734 Ops[i + Factor] = OpHi;
3745 for (
unsigned i = 0; i != Factor; ++i) {
3746 unsigned IdxLo = 2 * i;
3747 unsigned IdxHi = 2 * i + 1;
3748 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3749 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3761bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3766 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3769 switch (
N->getOpcode()) {
3772 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3781 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3788 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3791 Res = SplitVecOp_TruncateHelper(
N);
3797 Res = SplitVecOp_FP_ROUND(
N);
3809 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3816 case ISD::VP_SCATTER:
3820 case ISD::VP_GATHER:
3824 Res = SplitVecOp_VSELECT(
N, OpNo);
3830 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3833 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3839 if (
N->getValueType(0).bitsLT(
3840 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3841 Res = SplitVecOp_TruncateHelper(
N);
3843 Res = SplitVecOp_UnaryOp(
N);
3847 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3863 Res = SplitVecOp_UnaryOp(
N);
3866 Res = SplitVecOp_FPOpDifferentTypes(
N);
3871 Res = SplitVecOp_CMP(
N);
3875 Res = SplitVecOp_FAKE_USE(
N);
3880 Res = SplitVecOp_ExtVecInRegOp(
N);
3900 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3904 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3906 case ISD::VP_REDUCE_FADD:
3907 case ISD::VP_REDUCE_SEQ_FADD:
3908 case ISD::VP_REDUCE_FMUL:
3909 case ISD::VP_REDUCE_SEQ_FMUL:
3910 case ISD::VP_REDUCE_ADD:
3911 case ISD::VP_REDUCE_MUL:
3912 case ISD::VP_REDUCE_AND:
3913 case ISD::VP_REDUCE_OR:
3914 case ISD::VP_REDUCE_XOR:
3915 case ISD::VP_REDUCE_SMAX:
3916 case ISD::VP_REDUCE_SMIN:
3917 case ISD::VP_REDUCE_UMAX:
3918 case ISD::VP_REDUCE_UMIN:
3919 case ISD::VP_REDUCE_FMAX:
3920 case ISD::VP_REDUCE_FMIN:
3921 case ISD::VP_REDUCE_FMAXIMUM:
3922 case ISD::VP_REDUCE_FMINIMUM:
3923 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3927 Res = SplitVecOp_CttzElts(
N);
3929 case ISD::VP_CTTZ_ELTS:
3930 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3931 Res = SplitVecOp_VP_CttzElements(
N);
3934 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3940 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3943 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
3948 if (!Res.
getNode())
return false;
3955 if (
N->isStrictFPOpcode())
3957 "Invalid operand expansion");
3960 "Invalid operand expansion");
3962 ReplaceValueWith(
SDValue(
N, 0), Res);
3966SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3970 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3972 EVT VT =
N->getValueType(0);
3985 getSetCCResultType(MVT::i1), MVT::i1);
3990 DAG.getElementCount(
DL, VT, SplitEC)),
3994SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3997 assert(OpNo == 0 &&
"Illegal operand must be mask");
4004 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4007 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4008 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4009 "Lo and Hi have differing types");
4012 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4013 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4015 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4016 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4017 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4018 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4028SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4029 assert(OpNo == 2 &&
"Illegal operand must be mask");
4032 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4033 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4035 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4038 RHSLo, MaskLo,
N->getFlags());
4040 RHSHi, MaskHi,
N->getFlags());
4044SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4047 assert(OpNo == 1 &&
"Illegal operand must be mask");
4052 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4054 EVT VecVT =
N->getValueType(0);
4058SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4059 EVT ResVT =
N->getValueType(0);
4065 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4066 GetSplitVector(VecOp,
Lo,
Hi);
4068 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4073 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4074 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4078 EVT ResVT =
N->getValueType(0);
4084 SDNodeFlags
Flags =
N->getFlags();
4087 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4088 GetSplitVector(VecOp,
Lo,
Hi);
4090 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4096 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4099SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4100 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4101 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4103 unsigned Opc =
N->getOpcode();
4104 EVT ResVT =
N->getValueType(0);
4110 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4111 GetSplitVector(VecOp,
Lo,
Hi);
4114 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4117 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4119 const SDNodeFlags
Flags =
N->getFlags();
4123 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4128 EVT ResVT =
N->getValueType(0);
4131 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4132 EVT InVT =
Lo.getValueType();
4137 if (
N->isStrictFPOpcode()) {
4138 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4139 {N->getOperand(0), Lo});
4140 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4141 {N->getOperand(0), Hi});
4150 ReplaceValueWith(
SDValue(
N, 1), Ch);
4152 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4153 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4162 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4172 EVT ResVT =
N->getValueType(0);
4174 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4178 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4184 Lo = BitConvertToInteger(
Lo);
4185 Hi = BitConvertToInteger(
Hi);
4187 if (DAG.getDataLayout().isBigEndian())
4195 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4197 EVT ResVT =
N->getValueType(0);
4205 GetSplitVector(SubVec,
Lo,
Hi);
4214 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4216 return SecondInsertion;
4219SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4226 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4228 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4230 ElementCount IdxVal =
4234 EVT SrcVT =
N->getOperand(0).getValueType();
4253 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4254 LoEltsMin - IdxValMin);
4255 DAG.ExtractVectorElements(
Hi, Elts, 0,
4258 return DAG.getBuildVector(SubVT, dl, Elts);
4262 ElementCount ExtractIdx = IdxVal - LoElts;
4264 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4267 EVT HiVT =
Hi.getValueType();
4269 "Only fixed-vector extracts are supported in this case");
4279 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4280 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4286 "Extracting scalable subvector from fixed-width unsupported");
4294 "subvector from a scalable predicate vector");
4300 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4302 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4303 auto &MF = DAG.getMachineFunction();
4307 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4311 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4314 SubVT, dl,
Store, StackPtr,
4318SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4327 GetSplitVector(Vec,
Lo,
Hi);
4329 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4331 if (IdxVal < LoElts)
4332 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4335 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4340 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4352 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4358 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4360 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4361 auto &MF = DAG.getMachineFunction();
4364 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4368 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4372 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4374 return DAG.getExtLoad(
4385 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4393 SplitVecRes_Gather(
N,
Lo,
Hi);
4396 ReplaceValueWith(
SDValue(
N, 0), Res);
4401 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4405 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4407 SDValue EVL =
N->getVectorLength();
4415 GetSplitVector(
Data, DataLo, DataHi);
4417 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4422 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4425 GetSplitVector(Mask, MaskLo, MaskHi);
4427 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4430 EVT MemoryVT =
N->getMemoryVT();
4431 EVT LoMemVT, HiMemVT;
4432 bool HiIsEmpty =
false;
4433 std::tie(LoMemVT, HiMemVT) =
4434 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4438 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4441 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4444 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4446 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4447 N->getAddressingMode(),
N->isTruncatingStore(),
4448 N->isCompressingStore());
4454 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4455 N->isCompressingStore());
4457 MachinePointerInfo MPI;
4461 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4466 MMO = DAG.getMachineFunction().getMachineMemOperand(
4468 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4470 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4471 N->getAddressingMode(),
N->isTruncatingStore(),
4472 N->isCompressingStore());
4481 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4482 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4489 GetSplitVector(
Data, LoData, HiData);
4491 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4493 EVT LoMemVT, HiMemVT;
4494 bool HiIsEmpty =
false;
4495 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4501 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4502 else if (getTypeAction(
Mask.getValueType()) ==
4504 GetSplitVector(Mask, LoMask, HiMask);
4506 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4509 std::tie(LoEVL, HiEVL) =
4510 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4514 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4515 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4516 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4527 EVT PtrVT =
N->getBasePtr().getValueType();
4530 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4538 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4539 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4541 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4544 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4545 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4546 N->isCompressingStore());
4555 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4559 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4568 GetSplitVector(
Data, DataLo, DataHi);
4570 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4575 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4578 GetSplitVector(Mask, MaskLo, MaskHi);
4580 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4583 EVT MemoryVT =
N->getMemoryVT();
4584 EVT LoMemVT, HiMemVT;
4585 bool HiIsEmpty =
false;
4586 std::tie(LoMemVT, HiMemVT) =
4587 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4590 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4593 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4595 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4596 N->getAddressingMode(),
N->isTruncatingStore(),
4597 N->isCompressingStore());
4605 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4606 N->isCompressingStore());
4608 MachinePointerInfo MPI;
4612 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4617 MMO = DAG.getMachineFunction().getMachineMemOperand(
4619 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4621 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4622 N->getAddressingMode(),
N->isTruncatingStore(),
4623 N->isCompressingStore());
4636 EVT MemoryVT =
N->getMemoryVT();
4646 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4650 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4655 EVT LoMemVT, HiMemVT;
4656 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4661 GetSplitVector(
Ops.Data, DataLo, DataHi);
4663 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4668 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4670 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4674 if (getTypeAction(
Ops.Index.getValueType()) ==
4676 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4678 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4682 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4684 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4687 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4689 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4690 MSC->getIndexType(), MSC->isTruncatingStore());
4695 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4696 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4697 MMO, MSC->getIndexType(),
4698 MSC->isTruncatingStore());
4702 std::tie(EVLLo, EVLHi) =
4703 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4705 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4706 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4707 VPSC->getIndexType());
4712 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4713 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4714 VPSC->getIndexType());
4718 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4719 assert(OpNo == 1 &&
"Can only split the stored value");
4722 bool isTruncating =
N->isTruncatingStore();
4725 EVT MemoryVT =
N->getMemoryVT();
4728 AAMDNodes AAInfo =
N->getAAInfo();
4730 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4732 EVT LoMemVT, HiMemVT;
4733 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4737 return TLI.scalarizeVectorStore(
N, DAG);
4740 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4741 Alignment, MMOFlags, AAInfo);
4743 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4746 MachinePointerInfo MPI;
4747 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4750 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4751 HiMemVT, Alignment, MMOFlags, AAInfo);
4753 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4760 LLVMContext &Ctx = *DAG.getContext();
4778 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4779 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4783 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4786 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4787 DAG.getBitcast(MemVecVT, Wide), 0);
4789 N->getBasePtr(),
N->getMemOperand());
4797 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4799 N->getBasePtr(),
N->getMemOperand());
4813 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4819 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4840 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4841 SDValue InVec =
N->getOperand(OpNo);
4843 EVT OutVT =
N->getValueType(0);
4851 EVT LoOutVT, HiOutVT;
4852 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4853 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4858 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4860 return SplitVecOp_UnaryOp(
N);
4869 return SplitVecOp_UnaryOp(
N);
4873 GetSplitVector(InVec, InLoVec, InHiVec);
4879 EVT HalfElementVT = IsFloat ?
4881 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4888 if (
N->isStrictFPOpcode()) {
4889 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4890 {N->getOperand(0), InLoVec});
4891 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4892 {N->getOperand(0), InHiVec});
4898 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4899 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4903 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4911 if (
N->isStrictFPOpcode()) {
4915 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4923 DAG.getTargetConstant(
4924 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4931 assert(
N->getValueType(0).isVector() &&
4932 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4933 "Operand types must be vectors");
4935 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4937 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4938 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4940 EVT VT =
N->getValueType(0);
4941 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4947 assert(isStrict &&
"unexpected node");
4948 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4949 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4950 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4951 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4954 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4962 EVT OpVT =
N->getOperand(0).getValueType();
4965 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4971 EVT ResVT =
N->getValueType(0);
4974 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4975 EVT InVT =
Lo.getValueType();
4980 if (
N->isStrictFPOpcode()) {
4981 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4982 {N->getOperand(0), Lo, N->getOperand(2)});
4983 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4984 {N->getOperand(0), Hi, N->getOperand(2)});
4988 Lo.getValue(1),
Hi.getValue(1));
4989 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4991 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
4992 N->getOperand(2),
N->getOperand(3));
4993 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
4994 N->getOperand(2),
N->getOperand(3));
4996 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4997 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5008SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5011 EVT LHSLoVT, LHSHiVT;
5012 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5014 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5015 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5018 std::tie(LHSLo, LHSHi) =
5019 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5022 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5025 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5031 LLVMContext &Ctxt = *DAG.getContext();
5034 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5035 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5036 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5038 EVT ResVT =
N->getValueType(0);
5043 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5044 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5050 EVT ResVT =
N->getValueType(0);
5053 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5054 EVT InVT =
Lo.getValueType();
5060 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5061 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5068 EVT ResVT =
N->getValueType(0);
5072 GetSplitVector(VecOp,
Lo,
Hi);
5078 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5080 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5082 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5083 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5088 EVT ResVT =
N->getValueType(0);
5092 GetSplitVector(VecOp,
Lo,
Hi);
5094 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5095 auto [EVLLo, EVLHi] =
5097 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5103 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5105 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5106 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5109SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5120 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5121 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5122 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5123 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5124 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5125 OpsLo, MMO, IndexType);
5126 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5127 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5131SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5135 EVT LoResVT, HiResVT;
5136 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5138 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5140 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5143 N->getOperand(1), MaskLo,
N->getFlags());
5145 N->getOperand(1), MaskHi,
N->getFlags());
5151 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5154 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5158 NeedleLo,
N->getOperand(2),
N->getFlags());
5161 NeedleHi,
N->getOperand(2),
N->getFlags());
5162 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5165SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5168 "Accumulator should already be a legal type, and shouldn't need "
5169 "further splitting");
5172 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5173 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5174 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5175 unsigned Opcode =
N->getOpcode();
5178 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5179 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5186void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5187 unsigned WidenResNo) {
5188 unsigned NumResults =
N->getNumValues();
5189 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5190 if (ResNo == WidenResNo)
5192 EVT ResVT =
N->getValueType(ResNo);
5198 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5199 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5204void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5205 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5208 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5213 auto unrollExpandedOp = [&]() {
5218 EVT VT =
N->getValueType(0);
5219 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5220 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5221 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5223 if (
N->getNumValues() > 1)
5224 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5230 switch (
N->getOpcode()) {
5233 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5241 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5245 Res = WidenVecRes_ADDRSPACECAST(
N);
5252 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5259 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5263 Res = WidenVecRes_ScalarOp(
N);
5269 Res = WidenVecRes_Select(
N);
5272 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5274 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5281 case ISD::VP_LOAD_FF:
5284 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5288 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5296 case ISD::VP_GATHER:
5300 Res = WidenVecRes_VECTOR_REVERSE(
N);
5303 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5306 WidenVecRes_VECTOR_INTERLEAVE(
N);
5309 Res = WidenVecRes_VECTOR_MATCH(
N);
5312 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5366 Res = WidenVecRes_Binary(
N);
5373 Res = WidenVecRes_MaskedBinary(
N);
5378 Res = WidenVecRes_CMP(
N);
5384 if (unrollExpandedOp())
5399 Res = WidenVecRes_BinaryCanTrap(
N);
5408 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5411#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5412 case ISD::STRICT_##DAGN:
5413#include "llvm/IR/ConstrainedOps.def"
5414 Res = WidenVecRes_StrictFP(
N);
5423 Res = WidenVecRes_OverflowOp(
N, ResNo);
5427 Res = WidenVecRes_FCOPYSIGN(
N);
5432 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5437 if (!unrollExpandedOp())
5438 Res = WidenVecRes_ExpOp(
N);
5444 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5459 Res = WidenVecRes_Convert(
N);
5464 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5471 Res = WidenVecRes_XROUND(
N);
5497 if (unrollExpandedOp())
5519 Res = WidenVecRes_Unary(
N);
5524 Res = WidenVecRes_Ternary(
N);
5530 if (!unrollExpandedOp())
5531 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5538 SetWidenedVector(
SDValue(
N, ResNo), Res);
5544 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5545 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5546 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5547 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5548 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5554 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5555 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5556 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5557 if (
N->getNumOperands() == 2)
5558 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5561 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5562 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5563 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5564 "Expected VP opcode");
5568 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5569 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5574 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5575 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5576 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5579 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5580 Mask = ModifyToType(Mask, WideMaskVT,
true);
5581 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5586 LLVMContext &Ctxt = *DAG.getContext();
5591 EVT OpVT =
LHS.getValueType();
5593 LHS = GetWidenedVector(
LHS);
5594 RHS = GetWidenedVector(
RHS);
5595 OpVT =
LHS.getValueType();
5598 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5601 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5607SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5610 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5611 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5612 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5614 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5623 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5626 if (ConcatEnd == 1) {
5627 VT = ConcatOps[0].getValueType();
5629 return ConcatOps[0];
5632 SDLoc dl(ConcatOps[0]);
5639 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5640 int Idx = ConcatEnd - 1;
5641 VT = ConcatOps[Idx--].getValueType();
5642 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5655 unsigned NumToInsert = ConcatEnd - Idx - 1;
5656 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5658 ConcatOps[Idx+1] = VecOp;
5659 ConcatEnd = Idx + 2;
5665 unsigned RealVals = ConcatEnd - Idx - 1;
5666 unsigned SubConcatEnd = 0;
5667 unsigned SubConcatIdx = Idx + 1;
5668 while (SubConcatEnd < RealVals)
5669 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5670 while (SubConcatEnd < OpsToConcat)
5671 SubConcatOps[SubConcatEnd++] = undefVec;
5673 NextVT, SubConcatOps);
5674 ConcatEnd = SubConcatIdx + 1;
5679 if (ConcatEnd == 1) {
5680 VT = ConcatOps[0].getValueType();
5682 return ConcatOps[0];
5687 if (
NumOps != ConcatEnd ) {
5689 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5690 ConcatOps[j] = UndefVal;
5698 unsigned Opcode =
N->getOpcode();
5700 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5704 const SDNodeFlags
Flags =
N->getFlags();
5705 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5706 NumElts = NumElts / 2;
5710 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5712 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5713 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5714 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5722 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5725 TLI.isTypeLegal(WideMaskVT)) {
5726 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5727 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5728 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5730 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5731 N->getValueType(0).getVectorElementCount());
5732 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5746 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5747 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5748 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5751 unsigned ConcatEnd = 0;
5759 while (CurNumElts != 0) {
5760 while (CurNumElts >= NumElts) {
5761 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5762 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5763 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5765 CurNumElts -= NumElts;
5768 NumElts = NumElts / 2;
5770 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5773 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5774 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5775 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5776 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5787 switch (
N->getOpcode()) {
5790 return WidenVecRes_STRICT_FSETCC(
N);
5797 return WidenVecRes_Convert_StrictFP(
N);
5804 unsigned Opcode =
N->getOpcode();
5806 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5810 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5811 NumElts = NumElts / 2;
5822 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5826 unsigned ConcatEnd = 0;
5833 for (
unsigned i = 1; i < NumOpers; ++i) {
5839 Oper = GetWidenedVector(Oper);
5845 DAG.getPOISON(WideOpVT), Oper,
5846 DAG.getVectorIdxConstant(0, dl));
5858 while (CurNumElts != 0) {
5859 while (CurNumElts >= NumElts) {
5862 for (
unsigned i = 0; i < NumOpers; ++i) {
5865 EVT OpVT =
Op.getValueType();
5870 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5876 EVT OperVT[] = {VT, MVT::Other};
5878 ConcatOps[ConcatEnd++] = Oper;
5881 CurNumElts -= NumElts;
5884 NumElts = NumElts / 2;
5886 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5889 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5892 for (
unsigned i = 0; i < NumOpers; ++i) {
5895 EVT OpVT =
Op.getValueType();
5903 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5905 ConcatOps[ConcatEnd++] = Oper;
5914 if (Chains.
size() == 1)
5915 NewChain = Chains[0];
5918 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5923SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5925 EVT ResVT =
N->getValueType(0);
5926 EVT OvVT =
N->getValueType(1);
5927 EVT WideResVT, WideOvVT;
5932 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5937 WideLHS = GetWidenedVector(
N->getOperand(0));
5938 WideRHS = GetWidenedVector(
N->getOperand(1));
5940 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5949 N->getOperand(0), Zero);
5951 N->getOperand(1), Zero);
5954 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5955 SDNode *WideNode = DAG.getNode(
5956 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5959 unsigned OtherNo = 1 - ResNo;
5960 EVT OtherVT =
N->getValueType(OtherNo);
5967 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5970 return SDValue(WideNode, ResNo);
5974 LLVMContext &Ctx = *DAG.getContext();
5978 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5983 unsigned Opcode =
N->getOpcode();
5984 const SDNodeFlags
Flags =
N->getFlags();
5990 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5992 InOp = ZExtPromotedInteger(InOp);
6004 if (
N->getNumOperands() == 1)
6005 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6007 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6008 N->getOperand(3), Flags);
6009 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6013 InOp = GetWidenedVector(
N->getOperand(0));
6016 if (InVTEC == WidenEC)
6017 return MakeConvertNode(WidenVT, InOp);
6042 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6046 if (TLI.isTypeLegal(InWidenVT)) {
6054 unsigned NumConcat =
6059 return MakeConvertNode(WidenVT, InVec);
6063 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6065 return MakeConvertNode(WidenVT, InVal);
6074 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6075 for (
unsigned i=0; i < MinElts; ++i) {
6076 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6077 Ops[i] = MakeConvertNode(EltVT, Val);
6080 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6085 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6089 EVT SrcVT = Src.getValueType();
6093 Src = GetWidenedVector(Src);
6094 SrcVT = Src.getValueType();
6101 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6106 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6110 EVT SrcVT = Src.getValueType();
6114 Src = GetWidenedVector(Src);
6115 SrcVT = Src.getValueType();
6122 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6125SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6130 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6136 unsigned Opcode =
N->getOpcode();
6142 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6147 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6148 for (
unsigned i=0; i < MinElts; ++i) {
6149 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6150 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6154 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6156 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6159SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6160 unsigned Opcode =
N->getOpcode();
6164 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6173 InOp = GetWidenedVector(InOp);
6180 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6187 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6188 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6205 while (
Ops.size() != WidenNumElts)
6206 Ops.push_back(DAG.getPOISON(WidenSVT));
6208 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6214 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6215 return WidenVecRes_BinaryCanTrap(
N);
6218 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6225SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6227 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6230 SDValue Arg = GetWidenedVector(FpValue);
6231 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6236 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6237 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6239 EVT ExpVT =
RHS.getValueType();
6244 ExpOp = ModifyToType(
RHS, WideExpVT);
6247 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6252 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6253 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6254 if (
N->getNumOperands() == 1)
6255 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6257 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6262 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6267 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6268 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6269 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6272SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6274 EVT VT0 =
N->getValueType(0);
6275 EVT VT1 =
N->getValueType(1);
6279 "expected both results to be vectors of matching element count");
6281 LLVMContext &Ctx = *DAG.getContext();
6282 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6284 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6291 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6294 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6295 return SDValue(WidenNode, ResNo);
6298SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6299 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6300 return GetWidenedVector(WidenVec);
6305 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6315 InOp = GetWidenedVector(InOp);
6319 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6322 return DAG.getAddrSpaceCast(
DL, WidenVT, InOp,
6323 AddrSpaceCastN->getSrcAddressSpace(),
6324 AddrSpaceCastN->getDestAddressSpace());
6330 EVT VT =
N->getValueType(0);
6331 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6334 switch (getTypeAction(InVT)) {
6348 SDValue NInOp = GetPromotedInteger(InOp);
6350 if (WidenVT.
bitsEq(NInVT)) {
6353 if (DAG.getDataLayout().isBigEndian()) {
6356 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6374 InOp = GetWidenedVector(InOp);
6376 if (WidenVT.
bitsEq(InVT))
6386 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6391 unsigned NewNumParts = WidenSize / InSize;
6404 EVT OrigInVT =
N->getOperand(0).getValueType();
6409 if (TLI.isTypeLegal(NewInVT)) {
6417 if (WidenSize % InSize == 0) {
6424 DAG.ExtractVectorElements(InOp,
Ops);
6425 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6437 return CreateStackStoreLoad(InOp, WidenVT);
6440SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6442 N->getOpcode(), SDLoc(
N),
6443 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6444 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6450 EVT VT =
N->getValueType(0);
6454 EVT EltVT =
N->getOperand(0).getValueType();
6457 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6461 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6462 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6464 return DAG.getBuildVector(WidenVT, dl, NewOps);
6468 EVT InVT =
N->getOperand(0).getValueType();
6469 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6471 unsigned NumOperands =
N->getNumOperands();
6473 bool InputWidened =
false;
6477 if (WidenNumElts % NumInElts == 0) {
6479 unsigned NumConcat = WidenNumElts / NumInElts;
6480 SDValue UndefVal = DAG.getPOISON(InVT);
6482 for (
unsigned i=0; i < NumOperands; ++i)
6483 Ops[i] =
N->getOperand(i);
6484 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6489 InputWidened =
true;
6490 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6493 for (i=1; i < NumOperands; ++i)
6494 if (!
N->getOperand(i).isUndef())
6497 if (i == NumOperands)
6500 return GetWidenedVector(
N->getOperand(0));
6502 if (NumOperands == 2) {
6504 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6509 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6510 for (
unsigned i = 0; i < NumInElts; ++i) {
6512 MaskOps[i + NumInElts] = i + WidenNumElts;
6514 return DAG.getVectorShuffle(WidenVT, dl,
6515 GetWidenedVector(
N->getOperand(0)),
6516 GetWidenedVector(
N->getOperand(1)),
6523 SDValue WideVec = DAG.getPOISON(WidenVT);
6525 for (
unsigned I = 0;
I < NumOperands; ++
I)
6527 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6538 for (
unsigned i=0; i < NumOperands; ++i) {
6541 InOp = GetWidenedVector(InOp);
6542 for (
unsigned j = 0;
j < NumInElts; ++
j)
6543 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6545 SDValue UndefVal = DAG.getPOISON(EltVT);
6546 for (; Idx < WidenNumElts; ++Idx)
6547 Ops[Idx] = UndefVal;
6548 return DAG.getBuildVector(WidenVT, dl,
Ops);
6551SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6552 EVT VT =
N->getValueType(0);
6553 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6554 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6561SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6562 EVT VT =
N->getValueType(0);
6564 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6569 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6571 InOp = GetWidenedVector(InOp);
6577 if (IdxVal == 0 && InVT == WidenVT)
6584 assert(IdxVal % VTNumElts == 0 &&
6585 "Expected Idx to be a multiple of subvector minimum vector length");
6586 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6599 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6600 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6601 "down type's element count");
6608 for (;
I < VTNumElts / GCD; ++
I)
6610 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6611 for (;
I < WidenNumElts / GCD; ++
I)
6633 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6640 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6641 return DAG.getMaskedLoad(
6642 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6650 for (i = 0; i < VTNumElts; ++i)
6651 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6653 SDValue UndefVal = DAG.getPOISON(EltVT);
6654 for (; i < WidenNumElts; ++i)
6656 return DAG.getBuildVector(WidenVT, dl,
Ops);
6662 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6667SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6668 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6671 N->getOperand(1),
N->getOperand(2));
6680 "Load width must be less than or equal to first value type width");
6689 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6706 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6717 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6718 EVT LdVT =
LD->getMemoryVT();
6727 TypeSize WidthDiff = WidenWidth - LdWidth;
6730 std::optional<EVT> FirstVT =
6731 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6738 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6741 Chain, BasePtr,
LD->getMemOperand());
6745 FirstVTWidth, dl, DAG);
6763 if (!
LD->getMemoryVT().isByteSized()) {
6765 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6767 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6776 EVT VT =
LD->getValueType(0);
6777 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6778 EVT WideMaskVT = getSetCCResultType(WideVT);
6781 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6782 TLI.isTypeLegal(WideMaskVT)) {
6785 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6789 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6790 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6802 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6804 Result = GenWidenVectorLoads(LdChain, LD);
6811 if (LdChain.
size() == 1)
6812 NewChain = LdChain[0];
6818 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6829 SDValue NewLoad = DAG.getMaskedLoad(
6830 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6831 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6832 LD->getAddressingMode(),
LD->getExtensionType());
6842 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6844 SDValue EVL =
N->getVectorLength();
6851 "Unable to widen binary VP op");
6852 Mask = GetWidenedVector(Mask);
6853 assert(
Mask.getValueType().getVectorElementCount() ==
6854 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6855 .getVectorElementCount() &&
6856 "Unable to widen vector load");
6859 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6860 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6861 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6869 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6871 SDValue EVL =
N->getVectorLength();
6877 "Unable to widen binary VP op");
6878 Mask = GetWidenedVector(Mask);
6879 assert(
Mask.getValueType().getVectorElementCount() ==
6880 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6881 .getVectorElementCount() &&
6882 "Unable to widen vector load");
6884 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6885 Mask, EVL,
N->getMemOperand());
6898 "Unable to widen VP strided load");
6899 Mask = GetWidenedVector(Mask);
6901 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6902 assert(
Mask.getValueType().getVectorElementCount() ==
6904 "Data and mask vectors should have the same number of elements");
6906 SDValue Res = DAG.getStridedLoadVP(
6907 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6908 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6909 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6910 N->isExpandingLoad());
6918SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6923 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6925 Mask.getValueType().getVectorElementType(),
6928 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6929 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6930 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6932 WideMask, WidePassthru);
6936 EVT VT =
N->getValueType(0);
6937 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6939 EVT MaskVT =
Mask.getValueType();
6940 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6949 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6950 TLI.isTypeLegal(WideMaskVT) &&
6956 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6957 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6961 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6962 N->getMemoryVT(),
N->getMemOperand());
6966 if (!
N->getPassThru()->isUndef()) {
6970 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6971 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6972 DAG.getPOISON(WidenVT), EVL);
6983 Mask = ModifyToType(Mask, WideMaskVT,
true);
6985 SDValue Res = DAG.getMaskedLoad(
6986 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6987 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6988 ExtType,
N->isExpandingLoad());
6997 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6999 EVT MaskVT =
Mask.getValueType();
7000 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7008 Mask = ModifyToType(Mask, WideMaskVT,
true);
7013 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7014 Index = ModifyToType(Index, WideIndexVT);
7020 N->getMemoryVT().getScalarType(), WideEC);
7021 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7022 WideMemVT, dl,
Ops,
N->getMemOperand(),
7023 N->getIndexType(),
N->getExtensionType());
7032 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7040 N->getMemoryVT().getScalarType(), WideEC);
7041 Mask = GetWidenedMask(Mask, WideEC);
7044 Mask,
N->getVectorLength()};
7045 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7046 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7055 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7056 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7084 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7085 return N->getOperand(OpNo).getValueType();
7093 N =
N.getOperand(0);
7095 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7096 if (!
N->getOperand(i)->isUndef())
7098 N =
N.getOperand(0);
7102 N =
N.getOperand(0);
7104 N =
N.getOperand(0);
7131 { MaskVT, MVT::Other },
Ops);
7132 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7140 LLVMContext &Ctx = *DAG.getContext();
7143 if (MaskScalarBits < ToMaskScalBits) {
7147 }
else if (MaskScalarBits > ToMaskScalBits) {
7153 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7155 "Mask should have the right element size by now.");
7158 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7160 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7163 EVT SubVT =
Mask->getValueType(0);
7169 assert((
Mask->getValueType(0) == ToMaskVT) &&
7170 "A mask of ToMaskVT should have been produced by now.");
7180 LLVMContext &Ctx = *DAG.getContext();
7191 EVT CondVT =
Cond->getValueType(0);
7195 EVT VSelVT =
N->getValueType(0);
7207 EVT FinalVT = VSelVT;
7218 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7219 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7226 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7234 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7237 EVT ToMaskVT = VSelVT;
7244 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7260 if (ScalarBits0 != ScalarBits1) {
7261 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7262 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7274 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7275 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7276 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7279 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7287 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7292 unsigned Opcode =
N->getOpcode();
7294 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7295 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7296 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7298 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7304 Cond1 = GetWidenedVector(Cond1);
7312 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7313 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7318 Cond1 = ModifyToType(Cond1, CondWidenVT);
7321 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7322 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7324 if (Opcode == ISD::VP_MERGE)
7325 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7327 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7331 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7332 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7335 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7339 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7340 return DAG.getUNDEF(WidenVT);
7344 EVT VT =
N->getValueType(0);
7347 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7351 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7352 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7355 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7356 for (
unsigned i = 0; i != NumElts; ++i) {
7357 int Idx =
N->getMaskElt(i);
7358 if (Idx < (
int)NumElts)
7361 NewMask[i] = Idx - NumElts + WidenNumElts;
7363 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7367 EVT VT =
N->getValueType(0);
7371 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7372 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7378 unsigned IdxVal = WidenNumElts - VTNumElts;
7391 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7394 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7395 "down type's element count");
7398 for (; i < VTNumElts / GCD; ++i)
7400 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7401 for (; i < WidenNumElts / GCD; ++i)
7409 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7410 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7412 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7416SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7417 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7421void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7422 EVT VT =
N->getValueType(0);
7425 unsigned Factor =
N->getNumOperands();
7428 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7432 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7433 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7442 for (
unsigned Idx = 0; Idx != Factor; ++Idx)
7443 Slices[Idx] = Interleaved.
getValue(Idx);
7447 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7448 SDValue Narrow = DAG.getExtractSubvector(
7451 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7452 SetWidenedVector(
SDValue(
N, Idx), Wide);
7458 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7459 EVT SourceVT =
N->getOperand(0).getValueType();
7464 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7465 N->getOperand(0), 0);
7466 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7467 N->getOperand(2), 0);
7469 N->getOperand(1), WideMask,
N->getFlags());
7472void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7473 EVT VT =
N->getValueType(0);
7476 unsigned Factor =
N->getNumOperands();
7479 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7492 SDValue PackedWidenVec = DAG.getInsertSubvector(
7493 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7497 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7498 NewOps[Idx] = DAG.getExtractSubvector(
7499 DL, WidenVT, PackedWidenVec,
7506 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7511 assert(
N->getValueType(0).isVector() &&
7512 N->getOperand(0).getValueType().isVector() &&
7513 "Operands must be vectors");
7514 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7527 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7528 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7535 InOp1 = GetWidenedVector(InOp1);
7536 InOp2 = GetWidenedVector(InOp2);
7539 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7550 "Input not widened to expected type!");
7552 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7557 assert(
N->getValueType(0).isVector() &&
7558 N->getOperand(1).getValueType().isVector() &&
7559 "Operands must be vectors");
7560 EVT VT =
N->getValueType(0);
7561 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7571 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7576 for (
unsigned i = 0; i != NumElts; ++i) {
7577 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7578 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7580 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7581 {Chain, LHSElem, RHSElem, CC});
7582 Chains[i] = Scalars[i].getValue(1);
7583 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7584 DAG.getBoolConstant(
true, dl, EltVT, VT),
7585 DAG.getBoolConstant(
false, dl, EltVT, VT));
7589 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7591 return DAG.getBuildVector(WidenVT, dl, Scalars);
7597bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7598 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7602 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7605 switch (
N->getOpcode()) {
7608 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7616 Res = WidenVecOp_FAKE_USE(
N);
7622 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7626 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7627 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7628 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7633 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7635 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7636 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7638 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7639 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7649 Res = WidenVecOp_UnrollVectorOp(
N);
7656 Res = WidenVecOp_EXTEND(
N);
7661 Res = WidenVecOp_CMP(
N);
7679 Res = WidenVecOp_Convert(
N);
7684 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7704 Res = WidenVecOp_VECREDUCE(
N);
7708 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7710 case ISD::VP_REDUCE_FADD:
7711 case ISD::VP_REDUCE_SEQ_FADD:
7712 case ISD::VP_REDUCE_FMUL:
7713 case ISD::VP_REDUCE_SEQ_FMUL:
7714 case ISD::VP_REDUCE_ADD:
7715 case ISD::VP_REDUCE_MUL:
7716 case ISD::VP_REDUCE_AND:
7717 case ISD::VP_REDUCE_OR:
7718 case ISD::VP_REDUCE_XOR:
7719 case ISD::VP_REDUCE_SMAX:
7720 case ISD::VP_REDUCE_SMIN:
7721 case ISD::VP_REDUCE_UMAX:
7722 case ISD::VP_REDUCE_UMIN:
7723 case ISD::VP_REDUCE_FMAX:
7724 case ISD::VP_REDUCE_FMIN:
7725 case ISD::VP_REDUCE_FMAXIMUM:
7726 case ISD::VP_REDUCE_FMINIMUM:
7727 Res = WidenVecOp_VP_REDUCE(
N);
7731 Res = WidenVecOp_CttzElements(
N);
7733 case ISD::VP_CTTZ_ELTS:
7734 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7735 Res = WidenVecOp_VP_CttzElements(
N);
7738 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7741 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
7746 if (!Res.
getNode())
return false;
7754 if (
N->isStrictFPOpcode())
7756 "Invalid operand expansion");
7759 "Invalid operand expansion");
7761 ReplaceValueWith(
SDValue(
N, 0), Res);
7767 EVT VT =
N->getValueType(0);
7772 "Unexpected type action");
7773 InOp = GetWidenedVector(InOp);
7776 "Input wasn't widened!");
7784 EVT FixedEltVT = FixedVT.getVectorElementType();
7785 if (TLI.isTypeLegal(FixedVT) &&
7787 FixedEltVT == InEltVT) {
7789 "Not enough elements in the fixed type for the operand!");
7791 "We can't have the same type as we started with!");
7793 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7795 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7804 return WidenVecOp_Convert(
N);
7809 switch (
N->getOpcode()) {
7824 EVT OpVT =
N->getOperand(0).getValueType();
7825 EVT ResVT =
N->getValueType(0);
7832 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7833 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7839 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7840 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7842 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7849 return DAG.UnrollVectorOp(
N);
7854 EVT ResultVT =
N->getValueType(0);
7856 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7859 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7865 {WideArg,
Test},
N->getFlags());
7871 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7873 EVT OpVT =
N->getOperand(0).getValueType();
7876 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7881 EVT VT =
N->getValueType(0);
7887 "Unexpected type action");
7888 InOp = GetWidenedVector(InOp);
7890 unsigned Opcode =
N->getOpcode();
7895 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7898 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7899 return DAG.getNode(Opcode, dl, VT,
Op);
7906 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7908 if (
N->isStrictFPOpcode()) {
7910 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7913 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7914 {
N->getOperand(0), InOp });
7919 Res = MakeConvertNode(WideVT, InOp);
7921 return DAG.getExtractSubvector(dl, VT, Res, 0);
7929 if (
N->isStrictFPOpcode()) {
7932 for (
unsigned i=0; i < NumElts; ++i) {
7933 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7934 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7938 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7940 for (
unsigned i = 0; i < NumElts; ++i) {
7941 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7942 Ops[i] = MakeConvertNode(EltVT, Elt);
7946 return DAG.getBuildVector(VT, dl,
Ops);
7950 EVT DstVT =
N->getValueType(0);
7951 SDValue Src = GetWidenedVector(
N->getOperand(0));
7952 EVT SrcVT = Src.getValueType();
7959 if (TLI.isTypeLegal(WideDstVT)) {
7961 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7964 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7968 return DAG.UnrollVectorOp(
N);
7972 EVT VT =
N->getValueType(0);
7973 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7981 if (!VT.
isVector() && VT != MVT::x86mmx &&
7985 if (TLI.isTypeLegal(NewVT)) {
7987 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7999 ElementCount NewNumElts =
8001 .divideCoefficientBy(EltSize);
8003 if (TLI.isTypeLegal(NewVT)) {
8005 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8010 return CreateStackStoreLoad(InOp, VT);
8018 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8019 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8024 EVT VT =
N->getValueType(0);
8026 EVT InVT =
N->getOperand(0).getValueType();
8031 unsigned NumOperands =
N->getNumOperands();
8032 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8034 for (i = 1; i < NumOperands; ++i)
8035 if (!
N->getOperand(i).isUndef())
8038 if (i == NumOperands)
8039 return GetWidenedVector(
N->getOperand(0));
8049 for (
unsigned i=0; i < NumOperands; ++i) {
8053 "Unexpected type action");
8054 InOp = GetWidenedVector(InOp);
8055 for (
unsigned j = 0;
j < NumInElts; ++
j)
8056 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8058 return DAG.getBuildVector(VT, dl,
Ops);
8061SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8062 EVT VT =
N->getValueType(0);
8067 SubVec = GetWidenedVector(SubVec);
8072 bool IndicesValid =
false;
8075 IndicesValid =
true;
8079 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8080 Attribute::VScaleRange);
8085 IndicesValid =
true;
8091 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8097 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8104 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8126 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8134 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8135 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8140 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8145 unsigned Idx =
N->getConstantOperandVal(2);
8151 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8157SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8158 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8160 N->getValueType(0), InOp,
N->getOperand(1));
8163SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8164 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8166 N->getValueType(0), InOp,
N->getOperand(1));
8169SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8171 EVT ResVT =
N->getValueType(0);
8174 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8180 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8188 "Widened input size must be a multiple of result element size");
8191 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8193 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8194 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8202 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8203 return TLI.scalarizeVectorStore(ST, DAG);
8205 if (
ST->isTruncatingStore())
8206 return TLI.scalarizeVectorStore(ST, DAG);
8216 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8217 EVT WideMaskVT = getSetCCResultType(WideVT);
8219 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8220 TLI.isTypeLegal(WideMaskVT)) {
8223 StVal = GetWidenedVector(StVal);
8225 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8227 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8228 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8229 ST->getAddressingMode());
8233 if (GenWidenVectorStores(StChain, ST)) {
8234 if (StChain.
size() == 1)
8243 SDValue WideStVal = GetWidenedVector(StVal);
8247 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8248 ST->getOffset(), Mask,
ST->getMemoryVT(),
8249 ST->getMemOperand(),
ST->getAddressingMode(),
8250 ST->isTruncatingStore());
8257 EVT StVT =
ST->getMemoryVT();
8260 SDValue StVal = GetWidenedVector(
ST->getVal());
8265 TypeSize WidthDiff = WidenWidth - StWidth;
8271 std::optional<EVT> FirstVT =
8272 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8277 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8283 ST->getBasePtr(),
ST->getMemOperand());
8286SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8287 assert((OpNo == 1 || OpNo == 3) &&
8288 "Can widen only data or mask operand of vp_store");
8296 StVal = GetWidenedVector(StVal);
8302 "Unable to widen VP store");
8303 Mask = GetWidenedVector(Mask);
8305 Mask = GetWidenedVector(Mask);
8311 "Unable to widen VP store");
8312 StVal = GetWidenedVector(StVal);
8315 assert(
Mask.getValueType().getVectorElementCount() ==
8317 "Mask and data vectors should have the same number of elements");
8318 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8319 ST->getOffset(), Mask,
ST->getVectorLength(),
8320 ST->getMemoryVT(),
ST->getMemOperand(),
8321 ST->getAddressingMode(),
ST->isTruncatingStore(),
8322 ST->isCompressingStore());
8327 assert((OpNo == 1 || OpNo == 4) &&
8328 "Can widen only data or mask operand of vp_strided_store");
8337 "Unable to widen VP strided store");
8341 "Unable to widen VP strided store");
8343 StVal = GetWidenedVector(StVal);
8344 Mask = GetWidenedVector(Mask);
8347 Mask.getValueType().getVectorElementCount() &&
8348 "Data and mask vectors should have the same number of elements");
8350 return DAG.getStridedStoreVP(
8357SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8358 assert((OpNo == 1 || OpNo == 4) &&
8359 "Can widen only data or mask operand of mstore");
8362 EVT MaskVT =
Mask.getValueType();
8367 EVT WideVT, WideMaskVT;
8370 StVal = GetWidenedVector(StVal);
8377 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8384 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8386 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8387 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8396 Mask = ModifyToType(Mask, WideMaskVT,
true);
8399 Mask = ModifyToType(Mask, WideMaskVT,
true);
8401 StVal = ModifyToType(StVal, WideVT);
8404 assert(
Mask.getValueType().getVectorElementCount() ==
8406 "Mask and data vectors should have the same number of elements");
8413SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8414 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8416 SDValue DataOp = MG->getPassThru();
8418 SDValue Scale = MG->getScale();
8426 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8427 MG->getMemOperand(), MG->getIndexType(),
8428 MG->getExtensionType());
8434SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8443 DataOp = GetWidenedVector(DataOp);
8447 EVT IndexVT =
Index.getValueType();
8450 Index = ModifyToType(Index, WideIndexVT);
8453 EVT MaskVT =
Mask.getValueType();
8456 Mask = ModifyToType(Mask, WideMaskVT,
true);
8461 }
else if (OpNo == 4) {
8463 Index = GetWidenedVector(Index);
8469 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8474SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8483 DataOp = GetWidenedVector(DataOp);
8484 Index = GetWidenedVector(Index);
8486 Mask = GetWidenedMask(Mask, WideEC);
8489 }
else if (OpNo == 3) {
8491 Index = GetWidenedVector(Index);
8498 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8503 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8504 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8506 EVT VT =
N->getValueType(0);
8521 SVT, InOp0, InOp1,
N->getOperand(2));
8527 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8529 EVT OpVT =
N->getOperand(0).getValueType();
8532 return DAG.getNode(ExtendCode, dl, VT, CC);
8542 EVT VT =
N->getValueType(0);
8544 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8551 for (
unsigned i = 0; i != NumElts; ++i) {
8552 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8553 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8555 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8556 {Chain, LHSElem, RHSElem, CC});
8557 Chains[i] = Scalars[i].getValue(1);
8558 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8559 DAG.getBoolConstant(
true, dl, EltVT, VT),
8560 DAG.getBoolConstant(
false, dl, EltVT, VT));
8564 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8566 return DAG.getBuildVector(VT, dl, Scalars);
8590 SDValue Op = GetWidenedVector(
N->getOperand(0));
8591 EVT VT =
N->getValueType(0);
8592 EVT OrigVT =
N->getOperand(0).getValueType();
8593 EVT WideVT =
Op.getValueType();
8595 SDNodeFlags
Flags =
N->getFlags();
8597 unsigned Opc =
N->getOpcode();
8599 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8600 assert(NeutralElem &&
"Neutral element must exist");
8610 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8617 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8618 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8624 unsigned GCD = std::gcd(OrigElts, WideElts);
8627 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8628 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8629 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8630 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8633 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8634 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8636 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8645 EVT VT =
N->getValueType(0);
8647 EVT WideVT =
Op.getValueType();
8649 SDNodeFlags
Flags =
N->getFlags();
8651 unsigned Opc =
N->getOpcode();
8653 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8663 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8666 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8667 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8673 unsigned GCD = std::gcd(OrigElts, WideElts);
8676 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8677 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8678 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8679 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8682 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8683 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8685 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8689 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8692 SDValue Op = GetWidenedVector(
N->getOperand(1));
8694 Op.getValueType().getVectorElementCount());
8696 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8697 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8705 EVT VT =
N->getValueType(0);
8709 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8710 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8715 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8721 EVT SourceVT =
Source.getValueType();
8722 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8726 WideSource = GetWidenedVector(Source);
8733 WideSource = GetWidenedVector(Source);
8735 SmallVector<int>
Mask(WideElts);
8736 std::iota(
Mask.begin(),
Mask.end(), 0);
8738 Mask[
I] += WideElts;
8739 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
8741 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8745 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8752 EVT SrcVT =
Source.getValueType();
8756 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8757 {Source, Mask, N->getOperand(2)},
N->getFlags());
8760SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8763 EVT OrigMaskVT =
Mask.getValueType();
8764 SDValue WideMask = GetWidenedVector(Mask);
8770 if (OrigElts != WideElts) {
8771 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8773 Mask, DAG.getVectorIdxConstant(0,
DL));
8780SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
8783 EVT ResVT =
N->getValueType(0);
8784 EVT SourceVT =
N->getOperand(0).getValueType();
8785 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8790 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
8791 N->getOperand(0), 0);
8792 SDValue WideMask = DAG.getInsertSubvector(
8793 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
8795 N->getOperand(1), WideMask,
N->getFlags());
8796 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
8800 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
8806 return TLI.expandVectorMatch(
N, DAG);
8808 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
8812 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
8813 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
8816 N->getOperand(0), WideNeedle,
N->getOperand(2),
8834 unsigned WidenEx = 0) {
8839 unsigned AlignInBits =
Align*8;
8841 EVT RetVT = WidenEltVT;
8846 if (Width == WidenEltWidth)
8857 (WidenWidth % MemVTWidth) == 0 &&
8859 (MemVTWidth <= Width ||
8860 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8861 if (MemVTWidth == WidenWidth)
8880 (WidenWidth % MemVTWidth) == 0 &&
8882 (MemVTWidth <= Width ||
8883 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8892 return std::nullopt;
8903 unsigned Start,
unsigned End) {
8904 SDLoc dl(LdOps[Start]);
8905 EVT LdTy = LdOps[Start].getValueType();
8913 for (
unsigned i = Start + 1; i != End; ++i) {
8914 EVT NewLdTy = LdOps[i].getValueType();
8915 if (NewLdTy != LdTy) {
8934 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8935 EVT LdVT =
LD->getMemoryVT();
8945 AAMDNodes AAInfo =
LD->getAAInfo();
8949 TypeSize WidthDiff = WidenWidth - LdWidth;
8956 std::optional<EVT> FirstVT =
8957 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8964 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8969 std::optional<EVT> NewVT = FirstVT;
8970 TypeSize RemainingWidth = LdWidth;
8971 TypeSize NewVTWidth = FirstVTWidth;
8973 RemainingWidth -= NewVTWidth;
8980 NewVTWidth = NewVT->getSizeInBits();
8986 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8987 LD->getBaseAlign(), MMOFlags, AAInfo);
9000 MachinePointerInfo MPI =
LD->getPointerInfo();
9006 for (EVT MemVT : MemVTs) {
9007 Align NewAlign = ScaledOffset == 0
9008 ?
LD->getBaseAlign()
9011 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
9019 unsigned End = LdOps.
size();
9030 EVT LdTy = LdOps[i].getValueType();
9033 for (--i; i >= 0; --i) {
9034 LdTy = LdOps[i].getValueType();
9041 ConcatOps[--Idx] = LdOps[i];
9042 for (--i; i >= 0; --i) {
9043 EVT NewLdTy = LdOps[i].getValueType();
9044 if (NewLdTy != LdTy) {
9054 for (;
j != End-Idx; ++
j)
9055 WidenOps[j] = ConcatOps[Idx+j];
9057 WidenOps[j] = DAG.getPOISON(LdTy);
9064 ConcatOps[--Idx] = LdOps[i];
9069 ArrayRef(&ConcatOps[Idx], End - Idx));
9075 SDValue UndefVal = DAG.getPOISON(LdTy);
9078 for (; i != End-Idx; ++i)
9079 WidenOps[i] = ConcatOps[Idx+i];
9081 WidenOps[i] = UndefVal;
9092 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9093 EVT LdVT =
LD->getMemoryVT();
9102 AAMDNodes AAInfo =
LD->getAAInfo();
9116 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9117 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9123 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9124 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9125 LD->getBaseAlign(), MMOFlags, AAInfo);
9130 SDValue UndefVal = DAG.getPOISON(EltVT);
9131 for (; i != WidenNumElts; ++i)
9134 return DAG.getBuildVector(WidenVT, dl,
Ops);
9145 AAMDNodes AAInfo =
ST->getAAInfo();
9146 SDValue ValOp = GetWidenedVector(
ST->getValue());
9149 EVT StVT =
ST->getMemoryVT();
9157 "Mismatch between store and value types");
9161 MachinePointerInfo MPI =
ST->getPointerInfo();
9171 std::optional<EVT> NewVT =
9176 TypeSize NewVTWidth = NewVT->getSizeInBits();
9179 StWidth -= NewVTWidth;
9180 MemVTs.
back().second++;
9184 for (
const auto &Pair : MemVTs) {
9185 EVT NewVT = Pair.first;
9186 unsigned Count = Pair.second;
9192 Align NewAlign = ScaledOffset == 0
9193 ?
ST->getBaseAlign()
9195 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9196 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9212 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9213 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9214 ST->getBaseAlign(), MMOFlags, AAInfo);
9231 bool FillWithZeroes) {
9236 "input and widen element type must match");
9238 "cannot modify scalable vectors in this way");
9251 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9253 for (
unsigned i = 1; i != NumConcat; ++i)
9260 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9266 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9271 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9272 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9274 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9276 unsigned NumResultParts = NewNumElts / CommonFactor;
9277 if (NumResultParts > NumCopiedParts) {
9278 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9279 : DAG.getPOISON(PartVT);
9280 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9287 "Scalable vectors should have been handled already.");
9295 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9297 for (Idx = 0; Idx < MinNumElts; ++Idx)
9298 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9300 SDValue UndefVal = DAG.getPOISON(EltVT);
9301 for (; Idx < WidenNumElts; ++Idx)
9302 Ops[Idx] = UndefVal;
9304 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9305 if (!FillWithZeroes)
9309 "We expect to never want to FillWithZeroes for non-integral types.");
9312 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9313 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9315 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9316 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
static Type * getValueType(Value *V, bool LookThroughCmp=false)
Returns the "element type" of the given value/instruction V.
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.
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.
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.