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) ||
4718 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);
4806 }
else if (isStrict) {
4807 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4808 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4809 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4810 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4813 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4815 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4816 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4817 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4818 std::tie(EVLLo, EVLHi) =
4819 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4820 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4821 N->getOperand(2), MaskLo, EVLLo);
4822 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4823 N->getOperand(2), MaskHi, EVLHi);
4832 EVT ResVT =
N->getValueType(0);
4835 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4836 EVT InVT =
Lo.getValueType();
4841 if (
N->isStrictFPOpcode()) {
4842 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4843 {N->getOperand(0), Lo, N->getOperand(2)});
4844 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4845 {N->getOperand(0), Hi, N->getOperand(2)});
4849 Lo.getValue(1),
Hi.getValue(1));
4850 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4851 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4852 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4853 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4854 std::tie(EVLLo, EVLHi) =
4855 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4856 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4857 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4859 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4860 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
4871SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4874 EVT LHSLoVT, LHSHiVT;
4875 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4877 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4878 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4881 std::tie(LHSLo, LHSHi) =
4882 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4885 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4888 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4894 LLVMContext &Ctxt = *DAG.getContext();
4897 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4898 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4899 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4901 EVT ResVT =
N->getValueType(0);
4906 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4907 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4913 EVT ResVT =
N->getValueType(0);
4916 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4917 EVT InVT =
Lo.getValueType();
4923 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4924 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4931 EVT ResVT =
N->getValueType(0);
4935 GetSplitVector(VecOp,
Lo,
Hi);
4941 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
4943 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
4945 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
4946 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
4951 EVT ResVT =
N->getValueType(0);
4955 GetSplitVector(VecOp,
Lo,
Hi);
4957 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4958 auto [EVLLo, EVLHi] =
4960 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
4966 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
4968 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
4969 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
4972SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
4983 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
4984 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
4985 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
4986 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
4987 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
4988 OpsLo, MMO, IndexType);
4989 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
4990 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
4994SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
4997 "Accumulator should already be a legal type, and shouldn't need "
4998 "further splitting");
5001 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5002 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5003 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5004 unsigned Opcode =
N->getOpcode();
5007 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5008 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5015void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5016 unsigned WidenResNo) {
5017 unsigned NumResults =
N->getNumValues();
5018 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5019 if (ResNo == WidenResNo)
5021 EVT ResVT =
N->getValueType(ResNo);
5027 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5028 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5033void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5034 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5037 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5042 auto unrollExpandedOp = [&]() {
5047 EVT VT =
N->getValueType(0);
5048 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5049 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5050 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5052 if (
N->getNumValues() > 1)
5053 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5059 switch (
N->getOpcode()) {
5062 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5070 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5074 Res = WidenVecRes_ADDRSPACECAST(
N);
5081 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5088 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5092 Res = WidenVecRes_ScalarOp(
N);
5097 case ISD::VP_SELECT:
5099 Res = WidenVecRes_Select(
N);
5103 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5105 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5112 case ISD::VP_LOAD_FF:
5115 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5119 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5127 case ISD::VP_GATHER:
5131 Res = WidenVecRes_VECTOR_REVERSE(
N);
5134 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5144 case ISD::OR:
case ISD::VP_OR:
5155 case ISD::VP_FMINNUM:
5158 case ISD::VP_FMAXNUM:
5160 case ISD::VP_FMINIMUM:
5162 case ISD::VP_FMAXIMUM:
5195 case ISD::VP_FCOPYSIGN:
5196 Res = WidenVecRes_Binary(
N);
5203 Res = WidenVecRes_MaskedBinary(
N);
5208 Res = WidenVecRes_CMP(
N);
5214 if (unrollExpandedOp())
5229 Res = WidenVecRes_BinaryCanTrap(
N);
5238 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5241#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5242 case ISD::STRICT_##DAGN:
5243#include "llvm/IR/ConstrainedOps.def"
5244 Res = WidenVecRes_StrictFP(
N);
5253 Res = WidenVecRes_OverflowOp(
N, ResNo);
5257 Res = WidenVecRes_FCOPYSIGN(
N);
5262 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5267 if (!unrollExpandedOp())
5268 Res = WidenVecRes_ExpOp(
N);
5274 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5279 case ISD::VP_FP_EXTEND:
5281 case ISD::VP_FP_ROUND:
5283 case ISD::VP_FP_TO_SINT:
5285 case ISD::VP_FP_TO_UINT:
5287 case ISD::VP_SIGN_EXTEND:
5289 case ISD::VP_SINT_TO_FP:
5290 case ISD::VP_TRUNCATE:
5293 case ISD::VP_UINT_TO_FP:
5295 case ISD::VP_ZERO_EXTEND:
5297 Res = WidenVecRes_Convert(
N);
5302 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5308 case ISD::VP_LLRINT:
5311 Res = WidenVecRes_XROUND(
N);
5337 if (unrollExpandedOp())
5347 case ISD::VP_BITREVERSE:
5353 case ISD::VP_CTLZ_ZERO_UNDEF:
5359 case ISD::VP_CTTZ_ZERO_UNDEF:
5364 case ISD::VP_FFLOOR:
5366 case ISD::VP_FNEARBYINT:
5367 case ISD::VP_FROUND:
5368 case ISD::VP_FROUNDEVEN:
5369 case ISD::VP_FROUNDTOZERO:
5374 Res = WidenVecRes_Unary(
N);
5381 Res = WidenVecRes_Ternary(
N);
5387 if (!unrollExpandedOp())
5388 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5395 SetWidenedVector(
SDValue(
N, ResNo), Res);
5401 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5402 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5403 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5404 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5405 if (
N->getNumOperands() == 3)
5406 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5408 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5409 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5413 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5414 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5420 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5421 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5422 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5423 if (
N->getNumOperands() == 2)
5424 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5427 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5428 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5432 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5433 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5438 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5439 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5440 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5443 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5444 Mask = ModifyToType(Mask, WideMaskVT,
true);
5445 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5450 LLVMContext &Ctxt = *DAG.getContext();
5455 EVT OpVT =
LHS.getValueType();
5457 LHS = GetWidenedVector(
LHS);
5458 RHS = GetWidenedVector(
RHS);
5459 OpVT =
LHS.getValueType();
5462 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5465 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5471SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5474 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5475 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5476 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5478 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5487 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5490 if (ConcatEnd == 1) {
5491 VT = ConcatOps[0].getValueType();
5493 return ConcatOps[0];
5496 SDLoc dl(ConcatOps[0]);
5503 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5504 int Idx = ConcatEnd - 1;
5505 VT = ConcatOps[Idx--].getValueType();
5506 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5519 unsigned NumToInsert = ConcatEnd - Idx - 1;
5520 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5522 ConcatOps[Idx+1] = VecOp;
5523 ConcatEnd = Idx + 2;
5529 unsigned RealVals = ConcatEnd - Idx - 1;
5530 unsigned SubConcatEnd = 0;
5531 unsigned SubConcatIdx = Idx + 1;
5532 while (SubConcatEnd < RealVals)
5533 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5534 while (SubConcatEnd < OpsToConcat)
5535 SubConcatOps[SubConcatEnd++] = undefVec;
5537 NextVT, SubConcatOps);
5538 ConcatEnd = SubConcatIdx + 1;
5543 if (ConcatEnd == 1) {
5544 VT = ConcatOps[0].getValueType();
5546 return ConcatOps[0];
5551 if (
NumOps != ConcatEnd ) {
5553 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5554 ConcatOps[j] = UndefVal;
5562 unsigned Opcode =
N->getOpcode();
5564 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5568 const SDNodeFlags
Flags =
N->getFlags();
5569 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5570 NumElts = NumElts / 2;
5574 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5576 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5577 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5578 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5586 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5589 TLI.isTypeLegal(WideMaskVT)) {
5590 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5591 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5592 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5594 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5595 N->getValueType(0).getVectorElementCount());
5596 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5610 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5611 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5612 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5615 unsigned ConcatEnd = 0;
5623 while (CurNumElts != 0) {
5624 while (CurNumElts >= NumElts) {
5625 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5626 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5627 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5629 CurNumElts -= NumElts;
5632 NumElts = NumElts / 2;
5634 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5637 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5638 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5639 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5640 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5651 switch (
N->getOpcode()) {
5654 return WidenVecRes_STRICT_FSETCC(
N);
5661 return WidenVecRes_Convert_StrictFP(
N);
5668 unsigned Opcode =
N->getOpcode();
5670 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5674 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5675 NumElts = NumElts / 2;
5686 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5690 unsigned ConcatEnd = 0;
5697 for (
unsigned i = 1; i < NumOpers; ++i) {
5703 Oper = GetWidenedVector(Oper);
5709 DAG.getPOISON(WideOpVT), Oper,
5710 DAG.getVectorIdxConstant(0, dl));
5722 while (CurNumElts != 0) {
5723 while (CurNumElts >= NumElts) {
5726 for (
unsigned i = 0; i < NumOpers; ++i) {
5729 EVT OpVT =
Op.getValueType();
5734 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5740 EVT OperVT[] = {VT, MVT::Other};
5742 ConcatOps[ConcatEnd++] = Oper;
5745 CurNumElts -= NumElts;
5748 NumElts = NumElts / 2;
5750 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5753 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5756 for (
unsigned i = 0; i < NumOpers; ++i) {
5759 EVT OpVT =
Op.getValueType();
5767 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5769 ConcatOps[ConcatEnd++] = Oper;
5778 if (Chains.
size() == 1)
5779 NewChain = Chains[0];
5782 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5787SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5789 EVT ResVT =
N->getValueType(0);
5790 EVT OvVT =
N->getValueType(1);
5791 EVT WideResVT, WideOvVT;
5796 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5801 WideLHS = GetWidenedVector(
N->getOperand(0));
5802 WideRHS = GetWidenedVector(
N->getOperand(1));
5804 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5813 N->getOperand(0), Zero);
5815 N->getOperand(1), Zero);
5818 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5819 SDNode *WideNode = DAG.getNode(
5820 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5823 unsigned OtherNo = 1 - ResNo;
5824 EVT OtherVT =
N->getValueType(OtherNo);
5831 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5834 return SDValue(WideNode, ResNo);
5838 LLVMContext &Ctx = *DAG.getContext();
5842 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5847 unsigned Opcode =
N->getOpcode();
5848 const SDNodeFlags
Flags =
N->getFlags();
5854 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5856 InOp = ZExtPromotedInteger(InOp);
5867 InOp = GetWidenedVector(
N->getOperand(0));
5870 if (InVTEC == WidenEC) {
5871 if (
N->getNumOperands() == 1)
5872 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5873 if (
N->getNumOperands() == 3) {
5874 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5877 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5879 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5905 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5909 if (TLI.isTypeLegal(InWidenVT)) {
5917 unsigned NumConcat =
5922 if (
N->getNumOperands() == 1)
5923 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5924 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5928 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5930 if (
N->getNumOperands() == 1)
5931 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5932 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5941 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5942 for (
unsigned i=0; i < MinElts; ++i) {
5943 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5944 if (
N->getNumOperands() == 1)
5947 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5950 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5955 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5959 EVT SrcVT = Src.getValueType();
5963 Src = GetWidenedVector(Src);
5964 SrcVT = Src.getValueType();
5971 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
5976 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5980 EVT SrcVT = Src.getValueType();
5984 Src = GetWidenedVector(Src);
5985 SrcVT = Src.getValueType();
5992 if (
N->getNumOperands() == 1)
5993 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
5995 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
5996 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6000 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6003SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6008 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6014 unsigned Opcode =
N->getOpcode();
6020 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6025 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6026 for (
unsigned i=0; i < MinElts; ++i) {
6027 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6028 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6032 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6034 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6037SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6038 unsigned Opcode =
N->getOpcode();
6042 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6051 InOp = GetWidenedVector(InOp);
6058 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6065 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6066 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6083 while (
Ops.size() != WidenNumElts)
6084 Ops.push_back(DAG.getPOISON(WidenSVT));
6086 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6092 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6093 return WidenVecRes_BinaryCanTrap(
N);
6096 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6103SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6105 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6108 SDValue Arg = GetWidenedVector(FpValue);
6109 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6114 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6115 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6117 EVT ExpVT =
RHS.getValueType();
6122 ExpOp = ModifyToType(
RHS, WideExpVT);
6125 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6130 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6131 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6132 if (
N->getNumOperands() == 1)
6133 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6135 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6136 N->getOperand(1),
N->getFlags());
6138 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6139 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6143 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6144 {InOp,
Mask,
N->getOperand(2)});
6148 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6151 .getVectorElementType(),
6153 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6154 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6155 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6158SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6160 EVT VT0 =
N->getValueType(0);
6161 EVT VT1 =
N->getValueType(1);
6165 "expected both results to be vectors of matching element count");
6167 LLVMContext &Ctx = *DAG.getContext();
6168 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6170 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6177 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6180 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6181 return SDValue(WidenNode, ResNo);
6184SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6185 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6186 return GetWidenedVector(WidenVec);
6190 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6191 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6194 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6195 AddrSpaceCastN->getSrcAddressSpace(),
6196 AddrSpaceCastN->getDestAddressSpace());
6202 EVT VT =
N->getValueType(0);
6203 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6206 switch (getTypeAction(InVT)) {
6220 SDValue NInOp = GetPromotedInteger(InOp);
6222 if (WidenVT.
bitsEq(NInVT)) {
6225 if (DAG.getDataLayout().isBigEndian()) {
6228 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6246 InOp = GetWidenedVector(InOp);
6248 if (WidenVT.
bitsEq(InVT))
6258 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6263 unsigned NewNumParts = WidenSize / InSize;
6276 EVT OrigInVT =
N->getOperand(0).getValueType();
6281 if (TLI.isTypeLegal(NewInVT)) {
6289 if (WidenSize % InSize == 0) {
6296 DAG.ExtractVectorElements(InOp,
Ops);
6297 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6309 return CreateStackStoreLoad(InOp, WidenVT);
6312SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6314 N->getOpcode(), SDLoc(
N),
6315 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6316 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6322 EVT VT =
N->getValueType(0);
6326 EVT EltVT =
N->getOperand(0).getValueType();
6329 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6333 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6334 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6336 return DAG.getBuildVector(WidenVT, dl, NewOps);
6340 EVT InVT =
N->getOperand(0).getValueType();
6341 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6343 unsigned NumOperands =
N->getNumOperands();
6345 bool InputWidened =
false;
6349 if (WidenNumElts % NumInElts == 0) {
6351 unsigned NumConcat = WidenNumElts / NumInElts;
6352 SDValue UndefVal = DAG.getPOISON(InVT);
6354 for (
unsigned i=0; i < NumOperands; ++i)
6355 Ops[i] =
N->getOperand(i);
6356 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6361 InputWidened =
true;
6362 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6365 for (i=1; i < NumOperands; ++i)
6366 if (!
N->getOperand(i).isUndef())
6369 if (i == NumOperands)
6372 return GetWidenedVector(
N->getOperand(0));
6374 if (NumOperands == 2) {
6376 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6381 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6382 for (
unsigned i = 0; i < NumInElts; ++i) {
6384 MaskOps[i + NumInElts] = i + WidenNumElts;
6386 return DAG.getVectorShuffle(WidenVT, dl,
6387 GetWidenedVector(
N->getOperand(0)),
6388 GetWidenedVector(
N->getOperand(1)),
6395 "Cannot use build vectors to widen CONCAT_VECTOR result");
6403 for (
unsigned i=0; i < NumOperands; ++i) {
6406 InOp = GetWidenedVector(InOp);
6407 for (
unsigned j = 0;
j < NumInElts; ++
j)
6408 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6410 SDValue UndefVal = DAG.getPOISON(EltVT);
6411 for (; Idx < WidenNumElts; ++Idx)
6412 Ops[Idx] = UndefVal;
6413 return DAG.getBuildVector(WidenVT, dl,
Ops);
6416SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6417 EVT VT =
N->getValueType(0);
6418 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6419 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6426SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6427 EVT VT =
N->getValueType(0);
6429 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6434 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6436 InOp = GetWidenedVector(InOp);
6442 if (IdxVal == 0 && InVT == WidenVT)
6449 assert(IdxVal % VTNumElts == 0 &&
6450 "Expected Idx to be a multiple of subvector minimum vector length");
6451 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6464 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6465 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6466 "down type's element count");
6473 for (;
I < VTNumElts / GCD; ++
I)
6475 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6476 for (;
I < WidenNumElts / GCD; ++
I)
6484 Align Alignment = DAG.getReducedAlign(InVT,
false);
6486 MachineFunction &MF = DAG.getMachineFunction();
6498 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6505 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6506 return DAG.getMaskedLoad(
6507 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6515 for (i = 0; i < VTNumElts; ++i)
6516 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6518 SDValue UndefVal = DAG.getPOISON(EltVT);
6519 for (; i < WidenNumElts; ++i)
6521 return DAG.getBuildVector(WidenVT, dl,
Ops);
6527 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6532SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6533 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6536 N->getOperand(1),
N->getOperand(2));
6545 "Load width must be less than or equal to first value type width");
6554 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6565 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6566 EVT LdVT =
LD->getMemoryVT();
6570 "Must be scalable");
6572 "Expected equivalent element types");
6580 TypeSize WidthDiff = WidenWidth - LdWidth;
6583 std::optional<EVT> FirstVT =
6584 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6591 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6594 Chain, BasePtr,
LD->getMemOperand());
6598 FirstVTWidth, dl, DAG);
6616 if (!
LD->getMemoryVT().isByteSized()) {
6618 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6620 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6629 EVT VT =
LD->getValueType(0);
6630 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6631 EVT WideMaskVT = getSetCCResultType(WideVT);
6634 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6635 TLI.isTypeLegal(WideMaskVT)) {
6638 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6642 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6643 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6655 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6657 Result = GenWidenVectorLoads(LdChain, LD);
6664 if (LdChain.
size() == 1)
6665 NewChain = LdChain[0];
6671 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6682 SDValue NewLoad = DAG.getMaskedLoad(
6683 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6684 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6685 LD->getAddressingMode(),
LD->getExtensionType());
6695 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6697 SDValue EVL =
N->getVectorLength();
6704 "Unable to widen binary VP op");
6705 Mask = GetWidenedVector(Mask);
6706 assert(
Mask.getValueType().getVectorElementCount() ==
6707 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6708 .getVectorElementCount() &&
6709 "Unable to widen vector load");
6712 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6713 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6714 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6722 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6724 SDValue EVL =
N->getVectorLength();
6730 "Unable to widen binary VP op");
6731 Mask = GetWidenedVector(Mask);
6732 assert(
Mask.getValueType().getVectorElementCount() ==
6733 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6734 .getVectorElementCount() &&
6735 "Unable to widen vector load");
6737 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6738 Mask, EVL,
N->getMemOperand());
6751 "Unable to widen VP strided load");
6752 Mask = GetWidenedVector(Mask);
6754 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6755 assert(
Mask.getValueType().getVectorElementCount() ==
6757 "Data and mask vectors should have the same number of elements");
6759 SDValue Res = DAG.getStridedLoadVP(
6760 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6761 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6762 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6763 N->isExpandingLoad());
6771SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6776 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6778 Mask.getValueType().getVectorElementType(),
6781 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6782 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6783 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6785 WideMask, WidePassthru);
6789 EVT VT =
N->getValueType(0);
6790 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6792 EVT MaskVT =
Mask.getValueType();
6793 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6802 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6803 TLI.isTypeLegal(WideMaskVT) &&
6809 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6810 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6814 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6815 N->getMemoryVT(),
N->getMemOperand());
6819 if (!
N->getPassThru()->isUndef()) {
6823 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6824 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6825 DAG.getPOISON(WidenVT), EVL);
6836 Mask = ModifyToType(Mask, WideMaskVT,
true);
6838 SDValue Res = DAG.getMaskedLoad(
6839 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6840 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6841 ExtType,
N->isExpandingLoad());
6850 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6852 EVT MaskVT =
Mask.getValueType();
6853 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6862 Mask = ModifyToType(Mask, WideMaskVT,
true);
6867 Index.getValueType().getScalarType(),
6869 Index = ModifyToType(Index, WideIndexVT);
6875 N->getMemoryVT().getScalarType(), NumElts);
6876 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6877 WideMemVT, dl,
Ops,
N->getMemOperand(),
6878 N->getIndexType(),
N->getExtensionType());
6887 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6895 N->getMemoryVT().getScalarType(), WideEC);
6896 Mask = GetWidenedMask(Mask, WideEC);
6899 Mask,
N->getVectorLength()};
6900 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6901 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6910 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6911 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6939 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6940 return N->getOperand(OpNo).getValueType();
6948 N =
N.getOperand(0);
6950 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6951 if (!
N->getOperand(i)->isUndef())
6953 N =
N.getOperand(0);
6957 N =
N.getOperand(0);
6959 N =
N.getOperand(0);
6986 { MaskVT, MVT::Other },
Ops);
6987 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
6995 LLVMContext &Ctx = *DAG.getContext();
6998 if (MaskScalarBits < ToMaskScalBits) {
7002 }
else if (MaskScalarBits > ToMaskScalBits) {
7008 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7010 "Mask should have the right element size by now.");
7013 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7015 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7018 EVT SubVT =
Mask->getValueType(0);
7024 assert((
Mask->getValueType(0) == ToMaskVT) &&
7025 "A mask of ToMaskVT should have been produced by now.");
7035 LLVMContext &Ctx = *DAG.getContext();
7046 EVT CondVT =
Cond->getValueType(0);
7050 EVT VSelVT =
N->getValueType(0);
7062 EVT FinalVT = VSelVT;
7073 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7074 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7081 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7089 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7092 EVT ToMaskVT = VSelVT;
7099 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7115 if (ScalarBits0 != ScalarBits1) {
7116 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7117 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7129 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7130 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7131 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7134 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7142 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7147 unsigned Opcode =
N->getOpcode();
7149 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7150 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7151 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7153 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7159 Cond1 = GetWidenedVector(Cond1);
7167 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7168 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7173 Cond1 = ModifyToType(Cond1, CondWidenVT);
7176 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7177 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7179 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7180 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7182 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7186 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7187 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7190 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7194 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7195 return DAG.getUNDEF(WidenVT);
7199 EVT VT =
N->getValueType(0);
7202 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7206 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7207 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7210 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7211 for (
unsigned i = 0; i != NumElts; ++i) {
7212 int Idx =
N->getMaskElt(i);
7213 if (Idx < (
int)NumElts)
7216 NewMask[i] = Idx - NumElts + WidenNumElts;
7218 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7222 EVT VT =
N->getValueType(0);
7226 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7227 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7233 unsigned IdxVal = WidenNumElts - VTNumElts;
7246 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7249 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7250 "down type's element count");
7253 for (; i < VTNumElts / GCD; ++i)
7255 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7256 for (; i < WidenNumElts / GCD; ++i)
7264 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7265 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7267 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7271SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7272 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7277 assert(
N->getValueType(0).isVector() &&
7278 N->getOperand(0).getValueType().isVector() &&
7279 "Operands must be vectors");
7280 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7293 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7294 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7301 InOp1 = GetWidenedVector(InOp1);
7302 InOp2 = GetWidenedVector(InOp2);
7305 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7316 "Input not widened to expected type!");
7318 if (
N->getOpcode() == ISD::VP_SETCC) {
7321 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7322 N->getOperand(2), Mask,
N->getOperand(4));
7324 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7329 assert(
N->getValueType(0).isVector() &&
7330 N->getOperand(1).getValueType().isVector() &&
7331 "Operands must be vectors");
7332 EVT VT =
N->getValueType(0);
7333 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7343 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7348 for (
unsigned i = 0; i != NumElts; ++i) {
7349 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7350 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7352 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7353 {Chain, LHSElem, RHSElem, CC});
7354 Chains[i] = Scalars[i].getValue(1);
7355 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7356 DAG.getBoolConstant(
true, dl, EltVT, VT),
7357 DAG.getBoolConstant(
false, dl, EltVT, VT));
7361 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7363 return DAG.getBuildVector(WidenVT, dl, Scalars);
7369bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7370 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7374 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7377 switch (
N->getOpcode()) {
7380 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7388 Res = WidenVecOp_FAKE_USE(
N);
7394 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7395 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7396 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7397 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7402 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7404 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7405 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7407 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7408 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7418 Res = WidenVecOp_UnrollVectorOp(
N);
7425 Res = WidenVecOp_EXTEND(
N);
7430 Res = WidenVecOp_CMP(
N);
7447 Res = WidenVecOp_Convert(
N);
7452 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7470 Res = WidenVecOp_VECREDUCE(
N);
7474 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7476 case ISD::VP_REDUCE_FADD:
7477 case ISD::VP_REDUCE_SEQ_FADD:
7478 case ISD::VP_REDUCE_FMUL:
7479 case ISD::VP_REDUCE_SEQ_FMUL:
7480 case ISD::VP_REDUCE_ADD:
7481 case ISD::VP_REDUCE_MUL:
7482 case ISD::VP_REDUCE_AND:
7483 case ISD::VP_REDUCE_OR:
7484 case ISD::VP_REDUCE_XOR:
7485 case ISD::VP_REDUCE_SMAX:
7486 case ISD::VP_REDUCE_SMIN:
7487 case ISD::VP_REDUCE_UMAX:
7488 case ISD::VP_REDUCE_UMIN:
7489 case ISD::VP_REDUCE_FMAX:
7490 case ISD::VP_REDUCE_FMIN:
7491 case ISD::VP_REDUCE_FMAXIMUM:
7492 case ISD::VP_REDUCE_FMINIMUM:
7493 Res = WidenVecOp_VP_REDUCE(
N);
7495 case ISD::VP_CTTZ_ELTS:
7496 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7497 Res = WidenVecOp_VP_CttzElements(
N);
7500 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7505 if (!Res.
getNode())
return false;
7513 if (
N->isStrictFPOpcode())
7515 "Invalid operand expansion");
7518 "Invalid operand expansion");
7520 ReplaceValueWith(
SDValue(
N, 0), Res);
7526 EVT VT =
N->getValueType(0);
7531 "Unexpected type action");
7532 InOp = GetWidenedVector(InOp);
7535 "Input wasn't widened!");
7543 EVT FixedEltVT = FixedVT.getVectorElementType();
7544 if (TLI.isTypeLegal(FixedVT) &&
7546 FixedEltVT == InEltVT) {
7548 "Not enough elements in the fixed type for the operand!");
7550 "We can't have the same type as we started with!");
7552 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7554 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7563 return WidenVecOp_Convert(
N);
7568 switch (
N->getOpcode()) {
7583 EVT OpVT =
N->getOperand(0).getValueType();
7584 EVT ResVT =
N->getValueType(0);
7591 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7592 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7598 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7599 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7601 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7608 return DAG.UnrollVectorOp(
N);
7613 EVT ResultVT =
N->getValueType(0);
7615 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7618 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7624 {WideArg,
Test},
N->getFlags());
7630 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7632 EVT OpVT =
N->getOperand(0).getValueType();
7635 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7640 EVT VT =
N->getValueType(0);
7646 "Unexpected type action");
7647 InOp = GetWidenedVector(InOp);
7649 unsigned Opcode =
N->getOpcode();
7655 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7657 if (
N->isStrictFPOpcode()) {
7659 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7662 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7663 {
N->getOperand(0), InOp });
7669 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7671 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7673 return DAG.getExtractSubvector(dl, VT, Res, 0);
7681 if (
N->isStrictFPOpcode()) {
7684 for (
unsigned i=0; i < NumElts; ++i) {
7685 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7686 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7690 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7692 for (
unsigned i = 0; i < NumElts; ++i) {
7693 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7695 Ops[i] = DAG.
getNode(Opcode, dl, EltVT, Elt,
N->getOperand(1));
7697 Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
7701 return DAG.getBuildVector(VT, dl,
Ops);
7705 EVT DstVT =
N->getValueType(0);
7706 SDValue Src = GetWidenedVector(
N->getOperand(0));
7707 EVT SrcVT = Src.getValueType();
7714 if (TLI.isTypeLegal(WideDstVT)) {
7716 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7719 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7723 return DAG.UnrollVectorOp(
N);
7727 EVT VT =
N->getValueType(0);
7728 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7736 if (!VT.
isVector() && VT != MVT::x86mmx &&
7740 if (TLI.isTypeLegal(NewVT)) {
7742 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7754 ElementCount NewNumElts =
7756 .divideCoefficientBy(EltSize);
7758 if (TLI.isTypeLegal(NewVT)) {
7760 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7765 return CreateStackStoreLoad(InOp, VT);
7773 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7774 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7779 EVT VT =
N->getValueType(0);
7781 EVT InVT =
N->getOperand(0).getValueType();
7786 unsigned NumOperands =
N->getNumOperands();
7787 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7789 for (i = 1; i < NumOperands; ++i)
7790 if (!
N->getOperand(i).isUndef())
7793 if (i == NumOperands)
7794 return GetWidenedVector(
N->getOperand(0));
7804 for (
unsigned i=0; i < NumOperands; ++i) {
7808 "Unexpected type action");
7809 InOp = GetWidenedVector(InOp);
7810 for (
unsigned j = 0;
j < NumInElts; ++
j)
7811 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7813 return DAG.getBuildVector(VT, dl,
Ops);
7816SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7817 EVT VT =
N->getValueType(0);
7822 SubVec = GetWidenedVector(SubVec);
7827 bool IndicesValid =
false;
7830 IndicesValid =
true;
7834 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7835 Attribute::VScaleRange);
7840 IndicesValid =
true;
7846 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7852 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7859 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7866 Align Alignment = DAG.getReducedAlign(VT,
false);
7868 MachineFunction &MF = DAG.getMachineFunction();
7881 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7889 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7890 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7895 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7900 unsigned Idx =
N->getConstantOperandVal(2);
7906 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7912SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7913 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7915 N->getValueType(0), InOp,
N->getOperand(1));
7918SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7919 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7921 N->getValueType(0), InOp,
N->getOperand(1));
7924SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7926 EVT ResVT =
N->getValueType(0);
7929 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
7935 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
7943 "Widened input size must be a multiple of result element size");
7946 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
7948 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
7949 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
7957 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7958 return TLI.scalarizeVectorStore(ST, DAG);
7960 if (
ST->isTruncatingStore())
7961 return TLI.scalarizeVectorStore(ST, DAG);
7971 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
7972 EVT WideMaskVT = getSetCCResultType(WideVT);
7974 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
7975 TLI.isTypeLegal(WideMaskVT)) {
7978 StVal = GetWidenedVector(StVal);
7980 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7982 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
7983 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
7984 ST->getAddressingMode());
7988 if (GenWidenVectorStores(StChain, ST)) {
7989 if (StChain.
size() == 1)
7998 SDValue WideStVal = GetWidenedVector(StVal);
8002 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8003 ST->getOffset(), Mask,
ST->getMemoryVT(),
8004 ST->getMemOperand(),
ST->getAddressingMode(),
8005 ST->isTruncatingStore());
8011SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8012 assert((OpNo == 1 || OpNo == 3) &&
8013 "Can widen only data or mask operand of vp_store");
8021 StVal = GetWidenedVector(StVal);
8027 "Unable to widen VP store");
8028 Mask = GetWidenedVector(Mask);
8030 Mask = GetWidenedVector(Mask);
8036 "Unable to widen VP store");
8037 StVal = GetWidenedVector(StVal);
8040 assert(
Mask.getValueType().getVectorElementCount() ==
8042 "Mask and data vectors should have the same number of elements");
8043 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8044 ST->getOffset(), Mask,
ST->getVectorLength(),
8045 ST->getMemoryVT(),
ST->getMemOperand(),
8046 ST->getAddressingMode(),
ST->isTruncatingStore(),
8047 ST->isCompressingStore());
8052 assert((OpNo == 1 || OpNo == 4) &&
8053 "Can widen only data or mask operand of vp_strided_store");
8062 "Unable to widen VP strided store");
8066 "Unable to widen VP strided store");
8068 StVal = GetWidenedVector(StVal);
8069 Mask = GetWidenedVector(Mask);
8072 Mask.getValueType().getVectorElementCount() &&
8073 "Data and mask vectors should have the same number of elements");
8075 return DAG.getStridedStoreVP(
8082SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8083 assert((OpNo == 1 || OpNo == 4) &&
8084 "Can widen only data or mask operand of mstore");
8087 EVT MaskVT =
Mask.getValueType();
8092 EVT WideVT, WideMaskVT;
8095 StVal = GetWidenedVector(StVal);
8102 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8109 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8110 TLI.isTypeLegal(WideMaskVT)) {
8111 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8112 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8121 Mask = ModifyToType(Mask, WideMaskVT,
true);
8124 Mask = ModifyToType(Mask, WideMaskVT,
true);
8126 StVal = ModifyToType(StVal, WideVT);
8129 assert(
Mask.getValueType().getVectorElementCount() ==
8131 "Mask and data vectors should have the same number of elements");
8138SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8139 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8141 SDValue DataOp = MG->getPassThru();
8143 SDValue Scale = MG->getScale();
8151 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8152 MG->getMemOperand(), MG->getIndexType(),
8153 MG->getExtensionType());
8159SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8168 DataOp = GetWidenedVector(DataOp);
8172 EVT IndexVT =
Index.getValueType();
8175 Index = ModifyToType(Index, WideIndexVT);
8178 EVT MaskVT =
Mask.getValueType();
8181 Mask = ModifyToType(Mask, WideMaskVT,
true);
8186 }
else if (OpNo == 4) {
8188 Index = GetWidenedVector(Index);
8194 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8199SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8208 DataOp = GetWidenedVector(DataOp);
8209 Index = GetWidenedVector(Index);
8211 Mask = GetWidenedMask(Mask, WideEC);
8214 }
else if (OpNo == 3) {
8216 Index = GetWidenedVector(Index);
8223 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8228 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8229 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8231 EVT VT =
N->getValueType(0);
8246 SVT, InOp0, InOp1,
N->getOperand(2));
8252 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8254 EVT OpVT =
N->getOperand(0).getValueType();
8257 return DAG.getNode(ExtendCode, dl, VT, CC);
8267 EVT VT =
N->getValueType(0);
8269 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8276 for (
unsigned i = 0; i != NumElts; ++i) {
8277 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8278 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8280 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8281 {Chain, LHSElem, RHSElem, CC});
8282 Chains[i] = Scalars[i].getValue(1);
8283 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8284 DAG.getBoolConstant(
true, dl, EltVT, VT),
8285 DAG.getBoolConstant(
false, dl, EltVT, VT));
8289 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8291 return DAG.getBuildVector(VT, dl, Scalars);
8315 SDValue Op = GetWidenedVector(
N->getOperand(0));
8316 EVT VT =
N->getValueType(0);
8317 EVT OrigVT =
N->getOperand(0).getValueType();
8318 EVT WideVT =
Op.getValueType();
8320 SDNodeFlags
Flags =
N->getFlags();
8322 unsigned Opc =
N->getOpcode();
8324 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8325 assert(NeutralElem &&
"Neutral element must exist");
8335 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8342 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8343 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8349 unsigned GCD = std::gcd(OrigElts, WideElts);
8352 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8353 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8354 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8355 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8358 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8359 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8361 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8370 EVT VT =
N->getValueType(0);
8372 EVT WideVT =
Op.getValueType();
8374 SDNodeFlags
Flags =
N->getFlags();
8376 unsigned Opc =
N->getOpcode();
8378 SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
8388 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8391 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8392 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8398 unsigned GCD = std::gcd(OrigElts, WideElts);
8401 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8402 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8403 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8404 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8407 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8408 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8410 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8414 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8417 SDValue Op = GetWidenedVector(
N->getOperand(1));
8419 Op.getValueType().getVectorElementCount());
8421 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8422 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8430 EVT VT =
N->getValueType(0);
8434 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8435 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8440 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8446 EVT SrcVT =
Source.getValueType();
8450 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8451 {Source, Mask, N->getOperand(2)},
N->getFlags());
8454SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8457 EVT OrigMaskVT =
Mask.getValueType();
8458 SDValue WideMask = GetWidenedVector(Mask);
8464 if (OrigElts != WideElts) {
8465 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8467 Mask, DAG.getVectorIdxConstant(0,
DL));
8488 unsigned WidenEx = 0) {
8493 unsigned AlignInBits =
Align*8;
8495 EVT RetVT = WidenEltVT;
8500 if (Width == WidenEltWidth)
8511 (WidenWidth % MemVTWidth) == 0 &&
8513 (MemVTWidth <= Width ||
8514 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8515 if (MemVTWidth == WidenWidth)
8534 (WidenWidth % MemVTWidth) == 0 &&
8536 (MemVTWidth <= Width ||
8537 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8546 return std::nullopt;
8557 unsigned Start,
unsigned End) {
8558 SDLoc dl(LdOps[Start]);
8559 EVT LdTy = LdOps[Start].getValueType();
8567 for (
unsigned i = Start + 1; i != End; ++i) {
8568 EVT NewLdTy = LdOps[i].getValueType();
8569 if (NewLdTy != LdTy) {
8588 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8589 EVT LdVT =
LD->getMemoryVT();
8599 AAMDNodes AAInfo =
LD->getAAInfo();
8603 TypeSize WidthDiff = WidenWidth - LdWidth;
8610 std::optional<EVT> FirstVT =
8611 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8618 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8623 std::optional<EVT> NewVT = FirstVT;
8624 TypeSize RemainingWidth = LdWidth;
8625 TypeSize NewVTWidth = FirstVTWidth;
8627 RemainingWidth -= NewVTWidth;
8634 NewVTWidth = NewVT->getSizeInBits();
8640 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8641 LD->getBaseAlign(), MMOFlags, AAInfo);
8653 uint64_t ScaledOffset = 0;
8654 MachinePointerInfo MPI =
LD->getPointerInfo();
8660 for (EVT MemVT : MemVTs) {
8661 Align NewAlign = ScaledOffset == 0
8662 ?
LD->getBaseAlign()
8665 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8673 unsigned End = LdOps.
size();
8684 EVT LdTy = LdOps[i].getValueType();
8687 for (--i; i >= 0; --i) {
8688 LdTy = LdOps[i].getValueType();
8695 ConcatOps[--Idx] = LdOps[i];
8696 for (--i; i >= 0; --i) {
8697 EVT NewLdTy = LdOps[i].getValueType();
8698 if (NewLdTy != LdTy) {
8708 for (;
j != End-Idx; ++
j)
8709 WidenOps[j] = ConcatOps[Idx+j];
8711 WidenOps[j] = DAG.getPOISON(LdTy);
8718 ConcatOps[--Idx] = LdOps[i];
8723 ArrayRef(&ConcatOps[Idx], End - Idx));
8729 SDValue UndefVal = DAG.getPOISON(LdTy);
8732 for (; i != End-Idx; ++i)
8733 WidenOps[i] = ConcatOps[Idx+i];
8735 WidenOps[i] = UndefVal;
8746 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8747 EVT LdVT =
LD->getMemoryVT();
8756 AAMDNodes AAInfo =
LD->getAAInfo();
8770 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8771 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8777 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8778 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8779 LD->getBaseAlign(), MMOFlags, AAInfo);
8784 SDValue UndefVal = DAG.getPOISON(EltVT);
8785 for (; i != WidenNumElts; ++i)
8788 return DAG.getBuildVector(WidenVT, dl,
Ops);
8799 AAMDNodes AAInfo =
ST->getAAInfo();
8800 SDValue ValOp = GetWidenedVector(
ST->getValue());
8803 EVT StVT =
ST->getMemoryVT();
8811 "Mismatch between store and value types");
8815 MachinePointerInfo MPI =
ST->getPointerInfo();
8816 uint64_t ScaledOffset = 0;
8825 std::optional<EVT> NewVT =
8830 TypeSize NewVTWidth = NewVT->getSizeInBits();
8833 StWidth -= NewVTWidth;
8834 MemVTs.
back().second++;
8838 for (
const auto &Pair : MemVTs) {
8839 EVT NewVT = Pair.first;
8840 unsigned Count = Pair.second;
8846 Align NewAlign = ScaledOffset == 0
8847 ?
ST->getBaseAlign()
8849 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8850 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8866 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8867 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8868 ST->getBaseAlign(), MMOFlags, AAInfo);
8885 bool FillWithZeroes) {
8890 "input and widen element type must match");
8892 "cannot modify scalable vectors in this way");
8905 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
8907 for (
unsigned i = 1; i != NumConcat; ++i)
8914 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8917 "Scalable vectors should have been handled already.");
8925 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8927 for (Idx = 0; Idx < MinNumElts; ++Idx)
8928 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8930 SDValue UndefVal = DAG.getPOISON(EltVT);
8931 for (; Idx < WidenNumElts; ++Idx)
8932 Ops[Idx] = UndefVal;
8934 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8935 if (!FillWithZeroes)
8939 "We expect to never want to FillWithZeroes for non-integral types.");
8942 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8943 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8945 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8946 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
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.