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);
970 Res = ScalarizeVecOp_VECREDUCE(
N);
974 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
978 Res = ScalarizeVecOp_CMP(
N);
981 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
985 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
988 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
994 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
999 if (!Res.
getNode())
return false;
1007 "Invalid operand expansion");
1009 ReplaceValueWith(
SDValue(
N, 0), Res);
1016 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1018 N->getValueType(0), Elt);
1023 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1024 "Fake Use: Unexpected vector type!");
1025 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1026 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1032 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1033 "Unexpected vector type!");
1034 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1035 SDValue Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1036 N->getValueType(0).getScalarType(), Elt);
1044SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1045 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1046 "Unexpected vector type!");
1047 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1049 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1050 Elt,
N->getOperand(1));
1058SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1059 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1060 "Unexpected vector type!");
1061 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1063 {
N->getValueType(0).getScalarType(), MVT::Other },
1064 {
N->getOperand(0), Elt });
1074 ReplaceValueWith(
SDValue(
N, 0), Res);
1079SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1081 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1082 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1083 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1088SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1092 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1093 SDValue ContainingVec =
N->getOperand(0);
1101SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1102 EVT VT =
N->getValueType(0);
1103 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1115 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1116 EVT VT =
N->getValueType(0);
1118 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1127 assert(
N->getValueType(0).isVector() &&
1128 N->getOperand(0).getValueType().isVector() &&
1129 "Operand types must be vectors");
1130 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1131 "Expected single-element vector type");
1133 EVT VT =
N->getValueType(0);
1134 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1135 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1137 EVT OpVT =
N->getOperand(0).getValueType();
1149 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1155SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1157 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1158 assert(
N->getValueType(0).isVector() &&
1159 N->getOperand(1).getValueType().isVector() &&
1160 "Operand types must be vectors");
1161 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1162 "Expected single-element vector type");
1164 EVT VT =
N->getValueType(0);
1166 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1167 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1170 EVT OpVT =
N->getOperand(1).getValueType();
1174 {Ch, LHS, RHS, CC});
1183 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1188 ReplaceValueWith(
SDValue(
N, 0), Res);
1195 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1196 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1199 if (
N->isTruncatingStore())
1200 return DAG.getTruncStore(
1201 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1202 N->getBasePtr(),
N->getPointerInfo(),
1203 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1204 N->getMemOperand()->getFlags(),
N->getAAInfo());
1206 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1207 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1208 N->getMemOperand()->getFlags(),
N->getAAInfo());
1214 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1216 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1217 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1222SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1223 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1224 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1226 N->getValueType(0).getVectorElementType(), Elt,
1231SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1233 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1234 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1237 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1247 ReplaceValueWith(
SDValue(
N, 0), Res);
1254 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1256 N->getValueType(0).getVectorElementType(), Elt);
1262SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1263 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1266 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1267 {
N->getOperand(0), Elt});
1276 ReplaceValueWith(
SDValue(
N, 0), Res);
1281 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1288SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1294 SDValue Op = GetScalarizedVector(VecOp);
1295 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1296 AccOp,
Op,
N->getFlags());
1300 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1301 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1308SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1316 EVT VT =
N->getValueType(0);
1317 return DAG.getConstant(0, SDLoc(
N), VT);
1324 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1325 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1327 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1328 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1329 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1332SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1337 N->getValueType(0).getScalarType(), Mask,
1338 DAG.getVectorIdxConstant(0,
DL));
1343 return TLI.expandVectorMatch(
N, DAG);
1346SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1347 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1350 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1351 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1360 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1372void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1377 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1380 switch (
N->getOpcode()) {
1383 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1392 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1399 case ISD::VP_MERGE: SplitRes_Select(
N,
Lo,
Hi);
break;
1415 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1418 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1430 case ISD::VP_LOAD_FF:
1433 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1440 case ISD::VP_GATHER:
1444 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1447 SplitVecRes_SETCC(
N,
Lo,
Hi);
1450 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1457 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1460 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1463 SplitVecRes_VECTOR_INTERLEAVE(
N);
1466 SplitVecRes_VAARG(
N,
Lo,
Hi);
1472 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1526 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1529 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1535 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1541 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1597 SplitVecRes_BinOp(
N,
Lo,
Hi);
1603 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1608 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1612 SplitVecRes_CMP(
N,
Lo,
Hi);
1615#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1616 case ISD::STRICT_##DAGN:
1617#include "llvm/IR/ConstrainedOps.def"
1618 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1623 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1632 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1642 SplitVecRes_FIX(
N,
Lo,
Hi);
1644 case ISD::EXPERIMENTAL_VP_SPLICE:
1645 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1647 case ISD::EXPERIMENTAL_VP_REVERSE:
1648 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1654 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1657 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1660 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1669void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1676 SDValue BytesIncrement = DAG.getVScale(
1679 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1681 *ScaledOffset += IncrementSize;
1691std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1692 return SplitMask(Mask, SDLoc(Mask));
1695std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1698 EVT MaskVT =
Mask.getValueType();
1700 GetSplitVector(Mask, MaskLo, MaskHi);
1702 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1703 return std::make_pair(MaskLo, MaskHi);
1708 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1710 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1713 const SDNodeFlags
Flags =
N->getFlags();
1714 unsigned Opcode =
N->getOpcode();
1715 if (
N->getNumOperands() == 2) {
1716 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1717 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1721 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1722 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
1723 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
1724 "Expected VP opcode");
1727 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1730 std::tie(EVLLo, EVLHi) =
1731 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1734 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1736 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1742 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1744 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1748 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1750 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1754 const SDNodeFlags
Flags =
N->getFlags();
1755 unsigned Opcode =
N->getOpcode();
1756 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1758 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1765 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1767 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1769 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1772 const SDNodeFlags
Flags =
N->getFlags();
1773 unsigned Opcode =
N->getOpcode();
1775 DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1777 DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1781 LLVMContext &Ctxt = *DAG.getContext();
1787 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1789 GetSplitVector(
LHS, LHSLo, LHSHi);
1790 GetSplitVector(
RHS, RHSLo, RHSHi);
1792 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1793 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1797 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1798 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1803 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1805 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1809 unsigned Opcode =
N->getOpcode();
1810 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1812 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1821 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1828 switch (getTypeAction(InVT)) {
1842 GetExpandedOp(InOp,
Lo,
Hi);
1843 if (DAG.getDataLayout().isBigEndian())
1853 GetSplitVector(InOp,
Lo,
Hi);
1862 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1871 if (DAG.getDataLayout().isBigEndian())
1874 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1876 if (DAG.getDataLayout().isBigEndian())
1882void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1888 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1891 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1896 unsigned LaneOffset =
1899 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1901 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1908 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1911 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1914 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1919 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1921 unsigned NumSubvectors =
N->getNumOperands() / 2;
1922 if (NumSubvectors == 1) {
1923 Lo =
N->getOperand(0);
1924 Hi =
N->getOperand(1);
1929 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1938void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1945 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1960 GetSplitVector(Vec,
Lo,
Hi);
1963 EVT LoVT =
Lo.getValueType();
1973 if (IdxVal + SubElems <= LoElems) {
1981 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1983 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1989 SDValue WideSubVec = GetWidenedVector(SubVec);
1991 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1999 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2001 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2002 auto &MF = DAG.getMachineFunction();
2006 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2011 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2012 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2016 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2021 MachinePointerInfo MPI =
Load->getPointerInfo();
2022 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2025 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2034 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2039 EVT RHSVT =
RHS.getValueType();
2042 GetSplitVector(
RHS, RHSLo, RHSHi);
2044 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2059 SDValue FpValue =
N->getOperand(0);
2061 GetSplitVector(FpValue, ArgLo, ArgHi);
2063 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2065 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2074 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2078 std::tie(LoVT, HiVT) =
2082 DAG.getValueType(LoVT));
2084 DAG.getValueType(HiVT));
2089 unsigned Opcode =
N->getOpcode();
2096 GetSplitVector(N0, InLo, InHi);
2098 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2103 EVT OutLoVT, OutHiVT;
2104 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2106 assert((2 * OutNumElements) <= InNumElements &&
2107 "Illegal extend vector in reg split");
2116 SmallVector<int, 8> SplitHi(InNumElements, -1);
2117 for (
unsigned i = 0; i != OutNumElements; ++i)
2118 SplitHi[i] = i + OutNumElements;
2119 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2121 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2122 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2127 unsigned NumOps =
N->getNumOperands();
2131 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2141 for (
unsigned i = 1; i <
NumOps; ++i) {
2146 EVT InVT =
Op.getValueType();
2151 GetSplitVector(
Op, OpLo, OpHi);
2153 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2160 EVT LoValueVTs[] = {LoVT, MVT::Other};
2161 EVT HiValueVTs[] = {HiVT, MVT::Other};
2162 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2164 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2170 Lo.getValue(1),
Hi.getValue(1));
2174 ReplaceValueWith(
SDValue(
N, 1), Chain);
2177SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2179 EVT VT =
N->getValueType(0);
2190 else if (NE > ResNE)
2194 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2198 for (i = 0; i !=
NE; ++i) {
2200 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2201 SDValue Operand =
N->getOperand(j);
2205 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2211 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2219 for (; i < ResNE; ++i)
2220 Scalars.
push_back(DAG.getPOISON(EltVT));
2224 ReplaceValueWith(
SDValue(
N, 1), Chain);
2228 return DAG.getBuildVector(VecVT, dl, Scalars);
2231void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2234 EVT ResVT =
N->getValueType(0);
2235 EVT OvVT =
N->getValueType(1);
2236 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2237 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2238 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2240 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2242 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2243 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2245 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2246 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2249 unsigned Opcode =
N->getOpcode();
2250 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2251 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2253 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2255 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2261 unsigned OtherNo = 1 - ResNo;
2262 EVT OtherVT =
N->getValueType(OtherNo);
2264 SetSplitVector(
SDValue(
N, OtherNo),
2270 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2274void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2280 GetSplitVector(Vec,
Lo,
Hi);
2283 unsigned IdxVal = CIdx->getZExtValue();
2284 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2285 if (IdxVal < LoNumElts) {
2287 Lo.getValueType(),
Lo, Elt, Idx);
2290 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2310 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2312 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2313 auto &MF = DAG.getMachineFunction();
2317 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2322 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2323 Store = DAG.getTruncStore(
2329 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2332 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2336 MachinePointerInfo MPI =
Load->getPointerInfo();
2337 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2339 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2342 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2343 if (LoVT !=
Lo.getValueType())
2345 if (HiVT !=
Hi.getValueType())
2353 assert(
N->getValueType(0).isScalableVector() &&
2354 "Only scalable vectors are supported for STEP_VECTOR");
2355 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2376 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2377 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2379 Hi = DAG.getPOISON(HiVT);
2389 "Extended load during type legalization!");
2391 EVT VT =
LD->getValueType(0);
2393 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2401 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2402 Ch, Ptr,
LD->getMemOperand());
2407 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2409 Lo = DAG.getBitcast(LoVT, ExtractLo);
2410 Hi = DAG.getBitcast(HiVT, ExtractHi);
2422 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2428 EVT MemoryVT =
LD->getMemoryVT();
2430 AAMDNodes AAInfo =
LD->getAAInfo();
2432 EVT LoMemVT, HiMemVT;
2433 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2437 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2438 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2439 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2444 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2447 MachinePointerInfo MPI;
2448 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2451 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2460 ReplaceValueWith(
SDValue(LD, 1), Ch);
2465 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2468 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2474 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2475 Align Alignment =
LD->getBaseAlign();
2478 EVT MemoryVT =
LD->getMemoryVT();
2480 EVT LoMemVT, HiMemVT;
2481 bool HiIsEmpty =
false;
2482 std::tie(LoMemVT, HiMemVT) =
2483 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2488 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2491 GetSplitVector(Mask, MaskLo, MaskHi);
2493 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2498 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2500 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2503 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2506 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2507 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2515 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2516 LD->isExpandingLoad());
2518 MachinePointerInfo MPI;
2520 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2522 MPI =
LD->getPointerInfo().getWithOffset(
2525 MMO = DAG.getMachineFunction().getMachineMemOperand(
2527 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2529 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2530 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2531 LD->isExpandingLoad());
2541 ReplaceValueWith(
SDValue(LD, 1), Ch);
2547 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2551 Align Alignment =
LD->getBaseAlign();
2558 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2561 GetSplitVector(Mask, MaskLo, MaskHi);
2563 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2567 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2569 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2572 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2574 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2577 Hi = DAG.getPOISON(HiVT);
2579 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2580 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2586 "Indexed VP strided load during type legalization!");
2588 "Unexpected indexed variable-length load offset");
2593 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2595 EVT LoMemVT, HiMemVT;
2596 bool HiIsEmpty =
false;
2597 std::tie(LoMemVT, HiMemVT) =
2598 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2603 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2606 GetSplitVector(Mask, LoMask, HiMask);
2608 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2612 std::tie(LoEVL, HiEVL) =
2616 Lo = DAG.getStridedLoadVP(
2643 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2650 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2661 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2669 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2674 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2684 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2687 GetSplitVector(Mask, MaskLo, MaskHi);
2689 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2693 EVT LoMemVT, HiMemVT;
2694 bool HiIsEmpty =
false;
2695 std::tie(LoMemVT, HiMemVT) =
2696 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2698 SDValue PassThruLo, PassThruHi;
2700 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2702 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2704 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2708 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2718 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2721 MachinePointerInfo MPI;
2728 MMO = DAG.getMachineFunction().getMachineMemOperand(
2732 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2744 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2752 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2762 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2765 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2768 EVT MemoryVT =
N->getMemoryVT();
2769 Align Alignment =
N->getBaseAlign();
2774 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2776 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2779 EVT LoMemVT, HiMemVT;
2781 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2784 if (getTypeAction(
Ops.Index.getValueType()) ==
2786 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2788 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2791 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2793 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2796 SDValue PassThru = MGT->getPassThru();
2797 SDValue PassThruLo, PassThruHi;
2800 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2802 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2807 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2808 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2809 OpsLo, MMO, IndexTy, ExtType);
2811 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2812 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2813 OpsHi, MMO, IndexTy, ExtType);
2817 std::tie(EVLLo, EVLHi) =
2818 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2820 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2821 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2822 MMO, VPGT->getIndexType());
2824 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2825 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2826 MMO, VPGT->getIndexType());
2836 ReplaceValueWith(
SDValue(
N, 1), Ch);
2850 EVT VecVT =
N->getValueType(0);
2852 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2853 bool HasCustomLowering =
false;
2860 HasCustomLowering =
true;
2866 SDValue Passthru =
N->getOperand(2);
2867 if (!HasCustomLowering) {
2868 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2869 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2876 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2877 std::tie(LoMask, HiMask) = SplitMask(Mask);
2879 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2884 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2897 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2899 SDValue Chain = DAG.getEntryNode();
2900 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2904 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2909 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2913 assert(
N->getValueType(0).isVector() &&
2914 N->getOperand(0).getValueType().isVector() &&
2915 "Operand types must be vectors");
2919 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2923 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2925 GetSplitVector(
N->getOperand(0), LL, LH);
2927 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2929 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2931 GetSplitVector(
N->getOperand(1), RL, RH);
2933 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2935 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2936 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2944 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2948 EVT InVT =
N->getOperand(0).getValueType();
2950 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2952 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2954 const SDNodeFlags
Flags =
N->getFlags();
2955 unsigned Opcode =
N->getOpcode();
2957 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
2958 N->getOperand(3), Flags);
2959 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
2960 N->getOperand(3), Flags);
2966 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2967 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2969 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2970 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2977 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2981 EVT InVT =
N->getOperand(0).getValueType();
2983 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2985 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2988 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2989 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2990 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2991 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2994void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2999 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3000 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3004 EVT InVT =
N->getOperand(0).getValueType();
3006 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3008 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3010 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3011 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3013 SDNode *HiNode =
Hi.getNode();
3014 SDNode *LoNode =
Lo.getNode();
3017 unsigned OtherNo = 1 - ResNo;
3018 EVT OtherVT =
N->getValueType(OtherNo);
3026 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3033 EVT SrcVT =
N->getOperand(0).getValueType();
3034 EVT DestVT =
N->getValueType(0);
3036 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3053 LLVMContext &Ctx = *DAG.getContext();
3057 EVT SplitLoVT, SplitHiVT;
3058 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3059 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3060 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3061 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3062 N->dump(&DAG);
dbgs() <<
"\n");
3065 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3067 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3069 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3070 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3075 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3083 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3084 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3090 return N.getResNo() == 0 &&
3094 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3096 ArrayRef<int>
Mask) {
3099 "Expected build vector node.");
3102 for (
unsigned I = 0;
I < NewElts; ++
I) {
3105 unsigned Idx =
Mask[
I];
3107 Ops[
I] = Input2.getOperand(Idx - NewElts);
3109 Ops[
I] = Input1.getOperand(Idx);
3114 return DAG.getBuildVector(NewVT,
DL,
Ops);
3120 SmallVector<int> OrigMask(
N->getMask());
3122 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3123 &
DL](SmallVectorImpl<int> &
Mask) {
3125 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3126 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3137 for (
auto &
P : ShufflesIdxs) {
3138 if (
P.second.size() < 2)
3142 for (
int &Idx : Mask) {
3145 unsigned SrcRegIdx = Idx / NewElts;
3146 if (Inputs[SrcRegIdx].
isUndef()) {
3154 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3159 Idx = MaskElt % NewElts +
3160 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3166 Inputs[
P.second[0]] =
P.first.first;
3167 Inputs[
P.second[1]] =
P.first.second;
3170 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3173 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3174 for (
int &Idx : Mask) {
3177 unsigned SrcRegIdx = Idx / NewElts;
3178 if (Inputs[SrcRegIdx].
isUndef()) {
3185 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3186 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3189 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3191 if (UsedSubVector.count() > 1) {
3193 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3194 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3196 if (Pairs.
empty() || Pairs.
back().size() == 2)
3198 if (UsedSubVector.test(2 *
I)) {
3199 Pairs.
back().emplace_back(
I, 0);
3201 assert(UsedSubVector.test(2 *
I + 1) &&
3202 "Expected to be used one of the subvectors.");
3203 Pairs.
back().emplace_back(
I, 1);
3206 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3208 for (
int &Idx : Mask) {
3211 unsigned SrcRegIdx = Idx / NewElts;
3213 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3214 return Idxs.front().first == SrcRegIdx ||
3215 Idxs.back().first == SrcRegIdx;
3217 if (It == Pairs.
end())
3219 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3220 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3223 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3224 Inputs[Idxs.front().first] = DAG.
getNode(
3226 Inputs[Idxs.front().first].getValueType(),
3227 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3228 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3237 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3241 if (Shuffle->getOperand(0).getValueType() != NewVT)
3244 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3245 !Shuffle->isSplat()) {
3247 }
else if (!Inputs[
I].hasOneUse() &&
3248 !Shuffle->getOperand(1).isUndef()) {
3250 for (
int &Idx : Mask) {
3253 unsigned SrcRegIdx = Idx / NewElts;
3256 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3261 int OpIdx = MaskElt / NewElts;
3274 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3275 if (Shuffle->getOperand(OpIdx).isUndef())
3277 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3278 if (It == std::end(Inputs))
3280 int FoundOp = std::distance(std::begin(Inputs), It);
3283 for (
int &Idx : Mask) {
3286 unsigned SrcRegIdx = Idx / NewElts;
3289 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3294 int MaskIdx = MaskElt / NewElts;
3295 if (OpIdx == MaskIdx)
3296 Idx = MaskElt % NewElts + FoundOp * NewElts;
3299 Op = (OpIdx + 1) % 2;
3307 for (
int &Idx : Mask) {
3310 unsigned SrcRegIdx = Idx / NewElts;
3313 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3314 int OpIdx = MaskElt / NewElts;
3317 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3323 TryPeekThroughShufflesInputs(OrigMask);
3325 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3326 NewElts](SmallVectorImpl<int> &
Mask) {
3327 SetVector<SDValue> UniqueInputs;
3328 SetVector<SDValue> UniqueConstantInputs;
3329 for (
const auto &
I : Inputs) {
3331 UniqueConstantInputs.
insert(
I);
3332 else if (!
I.isUndef())
3337 if (UniqueInputs.
size() != std::size(Inputs)) {
3338 auto &&UniqueVec = UniqueInputs.
takeVector();
3339 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3340 unsigned ConstNum = UniqueConstantVec.size();
3341 for (
int &Idx : Mask) {
3344 unsigned SrcRegIdx = Idx / NewElts;
3345 if (Inputs[SrcRegIdx].
isUndef()) {
3349 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3350 if (It != UniqueConstantVec.end()) {
3351 Idx = (Idx % NewElts) +
3352 NewElts * std::distance(UniqueConstantVec.begin(), It);
3353 assert(Idx >= 0 &&
"Expected defined mask idx.");
3356 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3357 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3358 Idx = (Idx % NewElts) +
3359 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3360 assert(Idx >= 0 &&
"Expected defined mask idx.");
3362 copy(UniqueConstantVec, std::begin(Inputs));
3363 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3366 MakeUniqueInputs(OrigMask);
3368 copy(Inputs, std::begin(OrigInputs));
3374 unsigned FirstMaskIdx =
High * NewElts;
3377 assert(!Output &&
"Expected default initialized initial value.");
3378 TryPeekThroughShufflesInputs(Mask);
3379 MakeUniqueInputs(Mask);
3381 copy(Inputs, std::begin(TmpInputs));
3384 bool SecondIteration =
false;
3385 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3390 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3391 SecondIteration =
true;
3392 return SecondIteration;
3395 Mask, std::size(Inputs), std::size(Inputs),
3397 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3398 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3399 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3401 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3403 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3404 DAG.getPOISON(NewVT), Mask);
3405 Inputs[Idx] = Output;
3407 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3408 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3409 unsigned Idx2,
bool ) {
3410 if (AccumulateResults(Idx1)) {
3413 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3415 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3416 Inputs[Idx2], Mask);
3420 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3422 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3423 TmpInputs[Idx2], Mask);
3425 Inputs[Idx1] = Output;
3427 copy(OrigInputs, std::begin(Inputs));
3432 EVT OVT =
N->getValueType(0);
3439 const Align Alignment =
3440 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3442 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3443 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3448 ReplaceValueWith(
SDValue(
N, 1), Chain);
3453 EVT DstVTLo, DstVTHi;
3454 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3458 EVT SrcVT =
N->getOperand(0).getValueType();
3460 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3462 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3464 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3465 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3471 GetSplitVector(
N->getOperand(0), InLo, InHi);
3482 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3483 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3488 EVT VT =
N->getValueType(0);
3506 Align Alignment = DAG.getReducedAlign(VT,
false);
3511 EVT PtrVT =
StackPtr.getValueType();
3512 auto &MF = DAG.getMachineFunction();
3516 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3519 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3525 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3526 DAG.getConstant(1,
DL, PtrVT));
3528 DAG.getConstant(EltWidth,
DL, PtrVT));
3530 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3532 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3533 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3534 DAG.getPOISON(PtrVT), Stride, TrueMask,
3543 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3548 EVT VT =
N->getValueType(0);
3560 EVL1 = ZExtPromotedInteger(EVL1);
3574 Align Alignment = DAG.getReducedAlign(VT,
false);
3579 EVT PtrVT =
StackPtr.getValueType();
3580 auto &MF = DAG.getMachineFunction();
3584 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3587 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3593 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3598 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3599 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3601 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3603 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3607 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3612 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3613 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3617 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3626 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3634 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3636 DAG.getVectorIdxConstant(0,
DL));
3642void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3650 GetSplitVector(Acc, AccLo, AccHi);
3651 unsigned Opcode =
N->getOpcode();
3663 GetSplitVector(Input1, Input1Lo, Input1Hi);
3664 GetSplitVector(Input2, Input2Lo, Input2Hi);
3667 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3668 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3671void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3679 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3690 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3692 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3696 N->getOperand(1), MaskLo,
N->getFlags());
3698 N->getOperand(1), MaskHi,
N->getFlags());
3701void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3702 unsigned Factor =
N->getNumOperands();
3705 for (
unsigned i = 0; i != Factor; ++i) {
3707 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3709 Ops[i * 2 + 1] = OpHi;
3720 for (
unsigned i = 0; i != Factor; ++i)
3724void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3725 unsigned Factor =
N->getNumOperands();
3728 for (
unsigned i = 0; i != Factor; ++i) {
3730 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3732 Ops[i + Factor] = OpHi;
3743 for (
unsigned i = 0; i != Factor; ++i) {
3744 unsigned IdxLo = 2 * i;
3745 unsigned IdxHi = 2 * i + 1;
3746 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3747 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3759bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3764 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3767 switch (
N->getOpcode()) {
3770 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3779 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3786 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3789 Res = SplitVecOp_TruncateHelper(
N);
3795 Res = SplitVecOp_FP_ROUND(
N);
3807 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3814 case ISD::VP_SCATTER:
3818 case ISD::VP_GATHER:
3822 Res = SplitVecOp_VSELECT(
N, OpNo);
3828 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3831 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3837 if (
N->getValueType(0).bitsLT(
3838 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3839 Res = SplitVecOp_TruncateHelper(
N);
3841 Res = SplitVecOp_UnaryOp(
N);
3845 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3861 Res = SplitVecOp_UnaryOp(
N);
3864 Res = SplitVecOp_FPOpDifferentTypes(
N);
3869 Res = SplitVecOp_CMP(
N);
3873 Res = SplitVecOp_FAKE_USE(
N);
3878 Res = SplitVecOp_ExtVecInRegOp(
N);
3896 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3900 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3902 case ISD::VP_REDUCE_FADD:
3903 case ISD::VP_REDUCE_SEQ_FADD:
3904 case ISD::VP_REDUCE_FMUL:
3905 case ISD::VP_REDUCE_SEQ_FMUL:
3906 case ISD::VP_REDUCE_ADD:
3907 case ISD::VP_REDUCE_MUL:
3908 case ISD::VP_REDUCE_AND:
3909 case ISD::VP_REDUCE_OR:
3910 case ISD::VP_REDUCE_XOR:
3911 case ISD::VP_REDUCE_SMAX:
3912 case ISD::VP_REDUCE_SMIN:
3913 case ISD::VP_REDUCE_UMAX:
3914 case ISD::VP_REDUCE_UMIN:
3915 case ISD::VP_REDUCE_FMAX:
3916 case ISD::VP_REDUCE_FMIN:
3917 case ISD::VP_REDUCE_FMAXIMUM:
3918 case ISD::VP_REDUCE_FMINIMUM:
3919 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3923 Res = SplitVecOp_CttzElts(
N);
3925 case ISD::VP_CTTZ_ELTS:
3926 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3927 Res = SplitVecOp_VP_CttzElements(
N);
3930 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3936 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3939 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
3944 if (!Res.
getNode())
return false;
3951 if (
N->isStrictFPOpcode())
3953 "Invalid operand expansion");
3956 "Invalid operand expansion");
3958 ReplaceValueWith(
SDValue(
N, 0), Res);
3962SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3966 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3968 EVT VT =
N->getValueType(0);
3981 getSetCCResultType(MVT::i1), MVT::i1);
3986 DAG.getElementCount(
DL, VT, SplitEC)),
3990SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3993 assert(OpNo == 0 &&
"Illegal operand must be mask");
4000 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4003 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4004 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4005 "Lo and Hi have differing types");
4008 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4009 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4011 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4012 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4013 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4014 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4024SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4025 assert(OpNo == 2 &&
"Illegal operand must be mask");
4028 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4029 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4031 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4034 RHSLo, MaskLo,
N->getFlags());
4036 RHSHi, MaskHi,
N->getFlags());
4040SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4043 assert(OpNo == 1 &&
"Illegal operand must be mask");
4048 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4050 EVT VecVT =
N->getValueType(0);
4054SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4055 EVT ResVT =
N->getValueType(0);
4061 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4062 GetSplitVector(VecOp,
Lo,
Hi);
4064 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4069 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4070 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4074 EVT ResVT =
N->getValueType(0);
4080 SDNodeFlags
Flags =
N->getFlags();
4083 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4084 GetSplitVector(VecOp,
Lo,
Hi);
4086 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4092 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4095SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4096 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4097 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4099 unsigned Opc =
N->getOpcode();
4100 EVT ResVT =
N->getValueType(0);
4106 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4107 GetSplitVector(VecOp,
Lo,
Hi);
4110 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4113 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4115 const SDNodeFlags
Flags =
N->getFlags();
4119 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4124 EVT ResVT =
N->getValueType(0);
4127 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4128 EVT InVT =
Lo.getValueType();
4133 if (
N->isStrictFPOpcode()) {
4134 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4135 {N->getOperand(0), Lo});
4136 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4137 {N->getOperand(0), Hi});
4146 ReplaceValueWith(
SDValue(
N, 1), Ch);
4148 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4149 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4158 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4168 EVT ResVT =
N->getValueType(0);
4170 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4174 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4180 Lo = BitConvertToInteger(
Lo);
4181 Hi = BitConvertToInteger(
Hi);
4183 if (DAG.getDataLayout().isBigEndian())
4191 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4193 EVT ResVT =
N->getValueType(0);
4201 GetSplitVector(SubVec,
Lo,
Hi);
4210 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4212 return SecondInsertion;
4215SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4222 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4224 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4226 ElementCount IdxVal =
4230 EVT SrcVT =
N->getOperand(0).getValueType();
4249 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4250 LoEltsMin - IdxValMin);
4251 DAG.ExtractVectorElements(
Hi, Elts, 0,
4254 return DAG.getBuildVector(SubVT, dl, Elts);
4258 ElementCount ExtractIdx = IdxVal - LoElts;
4260 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4263 EVT HiVT =
Hi.getValueType();
4265 "Only fixed-vector extracts are supported in this case");
4275 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4276 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4282 "Extracting scalable subvector from fixed-width unsupported");
4290 "subvector from a scalable predicate vector");
4296 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4298 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4299 auto &MF = DAG.getMachineFunction();
4303 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4307 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4310 SubVT, dl,
Store, StackPtr,
4314SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4323 GetSplitVector(Vec,
Lo,
Hi);
4325 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4327 if (IdxVal < LoElts)
4328 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4331 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4336 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4348 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4354 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4356 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4357 auto &MF = DAG.getMachineFunction();
4360 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4364 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4368 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4370 return DAG.getExtLoad(
4381 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4389 SplitVecRes_Gather(
N,
Lo,
Hi);
4392 ReplaceValueWith(
SDValue(
N, 0), Res);
4397 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4401 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4403 SDValue EVL =
N->getVectorLength();
4405 Align Alignment =
N->getBaseAlign();
4411 GetSplitVector(
Data, DataLo, DataHi);
4413 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4418 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4421 GetSplitVector(Mask, MaskLo, MaskHi);
4423 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4426 EVT MemoryVT =
N->getMemoryVT();
4427 EVT LoMemVT, HiMemVT;
4428 bool HiIsEmpty =
false;
4429 std::tie(LoMemVT, HiMemVT) =
4430 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4434 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4437 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4440 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4442 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4443 N->getAddressingMode(),
N->isTruncatingStore(),
4444 N->isCompressingStore());
4450 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4451 N->isCompressingStore());
4453 MachinePointerInfo MPI;
4457 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4462 MMO = DAG.getMachineFunction().getMachineMemOperand(
4464 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4466 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4467 N->getAddressingMode(),
N->isTruncatingStore(),
4468 N->isCompressingStore());
4477 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4478 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4485 GetSplitVector(
Data, LoData, HiData);
4487 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4489 EVT LoMemVT, HiMemVT;
4490 bool HiIsEmpty =
false;
4491 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4497 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4498 else if (getTypeAction(
Mask.getValueType()) ==
4500 GetSplitVector(Mask, LoMask, HiMask);
4502 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4505 std::tie(LoEVL, HiEVL) =
4506 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4510 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4511 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4512 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4523 EVT PtrVT =
N->getBasePtr().getValueType();
4526 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4529 Align Alignment =
N->getBaseAlign();
4534 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4535 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4537 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4540 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4541 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4542 N->isCompressingStore());
4551 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4555 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4558 Align Alignment =
N->getBaseAlign();
4564 GetSplitVector(
Data, DataLo, DataHi);
4566 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4571 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4574 GetSplitVector(Mask, MaskLo, MaskHi);
4576 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4579 EVT MemoryVT =
N->getMemoryVT();
4580 EVT LoMemVT, HiMemVT;
4581 bool HiIsEmpty =
false;
4582 std::tie(LoMemVT, HiMemVT) =
4583 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4586 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4589 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4591 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4592 N->getAddressingMode(),
N->isTruncatingStore(),
4593 N->isCompressingStore());
4601 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4602 N->isCompressingStore());
4604 MachinePointerInfo MPI;
4608 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4613 MMO = DAG.getMachineFunction().getMachineMemOperand(
4615 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4617 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4618 N->getAddressingMode(),
N->isTruncatingStore(),
4619 N->isCompressingStore());
4632 EVT MemoryVT =
N->getMemoryVT();
4633 Align Alignment =
N->getBaseAlign();
4642 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4646 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4651 EVT LoMemVT, HiMemVT;
4652 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4657 GetSplitVector(
Ops.Data, DataLo, DataHi);
4659 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4664 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4666 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4670 if (getTypeAction(
Ops.Index.getValueType()) ==
4672 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4674 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4678 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4680 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4683 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4685 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4686 MSC->getIndexType(), MSC->isTruncatingStore());
4691 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4692 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4693 MMO, MSC->getIndexType(),
4694 MSC->isTruncatingStore());
4698 std::tie(EVLLo, EVLHi) =
4699 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4701 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4702 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4703 VPSC->getIndexType());
4708 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4709 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4710 VPSC->getIndexType());
4714 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4715 assert(OpNo == 1 &&
"Can only split the stored value");
4718 bool isTruncating =
N->isTruncatingStore();
4721 EVT MemoryVT =
N->getMemoryVT();
4722 Align Alignment =
N->getBaseAlign();
4724 AAMDNodes AAInfo =
N->getAAInfo();
4726 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4728 EVT LoMemVT, HiMemVT;
4729 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4733 return TLI.scalarizeVectorStore(
N, DAG);
4736 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4737 Alignment, MMOFlags, AAInfo);
4739 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4742 MachinePointerInfo MPI;
4743 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4746 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4747 HiMemVT, Alignment, MMOFlags, AAInfo);
4749 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4756 LLVMContext &Ctx = *DAG.getContext();
4774 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4775 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4779 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4782 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4783 DAG.getBitcast(MemVecVT, Wide), 0);
4785 N->getBasePtr(),
N->getMemOperand());
4793 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4795 N->getBasePtr(),
N->getMemOperand());
4809 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4815 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4836 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4837 SDValue InVec =
N->getOperand(OpNo);
4839 EVT OutVT =
N->getValueType(0);
4847 EVT LoOutVT, HiOutVT;
4848 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4849 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4854 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4856 return SplitVecOp_UnaryOp(
N);
4865 return SplitVecOp_UnaryOp(
N);
4869 GetSplitVector(InVec, InLoVec, InHiVec);
4875 EVT HalfElementVT = IsFloat ?
4877 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4884 if (
N->isStrictFPOpcode()) {
4885 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4886 {N->getOperand(0), InLoVec});
4887 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4888 {N->getOperand(0), InHiVec});
4894 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4895 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4899 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4907 if (
N->isStrictFPOpcode()) {
4911 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4919 DAG.getTargetConstant(
4920 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4927 assert(
N->getValueType(0).isVector() &&
4928 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4929 "Operand types must be vectors");
4931 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4933 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4934 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4936 EVT VT =
N->getValueType(0);
4937 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4943 assert(isStrict &&
"unexpected node");
4944 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4945 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4946 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4947 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4950 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4958 EVT OpVT =
N->getOperand(0).getValueType();
4961 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4967 EVT ResVT =
N->getValueType(0);
4970 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4971 EVT InVT =
Lo.getValueType();
4976 if (
N->isStrictFPOpcode()) {
4977 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4978 {N->getOperand(0), Lo, N->getOperand(2)});
4979 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4980 {N->getOperand(0), Hi, N->getOperand(2)});
4984 Lo.getValue(1),
Hi.getValue(1));
4985 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4987 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
4988 N->getOperand(2),
N->getOperand(3));
4989 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
4990 N->getOperand(2),
N->getOperand(3));
4992 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4993 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5004SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5007 EVT LHSLoVT, LHSHiVT;
5008 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5010 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5011 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5014 std::tie(LHSLo, LHSHi) =
5015 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5018 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5021 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5027 LLVMContext &Ctxt = *DAG.getContext();
5030 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5031 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5032 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5034 EVT ResVT =
N->getValueType(0);
5039 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5040 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5046 EVT ResVT =
N->getValueType(0);
5049 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5050 EVT InVT =
Lo.getValueType();
5056 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5057 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5064 EVT ResVT =
N->getValueType(0);
5068 GetSplitVector(VecOp,
Lo,
Hi);
5074 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5076 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5078 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5079 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5084 EVT ResVT =
N->getValueType(0);
5088 GetSplitVector(VecOp,
Lo,
Hi);
5090 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5091 auto [EVLLo, EVLHi] =
5093 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5099 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5101 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5102 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5105SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5116 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5117 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5118 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5119 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5120 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5121 OpsLo, MMO, IndexType);
5122 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5123 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5127SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5131 EVT LoResVT, HiResVT;
5132 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5134 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5136 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5139 N->getOperand(1), MaskLo,
N->getFlags());
5141 N->getOperand(1), MaskHi,
N->getFlags());
5147 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5150 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5154 NeedleLo,
N->getOperand(2),
N->getFlags());
5157 NeedleHi,
N->getOperand(2),
N->getFlags());
5158 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5161SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5164 "Accumulator should already be a legal type, and shouldn't need "
5165 "further splitting");
5168 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5169 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5170 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5171 unsigned Opcode =
N->getOpcode();
5174 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5175 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5182void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5183 unsigned WidenResNo) {
5184 unsigned NumResults =
N->getNumValues();
5185 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5186 if (ResNo == WidenResNo)
5188 EVT ResVT =
N->getValueType(ResNo);
5194 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5195 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5200void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5201 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5204 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5209 auto unrollExpandedOp = [&]() {
5214 EVT VT =
N->getValueType(0);
5215 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5216 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5217 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5219 if (
N->getNumValues() > 1)
5220 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5226 switch (
N->getOpcode()) {
5229 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5237 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5241 Res = WidenVecRes_ADDRSPACECAST(
N);
5248 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5255 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5259 Res = WidenVecRes_ScalarOp(
N);
5265 Res = WidenVecRes_Select(
N);
5268 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5270 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5277 case ISD::VP_LOAD_FF:
5280 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5284 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5292 case ISD::VP_GATHER:
5296 Res = WidenVecRes_VECTOR_REVERSE(
N);
5299 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5302 WidenVecRes_VECTOR_INTERLEAVE(
N);
5305 Res = WidenVecRes_VECTOR_MATCH(
N);
5308 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5362 Res = WidenVecRes_Binary(
N);
5369 Res = WidenVecRes_MaskedBinary(
N);
5374 Res = WidenVecRes_CMP(
N);
5380 if (unrollExpandedOp())
5395 Res = WidenVecRes_BinaryCanTrap(
N);
5404 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5407#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5408 case ISD::STRICT_##DAGN:
5409#include "llvm/IR/ConstrainedOps.def"
5410 Res = WidenVecRes_StrictFP(
N);
5419 Res = WidenVecRes_OverflowOp(
N, ResNo);
5423 Res = WidenVecRes_FCOPYSIGN(
N);
5428 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5433 if (!unrollExpandedOp())
5434 Res = WidenVecRes_ExpOp(
N);
5440 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5455 Res = WidenVecRes_Convert(
N);
5460 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5467 Res = WidenVecRes_XROUND(
N);
5493 if (unrollExpandedOp())
5515 Res = WidenVecRes_Unary(
N);
5520 Res = WidenVecRes_Ternary(
N);
5526 if (!unrollExpandedOp())
5527 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5534 SetWidenedVector(
SDValue(
N, ResNo), Res);
5540 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5541 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5542 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5543 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5544 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5550 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5551 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5552 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5553 if (
N->getNumOperands() == 2)
5554 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5557 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5558 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5559 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5560 "Expected VP opcode");
5564 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5565 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5570 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5571 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5572 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5575 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5576 Mask = ModifyToType(Mask, WideMaskVT,
true);
5577 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5582 LLVMContext &Ctxt = *DAG.getContext();
5587 EVT OpVT =
LHS.getValueType();
5589 LHS = GetWidenedVector(
LHS);
5590 RHS = GetWidenedVector(
RHS);
5591 OpVT =
LHS.getValueType();
5594 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5597 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5603SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5606 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5607 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5608 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5610 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5619 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5622 if (ConcatEnd == 1) {
5623 VT = ConcatOps[0].getValueType();
5625 return ConcatOps[0];
5628 SDLoc dl(ConcatOps[0]);
5635 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5636 int Idx = ConcatEnd - 1;
5637 VT = ConcatOps[Idx--].getValueType();
5638 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5651 unsigned NumToInsert = ConcatEnd - Idx - 1;
5652 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5654 ConcatOps[Idx+1] = VecOp;
5655 ConcatEnd = Idx + 2;
5661 unsigned RealVals = ConcatEnd - Idx - 1;
5662 unsigned SubConcatEnd = 0;
5663 unsigned SubConcatIdx = Idx + 1;
5664 while (SubConcatEnd < RealVals)
5665 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5666 while (SubConcatEnd < OpsToConcat)
5667 SubConcatOps[SubConcatEnd++] = undefVec;
5669 NextVT, SubConcatOps);
5670 ConcatEnd = SubConcatIdx + 1;
5675 if (ConcatEnd == 1) {
5676 VT = ConcatOps[0].getValueType();
5678 return ConcatOps[0];
5683 if (
NumOps != ConcatEnd ) {
5685 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5686 ConcatOps[j] = UndefVal;
5694 unsigned Opcode =
N->getOpcode();
5696 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5700 const SDNodeFlags
Flags =
N->getFlags();
5701 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5702 NumElts = NumElts / 2;
5706 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5708 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5709 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5710 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5718 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5721 TLI.isTypeLegal(WideMaskVT)) {
5722 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5723 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5724 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5726 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5727 N->getValueType(0).getVectorElementCount());
5728 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5742 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5743 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5744 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5747 unsigned ConcatEnd = 0;
5755 while (CurNumElts != 0) {
5756 while (CurNumElts >= NumElts) {
5757 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5758 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5759 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5761 CurNumElts -= NumElts;
5764 NumElts = NumElts / 2;
5766 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5769 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5770 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5771 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5772 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5783 switch (
N->getOpcode()) {
5786 return WidenVecRes_STRICT_FSETCC(
N);
5793 return WidenVecRes_Convert_StrictFP(
N);
5800 unsigned Opcode =
N->getOpcode();
5802 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5806 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5807 NumElts = NumElts / 2;
5818 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5822 unsigned ConcatEnd = 0;
5829 for (
unsigned i = 1; i < NumOpers; ++i) {
5835 Oper = GetWidenedVector(Oper);
5841 DAG.getPOISON(WideOpVT), Oper,
5842 DAG.getVectorIdxConstant(0, dl));
5854 while (CurNumElts != 0) {
5855 while (CurNumElts >= NumElts) {
5858 for (
unsigned i = 0; i < NumOpers; ++i) {
5861 EVT OpVT =
Op.getValueType();
5866 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5872 EVT OperVT[] = {VT, MVT::Other};
5874 ConcatOps[ConcatEnd++] = Oper;
5877 CurNumElts -= NumElts;
5880 NumElts = NumElts / 2;
5882 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5885 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5888 for (
unsigned i = 0; i < NumOpers; ++i) {
5891 EVT OpVT =
Op.getValueType();
5899 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5901 ConcatOps[ConcatEnd++] = Oper;
5910 if (Chains.
size() == 1)
5911 NewChain = Chains[0];
5914 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5919SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5921 EVT ResVT =
N->getValueType(0);
5922 EVT OvVT =
N->getValueType(1);
5923 EVT WideResVT, WideOvVT;
5928 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5933 WideLHS = GetWidenedVector(
N->getOperand(0));
5934 WideRHS = GetWidenedVector(
N->getOperand(1));
5936 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5945 N->getOperand(0), Zero);
5947 N->getOperand(1), Zero);
5950 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5951 SDNode *WideNode = DAG.getNode(
5952 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5955 unsigned OtherNo = 1 - ResNo;
5956 EVT OtherVT =
N->getValueType(OtherNo);
5963 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5966 return SDValue(WideNode, ResNo);
5970 LLVMContext &Ctx = *DAG.getContext();
5974 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5979 unsigned Opcode =
N->getOpcode();
5980 const SDNodeFlags
Flags =
N->getFlags();
5986 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5988 InOp = ZExtPromotedInteger(InOp);
6000 if (
N->getNumOperands() == 1)
6001 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6003 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6004 N->getOperand(3), Flags);
6005 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6009 InOp = GetWidenedVector(
N->getOperand(0));
6012 if (InVTEC == WidenEC)
6013 return MakeConvertNode(WidenVT, InOp);
6038 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6042 if (TLI.isTypeLegal(InWidenVT)) {
6050 unsigned NumConcat =
6055 return MakeConvertNode(WidenVT, InVec);
6059 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6061 return MakeConvertNode(WidenVT, InVal);
6070 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6071 for (
unsigned i=0; i < MinElts; ++i) {
6072 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6073 Ops[i] = MakeConvertNode(EltVT, Val);
6076 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6081 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6085 EVT SrcVT = Src.getValueType();
6089 Src = GetWidenedVector(Src);
6090 SrcVT = Src.getValueType();
6097 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6102 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6106 EVT SrcVT = Src.getValueType();
6110 Src = GetWidenedVector(Src);
6111 SrcVT = Src.getValueType();
6118 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6121SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6126 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6132 unsigned Opcode =
N->getOpcode();
6138 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6143 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6144 for (
unsigned i=0; i < MinElts; ++i) {
6145 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6146 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6150 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6152 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6155SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6156 unsigned Opcode =
N->getOpcode();
6160 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6169 InOp = GetWidenedVector(InOp);
6176 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6183 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6184 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6201 while (
Ops.size() != WidenNumElts)
6202 Ops.push_back(DAG.getPOISON(WidenSVT));
6204 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6210 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6211 return WidenVecRes_BinaryCanTrap(
N);
6214 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6221SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6223 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6226 SDValue Arg = GetWidenedVector(FpValue);
6227 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6232 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6233 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6235 EVT ExpVT =
RHS.getValueType();
6240 ExpOp = ModifyToType(
RHS, WideExpVT);
6243 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6248 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6249 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6250 if (
N->getNumOperands() == 1)
6251 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6253 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6258 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6263 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6264 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6265 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6268SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6270 EVT VT0 =
N->getValueType(0);
6271 EVT VT1 =
N->getValueType(1);
6275 "expected both results to be vectors of matching element count");
6277 LLVMContext &Ctx = *DAG.getContext();
6278 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6280 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6287 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6290 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6291 return SDValue(WidenNode, ResNo);
6294SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6295 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6296 return GetWidenedVector(WidenVec);
6301 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6311 InOp = GetWidenedVector(InOp);
6315 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6318 return DAG.getAddrSpaceCast(
DL, WidenVT, InOp,
6319 AddrSpaceCastN->getSrcAddressSpace(),
6320 AddrSpaceCastN->getDestAddressSpace());
6326 EVT VT =
N->getValueType(0);
6327 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6330 switch (getTypeAction(InVT)) {
6344 SDValue NInOp = GetPromotedInteger(InOp);
6346 if (WidenVT.
bitsEq(NInVT)) {
6349 if (DAG.getDataLayout().isBigEndian()) {
6352 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6370 InOp = GetWidenedVector(InOp);
6372 if (WidenVT.
bitsEq(InVT))
6382 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6387 unsigned NewNumParts = WidenSize / InSize;
6400 EVT OrigInVT =
N->getOperand(0).getValueType();
6405 if (TLI.isTypeLegal(NewInVT)) {
6413 if (WidenSize % InSize == 0) {
6420 DAG.ExtractVectorElements(InOp,
Ops);
6421 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6433 return CreateStackStoreLoad(InOp, WidenVT);
6436SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6438 N->getOpcode(), SDLoc(
N),
6439 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6440 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6446 EVT VT =
N->getValueType(0);
6450 EVT EltVT =
N->getOperand(0).getValueType();
6453 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6457 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6458 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6460 return DAG.getBuildVector(WidenVT, dl, NewOps);
6464 EVT InVT =
N->getOperand(0).getValueType();
6465 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6467 unsigned NumOperands =
N->getNumOperands();
6469 bool InputWidened =
false;
6473 if (WidenNumElts % NumInElts == 0) {
6475 unsigned NumConcat = WidenNumElts / NumInElts;
6476 SDValue UndefVal = DAG.getPOISON(InVT);
6478 for (
unsigned i=0; i < NumOperands; ++i)
6479 Ops[i] =
N->getOperand(i);
6480 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6485 InputWidened =
true;
6486 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6489 for (i=1; i < NumOperands; ++i)
6490 if (!
N->getOperand(i).isUndef())
6493 if (i == NumOperands)
6496 return GetWidenedVector(
N->getOperand(0));
6498 if (NumOperands == 2) {
6500 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6505 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6506 for (
unsigned i = 0; i < NumInElts; ++i) {
6508 MaskOps[i + NumInElts] = i + WidenNumElts;
6510 return DAG.getVectorShuffle(WidenVT, dl,
6511 GetWidenedVector(
N->getOperand(0)),
6512 GetWidenedVector(
N->getOperand(1)),
6519 SDValue WideVec = DAG.getPOISON(WidenVT);
6521 for (
unsigned I = 0;
I < NumOperands; ++
I)
6523 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6534 for (
unsigned i=0; i < NumOperands; ++i) {
6537 InOp = GetWidenedVector(InOp);
6538 for (
unsigned j = 0;
j < NumInElts; ++
j)
6539 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6541 SDValue UndefVal = DAG.getPOISON(EltVT);
6542 for (; Idx < WidenNumElts; ++Idx)
6543 Ops[Idx] = UndefVal;
6544 return DAG.getBuildVector(WidenVT, dl,
Ops);
6547SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6548 EVT VT =
N->getValueType(0);
6549 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6550 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6557SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6558 EVT VT =
N->getValueType(0);
6560 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6565 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6567 InOp = GetWidenedVector(InOp);
6573 if (IdxVal == 0 && InVT == WidenVT)
6580 assert(IdxVal % VTNumElts == 0 &&
6581 "Expected Idx to be a multiple of subvector minimum vector length");
6582 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6595 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6596 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6597 "down type's element count");
6604 for (;
I < VTNumElts / GCD; ++
I)
6606 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6607 for (;
I < WidenNumElts / GCD; ++
I)
6615 Align Alignment = DAG.getReducedAlign(InVT,
false);
6629 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6636 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6637 return DAG.getMaskedLoad(
6638 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6646 for (i = 0; i < VTNumElts; ++i)
6647 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6649 SDValue UndefVal = DAG.getPOISON(EltVT);
6650 for (; i < WidenNumElts; ++i)
6652 return DAG.getBuildVector(WidenVT, dl,
Ops);
6658 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6663SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6664 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6667 N->getOperand(1),
N->getOperand(2));
6676 "Load width must be less than or equal to first value type width");
6685 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6702 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6713 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6714 EVT LdVT =
LD->getMemoryVT();
6723 TypeSize WidthDiff = WidenWidth - LdWidth;
6726 std::optional<EVT> FirstVT =
6727 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6734 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6737 Chain, BasePtr,
LD->getMemOperand());
6741 FirstVTWidth, dl, DAG);
6759 if (!
LD->getMemoryVT().isByteSized()) {
6761 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6763 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6772 EVT VT =
LD->getValueType(0);
6773 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6774 EVT WideMaskVT = getSetCCResultType(WideVT);
6777 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6778 TLI.isTypeLegal(WideMaskVT)) {
6781 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6785 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6786 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6798 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6800 Result = GenWidenVectorLoads(LdChain, LD);
6807 if (LdChain.
size() == 1)
6808 NewChain = LdChain[0];
6814 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6825 SDValue NewLoad = DAG.getMaskedLoad(
6826 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6827 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6828 LD->getAddressingMode(),
LD->getExtensionType());
6838 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6840 SDValue EVL =
N->getVectorLength();
6847 "Unable to widen binary VP op");
6848 Mask = GetWidenedVector(Mask);
6849 assert(
Mask.getValueType().getVectorElementCount() ==
6850 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6851 .getVectorElementCount() &&
6852 "Unable to widen vector load");
6855 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6856 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6857 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6865 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6867 SDValue EVL =
N->getVectorLength();
6873 "Unable to widen binary VP op");
6874 Mask = GetWidenedVector(Mask);
6875 assert(
Mask.getValueType().getVectorElementCount() ==
6876 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6877 .getVectorElementCount() &&
6878 "Unable to widen vector load");
6880 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6881 Mask, EVL,
N->getMemOperand());
6894 "Unable to widen VP strided load");
6895 Mask = GetWidenedVector(Mask);
6897 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6898 assert(
Mask.getValueType().getVectorElementCount() ==
6900 "Data and mask vectors should have the same number of elements");
6902 SDValue Res = DAG.getStridedLoadVP(
6903 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6904 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6905 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6906 N->isExpandingLoad());
6914SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6919 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6921 Mask.getValueType().getVectorElementType(),
6924 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6925 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6926 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6928 WideMask, WidePassthru);
6932 EVT VT =
N->getValueType(0);
6933 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6935 EVT MaskVT =
Mask.getValueType();
6936 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6945 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6946 TLI.isTypeLegal(WideMaskVT) &&
6952 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6953 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6957 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6958 N->getMemoryVT(),
N->getMemOperand());
6962 if (!
N->getPassThru()->isUndef()) {
6966 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6967 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6968 DAG.getPOISON(WidenVT), EVL);
6979 Mask = ModifyToType(Mask, WideMaskVT,
true);
6981 SDValue Res = DAG.getMaskedLoad(
6982 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6983 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6984 ExtType,
N->isExpandingLoad());
6993 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6995 EVT MaskVT =
Mask.getValueType();
6996 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7004 Mask = ModifyToType(Mask, WideMaskVT,
true);
7009 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7010 Index = ModifyToType(Index, WideIndexVT);
7016 N->getMemoryVT().getScalarType(), WideEC);
7017 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7018 WideMemVT, dl,
Ops,
N->getMemOperand(),
7019 N->getIndexType(),
N->getExtensionType());
7028 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7036 N->getMemoryVT().getScalarType(), WideEC);
7037 Mask = GetWidenedMask(Mask, WideEC);
7040 Mask,
N->getVectorLength()};
7041 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7042 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7051 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7052 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7080 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7081 return N->getOperand(OpNo).getValueType();
7089 N =
N.getOperand(0);
7091 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7092 if (!
N->getOperand(i)->isUndef())
7094 N =
N.getOperand(0);
7098 N =
N.getOperand(0);
7100 N =
N.getOperand(0);
7127 { MaskVT, MVT::Other },
Ops);
7128 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7136 LLVMContext &Ctx = *DAG.getContext();
7139 if (MaskScalarBits < ToMaskScalBits) {
7143 }
else if (MaskScalarBits > ToMaskScalBits) {
7149 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7151 "Mask should have the right element size by now.");
7154 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7156 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7159 EVT SubVT =
Mask->getValueType(0);
7165 assert((
Mask->getValueType(0) == ToMaskVT) &&
7166 "A mask of ToMaskVT should have been produced by now.");
7176 LLVMContext &Ctx = *DAG.getContext();
7187 EVT CondVT =
Cond->getValueType(0);
7191 EVT VSelVT =
N->getValueType(0);
7203 EVT FinalVT = VSelVT;
7214 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7215 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7222 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7230 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7233 EVT ToMaskVT = VSelVT;
7240 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7256 if (ScalarBits0 != ScalarBits1) {
7257 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7258 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7270 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7271 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7272 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7275 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7283 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7288 unsigned Opcode =
N->getOpcode();
7290 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7291 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7292 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7294 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7300 Cond1 = GetWidenedVector(Cond1);
7308 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7309 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7314 Cond1 = ModifyToType(Cond1, CondWidenVT);
7317 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7318 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7320 if (Opcode == ISD::VP_MERGE)
7321 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7323 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7327 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7328 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7331 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7335 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7336 return DAG.getUNDEF(WidenVT);
7340 EVT VT =
N->getValueType(0);
7343 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7347 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7348 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7351 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7352 for (
unsigned i = 0; i != NumElts; ++i) {
7353 int Idx =
N->getMaskElt(i);
7354 if (Idx < (
int)NumElts)
7357 NewMask[i] = Idx - NumElts + WidenNumElts;
7359 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7363 EVT VT =
N->getValueType(0);
7367 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7368 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7374 unsigned IdxVal = WidenNumElts - VTNumElts;
7387 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7390 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7391 "down type's element count");
7394 for (; i < VTNumElts / GCD; ++i)
7396 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7397 for (; i < WidenNumElts / GCD; ++i)
7405 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7406 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7408 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7412SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7413 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7417void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7418 EVT VT =
N->getValueType(0);
7421 unsigned Factor =
N->getNumOperands();
7424 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7428 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7429 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7438 for (
unsigned Idx = 0; Idx != Factor; ++Idx)
7439 Slices[Idx] = Interleaved.
getValue(Idx);
7443 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7444 SDValue Narrow = DAG.getExtractSubvector(
7447 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7448 SetWidenedVector(
SDValue(
N, Idx), Wide);
7454 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7455 EVT SourceVT =
N->getOperand(0).getValueType();
7460 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7461 N->getOperand(0), 0);
7462 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7463 N->getOperand(2), 0);
7465 N->getOperand(1), WideMask,
N->getFlags());
7468void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7469 EVT VT =
N->getValueType(0);
7472 unsigned Factor =
N->getNumOperands();
7475 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7488 SDValue PackedWidenVec = DAG.getInsertSubvector(
7489 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7493 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7494 NewOps[Idx] = DAG.getExtractSubvector(
7495 DL, WidenVT, PackedWidenVec,
7502 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7507 assert(
N->getValueType(0).isVector() &&
7508 N->getOperand(0).getValueType().isVector() &&
7509 "Operands must be vectors");
7510 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7523 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7524 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7531 InOp1 = GetWidenedVector(InOp1);
7532 InOp2 = GetWidenedVector(InOp2);
7535 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7546 "Input not widened to expected type!");
7548 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7553 assert(
N->getValueType(0).isVector() &&
7554 N->getOperand(1).getValueType().isVector() &&
7555 "Operands must be vectors");
7556 EVT VT =
N->getValueType(0);
7557 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7567 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7572 for (
unsigned i = 0; i != NumElts; ++i) {
7573 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7574 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7576 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7577 {Chain, LHSElem, RHSElem, CC});
7578 Chains[i] = Scalars[i].getValue(1);
7579 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7580 DAG.getBoolConstant(
true, dl, EltVT, VT),
7581 DAG.getBoolConstant(
false, dl, EltVT, VT));
7585 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7587 return DAG.getBuildVector(WidenVT, dl, Scalars);
7593bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7594 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7598 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7601 switch (
N->getOpcode()) {
7604 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7612 Res = WidenVecOp_FAKE_USE(
N);
7618 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7622 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7623 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7624 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7629 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7631 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7632 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7634 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7635 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7645 Res = WidenVecOp_UnrollVectorOp(
N);
7652 Res = WidenVecOp_EXTEND(
N);
7657 Res = WidenVecOp_CMP(
N);
7675 Res = WidenVecOp_Convert(
N);
7680 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7698 Res = WidenVecOp_VECREDUCE(
N);
7702 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7704 case ISD::VP_REDUCE_FADD:
7705 case ISD::VP_REDUCE_SEQ_FADD:
7706 case ISD::VP_REDUCE_FMUL:
7707 case ISD::VP_REDUCE_SEQ_FMUL:
7708 case ISD::VP_REDUCE_ADD:
7709 case ISD::VP_REDUCE_MUL:
7710 case ISD::VP_REDUCE_AND:
7711 case ISD::VP_REDUCE_OR:
7712 case ISD::VP_REDUCE_XOR:
7713 case ISD::VP_REDUCE_SMAX:
7714 case ISD::VP_REDUCE_SMIN:
7715 case ISD::VP_REDUCE_UMAX:
7716 case ISD::VP_REDUCE_UMIN:
7717 case ISD::VP_REDUCE_FMAX:
7718 case ISD::VP_REDUCE_FMIN:
7719 case ISD::VP_REDUCE_FMAXIMUM:
7720 case ISD::VP_REDUCE_FMINIMUM:
7721 Res = WidenVecOp_VP_REDUCE(
N);
7725 Res = WidenVecOp_CttzElements(
N);
7727 case ISD::VP_CTTZ_ELTS:
7728 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7729 Res = WidenVecOp_VP_CttzElements(
N);
7732 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7735 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
7740 if (!Res.
getNode())
return false;
7748 if (
N->isStrictFPOpcode())
7750 "Invalid operand expansion");
7753 "Invalid operand expansion");
7755 ReplaceValueWith(
SDValue(
N, 0), Res);
7761 EVT VT =
N->getValueType(0);
7766 "Unexpected type action");
7767 InOp = GetWidenedVector(InOp);
7770 "Input wasn't widened!");
7778 EVT FixedEltVT = FixedVT.getVectorElementType();
7779 if (TLI.isTypeLegal(FixedVT) &&
7781 FixedEltVT == InEltVT) {
7783 "Not enough elements in the fixed type for the operand!");
7785 "We can't have the same type as we started with!");
7787 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7789 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7798 return WidenVecOp_Convert(
N);
7803 switch (
N->getOpcode()) {
7818 EVT OpVT =
N->getOperand(0).getValueType();
7819 EVT ResVT =
N->getValueType(0);
7826 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7827 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7833 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7834 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7836 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7843 return DAG.UnrollVectorOp(
N);
7848 EVT ResultVT =
N->getValueType(0);
7850 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7853 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7859 {WideArg,
Test},
N->getFlags());
7865 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7867 EVT OpVT =
N->getOperand(0).getValueType();
7870 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7875 EVT VT =
N->getValueType(0);
7881 "Unexpected type action");
7882 InOp = GetWidenedVector(InOp);
7884 unsigned Opcode =
N->getOpcode();
7889 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7892 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7893 return DAG.getNode(Opcode, dl, VT,
Op);
7900 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7902 if (
N->isStrictFPOpcode()) {
7904 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7907 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7908 {
N->getOperand(0), InOp });
7913 Res = MakeConvertNode(WideVT, InOp);
7915 return DAG.getExtractSubvector(dl, VT, Res, 0);
7923 if (
N->isStrictFPOpcode()) {
7926 for (
unsigned i=0; i < NumElts; ++i) {
7927 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7928 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7932 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7934 for (
unsigned i = 0; i < NumElts; ++i) {
7935 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7936 Ops[i] = MakeConvertNode(EltVT, Elt);
7940 return DAG.getBuildVector(VT, dl,
Ops);
7944 EVT DstVT =
N->getValueType(0);
7945 SDValue Src = GetWidenedVector(
N->getOperand(0));
7946 EVT SrcVT = Src.getValueType();
7953 if (TLI.isTypeLegal(WideDstVT)) {
7955 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7958 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7962 return DAG.UnrollVectorOp(
N);
7966 EVT VT =
N->getValueType(0);
7967 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7975 if (!VT.
isVector() && VT != MVT::x86mmx &&
7979 if (TLI.isTypeLegal(NewVT)) {
7981 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7993 ElementCount NewNumElts =
7995 .divideCoefficientBy(EltSize);
7997 if (TLI.isTypeLegal(NewVT)) {
7999 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8004 return CreateStackStoreLoad(InOp, VT);
8012 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8013 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8018 EVT VT =
N->getValueType(0);
8020 EVT InVT =
N->getOperand(0).getValueType();
8025 unsigned NumOperands =
N->getNumOperands();
8026 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8028 for (i = 1; i < NumOperands; ++i)
8029 if (!
N->getOperand(i).isUndef())
8032 if (i == NumOperands)
8033 return GetWidenedVector(
N->getOperand(0));
8043 for (
unsigned i=0; i < NumOperands; ++i) {
8047 "Unexpected type action");
8048 InOp = GetWidenedVector(InOp);
8049 for (
unsigned j = 0;
j < NumInElts; ++
j)
8050 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8052 return DAG.getBuildVector(VT, dl,
Ops);
8055SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8056 EVT VT =
N->getValueType(0);
8061 SubVec = GetWidenedVector(SubVec);
8066 bool IndicesValid =
false;
8069 IndicesValid =
true;
8073 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8074 Attribute::VScaleRange);
8079 IndicesValid =
true;
8085 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8091 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8098 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8105 Align Alignment = DAG.getReducedAlign(VT,
false);
8120 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8128 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8129 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8134 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8139 unsigned Idx =
N->getConstantOperandVal(2);
8145 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8151SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8152 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8154 N->getValueType(0), InOp,
N->getOperand(1));
8157SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8158 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8160 N->getValueType(0), InOp,
N->getOperand(1));
8163SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8165 EVT ResVT =
N->getValueType(0);
8168 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8174 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8182 "Widened input size must be a multiple of result element size");
8185 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8187 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8188 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8196 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8197 return TLI.scalarizeVectorStore(ST, DAG);
8199 if (
ST->isTruncatingStore())
8200 return TLI.scalarizeVectorStore(ST, DAG);
8210 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8211 EVT WideMaskVT = getSetCCResultType(WideVT);
8213 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8214 TLI.isTypeLegal(WideMaskVT)) {
8217 StVal = GetWidenedVector(StVal);
8219 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8221 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8222 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8223 ST->getAddressingMode());
8227 if (GenWidenVectorStores(StChain, ST)) {
8228 if (StChain.
size() == 1)
8237 SDValue WideStVal = GetWidenedVector(StVal);
8241 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8242 ST->getOffset(), Mask,
ST->getMemoryVT(),
8243 ST->getMemOperand(),
ST->getAddressingMode(),
8244 ST->isTruncatingStore());
8251 EVT StVT =
ST->getMemoryVT();
8254 SDValue StVal = GetWidenedVector(
ST->getVal());
8259 TypeSize WidthDiff = WidenWidth - StWidth;
8265 std::optional<EVT> FirstVT =
8266 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8271 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8277 ST->getBasePtr(),
ST->getMemOperand());
8280SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8281 assert((OpNo == 1 || OpNo == 3) &&
8282 "Can widen only data or mask operand of vp_store");
8290 StVal = GetWidenedVector(StVal);
8296 "Unable to widen VP store");
8297 Mask = GetWidenedVector(Mask);
8299 Mask = GetWidenedVector(Mask);
8305 "Unable to widen VP store");
8306 StVal = GetWidenedVector(StVal);
8309 assert(
Mask.getValueType().getVectorElementCount() ==
8311 "Mask and data vectors should have the same number of elements");
8312 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8313 ST->getOffset(), Mask,
ST->getVectorLength(),
8314 ST->getMemoryVT(),
ST->getMemOperand(),
8315 ST->getAddressingMode(),
ST->isTruncatingStore(),
8316 ST->isCompressingStore());
8321 assert((OpNo == 1 || OpNo == 4) &&
8322 "Can widen only data or mask operand of vp_strided_store");
8331 "Unable to widen VP strided store");
8335 "Unable to widen VP strided store");
8337 StVal = GetWidenedVector(StVal);
8338 Mask = GetWidenedVector(Mask);
8341 Mask.getValueType().getVectorElementCount() &&
8342 "Data and mask vectors should have the same number of elements");
8344 return DAG.getStridedStoreVP(
8351SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8352 assert((OpNo == 1 || OpNo == 4) &&
8353 "Can widen only data or mask operand of mstore");
8356 EVT MaskVT =
Mask.getValueType();
8361 EVT WideVT, WideMaskVT;
8364 StVal = GetWidenedVector(StVal);
8371 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8378 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8380 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8381 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8390 Mask = ModifyToType(Mask, WideMaskVT,
true);
8393 Mask = ModifyToType(Mask, WideMaskVT,
true);
8395 StVal = ModifyToType(StVal, WideVT);
8398 assert(
Mask.getValueType().getVectorElementCount() ==
8400 "Mask and data vectors should have the same number of elements");
8407SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8408 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8410 SDValue DataOp = MG->getPassThru();
8412 SDValue Scale = MG->getScale();
8420 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8421 MG->getMemOperand(), MG->getIndexType(),
8422 MG->getExtensionType());
8428SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8437 DataOp = GetWidenedVector(DataOp);
8441 EVT IndexVT =
Index.getValueType();
8444 Index = ModifyToType(Index, WideIndexVT);
8447 EVT MaskVT =
Mask.getValueType();
8450 Mask = ModifyToType(Mask, WideMaskVT,
true);
8455 }
else if (OpNo == 4) {
8457 Index = GetWidenedVector(Index);
8463 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8468SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8477 DataOp = GetWidenedVector(DataOp);
8478 Index = GetWidenedVector(Index);
8480 Mask = GetWidenedMask(Mask, WideEC);
8483 }
else if (OpNo == 3) {
8485 Index = GetWidenedVector(Index);
8492 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8497 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8498 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8500 EVT VT =
N->getValueType(0);
8515 SVT, InOp0, InOp1,
N->getOperand(2));
8521 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8523 EVT OpVT =
N->getOperand(0).getValueType();
8526 return DAG.getNode(ExtendCode, dl, VT, CC);
8536 EVT VT =
N->getValueType(0);
8538 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8545 for (
unsigned i = 0; i != NumElts; ++i) {
8546 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8547 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8549 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8550 {Chain, LHSElem, RHSElem, CC});
8551 Chains[i] = Scalars[i].getValue(1);
8552 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8553 DAG.getBoolConstant(
true, dl, EltVT, VT),
8554 DAG.getBoolConstant(
false, dl, EltVT, VT));
8558 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8560 return DAG.getBuildVector(VT, dl, Scalars);
8584 SDValue Op = GetWidenedVector(
N->getOperand(0));
8585 EVT VT =
N->getValueType(0);
8586 EVT OrigVT =
N->getOperand(0).getValueType();
8587 EVT WideVT =
Op.getValueType();
8589 SDNodeFlags
Flags =
N->getFlags();
8591 unsigned Opc =
N->getOpcode();
8593 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8594 assert(NeutralElem &&
"Neutral element must exist");
8604 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8611 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8612 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8618 unsigned GCD = std::gcd(OrigElts, WideElts);
8621 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8622 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8623 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8624 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8627 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8628 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8630 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8639 EVT VT =
N->getValueType(0);
8641 EVT WideVT =
Op.getValueType();
8643 SDNodeFlags
Flags =
N->getFlags();
8645 unsigned Opc =
N->getOpcode();
8647 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8657 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8660 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8661 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8667 unsigned GCD = std::gcd(OrigElts, WideElts);
8670 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8671 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8672 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8673 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8676 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8677 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8679 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8683 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8686 SDValue Op = GetWidenedVector(
N->getOperand(1));
8688 Op.getValueType().getVectorElementCount());
8690 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8691 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8699 EVT VT =
N->getValueType(0);
8703 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8704 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8709 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8716 TLI.getTypeToTransformTo(*DAG.getContext(),
Source.getValueType());
8720 WideSource = GetWidenedVector(Source);
8725 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8728 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8735 EVT SrcVT =
Source.getValueType();
8739 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8740 {Source, Mask, N->getOperand(2)},
N->getFlags());
8743SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8746 EVT OrigMaskVT =
Mask.getValueType();
8747 SDValue WideMask = GetWidenedVector(Mask);
8753 if (OrigElts != WideElts) {
8754 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8756 Mask, DAG.getVectorIdxConstant(0,
DL));
8763SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
8766 EVT ResVT =
N->getValueType(0);
8767 EVT SourceVT =
N->getOperand(0).getValueType();
8768 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8773 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
8774 N->getOperand(0), 0);
8775 SDValue WideMask = DAG.getInsertSubvector(
8776 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
8778 N->getOperand(1), WideMask,
N->getFlags());
8779 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
8783 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
8789 return TLI.expandVectorMatch(
N, DAG);
8791 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
8795 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
8796 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
8799 N->getOperand(0), WideNeedle,
N->getOperand(2),
8817 unsigned WidenEx = 0) {
8822 unsigned AlignInBits =
Align*8;
8824 EVT RetVT = WidenEltVT;
8829 if (Width == WidenEltWidth)
8840 (WidenWidth % MemVTWidth) == 0 &&
8842 (MemVTWidth <= Width ||
8843 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8844 if (MemVTWidth == WidenWidth)
8863 (WidenWidth % MemVTWidth) == 0 &&
8865 (MemVTWidth <= Width ||
8866 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8875 return std::nullopt;
8886 unsigned Start,
unsigned End) {
8887 SDLoc dl(LdOps[Start]);
8888 EVT LdTy = LdOps[Start].getValueType();
8896 for (
unsigned i = Start + 1; i != End; ++i) {
8897 EVT NewLdTy = LdOps[i].getValueType();
8898 if (NewLdTy != LdTy) {
8917 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8918 EVT LdVT =
LD->getMemoryVT();
8928 AAMDNodes AAInfo =
LD->getAAInfo();
8932 TypeSize WidthDiff = WidenWidth - LdWidth;
8939 std::optional<EVT> FirstVT =
8940 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8947 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8952 std::optional<EVT> NewVT = FirstVT;
8953 TypeSize RemainingWidth = LdWidth;
8954 TypeSize NewVTWidth = FirstVTWidth;
8956 RemainingWidth -= NewVTWidth;
8963 NewVTWidth = NewVT->getSizeInBits();
8969 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8970 LD->getBaseAlign(), MMOFlags, AAInfo);
8983 MachinePointerInfo MPI =
LD->getPointerInfo();
8989 for (EVT MemVT : MemVTs) {
8990 Align NewAlign = ScaledOffset == 0
8991 ?
LD->getBaseAlign()
8994 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
9002 unsigned End = LdOps.
size();
9013 EVT LdTy = LdOps[i].getValueType();
9016 for (--i; i >= 0; --i) {
9017 LdTy = LdOps[i].getValueType();
9024 ConcatOps[--Idx] = LdOps[i];
9025 for (--i; i >= 0; --i) {
9026 EVT NewLdTy = LdOps[i].getValueType();
9027 if (NewLdTy != LdTy) {
9037 for (;
j != End-Idx; ++
j)
9038 WidenOps[j] = ConcatOps[Idx+j];
9040 WidenOps[j] = DAG.getPOISON(LdTy);
9047 ConcatOps[--Idx] = LdOps[i];
9052 ArrayRef(&ConcatOps[Idx], End - Idx));
9058 SDValue UndefVal = DAG.getPOISON(LdTy);
9061 for (; i != End-Idx; ++i)
9062 WidenOps[i] = ConcatOps[Idx+i];
9064 WidenOps[i] = UndefVal;
9075 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9076 EVT LdVT =
LD->getMemoryVT();
9085 AAMDNodes AAInfo =
LD->getAAInfo();
9099 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9100 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9106 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9107 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9108 LD->getBaseAlign(), MMOFlags, AAInfo);
9113 SDValue UndefVal = DAG.getPOISON(EltVT);
9114 for (; i != WidenNumElts; ++i)
9117 return DAG.getBuildVector(WidenVT, dl,
Ops);
9128 AAMDNodes AAInfo =
ST->getAAInfo();
9129 SDValue ValOp = GetWidenedVector(
ST->getValue());
9132 EVT StVT =
ST->getMemoryVT();
9140 "Mismatch between store and value types");
9144 MachinePointerInfo MPI =
ST->getPointerInfo();
9154 std::optional<EVT> NewVT =
9159 TypeSize NewVTWidth = NewVT->getSizeInBits();
9162 StWidth -= NewVTWidth;
9163 MemVTs.
back().second++;
9167 for (
const auto &Pair : MemVTs) {
9168 EVT NewVT = Pair.first;
9169 unsigned Count = Pair.second;
9175 Align NewAlign = ScaledOffset == 0
9176 ?
ST->getBaseAlign()
9178 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9179 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9195 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9196 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9197 ST->getBaseAlign(), MMOFlags, AAInfo);
9214 bool FillWithZeroes) {
9219 "input and widen element type must match");
9221 "cannot modify scalable vectors in this way");
9234 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9236 for (
unsigned i = 1; i != NumConcat; ++i)
9243 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9246 "Scalable vectors should have been handled already.");
9254 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9256 for (Idx = 0; Idx < MinNumElts; ++Idx)
9257 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9259 SDValue UndefVal = DAG.getPOISON(EltVT);
9260 for (; Idx < WidenNumElts; ++Idx)
9261 Ops[Idx] = UndefVal;
9263 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9264 if (!FillWithZeroes)
9268 "We expect to never want to FillWithZeroes for non-integral types.");
9271 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9272 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9274 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9275 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.
@ 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.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
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.