35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
46 switch (
N->getOpcode()) {
49 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
58 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
66 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
72 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
84 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
86 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
92 R = ScalarizeVecRes_VecInregOp(
N);
143 R = ScalarizeVecRes_UnaryOp(
N);
146 R = ScalarizeVecRes_ADDRSPACECAST(
N);
152 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
209 R = ScalarizeVecRes_BinOp(
N);
216 R = ScalarizeVecRes_MaskedBinOp(
N);
221 R = ScalarizeVecRes_CMP(
N);
227 R = ScalarizeVecRes_TernaryOp(
N);
230#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
231 case ISD::STRICT_##DAGN:
232#include "llvm/IR/ConstrainedOps.def"
233 R = ScalarizeVecRes_StrictFPOp(
N);
238 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
247 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
257 R = ScalarizeVecRes_FIX(
N);
263 SetScalarizedVector(
SDValue(
N, ResNo), R);
267 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
268 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
269 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
275 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
276 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
278 EVT MaskVT =
Mask.getValueType();
283 Mask = GetScalarizedVector(Mask);
292 DAG.getConstant(1,
DL,
LHS.getValueType()));
294 LHS.getValueType(),
LHS, Divisor);
302 if (getTypeAction(
LHS.getValueType()) ==
304 LHS = GetScalarizedVector(
LHS);
305 RHS = GetScalarizedVector(
RHS);
307 EVT VT =
LHS.getValueType().getVectorElementType();
308 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
309 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
312 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
313 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
317 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
318 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
319 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
320 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
325 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
326 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
333DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
335 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
336 "Unexpected vector type!");
337 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
339 EVT VT0 =
N->getValueType(0);
340 EVT VT1 =
N->getValueType(1);
344 DAG.getNode(
N->getOpcode(), dl,
345 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
349 unsigned OtherNo = 1 - ResNo;
350 EVT OtherVT =
N->getValueType(OtherNo);
352 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
356 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
359 return SDValue(ScalarNode, ResNo);
364 unsigned NumOpers =
N->getNumOperands();
366 EVT ValueVTs[] = {VT, MVT::Other};
375 for (
unsigned i = 1; i < NumOpers; ++i) {
381 Oper = GetScalarizedVector(Oper);
390 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
391 Opers,
N->getFlags());
402 EVT ResVT =
N->getValueType(0);
403 EVT OvVT =
N->getValueType(1);
407 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
408 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
411 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
412 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
413 ScalarLHS = ElemsLHS[0];
414 ScalarRHS = ElemsRHS[0];
417 SDVTList ScalarVTs = DAG.getVTList(
419 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
420 {ScalarLHS, ScalarRHS},
N->getFlags())
424 unsigned OtherNo = 1 - ResNo;
425 EVT OtherVT =
N->getValueType(OtherNo);
427 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
431 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
434 return SDValue(ScalarNode, ResNo);
439 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
440 return GetScalarizedVector(
Op);
443SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
445 SDValue SourceValue =
N->getOperand(0);
446 SDValue SinkValue =
N->getOperand(1);
447 SDValue EltSizeInBytes =
N->getOperand(2);
448 SDValue LaneOffset =
N->getOperand(3);
456 if (IsReadAfterWrite)
464 EVT CmpVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
469 return DAG.getNode(
ISD::OR,
DL, CmpVT, Cmp,
476 Op = GetScalarizedVector(
Op);
477 EVT NewVT =
N->getValueType(0).getVectorElementType();
482SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
492SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
494 N->getValueType(0).getVectorElementType(),
495 N->getOperand(0),
N->getOperand(1));
501 EVT OpVT =
Op.getValueType();
505 Op = GetScalarizedVector(
Op);
508 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
511 N->getValueType(0).getVectorElementType(),
Op,
515SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
518 EVT OpVT =
Op.getValueType();
522 Op = GetScalarizedVector(
Op);
525 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
528 N->getValueType(0).getVectorElementType(),
Op,
532SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
533 SDValue Op = GetScalarizedVector(
N->getOperand(0));
534 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
538SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
543 if (
Op.getValueType() != EltVT)
551 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
552 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
562 assert(
N->isUnindexed() &&
"Indexed vector load?");
566 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
567 N->getBasePtr(), DAG.getUNDEF(
N->getBasePtr().getValueType()),
568 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
569 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
581 EVT OpVT =
Op.getValueType();
591 Op = GetScalarizedVector(
Op);
594 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
596 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
602 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
603 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
604 LHS, DAG.getValueType(ExtVT));
611 EVT OpVT =
Op.getValueType();
616 Op = GetScalarizedVector(
Op);
618 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
621 switch (
N->getOpcode()) {
633SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
636 EVT OpVT =
Op.getValueType();
646 Op = GetScalarizedVector(
Op);
649 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
652 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
653 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
654 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS);
657SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
669 EVT OpVT =
Cond.getValueType();
678 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
681 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
683 TLI.getBooleanContents(
false,
false);
690 if (TLI.getBooleanContents(
false,
false) !=
691 TLI.getBooleanContents(
false,
true)) {
695 EVT OpVT =
Cond->getOperand(0).getValueType();
697 VecBool = TLI.getBooleanContents(OpVT);
702 EVT CondVT =
Cond.getValueType();
703 if (ScalarBool != VecBool) {
704 switch (ScalarBool) {
712 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
719 Cond, DAG.getValueType(MVT::i1));
725 auto BoolVT = getSetCCResultType(CondVT);
726 if (BoolVT.bitsLT(CondVT))
729 return DAG.getSelect(SDLoc(
N),
731 GetScalarizedVector(
N->getOperand(2)));
735 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
736 return DAG.getSelect(SDLoc(
N),
737 LHS.getValueType(),
N->getOperand(0),
LHS,
738 GetScalarizedVector(
N->getOperand(2)));
742 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
744 N->getOperand(0),
N->getOperand(1),
745 LHS, GetScalarizedVector(
N->getOperand(3)),
750 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
753SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
757 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
759 return GetScalarizedVector(
N->getOperand(
Op));
762SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
764 EVT SrcVT = Src.getValueType();
769 Src = GetScalarizedVector(Src);
773 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
775 EVT DstVT =
N->getValueType(0).getVectorElementType();
776 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
780 assert(
N->getValueType(0).isVector() &&
781 N->getOperand(0).getValueType().isVector() &&
782 "Operand types must be vectors");
785 EVT OpVT =
LHS.getValueType();
786 EVT NVT =
N->getValueType(0).getVectorElementType();
791 LHS = GetScalarizedVector(
LHS);
792 RHS = GetScalarizedVector(
RHS);
795 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
796 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
806 return DAG.getNode(ExtendCode,
DL, NVT, Res);
817 Arg = GetScalarizedVector(Arg);
820 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
829 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
836bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
841 switch (
N->getOpcode()) {
844 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
851 Res = ScalarizeVecOp_BITCAST(
N);
854 Res = ScalarizeVecOp_FAKE_USE(
N);
868 Res = ScalarizeVecOp_UnaryOp(
N);
873 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
879 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
882 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
885 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
888 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
891 Res = ScalarizeVecOp_VSELECT(
N);
894 Res = ScalarizeVecOp_VSETCC(
N);
898 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
904 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
907 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
910 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
913 Res = ScalarizeVecOp_FP_EXTEND(
N);
930 Res = ScalarizeVecOp_VECREDUCE(
N);
934 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
938 Res = ScalarizeVecOp_CMP(
N);
941 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
945 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
951 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
956 if (!Res.
getNode())
return false;
964 "Invalid operand expansion");
966 ReplaceValueWith(
SDValue(
N, 0), Res);
973 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
975 N->getValueType(0), Elt);
980 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
981 "Fake Use: Unexpected vector type!");
982 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
983 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
989 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
990 "Unexpected vector type!");
991 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
993 N->getValueType(0).getScalarType(), Elt);
1001SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1002 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1003 "Unexpected vector type!");
1004 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1006 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1007 Elt,
N->getOperand(1));
1015SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1016 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1017 "Unexpected vector type!");
1018 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1020 {
N->getValueType(0).getScalarType(), MVT::Other },
1021 {
N->getOperand(0), Elt });
1031 ReplaceValueWith(
SDValue(
N, 0), Res);
1036SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1038 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1039 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1040 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1045SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1049 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1050 SDValue ContainingVec =
N->getOperand(0);
1058SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1059 EVT VT =
N->getValueType(0);
1060 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1072 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1073 EVT VT =
N->getValueType(0);
1075 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1083 assert(
N->getValueType(0).isVector() &&
1084 N->getOperand(0).getValueType().isVector() &&
1085 "Operand types must be vectors");
1086 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1088 EVT VT =
N->getValueType(0);
1089 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1090 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1092 EVT OpVT =
N->getOperand(0).getValueType();
1104 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1110SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1112 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1113 assert(
N->getValueType(0).isVector() &&
1114 N->getOperand(1).getValueType().isVector() &&
1115 "Operand types must be vectors");
1116 assert(
N->getValueType(0) == MVT::v1i1 &&
"Expected v1i1 type");
1118 EVT VT =
N->getValueType(0);
1120 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1121 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1124 EVT OpVT =
N->getOperand(1).getValueType();
1128 {Ch, LHS, RHS, CC});
1137 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1142 ReplaceValueWith(
SDValue(
N, 0), Res);
1149 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1150 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1153 if (
N->isTruncatingStore())
1154 return DAG.getTruncStore(
1155 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1156 N->getBasePtr(),
N->getPointerInfo(),
1157 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1158 N->getMemOperand()->getFlags(),
N->getAAInfo());
1160 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1161 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1162 N->getMemOperand()->getFlags(),
N->getAAInfo());
1167SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1168 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1169 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1171 N->getValueType(0).getVectorElementType(), Elt,
1176SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1178 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1179 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1182 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1192 ReplaceValueWith(
SDValue(
N, 0), Res);
1199 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1201 N->getValueType(0).getVectorElementType(), Elt);
1207SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1208 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1211 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1212 {
N->getOperand(0), Elt});
1221 ReplaceValueWith(
SDValue(
N, 0), Res);
1226 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1233SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1239 SDValue Op = GetScalarizedVector(VecOp);
1240 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1241 AccOp,
Op,
N->getFlags());
1245 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1246 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1253SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1261 EVT VT =
N->getValueType(0);
1262 return DAG.getConstant(0, SDLoc(
N), VT);
1269 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1270 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1272 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1273 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1274 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1277SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1278 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1281 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1282 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1291 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1303void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1308 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1311 switch (
N->getOpcode()) {
1314 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1323 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1331 case ISD::VP_SELECT: SplitRes_Select(
N,
Lo,
Hi);
break;
1347 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1350 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1359 case ISD::VP_LOAD_FF:
1362 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1369 case ISD::VP_GATHER:
1373 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1377 SplitVecRes_SETCC(
N,
Lo,
Hi);
1380 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1387 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1390 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1393 SplitVecRes_VECTOR_INTERLEAVE(
N);
1396 SplitVecRes_VAARG(
N,
Lo,
Hi);
1402 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1408 case ISD::VP_BITREVERSE:
1416 case ISD::VP_CTLZ_ZERO_UNDEF:
1418 case ISD::VP_CTTZ_ZERO_UNDEF:
1433 case ISD::VP_FFLOOR:
1438 case ISD::VP_FNEARBYINT:
1443 case ISD::VP_FP_EXTEND:
1445 case ISD::VP_FP_ROUND:
1447 case ISD::VP_FP_TO_SINT:
1449 case ISD::VP_FP_TO_UINT:
1455 case ISD::VP_LLRINT:
1457 case ISD::VP_FROUND:
1459 case ISD::VP_FROUNDEVEN:
1468 case ISD::VP_FROUNDTOZERO:
1470 case ISD::VP_SINT_TO_FP:
1472 case ISD::VP_TRUNCATE:
1474 case ISD::VP_UINT_TO_FP:
1478 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1481 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1487 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1493 case ISD::VP_SIGN_EXTEND:
1494 case ISD::VP_ZERO_EXTEND:
1495 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1517 case ISD::VP_FMINNUM:
1520 case ISD::VP_FMAXNUM:
1522 case ISD::VP_FMINIMUM:
1524 case ISD::VP_FMAXIMUM:
1533 case ISD::OR:
case ISD::VP_OR:
1553 case ISD::VP_FCOPYSIGN:
1554 SplitVecRes_BinOp(
N,
Lo,
Hi);
1560 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1567 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1571 SplitVecRes_CMP(
N,
Lo,
Hi);
1574#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1575 case ISD::STRICT_##DAGN:
1576#include "llvm/IR/ConstrainedOps.def"
1577 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1582 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1591 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1601 SplitVecRes_FIX(
N,
Lo,
Hi);
1603 case ISD::EXPERIMENTAL_VP_SPLICE:
1604 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1606 case ISD::EXPERIMENTAL_VP_REVERSE:
1607 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1613 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1616 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1625void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1627 uint64_t *ScaledOffset) {
1632 SDValue BytesIncrement = DAG.getVScale(
1635 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1637 *ScaledOffset += IncrementSize;
1647std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1648 return SplitMask(Mask, SDLoc(Mask));
1651std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1654 EVT MaskVT =
Mask.getValueType();
1656 GetSplitVector(Mask, MaskLo, MaskHi);
1658 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1659 return std::make_pair(MaskLo, MaskHi);
1664 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1666 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1669 const SDNodeFlags
Flags =
N->getFlags();
1670 unsigned Opcode =
N->getOpcode();
1671 if (
N->getNumOperands() == 2) {
1672 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1673 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1677 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1678 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1681 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1684 std::tie(EVLLo, EVLHi) =
1685 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1688 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1690 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1696 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1698 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1699 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(2));
1702 const SDNodeFlags
Flags =
N->getFlags();
1703 unsigned Opcode =
N->getOpcode();
1704 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1706 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1713 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1715 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1717 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1720 const SDNodeFlags
Flags =
N->getFlags();
1721 unsigned Opcode =
N->getOpcode();
1722 if (
N->getNumOperands() == 3) {
1723 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1724 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1728 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1729 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1732 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1735 std::tie(EVLLo, EVLHi) =
1736 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1739 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1741 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1745 LLVMContext &Ctxt = *DAG.getContext();
1751 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1753 GetSplitVector(
LHS, LHSLo, LHSHi);
1754 GetSplitVector(
RHS, RHSLo, RHSHi);
1756 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1757 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1761 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1762 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1767 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1769 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1773 unsigned Opcode =
N->getOpcode();
1774 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1776 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1785 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1792 switch (getTypeAction(InVT)) {
1806 GetExpandedOp(InOp,
Lo,
Hi);
1807 if (DAG.getDataLayout().isBigEndian())
1817 GetSplitVector(InOp,
Lo,
Hi);
1826 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1835 if (DAG.getDataLayout().isBigEndian())
1838 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1840 if (DAG.getDataLayout().isBigEndian())
1846void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1852 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1855 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1860 unsigned LaneOffset =
1863 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1865 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1872 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1875 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1878 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1883 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1885 unsigned NumSubvectors =
N->getNumOperands() / 2;
1886 if (NumSubvectors == 1) {
1887 Lo =
N->getOperand(0);
1888 Hi =
N->getOperand(1);
1893 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1902void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1909 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1924 GetSplitVector(Vec,
Lo,
Hi);
1927 EVT LoVT =
Lo.getValueType();
1937 if (IdxVal + SubElems <= LoElems) {
1945 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1947 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1953 SDValue WideSubVec = GetWidenedVector(SubVec);
1955 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1963 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1965 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1966 auto &MF = DAG.getMachineFunction();
1970 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1975 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1976 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1980 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1985 MachinePointerInfo MPI =
Load->getPointerInfo();
1986 IncrementPointer(Load, LoVT, MPI, StackPtr);
1989 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1998 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2003 EVT RHSVT =
RHS.getValueType();
2006 GetSplitVector(
RHS, RHSLo, RHSHi);
2008 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2023 SDValue FpValue =
N->getOperand(0);
2025 GetSplitVector(FpValue, ArgLo, ArgHi);
2027 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2029 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2038 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2042 std::tie(LoVT, HiVT) =
2046 DAG.getValueType(LoVT));
2048 DAG.getValueType(HiVT));
2053 unsigned Opcode =
N->getOpcode();
2060 GetSplitVector(N0, InLo, InHi);
2062 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2067 EVT OutLoVT, OutHiVT;
2068 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2070 assert((2 * OutNumElements) <= InNumElements &&
2071 "Illegal extend vector in reg split");
2080 SmallVector<int, 8> SplitHi(InNumElements, -1);
2081 for (
unsigned i = 0; i != OutNumElements; ++i)
2082 SplitHi[i] = i + OutNumElements;
2083 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2085 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2086 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2091 unsigned NumOps =
N->getNumOperands();
2095 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2105 for (
unsigned i = 1; i <
NumOps; ++i) {
2110 EVT InVT =
Op.getValueType();
2115 GetSplitVector(
Op, OpLo, OpHi);
2117 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2124 EVT LoValueVTs[] = {LoVT, MVT::Other};
2125 EVT HiValueVTs[] = {HiVT, MVT::Other};
2126 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2128 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2134 Lo.getValue(1),
Hi.getValue(1));
2138 ReplaceValueWith(
SDValue(
N, 1), Chain);
2141SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2143 EVT VT =
N->getValueType(0);
2154 else if (NE > ResNE)
2158 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2162 for (i = 0; i !=
NE; ++i) {
2163 Operands[0] = Chain;
2164 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2165 SDValue Operand =
N->getOperand(j);
2169 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2171 Operands[
j] = Operand;
2175 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2183 for (; i < ResNE; ++i)
2184 Scalars.
push_back(DAG.getPOISON(EltVT));
2188 ReplaceValueWith(
SDValue(
N, 1), Chain);
2192 return DAG.getBuildVector(VecVT, dl, Scalars);
2195void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2198 EVT ResVT =
N->getValueType(0);
2199 EVT OvVT =
N->getValueType(1);
2200 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2201 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2202 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2204 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2206 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2207 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2209 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2210 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2213 unsigned Opcode =
N->getOpcode();
2214 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2215 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2217 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2219 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2225 unsigned OtherNo = 1 - ResNo;
2226 EVT OtherVT =
N->getValueType(OtherNo);
2228 SetSplitVector(
SDValue(
N, OtherNo),
2234 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2238void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2244 GetSplitVector(Vec,
Lo,
Hi);
2247 unsigned IdxVal = CIdx->getZExtValue();
2248 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2249 if (IdxVal < LoNumElts) {
2251 Lo.getValueType(),
Lo, Elt, Idx);
2254 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2274 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2276 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2277 auto &MF = DAG.getMachineFunction();
2281 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2286 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2287 Store = DAG.getTruncStore(
2293 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2296 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2300 MachinePointerInfo MPI =
Load->getPointerInfo();
2301 IncrementPointer(Load, LoVT, MPI, StackPtr);
2303 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2306 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2307 if (LoVT !=
Lo.getValueType())
2309 if (HiVT !=
Hi.getValueType())
2317 assert(
N->getValueType(0).isScalableVector() &&
2318 "Only scalable vectors are supported for STEP_VECTOR");
2319 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2340 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2341 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2343 Hi = DAG.getPOISON(HiVT);
2355 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2361 EVT MemoryVT =
LD->getMemoryVT();
2363 AAMDNodes AAInfo =
LD->getAAInfo();
2365 EVT LoMemVT, HiMemVT;
2366 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2370 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2371 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2372 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2377 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2380 MachinePointerInfo MPI;
2381 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2384 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2393 ReplaceValueWith(
SDValue(LD, 1), Ch);
2398 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2401 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2407 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2408 Align Alignment =
LD->getBaseAlign();
2411 EVT MemoryVT =
LD->getMemoryVT();
2413 EVT LoMemVT, HiMemVT;
2414 bool HiIsEmpty =
false;
2415 std::tie(LoMemVT, HiMemVT) =
2416 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2421 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2424 GetSplitVector(Mask, MaskLo, MaskHi);
2426 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2431 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2433 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2439 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2440 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2448 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2449 LD->isExpandingLoad());
2451 MachinePointerInfo MPI;
2453 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2455 MPI =
LD->getPointerInfo().getWithOffset(
2458 MMO = DAG.getMachineFunction().getMachineMemOperand(
2460 Alignment,
LD->getAAInfo(),
LD->getRanges());
2462 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2463 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2464 LD->isExpandingLoad());
2474 ReplaceValueWith(
SDValue(LD, 1), Ch);
2480 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2484 Align Alignment =
LD->getBaseAlign();
2491 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2494 GetSplitVector(Mask, MaskLo, MaskHi);
2496 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2500 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2502 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2507 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2510 Hi = DAG.getPOISON(HiVT);
2512 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2513 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2519 "Indexed VP strided load during type legalization!");
2521 "Unexpected indexed variable-length load offset");
2526 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2528 EVT LoMemVT, HiMemVT;
2529 bool HiIsEmpty =
false;
2530 std::tie(LoMemVT, HiMemVT) =
2531 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2536 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2539 GetSplitVector(Mask, LoMask, HiMask);
2541 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2545 std::tie(LoEVL, HiEVL) =
2549 Lo = DAG.getStridedLoadVP(
2576 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2583 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2594 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2602 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2607 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2617 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2620 GetSplitVector(Mask, MaskLo, MaskHi);
2622 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2626 EVT LoMemVT, HiMemVT;
2627 bool HiIsEmpty =
false;
2628 std::tie(LoMemVT, HiMemVT) =
2629 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2631 SDValue PassThruLo, PassThruHi;
2633 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2635 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2637 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2641 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2651 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2654 MachinePointerInfo MPI;
2661 MMO = DAG.getMachineFunction().getMachineMemOperand(
2665 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2677 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2685 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2693 }
Ops = [&]() -> Operands {
2695 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2698 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2701 EVT MemoryVT =
N->getMemoryVT();
2702 Align Alignment =
N->getBaseAlign();
2707 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2709 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2712 EVT LoMemVT, HiMemVT;
2714 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2717 if (getTypeAction(
Ops.Index.getValueType()) ==
2719 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2721 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2724 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2726 Alignment,
N->getAAInfo(),
N->getRanges());
2729 SDValue PassThru = MGT->getPassThru();
2730 SDValue PassThruLo, PassThruHi;
2733 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2735 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2740 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2741 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2742 OpsLo, MMO, IndexTy, ExtType);
2744 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2745 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2746 OpsHi, MMO, IndexTy, ExtType);
2750 std::tie(EVLLo, EVLHi) =
2751 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2753 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2754 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2755 MMO, VPGT->getIndexType());
2757 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2758 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2759 MMO, VPGT->getIndexType());
2769 ReplaceValueWith(
SDValue(
N, 1), Ch);
2783 EVT VecVT =
N->getValueType(0);
2785 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2786 bool HasCustomLowering =
false;
2793 HasCustomLowering =
true;
2799 SDValue Passthru =
N->getOperand(2);
2800 if (!HasCustomLowering) {
2801 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2802 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2809 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2810 std::tie(LoMask, HiMask) = SplitMask(Mask);
2812 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2817 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2818 MachineFunction &MF = DAG.getMachineFunction();
2830 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2832 SDValue Chain = DAG.getEntryNode();
2833 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2837 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2842 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2846 assert(
N->getValueType(0).isVector() &&
2847 N->getOperand(0).getValueType().isVector() &&
2848 "Operand types must be vectors");
2852 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2856 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2858 GetSplitVector(
N->getOperand(0), LL, LH);
2860 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2862 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2864 GetSplitVector(
N->getOperand(1), RL, RH);
2866 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2869 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2870 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2872 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2873 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2874 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2875 std::tie(EVLLo, EVLHi) =
2876 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2877 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2879 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2889 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2893 EVT InVT =
N->getOperand(0).getValueType();
2895 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2897 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2899 const SDNodeFlags
Flags =
N->getFlags();
2900 unsigned Opcode =
N->getOpcode();
2901 if (
N->getNumOperands() <= 2) {
2904 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2905 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2907 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2908 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2913 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2914 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2917 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2920 std::tie(EVLLo, EVLHi) =
2921 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2924 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2930 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2934 EVT InVT =
N->getOperand(0).getValueType();
2936 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2938 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2941 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2942 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2943 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2944 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2947void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2952 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2953 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2957 EVT InVT =
N->getOperand(0).getValueType();
2959 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2961 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2963 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2964 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
2966 SDNode *HiNode =
Hi.getNode();
2967 SDNode *LoNode =
Lo.getNode();
2970 unsigned OtherNo = 1 - ResNo;
2971 EVT OtherVT =
N->getValueType(OtherNo);
2979 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2986 EVT SrcVT =
N->getOperand(0).getValueType();
2987 EVT DestVT =
N->getValueType(0);
2989 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3006 LLVMContext &Ctx = *DAG.getContext();
3010 EVT SplitLoVT, SplitHiVT;
3011 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3012 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3013 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3014 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3015 N->dump(&DAG);
dbgs() <<
"\n");
3016 if (!
N->isVPOpcode()) {
3019 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3021 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3023 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3024 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3030 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
3031 N->getOperand(1),
N->getOperand(2));
3033 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3036 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3039 std::tie(EVLLo, EVLHi) =
3040 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3042 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
3043 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
3048 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3056 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3057 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3063 return N.getResNo() == 0 &&
3067 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3069 ArrayRef<int>
Mask) {
3072 "Expected build vector node.");
3075 for (
unsigned I = 0;
I < NewElts; ++
I) {
3078 unsigned Idx =
Mask[
I];
3080 Ops[
I] = Input2.getOperand(Idx - NewElts);
3082 Ops[
I] = Input1.getOperand(Idx);
3087 return DAG.getBuildVector(NewVT,
DL,
Ops);
3093 SmallVector<int> OrigMask(
N->getMask());
3095 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3096 &
DL](SmallVectorImpl<int> &
Mask) {
3098 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3099 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3110 for (
auto &
P : ShufflesIdxs) {
3111 if (
P.second.size() < 2)
3115 for (
int &Idx : Mask) {
3118 unsigned SrcRegIdx = Idx / NewElts;
3119 if (Inputs[SrcRegIdx].
isUndef()) {
3127 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3132 Idx = MaskElt % NewElts +
3133 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3139 Inputs[
P.second[0]] =
P.first.first;
3140 Inputs[
P.second[1]] =
P.first.second;
3143 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3146 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3147 for (
int &Idx : Mask) {
3150 unsigned SrcRegIdx = Idx / NewElts;
3151 if (Inputs[SrcRegIdx].
isUndef()) {
3158 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3159 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3162 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3164 if (UsedSubVector.count() > 1) {
3166 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3167 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3169 if (Pairs.
empty() || Pairs.
back().size() == 2)
3171 if (UsedSubVector.test(2 *
I)) {
3172 Pairs.
back().emplace_back(
I, 0);
3174 assert(UsedSubVector.test(2 *
I + 1) &&
3175 "Expected to be used one of the subvectors.");
3176 Pairs.
back().emplace_back(
I, 1);
3179 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3181 for (
int &Idx : Mask) {
3184 unsigned SrcRegIdx = Idx / NewElts;
3186 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3187 return Idxs.front().first == SrcRegIdx ||
3188 Idxs.back().first == SrcRegIdx;
3190 if (It == Pairs.
end())
3192 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3193 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3196 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3197 Inputs[Idxs.front().first] = DAG.
getNode(
3199 Inputs[Idxs.front().first].getValueType(),
3200 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3201 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3210 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3214 if (Shuffle->getOperand(0).getValueType() != NewVT)
3217 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3218 !Shuffle->isSplat()) {
3220 }
else if (!Inputs[
I].hasOneUse() &&
3221 !Shuffle->getOperand(1).isUndef()) {
3223 for (
int &Idx : Mask) {
3226 unsigned SrcRegIdx = Idx / NewElts;
3229 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3234 int OpIdx = MaskElt / NewElts;
3248 if (Shuffle->getOperand(
OpIdx).isUndef())
3250 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3251 if (It == std::end(Inputs))
3253 int FoundOp = std::distance(std::begin(Inputs), It);
3256 for (
int &Idx : Mask) {
3259 unsigned SrcRegIdx = Idx / NewElts;
3262 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3267 int MaskIdx = MaskElt / NewElts;
3268 if (
OpIdx == MaskIdx)
3269 Idx = MaskElt % NewElts + FoundOp * NewElts;
3280 for (
int &Idx : Mask) {
3283 unsigned SrcRegIdx = Idx / NewElts;
3286 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3287 int OpIdx = MaskElt / NewElts;
3290 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3296 TryPeekThroughShufflesInputs(OrigMask);
3298 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3299 NewElts](SmallVectorImpl<int> &
Mask) {
3300 SetVector<SDValue> UniqueInputs;
3301 SetVector<SDValue> UniqueConstantInputs;
3302 for (
const auto &
I : Inputs) {
3304 UniqueConstantInputs.
insert(
I);
3305 else if (!
I.isUndef())
3310 if (UniqueInputs.
size() != std::size(Inputs)) {
3311 auto &&UniqueVec = UniqueInputs.
takeVector();
3312 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3313 unsigned ConstNum = UniqueConstantVec.size();
3314 for (
int &Idx : Mask) {
3317 unsigned SrcRegIdx = Idx / NewElts;
3318 if (Inputs[SrcRegIdx].
isUndef()) {
3322 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3323 if (It != UniqueConstantVec.end()) {
3324 Idx = (Idx % NewElts) +
3325 NewElts * std::distance(UniqueConstantVec.begin(), It);
3326 assert(Idx >= 0 &&
"Expected defined mask idx.");
3329 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3330 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3331 Idx = (Idx % NewElts) +
3332 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3333 assert(Idx >= 0 &&
"Expected defined mask idx.");
3335 copy(UniqueConstantVec, std::begin(Inputs));
3336 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3339 MakeUniqueInputs(OrigMask);
3341 copy(Inputs, std::begin(OrigInputs));
3347 unsigned FirstMaskIdx =
High * NewElts;
3350 assert(!Output &&
"Expected default initialized initial value.");
3351 TryPeekThroughShufflesInputs(Mask);
3352 MakeUniqueInputs(Mask);
3354 copy(Inputs, std::begin(TmpInputs));
3357 bool SecondIteration =
false;
3358 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3363 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3364 SecondIteration =
true;
3365 return SecondIteration;
3368 Mask, std::size(Inputs), std::size(Inputs),
3370 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3371 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3372 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3374 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3376 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3377 DAG.getPOISON(NewVT), Mask);
3378 Inputs[Idx] = Output;
3380 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3381 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3382 unsigned Idx2,
bool ) {
3383 if (AccumulateResults(Idx1)) {
3386 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3388 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3389 Inputs[Idx2], Mask);
3393 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3395 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3396 TmpInputs[Idx2], Mask);
3398 Inputs[Idx1] = Output;
3400 copy(OrigInputs, std::begin(Inputs));
3405 EVT OVT =
N->getValueType(0);
3412 const Align Alignment =
3413 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3415 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3416 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3421 ReplaceValueWith(
SDValue(
N, 1), Chain);
3426 EVT DstVTLo, DstVTHi;
3427 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3431 EVT SrcVT =
N->getOperand(0).getValueType();
3433 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3435 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3437 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3438 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3444 GetSplitVector(
N->getOperand(0), InLo, InHi);
3455 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3456 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3461 EVT VT =
N->getValueType(0);
3468 Align Alignment = DAG.getReducedAlign(VT,
false);
3473 EVT PtrVT =
StackPtr.getValueType();
3474 auto &MF = DAG.getMachineFunction();
3478 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3481 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3487 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3488 DAG.getConstant(1,
DL, PtrVT));
3490 DAG.getConstant(EltWidth,
DL, PtrVT));
3492 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3494 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3495 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3496 DAG.getPOISON(PtrVT), Stride, TrueMask,
3499 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3501 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3506 EVT VT =
N->getValueType(0);
3518 EVL1 = ZExtPromotedInteger(EVL1);
3520 Align Alignment = DAG.getReducedAlign(VT,
false);
3525 EVT PtrVT =
StackPtr.getValueType();
3526 auto &MF = DAG.getMachineFunction();
3530 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3533 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3537 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3538 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3540 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3542 DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr, PoisonPtr, TrueMask,
3546 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3551 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3552 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3554 uint64_t TrailingElts = -
Imm;
3556 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3565 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3569 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3571 DAG.getVectorIdxConstant(0,
DL));
3577void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3585 GetSplitVector(Acc, AccLo, AccHi);
3586 unsigned Opcode =
N->getOpcode();
3598 GetSplitVector(Input1, Input1Lo, Input1Hi);
3599 GetSplitVector(Input2, Input2Lo, Input2Hi);
3602 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3603 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3606void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3614 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3622void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3623 unsigned Factor =
N->getNumOperands();
3626 for (
unsigned i = 0; i != Factor; ++i) {
3628 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3630 Ops[i * 2 + 1] = OpHi;
3641 for (
unsigned i = 0; i != Factor; ++i)
3645void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3646 unsigned Factor =
N->getNumOperands();
3649 for (
unsigned i = 0; i != Factor; ++i) {
3651 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3653 Ops[i + Factor] = OpHi;
3664 for (
unsigned i = 0; i != Factor; ++i) {
3665 unsigned IdxLo = 2 * i;
3666 unsigned IdxHi = 2 * i + 1;
3667 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3668 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3680bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3685 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3688 switch (
N->getOpcode()) {
3691 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3701 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3708 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3710 case ISD::VP_TRUNCATE:
3712 Res = SplitVecOp_TruncateHelper(
N);
3715 case ISD::VP_FP_ROUND:
3718 Res = SplitVecOp_FP_ROUND(
N);
3727 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3734 case ISD::VP_SCATTER:
3738 case ISD::VP_GATHER:
3742 Res = SplitVecOp_VSELECT(
N, OpNo);
3745 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3751 case ISD::VP_SINT_TO_FP:
3752 case ISD::VP_UINT_TO_FP:
3753 if (
N->getValueType(0).bitsLT(
3754 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3755 Res = SplitVecOp_TruncateHelper(
N);
3757 Res = SplitVecOp_UnaryOp(
N);
3761 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3765 case ISD::VP_FP_TO_SINT:
3766 case ISD::VP_FP_TO_UINT:
3779 Res = SplitVecOp_UnaryOp(
N);
3782 Res = SplitVecOp_FPOpDifferentTypes(
N);
3787 Res = SplitVecOp_CMP(
N);
3791 Res = SplitVecOp_FAKE_USE(
N);
3796 Res = SplitVecOp_ExtVecInRegOp(
N);
3814 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3818 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3820 case ISD::VP_REDUCE_FADD:
3821 case ISD::VP_REDUCE_SEQ_FADD:
3822 case ISD::VP_REDUCE_FMUL:
3823 case ISD::VP_REDUCE_SEQ_FMUL:
3824 case ISD::VP_REDUCE_ADD:
3825 case ISD::VP_REDUCE_MUL:
3826 case ISD::VP_REDUCE_AND:
3827 case ISD::VP_REDUCE_OR:
3828 case ISD::VP_REDUCE_XOR:
3829 case ISD::VP_REDUCE_SMAX:
3830 case ISD::VP_REDUCE_SMIN:
3831 case ISD::VP_REDUCE_UMAX:
3832 case ISD::VP_REDUCE_UMIN:
3833 case ISD::VP_REDUCE_FMAX:
3834 case ISD::VP_REDUCE_FMIN:
3835 case ISD::VP_REDUCE_FMAXIMUM:
3836 case ISD::VP_REDUCE_FMINIMUM:
3837 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3841 Res = SplitVecOp_CttzElts(
N);
3843 case ISD::VP_CTTZ_ELTS:
3844 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
3845 Res = SplitVecOp_VP_CttzElements(
N);
3848 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3854 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3859 if (!Res.
getNode())
return false;
3866 if (
N->isStrictFPOpcode())
3868 "Invalid operand expansion");
3871 "Invalid operand expansion");
3873 ReplaceValueWith(
SDValue(
N, 0), Res);
3877SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3881 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3883 EVT VT =
N->getValueType(0);
3896 getSetCCResultType(MVT::i1), MVT::i1);
3901 DAG.getElementCount(
DL, VT, SplitEC)),
3905SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3908 assert(OpNo == 0 &&
"Illegal operand must be mask");
3915 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3918 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3919 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3920 "Lo and Hi have differing types");
3923 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3924 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3926 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3927 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3928 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3929 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3939SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3942 assert(OpNo == 1 &&
"Illegal operand must be mask");
3947 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3949 EVT VecVT =
N->getValueType(0);
3953SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3954 EVT ResVT =
N->getValueType(0);
3960 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3961 GetSplitVector(VecOp,
Lo,
Hi);
3963 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3968 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
3969 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
3973 EVT ResVT =
N->getValueType(0);
3979 SDNodeFlags
Flags =
N->getFlags();
3982 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3983 GetSplitVector(VecOp,
Lo,
Hi);
3985 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
3991 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
3994SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
3995 assert(
N->isVPOpcode() &&
"Expected VP opcode");
3996 assert(OpNo == 1 &&
"Can only split reduce vector operand");
3998 unsigned Opc =
N->getOpcode();
3999 EVT ResVT =
N->getValueType(0);
4005 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4006 GetSplitVector(VecOp,
Lo,
Hi);
4009 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4012 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4014 const SDNodeFlags
Flags =
N->getFlags();
4018 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4023 EVT ResVT =
N->getValueType(0);
4026 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4027 EVT InVT =
Lo.getValueType();
4032 if (
N->isStrictFPOpcode()) {
4033 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4034 {N->getOperand(0), Lo});
4035 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4036 {N->getOperand(0), Hi});
4045 ReplaceValueWith(
SDValue(
N, 1), Ch);
4046 }
else if (
N->getNumOperands() == 3) {
4047 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4048 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4049 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4050 std::tie(EVLLo, EVLHi) =
4051 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4052 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4053 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4055 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4056 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4065 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4075 EVT ResVT =
N->getValueType(0);
4077 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4081 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4087 Lo = BitConvertToInteger(
Lo);
4088 Hi = BitConvertToInteger(
Hi);
4090 if (DAG.getDataLayout().isBigEndian())
4098 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4100 EVT ResVT =
N->getValueType(0);
4108 GetSplitVector(SubVec,
Lo,
Hi);
4117 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4119 return SecondInsertion;
4122SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4129 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4131 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4133 ElementCount IdxVal =
4137 EVT SrcVT =
N->getOperand(0).getValueType();
4156 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4157 LoEltsMin - IdxValMin);
4158 DAG.ExtractVectorElements(
Hi, Elts, 0,
4161 return DAG.getBuildVector(SubVT, dl, Elts);
4165 ElementCount ExtractIdx = IdxVal - LoElts;
4167 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4170 EVT HiVT =
Hi.getValueType();
4172 "Only fixed-vector extracts are supported in this case");
4182 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4183 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4189 "Extracting scalable subvector from fixed-width unsupported");
4197 "subvector from a scalable predicate vector");
4203 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4205 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4206 auto &MF = DAG.getMachineFunction();
4210 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4214 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4217 SubVT, dl, Store, StackPtr,
4221SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4227 uint64_t IdxVal =
Index->getZExtValue();
4230 GetSplitVector(Vec,
Lo,
Hi);
4232 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4234 if (IdxVal < LoElts)
4235 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4238 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4243 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4255 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4261 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4263 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4264 auto &MF = DAG.getMachineFunction();
4267 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4271 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4275 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4277 return DAG.getExtLoad(
4288 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4296 SplitVecRes_Gather(
N,
Lo,
Hi);
4299 ReplaceValueWith(
SDValue(
N, 0), Res);
4304 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4308 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4310 SDValue EVL =
N->getVectorLength();
4312 Align Alignment =
N->getBaseAlign();
4318 GetSplitVector(
Data, DataLo, DataHi);
4320 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4325 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4328 GetSplitVector(Mask, MaskLo, MaskHi);
4330 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4333 EVT MemoryVT =
N->getMemoryVT();
4334 EVT LoMemVT, HiMemVT;
4335 bool HiIsEmpty =
false;
4336 std::tie(LoMemVT, HiMemVT) =
4337 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4341 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4344 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4349 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4350 N->getAddressingMode(),
N->isTruncatingStore(),
4351 N->isCompressingStore());
4357 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4358 N->isCompressingStore());
4360 MachinePointerInfo MPI;
4364 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4369 MMO = DAG.getMachineFunction().getMachineMemOperand(
4371 Alignment,
N->getAAInfo(),
N->getRanges());
4373 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4374 N->getAddressingMode(),
N->isTruncatingStore(),
4375 N->isCompressingStore());
4384 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4385 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4392 GetSplitVector(
Data, LoData, HiData);
4394 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4396 EVT LoMemVT, HiMemVT;
4397 bool HiIsEmpty =
false;
4398 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4404 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4405 else if (getTypeAction(
Mask.getValueType()) ==
4407 GetSplitVector(Mask, LoMask, HiMask);
4409 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4412 std::tie(LoEVL, HiEVL) =
4413 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4417 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4418 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4419 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4430 EVT PtrVT =
N->getBasePtr().getValueType();
4433 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4436 Align Alignment =
N->getBaseAlign();
4441 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4442 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4444 Alignment,
N->getAAInfo(),
N->getRanges());
4447 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4448 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4449 N->isCompressingStore());
4458 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4462 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4465 Align Alignment =
N->getBaseAlign();
4471 GetSplitVector(
Data, DataLo, DataHi);
4473 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4478 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4481 GetSplitVector(Mask, MaskLo, MaskHi);
4483 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4486 EVT MemoryVT =
N->getMemoryVT();
4487 EVT LoMemVT, HiMemVT;
4488 bool HiIsEmpty =
false;
4489 std::tie(LoMemVT, HiMemVT) =
4490 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4493 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4498 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4499 N->getAddressingMode(),
N->isTruncatingStore(),
4500 N->isCompressingStore());
4508 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4509 N->isCompressingStore());
4511 MachinePointerInfo MPI;
4515 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4520 MMO = DAG.getMachineFunction().getMachineMemOperand(
4522 Alignment,
N->getAAInfo(),
N->getRanges());
4524 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4525 N->getAddressingMode(),
N->isTruncatingStore(),
4526 N->isCompressingStore());
4539 EVT MemoryVT =
N->getMemoryVT();
4540 Align Alignment =
N->getBaseAlign();
4547 }
Ops = [&]() -> Operands {
4549 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4553 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4558 EVT LoMemVT, HiMemVT;
4559 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4564 GetSplitVector(
Ops.Data, DataLo, DataHi);
4566 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4571 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4573 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4577 if (getTypeAction(
Ops.Index.getValueType()) ==
4579 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4581 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4585 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4587 Alignment,
N->getAAInfo(),
N->getRanges());
4590 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4592 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4593 MSC->getIndexType(), MSC->isTruncatingStore());
4598 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4599 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4600 MMO, MSC->getIndexType(),
4601 MSC->isTruncatingStore());
4605 std::tie(EVLLo, EVLHi) =
4606 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4608 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4609 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4610 VPSC->getIndexType());
4615 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4616 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4617 VPSC->getIndexType());
4621 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4622 assert(OpNo == 1 &&
"Can only split the stored value");
4625 bool isTruncating =
N->isTruncatingStore();
4628 EVT MemoryVT =
N->getMemoryVT();
4629 Align Alignment =
N->getBaseAlign();
4631 AAMDNodes AAInfo =
N->getAAInfo();
4633 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4635 EVT LoMemVT, HiMemVT;
4636 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4640 return TLI.scalarizeVectorStore(
N, DAG);
4643 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4644 Alignment, MMOFlags, AAInfo);
4646 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4649 MachinePointerInfo MPI;
4650 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4653 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4654 HiMemVT, Alignment, MMOFlags, AAInfo);
4656 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4672 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4678 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4699 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4700 SDValue InVec =
N->getOperand(OpNo);
4702 EVT OutVT =
N->getValueType(0);
4710 EVT LoOutVT, HiOutVT;
4711 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4712 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4717 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4719 return SplitVecOp_UnaryOp(
N);
4728 return SplitVecOp_UnaryOp(
N);
4732 GetSplitVector(InVec, InLoVec, InHiVec);
4738 EVT HalfElementVT = IsFloat ?
4740 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4747 if (
N->isStrictFPOpcode()) {
4748 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4749 {N->getOperand(0), InLoVec});
4750 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4751 {N->getOperand(0), InHiVec});
4757 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4758 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4762 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4770 if (
N->isStrictFPOpcode()) {
4774 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4782 DAG.getTargetConstant(
4783 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4790 assert(
N->getValueType(0).isVector() &&
4791 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4792 "Operand types must be vectors");
4794 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4796 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4797 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4799 EVT VT =
N->getValueType(0);
4800 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4805 }
else if (isStrict) {
4806 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4807 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4808 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4809 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4812 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4814 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4815 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4816 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4817 std::tie(EVLLo, EVLHi) =
4818 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4819 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4820 N->getOperand(2), MaskLo, EVLLo);
4821 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4822 N->getOperand(2), MaskHi, EVLHi);
4830 EVT OpVT =
N->getOperand(0).getValueType();
4833 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4839 EVT ResVT =
N->getValueType(0);
4842 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4843 EVT InVT =
Lo.getValueType();
4848 if (
N->isStrictFPOpcode()) {
4849 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4850 {N->getOperand(0), Lo, N->getOperand(2)});
4851 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4852 {N->getOperand(0), Hi, N->getOperand(2)});
4856 Lo.getValue(1),
Hi.getValue(1));
4857 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4858 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4859 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4860 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4861 std::tie(EVLLo, EVLHi) =
4862 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4863 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4864 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4866 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4867 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
4878SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4881 EVT LHSLoVT, LHSHiVT;
4882 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4884 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4885 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4888 std::tie(LHSLo, LHSHi) =
4889 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4892 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4895 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4901 LLVMContext &Ctxt = *DAG.getContext();
4904 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4905 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4906 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4908 EVT ResVT =
N->getValueType(0);
4913 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4914 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4920 EVT ResVT =
N->getValueType(0);
4923 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4924 EVT InVT =
Lo.getValueType();
4930 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4931 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4938 EVT ResVT =
N->getValueType(0);
4942 GetSplitVector(VecOp,
Lo,
Hi);
4948 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
4950 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
4952 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
4953 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
4958 EVT ResVT =
N->getValueType(0);
4962 GetSplitVector(VecOp,
Lo,
Hi);
4964 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4965 auto [EVLLo, EVLHi] =
4967 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4973 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4975 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4976 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4979SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4990 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4991 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4992 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4993 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4994 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4995 OpsLo, MMO, IndexType);
4996 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4997 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5001SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5004 "Accumulator should already be a legal type, and shouldn't need "
5005 "further splitting");
5008 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5009 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5010 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5011 unsigned Opcode =
N->getOpcode();
5014 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5015 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5022void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5023 unsigned WidenResNo) {
5024 unsigned NumResults =
N->getNumValues();
5025 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5026 if (ResNo == WidenResNo)
5028 EVT ResVT =
N->getValueType(ResNo);
5034 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5035 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5040void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5041 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5044 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5049 auto unrollExpandedOp = [&]() {
5054 EVT VT =
N->getValueType(0);
5055 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5056 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5057 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5059 if (
N->getNumValues() > 1)
5060 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5066 switch (
N->getOpcode()) {
5069 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5077 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5081 Res = WidenVecRes_ADDRSPACECAST(
N);
5088 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5095 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5099 Res = WidenVecRes_ScalarOp(
N);
5104 case ISD::VP_SELECT:
5106 Res = WidenVecRes_Select(
N);
5110 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5112 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5119 case ISD::VP_LOAD_FF:
5122 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5126 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5134 case ISD::VP_GATHER:
5138 Res = WidenVecRes_VECTOR_REVERSE(
N);
5141 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5151 case ISD::OR:
case ISD::VP_OR:
5162 case ISD::VP_FMINNUM:
5165 case ISD::VP_FMAXNUM:
5167 case ISD::VP_FMINIMUM:
5169 case ISD::VP_FMAXIMUM:
5202 case ISD::VP_FCOPYSIGN:
5203 Res = WidenVecRes_Binary(
N);
5210 Res = WidenVecRes_MaskedBinary(
N);
5215 Res = WidenVecRes_CMP(
N);
5221 if (unrollExpandedOp())
5236 Res = WidenVecRes_BinaryCanTrap(
N);
5245 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5248#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5249 case ISD::STRICT_##DAGN:
5250#include "llvm/IR/ConstrainedOps.def"
5251 Res = WidenVecRes_StrictFP(
N);
5260 Res = WidenVecRes_OverflowOp(
N, ResNo);
5264 Res = WidenVecRes_FCOPYSIGN(
N);
5269 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5274 if (!unrollExpandedOp())
5275 Res = WidenVecRes_ExpOp(
N);
5281 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5286 case ISD::VP_FP_EXTEND:
5288 case ISD::VP_FP_ROUND:
5290 case ISD::VP_FP_TO_SINT:
5292 case ISD::VP_FP_TO_UINT:
5294 case ISD::VP_SIGN_EXTEND:
5296 case ISD::VP_SINT_TO_FP:
5297 case ISD::VP_TRUNCATE:
5300 case ISD::VP_UINT_TO_FP:
5302 case ISD::VP_ZERO_EXTEND:
5304 Res = WidenVecRes_Convert(
N);
5309 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5315 case ISD::VP_LLRINT:
5318 Res = WidenVecRes_XROUND(
N);
5344 if (unrollExpandedOp())
5354 case ISD::VP_BITREVERSE:
5360 case ISD::VP_CTLZ_ZERO_UNDEF:
5366 case ISD::VP_CTTZ_ZERO_UNDEF:
5371 case ISD::VP_FFLOOR:
5373 case ISD::VP_FNEARBYINT:
5374 case ISD::VP_FROUND:
5375 case ISD::VP_FROUNDEVEN:
5376 case ISD::VP_FROUNDTOZERO:
5381 Res = WidenVecRes_Unary(
N);
5388 Res = WidenVecRes_Ternary(
N);
5394 if (!unrollExpandedOp())
5395 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5402 SetWidenedVector(
SDValue(
N, ResNo), Res);
5408 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5409 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5410 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5411 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5412 if (
N->getNumOperands() == 3)
5413 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5415 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5416 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5420 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5421 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5427 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5428 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5429 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5430 if (
N->getNumOperands() == 2)
5431 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5434 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5435 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5439 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5440 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5445 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5446 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5447 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5450 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5451 Mask = ModifyToType(Mask, WideMaskVT,
true);
5452 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5457 LLVMContext &Ctxt = *DAG.getContext();
5462 EVT OpVT =
LHS.getValueType();
5464 LHS = GetWidenedVector(
LHS);
5465 RHS = GetWidenedVector(
RHS);
5466 OpVT =
LHS.getValueType();
5469 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5472 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5478SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5481 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5482 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5483 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5485 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5494 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5497 if (ConcatEnd == 1) {
5498 VT = ConcatOps[0].getValueType();
5500 return ConcatOps[0];
5503 SDLoc dl(ConcatOps[0]);
5510 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5511 int Idx = ConcatEnd - 1;
5512 VT = ConcatOps[Idx--].getValueType();
5513 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5526 unsigned NumToInsert = ConcatEnd - Idx - 1;
5527 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5529 ConcatOps[Idx+1] = VecOp;
5530 ConcatEnd = Idx + 2;
5536 unsigned RealVals = ConcatEnd - Idx - 1;
5537 unsigned SubConcatEnd = 0;
5538 unsigned SubConcatIdx = Idx + 1;
5539 while (SubConcatEnd < RealVals)
5540 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5541 while (SubConcatEnd < OpsToConcat)
5542 SubConcatOps[SubConcatEnd++] = undefVec;
5544 NextVT, SubConcatOps);
5545 ConcatEnd = SubConcatIdx + 1;
5550 if (ConcatEnd == 1) {
5551 VT = ConcatOps[0].getValueType();
5553 return ConcatOps[0];
5558 if (
NumOps != ConcatEnd ) {
5560 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5561 ConcatOps[j] = UndefVal;
5569 unsigned Opcode =
N->getOpcode();
5571 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5575 const SDNodeFlags
Flags =
N->getFlags();
5576 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5577 NumElts = NumElts / 2;
5581 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5583 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5584 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5585 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5593 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5596 TLI.isTypeLegal(WideMaskVT)) {
5597 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5598 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5599 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5601 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5602 N->getValueType(0).getVectorElementCount());
5603 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5617 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5618 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5619 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5622 unsigned ConcatEnd = 0;
5630 while (CurNumElts != 0) {
5631 while (CurNumElts >= NumElts) {
5632 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5633 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5634 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5636 CurNumElts -= NumElts;
5639 NumElts = NumElts / 2;
5641 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5644 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5645 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5646 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5647 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5658 switch (
N->getOpcode()) {
5661 return WidenVecRes_STRICT_FSETCC(
N);
5668 return WidenVecRes_Convert_StrictFP(
N);
5675 unsigned Opcode =
N->getOpcode();
5677 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5681 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5682 NumElts = NumElts / 2;
5693 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5697 unsigned ConcatEnd = 0;
5704 for (
unsigned i = 1; i < NumOpers; ++i) {
5710 Oper = GetWidenedVector(Oper);
5716 DAG.getPOISON(WideOpVT), Oper,
5717 DAG.getVectorIdxConstant(0, dl));
5729 while (CurNumElts != 0) {
5730 while (CurNumElts >= NumElts) {
5733 for (
unsigned i = 0; i < NumOpers; ++i) {
5736 EVT OpVT =
Op.getValueType();
5741 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5747 EVT OperVT[] = {VT, MVT::Other};
5749 ConcatOps[ConcatEnd++] = Oper;
5752 CurNumElts -= NumElts;
5755 NumElts = NumElts / 2;
5757 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5760 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5763 for (
unsigned i = 0; i < NumOpers; ++i) {
5766 EVT OpVT =
Op.getValueType();
5774 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5776 ConcatOps[ConcatEnd++] = Oper;
5785 if (Chains.
size() == 1)
5786 NewChain = Chains[0];
5789 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5794SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5796 EVT ResVT =
N->getValueType(0);
5797 EVT OvVT =
N->getValueType(1);
5798 EVT WideResVT, WideOvVT;
5803 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5808 WideLHS = GetWidenedVector(
N->getOperand(0));
5809 WideRHS = GetWidenedVector(
N->getOperand(1));
5811 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5820 N->getOperand(0), Zero);
5822 N->getOperand(1), Zero);
5825 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5826 SDNode *WideNode = DAG.getNode(
5827 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5830 unsigned OtherNo = 1 - ResNo;
5831 EVT OtherVT =
N->getValueType(OtherNo);
5838 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5841 return SDValue(WideNode, ResNo);
5845 LLVMContext &Ctx = *DAG.getContext();
5849 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5854 unsigned Opcode =
N->getOpcode();
5855 const SDNodeFlags
Flags =
N->getFlags();
5861 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5863 InOp = ZExtPromotedInteger(InOp);
5874 InOp = GetWidenedVector(
N->getOperand(0));
5877 if (InVTEC == WidenEC) {
5878 if (
N->getNumOperands() == 1)
5879 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5880 if (
N->getNumOperands() == 3) {
5881 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5884 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5886 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5912 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5916 if (TLI.isTypeLegal(InWidenVT)) {
5924 unsigned NumConcat =
5929 if (
N->getNumOperands() == 1)
5930 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5931 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5935 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5937 if (
N->getNumOperands() == 1)
5938 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5939 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5948 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5949 for (
unsigned i=0; i < MinElts; ++i) {
5950 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5951 if (
N->getNumOperands() == 1)
5954 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5957 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5962 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5966 EVT SrcVT = Src.getValueType();
5970 Src = GetWidenedVector(Src);
5971 SrcVT = Src.getValueType();
5978 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5983 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5987 EVT SrcVT = Src.getValueType();
5991 Src = GetWidenedVector(Src);
5992 SrcVT = Src.getValueType();
5999 if (
N->getNumOperands() == 1)
6000 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6002 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6003 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6007 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6010SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6015 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6021 unsigned Opcode =
N->getOpcode();
6027 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6032 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6033 for (
unsigned i=0; i < MinElts; ++i) {
6034 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6035 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6039 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6041 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6044SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6045 unsigned Opcode =
N->getOpcode();
6049 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6058 InOp = GetWidenedVector(InOp);
6065 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6072 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6073 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6090 while (
Ops.size() != WidenNumElts)
6091 Ops.push_back(DAG.getPOISON(WidenSVT));
6093 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6099 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6100 return WidenVecRes_BinaryCanTrap(
N);
6103 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6110SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6112 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6115 SDValue Arg = GetWidenedVector(FpValue);
6116 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6121 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6122 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6124 EVT ExpVT =
RHS.getValueType();
6129 ExpOp = ModifyToType(
RHS, WideExpVT);
6132 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6137 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6138 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6139 if (
N->getNumOperands() == 1)
6140 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6142 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6143 N->getOperand(1),
N->getFlags());
6145 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6146 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6150 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6151 {InOp,
Mask,
N->getOperand(2)});
6155 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6160 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6161 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6162 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6165SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6167 EVT VT0 =
N->getValueType(0);
6168 EVT VT1 =
N->getValueType(1);
6172 "expected both results to be vectors of matching element count");
6174 LLVMContext &Ctx = *DAG.getContext();
6175 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6177 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6184 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6187 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6188 return SDValue(WidenNode, ResNo);
6191SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6192 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6193 return GetWidenedVector(WidenVec);
6197 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6198 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6201 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6202 AddrSpaceCastN->getSrcAddressSpace(),
6203 AddrSpaceCastN->getDestAddressSpace());
6209 EVT VT =
N->getValueType(0);
6210 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6213 switch (getTypeAction(InVT)) {
6227 SDValue NInOp = GetPromotedInteger(InOp);
6229 if (WidenVT.
bitsEq(NInVT)) {
6232 if (DAG.getDataLayout().isBigEndian()) {
6235 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6253 InOp = GetWidenedVector(InOp);
6255 if (WidenVT.
bitsEq(InVT))
6265 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6270 unsigned NewNumParts = WidenSize / InSize;
6283 EVT OrigInVT =
N->getOperand(0).getValueType();
6288 if (TLI.isTypeLegal(NewInVT)) {
6296 if (WidenSize % InSize == 0) {
6303 DAG.ExtractVectorElements(InOp,
Ops);
6304 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6316 return CreateStackStoreLoad(InOp, WidenVT);
6319SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6321 N->getOpcode(), SDLoc(
N),
6322 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6323 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6329 EVT VT =
N->getValueType(0);
6333 EVT EltVT =
N->getOperand(0).getValueType();
6336 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6340 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6341 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6343 return DAG.getBuildVector(WidenVT, dl, NewOps);
6347 EVT InVT =
N->getOperand(0).getValueType();
6348 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6350 unsigned NumOperands =
N->getNumOperands();
6352 bool InputWidened =
false;
6356 if (WidenNumElts % NumInElts == 0) {
6358 unsigned NumConcat = WidenNumElts / NumInElts;
6359 SDValue UndefVal = DAG.getPOISON(InVT);
6361 for (
unsigned i=0; i < NumOperands; ++i)
6362 Ops[i] =
N->getOperand(i);
6363 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6368 InputWidened =
true;
6369 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6372 for (i=1; i < NumOperands; ++i)
6373 if (!
N->getOperand(i).isUndef())
6376 if (i == NumOperands)
6379 return GetWidenedVector(
N->getOperand(0));
6381 if (NumOperands == 2) {
6383 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6388 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6389 for (
unsigned i = 0; i < NumInElts; ++i) {
6391 MaskOps[i + NumInElts] = i + WidenNumElts;
6393 return DAG.getVectorShuffle(WidenVT, dl,
6394 GetWidenedVector(
N->getOperand(0)),
6395 GetWidenedVector(
N->getOperand(1)),
6402 "Cannot use build vectors to widen CONCAT_VECTOR result");
6410 for (
unsigned i=0; i < NumOperands; ++i) {
6413 InOp = GetWidenedVector(InOp);
6414 for (
unsigned j = 0;
j < NumInElts; ++
j)
6415 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6417 SDValue UndefVal = DAG.getPOISON(EltVT);
6418 for (; Idx < WidenNumElts; ++Idx)
6419 Ops[Idx] = UndefVal;
6420 return DAG.getBuildVector(WidenVT, dl,
Ops);
6423SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6424 EVT VT =
N->getValueType(0);
6425 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6426 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6433SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6434 EVT VT =
N->getValueType(0);
6436 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6441 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6443 InOp = GetWidenedVector(InOp);
6449 if (IdxVal == 0 && InVT == WidenVT)
6456 assert(IdxVal % VTNumElts == 0 &&
6457 "Expected Idx to be a multiple of subvector minimum vector length");
6458 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6471 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6472 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6473 "down type's element count");
6480 for (;
I < VTNumElts / GCD; ++
I)
6482 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6483 for (;
I < WidenNumElts / GCD; ++
I)
6491 Align Alignment = DAG.getReducedAlign(InVT,
false);
6493 MachineFunction &MF = DAG.getMachineFunction();
6505 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6512 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6513 return DAG.getMaskedLoad(
6514 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6522 for (i = 0; i < VTNumElts; ++i)
6523 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6525 SDValue UndefVal = DAG.getPOISON(EltVT);
6526 for (; i < WidenNumElts; ++i)
6528 return DAG.getBuildVector(WidenVT, dl,
Ops);
6534 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6539SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6540 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6543 N->getOperand(1),
N->getOperand(2));
6552 "Load width must be less than or equal to first value type width");
6561 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6572 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6573 EVT LdVT =
LD->getMemoryVT();
6577 "Must be scalable");
6579 "Expected equivalent element types");
6587 TypeSize WidthDiff = WidenWidth - LdWidth;
6590 std::optional<EVT> FirstVT =
6591 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6598 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6601 Chain, BasePtr,
LD->getMemOperand());
6605 FirstVTWidth, dl, DAG);
6623 if (!
LD->getMemoryVT().isByteSized()) {
6625 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6627 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6636 EVT VT =
LD->getValueType(0);
6637 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6638 EVT WideMaskVT = getSetCCResultType(WideVT);
6641 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6642 TLI.isTypeLegal(WideMaskVT)) {
6645 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6649 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6650 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6662 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6664 Result = GenWidenVectorLoads(LdChain, LD);
6671 if (LdChain.
size() == 1)
6672 NewChain = LdChain[0];
6678 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6689 SDValue NewLoad = DAG.getMaskedLoad(
6690 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6691 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6692 LD->getAddressingMode(),
LD->getExtensionType());
6702 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6704 SDValue EVL =
N->getVectorLength();
6711 "Unable to widen binary VP op");
6712 Mask = GetWidenedVector(Mask);
6713 assert(
Mask.getValueType().getVectorElementCount() ==
6714 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6715 .getVectorElementCount() &&
6716 "Unable to widen vector load");
6719 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6720 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6721 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6729 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6731 SDValue EVL =
N->getVectorLength();
6737 "Unable to widen binary VP op");
6738 Mask = GetWidenedVector(Mask);
6739 assert(
Mask.getValueType().getVectorElementCount() ==
6740 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6741 .getVectorElementCount() &&
6742 "Unable to widen vector load");
6744 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6745 Mask, EVL,
N->getMemOperand());
6758 "Unable to widen VP strided load");
6759 Mask = GetWidenedVector(Mask);
6761 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6762 assert(
Mask.getValueType().getVectorElementCount() ==
6764 "Data and mask vectors should have the same number of elements");
6766 SDValue Res = DAG.getStridedLoadVP(
6767 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6768 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6769 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6770 N->isExpandingLoad());
6778SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6783 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6785 Mask.getValueType().getVectorElementType(),
6788 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6789 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6790 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6792 WideMask, WidePassthru);
6796 EVT VT =
N->getValueType(0);
6797 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6799 EVT MaskVT =
Mask.getValueType();
6800 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6809 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6810 TLI.isTypeLegal(WideMaskVT) &&
6816 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6817 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6821 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6822 N->getMemoryVT(),
N->getMemOperand());
6826 if (!
N->getPassThru()->isUndef()) {
6830 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6831 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6832 DAG.getPOISON(WidenVT), EVL);
6843 Mask = ModifyToType(Mask, WideMaskVT,
true);
6845 SDValue Res = DAG.getMaskedLoad(
6846 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6847 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6848 ExtType,
N->isExpandingLoad());
6857 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6859 EVT MaskVT =
Mask.getValueType();
6860 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6869 Mask = ModifyToType(Mask, WideMaskVT,
true);
6874 Index.getValueType().getScalarType(),
6876 Index = ModifyToType(Index, WideIndexVT);
6882 N->getMemoryVT().getScalarType(), NumElts);
6883 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6884 WideMemVT, dl,
Ops,
N->getMemOperand(),
6885 N->getIndexType(),
N->getExtensionType());
6894 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6902 N->getMemoryVT().getScalarType(), WideEC);
6903 Mask = GetWidenedMask(Mask, WideEC);
6906 Mask,
N->getVectorLength()};
6907 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6908 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6917 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6918 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6946 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6947 return N->getOperand(OpNo).getValueType();
6955 N =
N.getOperand(0);
6957 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6958 if (!
N->getOperand(i)->isUndef())
6960 N =
N.getOperand(0);
6964 N =
N.getOperand(0);
6966 N =
N.getOperand(0);
6993 { MaskVT, MVT::Other },
Ops);
6994 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7002 LLVMContext &Ctx = *DAG.getContext();
7005 if (MaskScalarBits < ToMaskScalBits) {
7009 }
else if (MaskScalarBits > ToMaskScalBits) {
7015 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7017 "Mask should have the right element size by now.");
7020 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7022 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7025 EVT SubVT =
Mask->getValueType(0);
7031 assert((
Mask->getValueType(0) == ToMaskVT) &&
7032 "A mask of ToMaskVT should have been produced by now.");
7042 LLVMContext &Ctx = *DAG.getContext();
7053 EVT CondVT =
Cond->getValueType(0);
7057 EVT VSelVT =
N->getValueType(0);
7069 EVT FinalVT = VSelVT;
7080 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7081 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7088 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7096 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7099 EVT ToMaskVT = VSelVT;
7106 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7122 if (ScalarBits0 != ScalarBits1) {
7123 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7124 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7136 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7137 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7138 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7141 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7149 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7154 unsigned Opcode =
N->getOpcode();
7156 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7157 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7158 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7160 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7166 Cond1 = GetWidenedVector(Cond1);
7174 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7175 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7180 Cond1 = ModifyToType(Cond1, CondWidenVT);
7183 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7184 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7186 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7187 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7189 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7193 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7194 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7197 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7201 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7202 return DAG.getUNDEF(WidenVT);
7206 EVT VT =
N->getValueType(0);
7209 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7213 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7214 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7217 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7218 for (
unsigned i = 0; i != NumElts; ++i) {
7219 int Idx =
N->getMaskElt(i);
7220 if (Idx < (
int)NumElts)
7223 NewMask[i] = Idx - NumElts + WidenNumElts;
7225 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7229 EVT VT =
N->getValueType(0);
7233 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7234 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7240 unsigned IdxVal = WidenNumElts - VTNumElts;
7253 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7256 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7257 "down type's element count");
7260 for (; i < VTNumElts / GCD; ++i)
7262 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7263 for (; i < WidenNumElts / GCD; ++i)
7271 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7272 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7274 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7278SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7279 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7284 assert(
N->getValueType(0).isVector() &&
7285 N->getOperand(0).getValueType().isVector() &&
7286 "Operands must be vectors");
7287 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7300 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7301 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7308 InOp1 = GetWidenedVector(InOp1);
7309 InOp2 = GetWidenedVector(InOp2);
7312 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7323 "Input not widened to expected type!");
7325 if (
N->getOpcode() == ISD::VP_SETCC) {
7328 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7329 N->getOperand(2), Mask,
N->getOperand(4));
7331 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7336 assert(
N->getValueType(0).isVector() &&
7337 N->getOperand(1).getValueType().isVector() &&
7338 "Operands must be vectors");
7339 EVT VT =
N->getValueType(0);
7340 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7350 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7355 for (
unsigned i = 0; i != NumElts; ++i) {
7356 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7357 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7359 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7360 {Chain, LHSElem, RHSElem, CC});
7361 Chains[i] = Scalars[i].getValue(1);
7362 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7363 DAG.getBoolConstant(
true, dl, EltVT, VT),
7364 DAG.getBoolConstant(
false, dl, EltVT, VT));
7368 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7370 return DAG.getBuildVector(WidenVT, dl, Scalars);
7376bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7377 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7381 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7384 switch (
N->getOpcode()) {
7387 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7395 Res = WidenVecOp_FAKE_USE(
N);
7401 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7402 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7403 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7404 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7409 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7411 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7412 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7414 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7415 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7425 Res = WidenVecOp_UnrollVectorOp(
N);
7432 Res = WidenVecOp_EXTEND(
N);
7437 Res = WidenVecOp_CMP(
N);
7454 Res = WidenVecOp_Convert(
N);
7459 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7477 Res = WidenVecOp_VECREDUCE(
N);
7481 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7483 case ISD::VP_REDUCE_FADD:
7484 case ISD::VP_REDUCE_SEQ_FADD:
7485 case ISD::VP_REDUCE_FMUL:
7486 case ISD::VP_REDUCE_SEQ_FMUL:
7487 case ISD::VP_REDUCE_ADD:
7488 case ISD::VP_REDUCE_MUL:
7489 case ISD::VP_REDUCE_AND:
7490 case ISD::VP_REDUCE_OR:
7491 case ISD::VP_REDUCE_XOR:
7492 case ISD::VP_REDUCE_SMAX:
7493 case ISD::VP_REDUCE_SMIN:
7494 case ISD::VP_REDUCE_UMAX:
7495 case ISD::VP_REDUCE_UMIN:
7496 case ISD::VP_REDUCE_FMAX:
7497 case ISD::VP_REDUCE_FMIN:
7498 case ISD::VP_REDUCE_FMAXIMUM:
7499 case ISD::VP_REDUCE_FMINIMUM:
7500 Res = WidenVecOp_VP_REDUCE(
N);
7502 case ISD::VP_CTTZ_ELTS:
7503 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7504 Res = WidenVecOp_VP_CttzElements(
N);
7507 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7512 if (!Res.
getNode())
return false;
7520 if (
N->isStrictFPOpcode())
7522 "Invalid operand expansion");
7525 "Invalid operand expansion");
7527 ReplaceValueWith(
SDValue(
N, 0), Res);
7533 EVT VT =
N->getValueType(0);
7538 "Unexpected type action");
7539 InOp = GetWidenedVector(InOp);
7542 "Input wasn't widened!");
7550 EVT FixedEltVT = FixedVT.getVectorElementType();
7551 if (TLI.isTypeLegal(FixedVT) &&
7553 FixedEltVT == InEltVT) {
7555 "Not enough elements in the fixed type for the operand!");
7557 "We can't have the same type as we started with!");
7559 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7561 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7570 return WidenVecOp_Convert(
N);
7575 switch (
N->getOpcode()) {
7590 EVT OpVT =
N->getOperand(0).getValueType();
7591 EVT ResVT =
N->getValueType(0);
7598 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7599 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7605 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7606 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7608 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7615 return DAG.UnrollVectorOp(
N);
7620 EVT ResultVT =
N->getValueType(0);
7622 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7625 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7631 {WideArg,
Test},
N->getFlags());
7637 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7639 EVT OpVT =
N->getOperand(0).getValueType();
7642 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7647 EVT VT =
N->getValueType(0);
7653 "Unexpected type action");
7654 InOp = GetWidenedVector(InOp);
7656 unsigned Opcode =
N->getOpcode();
7662 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7664 if (
N->isStrictFPOpcode()) {
7666 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7669 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7670 {
N->getOperand(0), InOp });
7676 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7678 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7680 return DAG.getExtractSubvector(dl, VT, Res, 0);
7688 if (
N->isStrictFPOpcode()) {
7691 for (
unsigned i=0; i < NumElts; ++i) {
7692 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7693 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7697 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7699 for (
unsigned i = 0; i < NumElts; ++i) {
7700 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7702 Ops[i] = DAG.
getNode(Opcode, dl, EltVT, Elt,
N->getOperand(1));
7704 Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
7708 return DAG.getBuildVector(VT, dl,
Ops);
7712 EVT DstVT =
N->getValueType(0);
7713 SDValue Src = GetWidenedVector(
N->getOperand(0));
7714 EVT SrcVT = Src.getValueType();
7721 if (TLI.isTypeLegal(WideDstVT)) {
7723 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7726 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7730 return DAG.UnrollVectorOp(
N);
7734 EVT VT =
N->getValueType(0);
7735 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7743 if (!VT.
isVector() && VT != MVT::x86mmx &&
7747 if (TLI.isTypeLegal(NewVT)) {
7749 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7761 ElementCount NewNumElts =
7763 .divideCoefficientBy(EltSize);
7765 if (TLI.isTypeLegal(NewVT)) {
7767 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7772 return CreateStackStoreLoad(InOp, VT);
7780 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7781 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7786 EVT VT =
N->getValueType(0);
7788 EVT InVT =
N->getOperand(0).getValueType();
7793 unsigned NumOperands =
N->getNumOperands();
7794 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7796 for (i = 1; i < NumOperands; ++i)
7797 if (!
N->getOperand(i).isUndef())
7800 if (i == NumOperands)
7801 return GetWidenedVector(
N->getOperand(0));
7811 for (
unsigned i=0; i < NumOperands; ++i) {
7815 "Unexpected type action");
7816 InOp = GetWidenedVector(InOp);
7817 for (
unsigned j = 0;
j < NumInElts; ++
j)
7818 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7820 return DAG.getBuildVector(VT, dl,
Ops);
7823SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7824 EVT VT =
N->getValueType(0);
7829 SubVec = GetWidenedVector(SubVec);
7834 bool IndicesValid =
false;
7837 IndicesValid =
true;
7841 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7842 Attribute::VScaleRange);
7847 IndicesValid =
true;
7853 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7859 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7866 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7873 Align Alignment = DAG.getReducedAlign(VT,
false);
7875 MachineFunction &MF = DAG.getMachineFunction();
7888 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7896 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7897 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7902 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7907 unsigned Idx =
N->getConstantOperandVal(2);
7913 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7919SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7920 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7922 N->getValueType(0), InOp,
N->getOperand(1));
7925SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7926 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7928 N->getValueType(0), InOp,
N->getOperand(1));
7931SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7933 EVT ResVT =
N->getValueType(0);
7936 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
7942 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
7950 "Widened input size must be a multiple of result element size");
7953 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
7955 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
7956 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
7964 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7965 return TLI.scalarizeVectorStore(ST, DAG);
7967 if (
ST->isTruncatingStore())
7968 return TLI.scalarizeVectorStore(ST, DAG);
7978 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7979 EVT WideMaskVT = getSetCCResultType(WideVT);
7981 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7982 TLI.isTypeLegal(WideMaskVT)) {
7985 StVal = GetWidenedVector(StVal);
7987 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7989 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7990 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7991 ST->getAddressingMode());
7995 if (GenWidenVectorStores(StChain, ST)) {
7996 if (StChain.
size() == 1)
8005 SDValue WideStVal = GetWidenedVector(StVal);
8009 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8010 ST->getOffset(), Mask,
ST->getMemoryVT(),
8011 ST->getMemOperand(),
ST->getAddressingMode(),
8012 ST->isTruncatingStore());
8018SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8019 assert((OpNo == 1 || OpNo == 3) &&
8020 "Can widen only data or mask operand of vp_store");
8028 StVal = GetWidenedVector(StVal);
8034 "Unable to widen VP store");
8035 Mask = GetWidenedVector(Mask);
8037 Mask = GetWidenedVector(Mask);
8043 "Unable to widen VP store");
8044 StVal = GetWidenedVector(StVal);
8047 assert(
Mask.getValueType().getVectorElementCount() ==
8049 "Mask and data vectors should have the same number of elements");
8050 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8051 ST->getOffset(), Mask,
ST->getVectorLength(),
8052 ST->getMemoryVT(),
ST->getMemOperand(),
8053 ST->getAddressingMode(),
ST->isTruncatingStore(),
8054 ST->isCompressingStore());
8059 assert((OpNo == 1 || OpNo == 4) &&
8060 "Can widen only data or mask operand of vp_strided_store");
8069 "Unable to widen VP strided store");
8073 "Unable to widen VP strided store");
8075 StVal = GetWidenedVector(StVal);
8076 Mask = GetWidenedVector(Mask);
8079 Mask.getValueType().getVectorElementCount() &&
8080 "Data and mask vectors should have the same number of elements");
8082 return DAG.getStridedStoreVP(
8089SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8090 assert((OpNo == 1 || OpNo == 4) &&
8091 "Can widen only data or mask operand of mstore");
8094 EVT MaskVT =
Mask.getValueType();
8099 EVT WideVT, WideMaskVT;
8102 StVal = GetWidenedVector(StVal);
8109 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8116 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8118 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8119 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8128 Mask = ModifyToType(Mask, WideMaskVT,
true);
8131 Mask = ModifyToType(Mask, WideMaskVT,
true);
8133 StVal = ModifyToType(StVal, WideVT);
8136 assert(
Mask.getValueType().getVectorElementCount() ==
8138 "Mask and data vectors should have the same number of elements");
8145SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8146 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8148 SDValue DataOp = MG->getPassThru();
8150 SDValue Scale = MG->getScale();
8158 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8159 MG->getMemOperand(), MG->getIndexType(),
8160 MG->getExtensionType());
8166SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8175 DataOp = GetWidenedVector(DataOp);
8179 EVT IndexVT =
Index.getValueType();
8182 Index = ModifyToType(Index, WideIndexVT);
8185 EVT MaskVT =
Mask.getValueType();
8188 Mask = ModifyToType(Mask, WideMaskVT,
true);
8193 }
else if (OpNo == 4) {
8195 Index = GetWidenedVector(Index);
8201 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8206SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8215 DataOp = GetWidenedVector(DataOp);
8216 Index = GetWidenedVector(Index);
8218 Mask = GetWidenedMask(Mask, WideEC);
8221 }
else if (OpNo == 3) {
8223 Index = GetWidenedVector(Index);
8230 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8235 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8236 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8238 EVT VT =
N->getValueType(0);
8253 SVT, InOp0, InOp1,
N->getOperand(2));
8259 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8261 EVT OpVT =
N->getOperand(0).getValueType();
8264 return DAG.getNode(ExtendCode, dl, VT, CC);
8274 EVT VT =
N->getValueType(0);
8276 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8283 for (
unsigned i = 0; i != NumElts; ++i) {
8284 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8285 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8287 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8288 {Chain, LHSElem, RHSElem, CC});
8289 Chains[i] = Scalars[i].getValue(1);
8290 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8291 DAG.getBoolConstant(
true, dl, EltVT, VT),
8292 DAG.getBoolConstant(
false, dl, EltVT, VT));
8296 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8298 return DAG.getBuildVector(VT, dl, Scalars);
8322 SDValue Op = GetWidenedVector(
N->getOperand(0));
8323 EVT VT =
N->getValueType(0);
8324 EVT OrigVT =
N->getOperand(0).getValueType();
8325 EVT WideVT =
Op.getValueType();
8327 SDNodeFlags
Flags =
N->getFlags();
8329 unsigned Opc =
N->getOpcode();
8331 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8332 assert(NeutralElem &&
"Neutral element must exist");
8342 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8349 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8350 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8356 unsigned GCD = std::gcd(OrigElts, WideElts);
8359 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8360 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8361 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8362 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8365 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8366 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8368 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8377 EVT VT =
N->getValueType(0);
8379 EVT WideVT =
Op.getValueType();
8381 SDNodeFlags
Flags =
N->getFlags();
8383 unsigned Opc =
N->getOpcode();
8385 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8395 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8398 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8399 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8405 unsigned GCD = std::gcd(OrigElts, WideElts);
8408 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8409 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8410 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8411 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8414 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8415 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8417 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8421 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8424 SDValue Op = GetWidenedVector(
N->getOperand(1));
8426 Op.getValueType().getVectorElementCount());
8428 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8429 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8437 EVT VT =
N->getValueType(0);
8441 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8442 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8447 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8453 EVT SrcVT =
Source.getValueType();
8457 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8458 {Source, Mask, N->getOperand(2)},
N->getFlags());
8461SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8464 EVT OrigMaskVT =
Mask.getValueType();
8465 SDValue WideMask = GetWidenedVector(Mask);
8471 if (OrigElts != WideElts) {
8472 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8474 Mask, DAG.getVectorIdxConstant(0,
DL));
8495 unsigned WidenEx = 0) {
8500 unsigned AlignInBits =
Align*8;
8502 EVT RetVT = WidenEltVT;
8507 if (Width == WidenEltWidth)
8518 (WidenWidth % MemVTWidth) == 0 &&
8520 (MemVTWidth <= Width ||
8521 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8522 if (MemVTWidth == WidenWidth)
8541 (WidenWidth % MemVTWidth) == 0 &&
8543 (MemVTWidth <= Width ||
8544 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8553 return std::nullopt;
8564 unsigned Start,
unsigned End) {
8565 SDLoc dl(LdOps[Start]);
8566 EVT LdTy = LdOps[Start].getValueType();
8574 for (
unsigned i = Start + 1; i != End; ++i) {
8575 EVT NewLdTy = LdOps[i].getValueType();
8576 if (NewLdTy != LdTy) {
8595 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8596 EVT LdVT =
LD->getMemoryVT();
8606 AAMDNodes AAInfo =
LD->getAAInfo();
8610 TypeSize WidthDiff = WidenWidth - LdWidth;
8617 std::optional<EVT> FirstVT =
8618 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8625 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8630 std::optional<EVT> NewVT = FirstVT;
8631 TypeSize RemainingWidth = LdWidth;
8632 TypeSize NewVTWidth = FirstVTWidth;
8634 RemainingWidth -= NewVTWidth;
8641 NewVTWidth = NewVT->getSizeInBits();
8647 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8648 LD->getBaseAlign(), MMOFlags, AAInfo);
8660 uint64_t ScaledOffset = 0;
8661 MachinePointerInfo MPI =
LD->getPointerInfo();
8667 for (EVT MemVT : MemVTs) {
8668 Align NewAlign = ScaledOffset == 0
8669 ?
LD->getBaseAlign()
8672 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8680 unsigned End = LdOps.
size();
8691 EVT LdTy = LdOps[i].getValueType();
8694 for (--i; i >= 0; --i) {
8695 LdTy = LdOps[i].getValueType();
8702 ConcatOps[--Idx] = LdOps[i];
8703 for (--i; i >= 0; --i) {
8704 EVT NewLdTy = LdOps[i].getValueType();
8705 if (NewLdTy != LdTy) {
8715 for (;
j != End-Idx; ++
j)
8716 WidenOps[j] = ConcatOps[Idx+j];
8718 WidenOps[j] = DAG.getPOISON(LdTy);
8725 ConcatOps[--Idx] = LdOps[i];
8730 ArrayRef(&ConcatOps[Idx], End - Idx));
8736 SDValue UndefVal = DAG.getPOISON(LdTy);
8739 for (; i != End-Idx; ++i)
8740 WidenOps[i] = ConcatOps[Idx+i];
8742 WidenOps[i] = UndefVal;
8753 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8754 EVT LdVT =
LD->getMemoryVT();
8763 AAMDNodes AAInfo =
LD->getAAInfo();
8777 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8778 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8784 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8785 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8786 LD->getBaseAlign(), MMOFlags, AAInfo);
8791 SDValue UndefVal = DAG.getPOISON(EltVT);
8792 for (; i != WidenNumElts; ++i)
8795 return DAG.getBuildVector(WidenVT, dl,
Ops);
8806 AAMDNodes AAInfo =
ST->getAAInfo();
8807 SDValue ValOp = GetWidenedVector(
ST->getValue());
8810 EVT StVT =
ST->getMemoryVT();
8818 "Mismatch between store and value types");
8822 MachinePointerInfo MPI =
ST->getPointerInfo();
8823 uint64_t ScaledOffset = 0;
8832 std::optional<EVT> NewVT =
8837 TypeSize NewVTWidth = NewVT->getSizeInBits();
8840 StWidth -= NewVTWidth;
8841 MemVTs.
back().second++;
8845 for (
const auto &Pair : MemVTs) {
8846 EVT NewVT = Pair.first;
8847 unsigned Count = Pair.second;
8853 Align NewAlign = ScaledOffset == 0
8854 ?
ST->getBaseAlign()
8856 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8857 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8873 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8874 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8875 ST->getBaseAlign(), MMOFlags, AAInfo);
8892 bool FillWithZeroes) {
8897 "input and widen element type must match");
8899 "cannot modify scalable vectors in this way");
8912 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
8914 for (
unsigned i = 1; i != NumConcat; ++i)
8921 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8924 "Scalable vectors should have been handled already.");
8932 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8934 for (Idx = 0; Idx < MinNumElts; ++Idx)
8935 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8937 SDValue UndefVal = DAG.getPOISON(EltVT);
8938 for (; Idx < WidenNumElts; ++Idx)
8939 Ops[Idx] = UndefVal;
8941 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8942 if (!FillWithZeroes)
8946 "We expect to never want to FillWithZeroes for non-integral types.");
8949 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8950 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8952 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8953 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")
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 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.
MachineInstr unsigned OpIdx
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V, bool LookThroughCmp=false)
Returns the "element type" of the given value/instruction V.
This file implements the SmallBitVector class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
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 base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, 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
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
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 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 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...
@ 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.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ 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...
@ 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_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.
@ 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.
@ 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...
@ 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.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
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)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
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.