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);
1362 case ISD::VP_LOAD_FF:
1365 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1372 case ISD::VP_GATHER:
1376 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1380 SplitVecRes_SETCC(
N,
Lo,
Hi);
1383 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1390 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1393 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1396 SplitVecRes_VECTOR_INTERLEAVE(
N);
1399 SplitVecRes_VAARG(
N,
Lo,
Hi);
1405 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1411 case ISD::VP_BITREVERSE:
1419 case ISD::VP_CTLZ_ZERO_POISON:
1421 case ISD::VP_CTTZ_ZERO_POISON:
1436 case ISD::VP_FFLOOR:
1441 case ISD::VP_FNEARBYINT:
1446 case ISD::VP_FP_EXTEND:
1448 case ISD::VP_FP_ROUND:
1450 case ISD::VP_FP_TO_SINT:
1452 case ISD::VP_FP_TO_UINT:
1458 case ISD::VP_LLRINT:
1460 case ISD::VP_FROUND:
1462 case ISD::VP_FROUNDEVEN:
1471 case ISD::VP_FROUNDTOZERO:
1473 case ISD::VP_SINT_TO_FP:
1475 case ISD::VP_TRUNCATE:
1477 case ISD::VP_UINT_TO_FP:
1481 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1484 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1490 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1496 case ISD::VP_SIGN_EXTEND:
1497 case ISD::VP_ZERO_EXTEND:
1498 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1520 case ISD::VP_FMINNUM:
1523 case ISD::VP_FMAXNUM:
1525 case ISD::VP_FMINIMUM:
1527 case ISD::VP_FMAXIMUM:
1536 case ISD::OR:
case ISD::VP_OR:
1556 case ISD::VP_FCOPYSIGN:
1557 SplitVecRes_BinOp(
N,
Lo,
Hi);
1563 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1570 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1574 SplitVecRes_CMP(
N,
Lo,
Hi);
1577#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1578 case ISD::STRICT_##DAGN:
1579#include "llvm/IR/ConstrainedOps.def"
1580 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1585 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1594 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1604 SplitVecRes_FIX(
N,
Lo,
Hi);
1606 case ISD::EXPERIMENTAL_VP_SPLICE:
1607 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1609 case ISD::EXPERIMENTAL_VP_REVERSE:
1610 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1616 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1619 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1628void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1630 uint64_t *ScaledOffset) {
1635 SDValue BytesIncrement = DAG.getVScale(
1638 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1640 *ScaledOffset += IncrementSize;
1650std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1651 return SplitMask(Mask, SDLoc(Mask));
1654std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1657 EVT MaskVT =
Mask.getValueType();
1659 GetSplitVector(Mask, MaskLo, MaskHi);
1661 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1662 return std::make_pair(MaskLo, MaskHi);
1667 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1669 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1672 const SDNodeFlags
Flags =
N->getFlags();
1673 unsigned Opcode =
N->getOpcode();
1674 if (
N->getNumOperands() == 2) {
1675 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1676 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1680 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1681 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1684 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1687 std::tie(EVLLo, EVLHi) =
1688 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1691 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1693 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1699 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1701 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1702 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(2));
1705 const SDNodeFlags
Flags =
N->getFlags();
1706 unsigned Opcode =
N->getOpcode();
1707 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1709 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1716 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1718 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1720 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1723 const SDNodeFlags
Flags =
N->getFlags();
1724 unsigned Opcode =
N->getOpcode();
1725 if (
N->getNumOperands() == 3) {
1726 Lo = DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1727 Hi = DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1731 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
1732 assert(
N->isVPOpcode() &&
"Expected VP opcode");
1735 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
1738 std::tie(EVLLo, EVLHi) =
1739 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0), dl);
1742 {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1744 {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1748 LLVMContext &Ctxt = *DAG.getContext();
1754 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1756 GetSplitVector(
LHS, LHSLo, LHSHi);
1757 GetSplitVector(
RHS, RHSLo, RHSHi);
1759 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1760 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1764 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1765 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1770 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1772 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1776 unsigned Opcode =
N->getOpcode();
1777 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1779 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1788 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1795 switch (getTypeAction(InVT)) {
1809 GetExpandedOp(InOp,
Lo,
Hi);
1810 if (DAG.getDataLayout().isBigEndian())
1820 GetSplitVector(InOp,
Lo,
Hi);
1829 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1838 if (DAG.getDataLayout().isBigEndian())
1841 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1843 if (DAG.getDataLayout().isBigEndian())
1849void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1855 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1858 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1863 unsigned LaneOffset =
1866 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1868 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1875 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1878 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1881 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1886 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1888 unsigned NumSubvectors =
N->getNumOperands() / 2;
1889 if (NumSubvectors == 1) {
1890 Lo =
N->getOperand(0);
1891 Hi =
N->getOperand(1);
1896 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1905void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1912 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1927 GetSplitVector(Vec,
Lo,
Hi);
1930 EVT LoVT =
Lo.getValueType();
1940 if (IdxVal + SubElems <= LoElems) {
1948 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1950 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1956 SDValue WideSubVec = GetWidenedVector(SubVec);
1958 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
1966 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
1968 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
1969 auto &MF = DAG.getMachineFunction();
1973 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1978 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1979 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1983 Lo = DAG.getLoad(
Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1988 MachinePointerInfo MPI =
Load->getPointerInfo();
1989 IncrementPointer(Load, LoVT, MPI, StackPtr);
1992 Hi = DAG.getLoad(
Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
2001 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2006 EVT RHSVT =
RHS.getValueType();
2009 GetSplitVector(
RHS, RHSLo, RHSHi);
2011 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2026 SDValue FpValue =
N->getOperand(0);
2028 GetSplitVector(FpValue, ArgLo, ArgHi);
2030 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2032 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2041 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2045 std::tie(LoVT, HiVT) =
2049 DAG.getValueType(LoVT));
2051 DAG.getValueType(HiVT));
2056 unsigned Opcode =
N->getOpcode();
2063 GetSplitVector(N0, InLo, InHi);
2065 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2070 EVT OutLoVT, OutHiVT;
2071 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2073 assert((2 * OutNumElements) <= InNumElements &&
2074 "Illegal extend vector in reg split");
2083 SmallVector<int, 8> SplitHi(InNumElements, -1);
2084 for (
unsigned i = 0; i != OutNumElements; ++i)
2085 SplitHi[i] = i + OutNumElements;
2086 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2088 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2089 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2094 unsigned NumOps =
N->getNumOperands();
2098 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2108 for (
unsigned i = 1; i <
NumOps; ++i) {
2113 EVT InVT =
Op.getValueType();
2118 GetSplitVector(
Op, OpLo, OpHi);
2120 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2127 EVT LoValueVTs[] = {LoVT, MVT::Other};
2128 EVT HiValueVTs[] = {HiVT, MVT::Other};
2129 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2131 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2137 Lo.getValue(1),
Hi.getValue(1));
2141 ReplaceValueWith(
SDValue(
N, 1), Chain);
2144SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2146 EVT VT =
N->getValueType(0);
2157 else if (NE > ResNE)
2161 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2165 for (i = 0; i !=
NE; ++i) {
2166 Operands[0] = Chain;
2167 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2168 SDValue Operand =
N->getOperand(j);
2172 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2174 Operands[
j] = Operand;
2178 DAG.getNode(
N->getOpcode(), dl, ChainVTs, Operands,
N->getFlags());
2186 for (; i < ResNE; ++i)
2187 Scalars.
push_back(DAG.getPOISON(EltVT));
2191 ReplaceValueWith(
SDValue(
N, 1), Chain);
2195 return DAG.getBuildVector(VecVT, dl, Scalars);
2198void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2201 EVT ResVT =
N->getValueType(0);
2202 EVT OvVT =
N->getValueType(1);
2203 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2204 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2205 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2207 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2209 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2210 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2212 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2213 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2216 unsigned Opcode =
N->getOpcode();
2217 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2218 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2220 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2222 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2228 unsigned OtherNo = 1 - ResNo;
2229 EVT OtherVT =
N->getValueType(OtherNo);
2231 SetSplitVector(
SDValue(
N, OtherNo),
2237 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2241void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2247 GetSplitVector(Vec,
Lo,
Hi);
2250 unsigned IdxVal = CIdx->getZExtValue();
2251 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2252 if (IdxVal < LoNumElts) {
2254 Lo.getValueType(),
Lo, Elt, Idx);
2257 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2277 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2279 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2280 auto &MF = DAG.getMachineFunction();
2284 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2289 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2290 Store = DAG.getTruncStore(
2296 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2299 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
2303 MachinePointerInfo MPI =
Load->getPointerInfo();
2304 IncrementPointer(Load, LoVT, MPI, StackPtr);
2306 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
2309 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2310 if (LoVT !=
Lo.getValueType())
2312 if (HiVT !=
Hi.getValueType())
2320 assert(
N->getValueType(0).isScalableVector() &&
2321 "Only scalable vectors are supported for STEP_VECTOR");
2322 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2343 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2344 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2346 Hi = DAG.getPOISON(HiVT);
2356 "Extended load during type legalization!");
2358 EVT VT =
LD->getValueType(0);
2360 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2368 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2369 Ch, Ptr,
LD->getMemOperand());
2374 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2376 Lo = DAG.getBitcast(LoVT, ExtractLo);
2377 Hi = DAG.getBitcast(HiVT, ExtractHi);
2389 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2395 EVT MemoryVT =
LD->getMemoryVT();
2397 AAMDNodes AAInfo =
LD->getAAInfo();
2399 EVT LoMemVT, HiMemVT;
2400 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2404 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2405 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2406 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2411 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2414 MachinePointerInfo MPI;
2415 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2418 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2427 ReplaceValueWith(
SDValue(LD, 1), Ch);
2432 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2435 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2441 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2442 Align Alignment =
LD->getBaseAlign();
2445 EVT MemoryVT =
LD->getMemoryVT();
2447 EVT LoMemVT, HiMemVT;
2448 bool HiIsEmpty =
false;
2449 std::tie(LoMemVT, HiMemVT) =
2450 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2455 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2458 GetSplitVector(Mask, MaskLo, MaskHi);
2460 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2465 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2467 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2473 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2474 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2482 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2483 LD->isExpandingLoad());
2485 MachinePointerInfo MPI;
2487 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2489 MPI =
LD->getPointerInfo().getWithOffset(
2492 MMO = DAG.getMachineFunction().getMachineMemOperand(
2494 Alignment,
LD->getAAInfo(),
LD->getRanges());
2496 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2497 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2498 LD->isExpandingLoad());
2508 ReplaceValueWith(
SDValue(LD, 1), Ch);
2514 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2518 Align Alignment =
LD->getBaseAlign();
2525 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2528 GetSplitVector(Mask, MaskLo, MaskHi);
2530 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2534 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2536 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2541 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2544 Hi = DAG.getPOISON(HiVT);
2546 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2547 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2553 "Indexed VP strided load during type legalization!");
2555 "Unexpected indexed variable-length load offset");
2560 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2562 EVT LoMemVT, HiMemVT;
2563 bool HiIsEmpty =
false;
2564 std::tie(LoMemVT, HiMemVT) =
2565 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2570 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2573 GetSplitVector(Mask, LoMask, HiMask);
2575 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2579 std::tie(LoEVL, HiEVL) =
2583 Lo = DAG.getStridedLoadVP(
2610 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2617 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2628 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2636 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2641 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2651 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2654 GetSplitVector(Mask, MaskLo, MaskHi);
2656 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2660 EVT LoMemVT, HiMemVT;
2661 bool HiIsEmpty =
false;
2662 std::tie(LoMemVT, HiMemVT) =
2663 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2665 SDValue PassThruLo, PassThruHi;
2667 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2669 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2671 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2675 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2685 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2688 MachinePointerInfo MPI;
2695 MMO = DAG.getMachineFunction().getMachineMemOperand(
2699 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2711 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2719 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2727 }
Ops = [&]() -> Operands {
2729 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2732 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2735 EVT MemoryVT =
N->getMemoryVT();
2736 Align Alignment =
N->getBaseAlign();
2741 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2743 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2746 EVT LoMemVT, HiMemVT;
2748 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2751 if (getTypeAction(
Ops.Index.getValueType()) ==
2753 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2755 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2758 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2760 Alignment,
N->getAAInfo(),
N->getRanges());
2763 SDValue PassThru = MGT->getPassThru();
2764 SDValue PassThruLo, PassThruHi;
2767 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2769 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2774 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2775 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2776 OpsLo, MMO, IndexTy, ExtType);
2778 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2779 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2780 OpsHi, MMO, IndexTy, ExtType);
2784 std::tie(EVLLo, EVLHi) =
2785 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2787 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2788 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2789 MMO, VPGT->getIndexType());
2791 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2792 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2793 MMO, VPGT->getIndexType());
2803 ReplaceValueWith(
SDValue(
N, 1), Ch);
2817 EVT VecVT =
N->getValueType(0);
2819 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2820 bool HasCustomLowering =
false;
2827 HasCustomLowering =
true;
2833 SDValue Passthru =
N->getOperand(2);
2834 if (!HasCustomLowering) {
2835 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2836 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2843 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2844 std::tie(LoMask, HiMask) = SplitMask(Mask);
2846 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2851 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2852 MachineFunction &MF = DAG.getMachineFunction();
2864 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2866 SDValue Chain = DAG.getEntryNode();
2867 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2871 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2876 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2880 assert(
N->getValueType(0).isVector() &&
2881 N->getOperand(0).getValueType().isVector() &&
2882 "Operand types must be vectors");
2886 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2890 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2892 GetSplitVector(
N->getOperand(0), LL, LH);
2894 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2896 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2898 GetSplitVector(
N->getOperand(1), RL, RH);
2900 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2903 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2904 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2906 assert(
N->getOpcode() == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
2907 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2908 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
2909 std::tie(EVLLo, EVLHi) =
2910 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
2911 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2), MaskLo,
2913 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2), MaskHi,
2923 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2927 EVT InVT =
N->getOperand(0).getValueType();
2929 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2931 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2933 const SDNodeFlags
Flags =
N->getFlags();
2934 unsigned Opcode =
N->getOpcode();
2935 if (
N->getNumOperands() <= 2) {
2938 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2939 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2941 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2942 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2947 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
2948 assert(
N->isVPOpcode() &&
"Expected VP opcode");
2951 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
2954 std::tie(EVLLo, EVLHi) =
2955 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
2958 Hi = DAG.getNode(Opcode, dl, HiVT, {
Hi, MaskHi, EVLHi},
Flags);
2964 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2968 EVT InVT =
N->getOperand(0).getValueType();
2970 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2972 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2975 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
2976 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
2977 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS);
2978 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS);
2981void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
2986 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
2987 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
2991 EVT InVT =
N->getOperand(0).getValueType();
2993 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2995 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2997 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
2998 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3000 SDNode *HiNode =
Hi.getNode();
3001 SDNode *LoNode =
Lo.getNode();
3004 unsigned OtherNo = 1 - ResNo;
3005 EVT OtherVT =
N->getValueType(OtherNo);
3013 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3020 EVT SrcVT =
N->getOperand(0).getValueType();
3021 EVT DestVT =
N->getValueType(0);
3023 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3040 LLVMContext &Ctx = *DAG.getContext();
3044 EVT SplitLoVT, SplitHiVT;
3045 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3046 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3047 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3048 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3049 N->dump(&DAG);
dbgs() <<
"\n");
3050 if (!
N->isVPOpcode()) {
3053 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3055 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3057 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3058 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3064 DAG.
getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0),
3065 N->getOperand(1),
N->getOperand(2));
3067 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3070 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
3073 std::tie(EVLLo, EVLHi) =
3074 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
3076 Lo = DAG.
getNode(
N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
3077 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
3082 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3090 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3091 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3097 return N.getResNo() == 0 &&
3101 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3103 ArrayRef<int>
Mask) {
3106 "Expected build vector node.");
3109 for (
unsigned I = 0;
I < NewElts; ++
I) {
3112 unsigned Idx =
Mask[
I];
3114 Ops[
I] = Input2.getOperand(Idx - NewElts);
3116 Ops[
I] = Input1.getOperand(Idx);
3121 return DAG.getBuildVector(NewVT,
DL,
Ops);
3127 SmallVector<int> OrigMask(
N->getMask());
3129 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3130 &
DL](SmallVectorImpl<int> &
Mask) {
3132 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3133 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3144 for (
auto &
P : ShufflesIdxs) {
3145 if (
P.second.size() < 2)
3149 for (
int &Idx : Mask) {
3152 unsigned SrcRegIdx = Idx / NewElts;
3153 if (Inputs[SrcRegIdx].
isUndef()) {
3161 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3166 Idx = MaskElt % NewElts +
3167 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3173 Inputs[
P.second[0]] =
P.first.first;
3174 Inputs[
P.second[1]] =
P.first.second;
3177 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3180 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3181 for (
int &Idx : Mask) {
3184 unsigned SrcRegIdx = Idx / NewElts;
3185 if (Inputs[SrcRegIdx].
isUndef()) {
3192 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3193 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3196 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3198 if (UsedSubVector.count() > 1) {
3200 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3201 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3203 if (Pairs.
empty() || Pairs.
back().size() == 2)
3205 if (UsedSubVector.test(2 *
I)) {
3206 Pairs.
back().emplace_back(
I, 0);
3208 assert(UsedSubVector.test(2 *
I + 1) &&
3209 "Expected to be used one of the subvectors.");
3210 Pairs.
back().emplace_back(
I, 1);
3213 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3215 for (
int &Idx : Mask) {
3218 unsigned SrcRegIdx = Idx / NewElts;
3220 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3221 return Idxs.front().first == SrcRegIdx ||
3222 Idxs.back().first == SrcRegIdx;
3224 if (It == Pairs.
end())
3226 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3227 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3230 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3231 Inputs[Idxs.front().first] = DAG.
getNode(
3233 Inputs[Idxs.front().first].getValueType(),
3234 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3235 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3244 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3248 if (Shuffle->getOperand(0).getValueType() != NewVT)
3251 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3252 !Shuffle->isSplat()) {
3254 }
else if (!Inputs[
I].hasOneUse() &&
3255 !Shuffle->getOperand(1).isUndef()) {
3257 for (
int &Idx : Mask) {
3260 unsigned SrcRegIdx = Idx / NewElts;
3263 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3268 int OpIdx = MaskElt / NewElts;
3282 if (Shuffle->getOperand(
OpIdx).isUndef())
3284 auto *It =
find(Inputs, Shuffle->getOperand(
OpIdx));
3285 if (It == std::end(Inputs))
3287 int FoundOp = std::distance(std::begin(Inputs), It);
3290 for (
int &Idx : Mask) {
3293 unsigned SrcRegIdx = Idx / NewElts;
3296 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3301 int MaskIdx = MaskElt / NewElts;
3302 if (
OpIdx == MaskIdx)
3303 Idx = MaskElt % NewElts + FoundOp * NewElts;
3314 for (
int &Idx : Mask) {
3317 unsigned SrcRegIdx = Idx / NewElts;
3320 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3321 int OpIdx = MaskElt / NewElts;
3324 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3330 TryPeekThroughShufflesInputs(OrigMask);
3332 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3333 NewElts](SmallVectorImpl<int> &
Mask) {
3334 SetVector<SDValue> UniqueInputs;
3335 SetVector<SDValue> UniqueConstantInputs;
3336 for (
const auto &
I : Inputs) {
3338 UniqueConstantInputs.
insert(
I);
3339 else if (!
I.isUndef())
3344 if (UniqueInputs.
size() != std::size(Inputs)) {
3345 auto &&UniqueVec = UniqueInputs.
takeVector();
3346 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3347 unsigned ConstNum = UniqueConstantVec.size();
3348 for (
int &Idx : Mask) {
3351 unsigned SrcRegIdx = Idx / NewElts;
3352 if (Inputs[SrcRegIdx].
isUndef()) {
3356 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3357 if (It != UniqueConstantVec.end()) {
3358 Idx = (Idx % NewElts) +
3359 NewElts * std::distance(UniqueConstantVec.begin(), It);
3360 assert(Idx >= 0 &&
"Expected defined mask idx.");
3363 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3364 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3365 Idx = (Idx % NewElts) +
3366 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3367 assert(Idx >= 0 &&
"Expected defined mask idx.");
3369 copy(UniqueConstantVec, std::begin(Inputs));
3370 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3373 MakeUniqueInputs(OrigMask);
3375 copy(Inputs, std::begin(OrigInputs));
3381 unsigned FirstMaskIdx =
High * NewElts;
3384 assert(!Output &&
"Expected default initialized initial value.");
3385 TryPeekThroughShufflesInputs(Mask);
3386 MakeUniqueInputs(Mask);
3388 copy(Inputs, std::begin(TmpInputs));
3391 bool SecondIteration =
false;
3392 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3397 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3398 SecondIteration =
true;
3399 return SecondIteration;
3402 Mask, std::size(Inputs), std::size(Inputs),
3404 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3405 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3406 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3408 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3410 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3411 DAG.getPOISON(NewVT), Mask);
3412 Inputs[Idx] = Output;
3414 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3415 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3416 unsigned Idx2,
bool ) {
3417 if (AccumulateResults(Idx1)) {
3420 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3422 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3423 Inputs[Idx2], Mask);
3427 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3429 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3430 TmpInputs[Idx2], Mask);
3432 Inputs[Idx1] = Output;
3434 copy(OrigInputs, std::begin(Inputs));
3439 EVT OVT =
N->getValueType(0);
3446 const Align Alignment =
3447 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3449 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.
value());
3450 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV, Alignment.
value());
3455 ReplaceValueWith(
SDValue(
N, 1), Chain);
3460 EVT DstVTLo, DstVTHi;
3461 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3465 EVT SrcVT =
N->getOperand(0).getValueType();
3467 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3469 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3471 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3472 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3478 GetSplitVector(
N->getOperand(0), InLo, InHi);
3489 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3490 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3495 EVT VT =
N->getValueType(0);
3502 Align Alignment = DAG.getReducedAlign(VT,
false);
3507 EVT PtrVT =
StackPtr.getValueType();
3508 auto &MF = DAG.getMachineFunction();
3512 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3515 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3521 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3522 DAG.getConstant(1,
DL, PtrVT));
3524 DAG.getConstant(EltWidth,
DL, PtrVT));
3526 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3528 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3529 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3530 DAG.getPOISON(PtrVT), Stride, TrueMask,
3533 SDValue Load = DAG.getLoadVP(VT,
DL, Store, StackPtr, Mask, EVL, LoadMMO);
3535 std::tie(
Lo,
Hi) = DAG.SplitVector(Load,
DL);
3540 EVT VT =
N->getValueType(0);
3552 EVL1 = ZExtPromotedInteger(EVL1);
3554 Align Alignment = DAG.getReducedAlign(VT,
false);
3559 EVT PtrVT =
StackPtr.getValueType();
3560 auto &MF = DAG.getMachineFunction();
3564 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3567 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3571 SDValue StackPtr2 = TLI.getVectorElementPointer(DAG, StackPtr, VT, EVL1);
3572 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3574 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3576 DAG.getStoreVP(DAG.getEntryNode(),
DL, V1, StackPtr, PoisonPtr, TrueMask,
3580 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3585 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3586 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3588 uint64_t TrailingElts = -
Imm;
3590 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3599 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3603 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
3605 DAG.getVectorIdxConstant(0,
DL));
3611void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3619 GetSplitVector(Acc, AccLo, AccHi);
3620 unsigned Opcode =
N->getOpcode();
3632 GetSplitVector(Input1, Input1Lo, Input1Hi);
3633 GetSplitVector(Input2, Input2Lo, Input2Hi);
3636 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3637 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3640void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3648 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3656void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3657 unsigned Factor =
N->getNumOperands();
3660 for (
unsigned i = 0; i != Factor; ++i) {
3662 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3664 Ops[i * 2 + 1] = OpHi;
3675 for (
unsigned i = 0; i != Factor; ++i)
3679void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3680 unsigned Factor =
N->getNumOperands();
3683 for (
unsigned i = 0; i != Factor; ++i) {
3685 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3687 Ops[i + Factor] = OpHi;
3698 for (
unsigned i = 0; i != Factor; ++i) {
3699 unsigned IdxLo = 2 * i;
3700 unsigned IdxHi = 2 * i + 1;
3701 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].getValue(IdxLo % Factor),
3702 Res[IdxHi / Factor].getValue(IdxHi % Factor));
3714bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3719 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3722 switch (
N->getOpcode()) {
3725 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3735 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3742 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3744 case ISD::VP_TRUNCATE:
3746 Res = SplitVecOp_TruncateHelper(
N);
3749 case ISD::VP_FP_ROUND:
3752 Res = SplitVecOp_FP_ROUND(
N);
3761 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3768 case ISD::VP_SCATTER:
3772 case ISD::VP_GATHER:
3776 Res = SplitVecOp_VSELECT(
N, OpNo);
3779 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3785 case ISD::VP_SINT_TO_FP:
3786 case ISD::VP_UINT_TO_FP:
3787 if (
N->getValueType(0).bitsLT(
3788 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3789 Res = SplitVecOp_TruncateHelper(
N);
3791 Res = SplitVecOp_UnaryOp(
N);
3795 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3799 case ISD::VP_FP_TO_SINT:
3800 case ISD::VP_FP_TO_UINT:
3813 Res = SplitVecOp_UnaryOp(
N);
3816 Res = SplitVecOp_FPOpDifferentTypes(
N);
3821 Res = SplitVecOp_CMP(
N);
3825 Res = SplitVecOp_FAKE_USE(
N);
3830 Res = SplitVecOp_ExtVecInRegOp(
N);
3848 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3852 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3854 case ISD::VP_REDUCE_FADD:
3855 case ISD::VP_REDUCE_SEQ_FADD:
3856 case ISD::VP_REDUCE_FMUL:
3857 case ISD::VP_REDUCE_SEQ_FMUL:
3858 case ISD::VP_REDUCE_ADD:
3859 case ISD::VP_REDUCE_MUL:
3860 case ISD::VP_REDUCE_AND:
3861 case ISD::VP_REDUCE_OR:
3862 case ISD::VP_REDUCE_XOR:
3863 case ISD::VP_REDUCE_SMAX:
3864 case ISD::VP_REDUCE_SMIN:
3865 case ISD::VP_REDUCE_UMAX:
3866 case ISD::VP_REDUCE_UMIN:
3867 case ISD::VP_REDUCE_FMAX:
3868 case ISD::VP_REDUCE_FMIN:
3869 case ISD::VP_REDUCE_FMAXIMUM:
3870 case ISD::VP_REDUCE_FMINIMUM:
3871 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3875 Res = SplitVecOp_CttzElts(
N);
3877 case ISD::VP_CTTZ_ELTS:
3878 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3879 Res = SplitVecOp_VP_CttzElements(
N);
3882 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3888 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3893 if (!Res.
getNode())
return false;
3900 if (
N->isStrictFPOpcode())
3902 "Invalid operand expansion");
3905 "Invalid operand expansion");
3907 ReplaceValueWith(
SDValue(
N, 0), Res);
3911SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3915 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3917 EVT VT =
N->getValueType(0);
3930 getSetCCResultType(MVT::i1), MVT::i1);
3935 DAG.getElementCount(
DL, VT, SplitEC)),
3939SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
3942 assert(OpNo == 0 &&
"Illegal operand must be mask");
3949 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
3952 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3953 assert(
Lo.getValueType() ==
Hi.getValueType() &&
3954 "Lo and Hi have differing types");
3957 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
3958 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
3960 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
3961 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
3962 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
3963 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
3973SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
3976 assert(OpNo == 1 &&
"Illegal operand must be mask");
3981 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
3983 EVT VecVT =
N->getValueType(0);
3987SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
3988 EVT ResVT =
N->getValueType(0);
3994 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
3995 GetSplitVector(VecOp,
Lo,
Hi);
3997 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4002 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4003 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4007 EVT ResVT =
N->getValueType(0);
4013 SDNodeFlags
Flags =
N->getFlags();
4016 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4017 GetSplitVector(VecOp,
Lo,
Hi);
4019 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4025 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4028SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4029 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4030 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4032 unsigned Opc =
N->getOpcode();
4033 EVT ResVT =
N->getValueType(0);
4039 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4040 GetSplitVector(VecOp,
Lo,
Hi);
4043 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4046 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4048 const SDNodeFlags
Flags =
N->getFlags();
4052 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4057 EVT ResVT =
N->getValueType(0);
4060 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4061 EVT InVT =
Lo.getValueType();
4066 if (
N->isStrictFPOpcode()) {
4067 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4068 {N->getOperand(0), Lo});
4069 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4070 {N->getOperand(0), Hi});
4079 ReplaceValueWith(
SDValue(
N, 1), Ch);
4080 }
else if (
N->getNumOperands() == 3) {
4081 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4082 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4083 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4084 std::tie(EVLLo, EVLHi) =
4085 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0), dl);
4086 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo, MaskLo, EVLLo);
4087 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi, MaskHi, EVLHi);
4089 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4090 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4099 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4109 EVT ResVT =
N->getValueType(0);
4111 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4115 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4121 Lo = BitConvertToInteger(
Lo);
4122 Hi = BitConvertToInteger(
Hi);
4124 if (DAG.getDataLayout().isBigEndian())
4132 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4134 EVT ResVT =
N->getValueType(0);
4142 GetSplitVector(SubVec,
Lo,
Hi);
4151 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4153 return SecondInsertion;
4156SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4163 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4165 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4167 ElementCount IdxVal =
4171 EVT SrcVT =
N->getOperand(0).getValueType();
4190 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4191 LoEltsMin - IdxValMin);
4192 DAG.ExtractVectorElements(
Hi, Elts, 0,
4195 return DAG.getBuildVector(SubVT, dl, Elts);
4199 ElementCount ExtractIdx = IdxVal - LoElts;
4201 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4204 EVT HiVT =
Hi.getValueType();
4206 "Only fixed-vector extracts are supported in this case");
4216 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4217 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4223 "Extracting scalable subvector from fixed-width unsupported");
4231 "subvector from a scalable predicate vector");
4237 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4239 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4240 auto &MF = DAG.getMachineFunction();
4244 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4248 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4251 SubVT, dl, Store, StackPtr,
4255SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4261 uint64_t IdxVal =
Index->getZExtValue();
4264 GetSplitVector(Vec,
Lo,
Hi);
4266 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4268 if (IdxVal < LoElts)
4269 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4272 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4277 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4289 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4295 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4297 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4298 auto &MF = DAG.getMachineFunction();
4301 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4305 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4309 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4311 return DAG.getExtLoad(
4322 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4330 SplitVecRes_Gather(
N,
Lo,
Hi);
4333 ReplaceValueWith(
SDValue(
N, 0), Res);
4338 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4342 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4344 SDValue EVL =
N->getVectorLength();
4346 Align Alignment =
N->getBaseAlign();
4352 GetSplitVector(
Data, DataLo, DataHi);
4354 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4359 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4362 GetSplitVector(Mask, MaskLo, MaskHi);
4364 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4367 EVT MemoryVT =
N->getMemoryVT();
4368 EVT LoMemVT, HiMemVT;
4369 bool HiIsEmpty =
false;
4370 std::tie(LoMemVT, HiMemVT) =
4371 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4375 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4378 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4383 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4384 N->getAddressingMode(),
N->isTruncatingStore(),
4385 N->isCompressingStore());
4391 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4392 N->isCompressingStore());
4394 MachinePointerInfo MPI;
4398 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4403 MMO = DAG.getMachineFunction().getMachineMemOperand(
4405 Alignment,
N->getAAInfo(),
N->getRanges());
4407 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4408 N->getAddressingMode(),
N->isTruncatingStore(),
4409 N->isCompressingStore());
4418 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4419 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4426 GetSplitVector(
Data, LoData, HiData);
4428 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4430 EVT LoMemVT, HiMemVT;
4431 bool HiIsEmpty =
false;
4432 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4438 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4439 else if (getTypeAction(
Mask.getValueType()) ==
4441 GetSplitVector(Mask, LoMask, HiMask);
4443 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4446 std::tie(LoEVL, HiEVL) =
4447 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4451 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4452 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4453 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4464 EVT PtrVT =
N->getBasePtr().getValueType();
4467 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4470 Align Alignment =
N->getBaseAlign();
4475 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4476 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4478 Alignment,
N->getAAInfo(),
N->getRanges());
4481 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4482 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4483 N->isCompressingStore());
4492 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4496 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4499 Align Alignment =
N->getBaseAlign();
4505 GetSplitVector(
Data, DataLo, DataHi);
4507 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4512 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4515 GetSplitVector(Mask, MaskLo, MaskHi);
4517 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4520 EVT MemoryVT =
N->getMemoryVT();
4521 EVT LoMemVT, HiMemVT;
4522 bool HiIsEmpty =
false;
4523 std::tie(LoMemVT, HiMemVT) =
4524 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4527 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4532 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4533 N->getAddressingMode(),
N->isTruncatingStore(),
4534 N->isCompressingStore());
4542 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4543 N->isCompressingStore());
4545 MachinePointerInfo MPI;
4549 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4554 MMO = DAG.getMachineFunction().getMachineMemOperand(
4556 Alignment,
N->getAAInfo(),
N->getRanges());
4558 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4559 N->getAddressingMode(),
N->isTruncatingStore(),
4560 N->isCompressingStore());
4573 EVT MemoryVT =
N->getMemoryVT();
4574 Align Alignment =
N->getBaseAlign();
4581 }
Ops = [&]() -> Operands {
4583 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4587 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4592 EVT LoMemVT, HiMemVT;
4593 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4598 GetSplitVector(
Ops.Data, DataLo, DataHi);
4600 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4605 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4607 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4611 if (getTypeAction(
Ops.Index.getValueType()) ==
4613 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4615 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4619 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4621 Alignment,
N->getAAInfo(),
N->getRanges());
4624 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4626 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4627 MSC->getIndexType(), MSC->isTruncatingStore());
4632 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4633 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4634 MMO, MSC->getIndexType(),
4635 MSC->isTruncatingStore());
4639 std::tie(EVLLo, EVLHi) =
4640 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4642 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4643 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4644 VPSC->getIndexType());
4649 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4650 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4651 VPSC->getIndexType());
4655 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4656 assert(OpNo == 1 &&
"Can only split the stored value");
4659 bool isTruncating =
N->isTruncatingStore();
4662 EVT MemoryVT =
N->getMemoryVT();
4663 Align Alignment =
N->getBaseAlign();
4665 AAMDNodes AAInfo =
N->getAAInfo();
4667 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4669 EVT LoMemVT, HiMemVT;
4670 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4674 return TLI.scalarizeVectorStore(
N, DAG);
4677 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4678 Alignment, MMOFlags, AAInfo);
4680 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4683 MachinePointerInfo MPI;
4684 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4687 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4688 HiMemVT, Alignment, MMOFlags, AAInfo);
4690 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4706 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4712 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4733 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4734 SDValue InVec =
N->getOperand(OpNo);
4736 EVT OutVT =
N->getValueType(0);
4744 EVT LoOutVT, HiOutVT;
4745 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4746 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4751 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4753 return SplitVecOp_UnaryOp(
N);
4762 return SplitVecOp_UnaryOp(
N);
4766 GetSplitVector(InVec, InLoVec, InHiVec);
4772 EVT HalfElementVT = IsFloat ?
4774 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4781 if (
N->isStrictFPOpcode()) {
4782 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4783 {N->getOperand(0), InLoVec});
4784 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4785 {N->getOperand(0), InHiVec});
4791 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4792 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4796 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4804 if (
N->isStrictFPOpcode()) {
4808 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4816 DAG.getTargetConstant(
4817 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4824 assert(
N->getValueType(0).isVector() &&
4825 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4826 "Operand types must be vectors");
4828 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4830 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4831 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4833 EVT VT =
N->getValueType(0);
4834 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4839 }
else if (isStrict) {
4840 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4841 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4842 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4843 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4846 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4848 assert(
Opc == ISD::VP_SETCC &&
"Expected VP_SETCC opcode");
4849 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4850 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(3));
4851 std::tie(EVLLo, EVLHi) =
4852 DAG.SplitEVL(
N->getOperand(4),
N->getValueType(0),
DL);
4853 LoRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Lo0, Lo1,
4854 N->getOperand(2), MaskLo, EVLLo);
4855 HiRes = DAG.
getNode(ISD::VP_SETCC,
DL, PartResVT, Hi0, Hi1,
4856 N->getOperand(2), MaskHi, EVLHi);
4864 EVT OpVT =
N->getOperand(0).getValueType();
4867 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4873 EVT ResVT =
N->getValueType(0);
4876 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4877 EVT InVT =
Lo.getValueType();
4882 if (
N->isStrictFPOpcode()) {
4883 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4884 {N->getOperand(0), Lo, N->getOperand(2)});
4885 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
4886 {N->getOperand(0), Hi, N->getOperand(2)});
4890 Lo.getValue(1),
Hi.getValue(1));
4891 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4892 }
else if (
N->getOpcode() == ISD::VP_FP_ROUND) {
4893 SDValue MaskLo, MaskHi, EVLLo, EVLHi;
4894 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(1));
4895 std::tie(EVLLo, EVLHi) =
4896 DAG.SplitEVL(
N->getOperand(2),
N->getValueType(0),
DL);
4897 Lo = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Lo, MaskLo, EVLLo);
4898 Hi = DAG.getNode(ISD::VP_FP_ROUND,
DL, OutVT,
Hi, MaskHi, EVLHi);
4900 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
4901 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
4912SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
4915 EVT LHSLoVT, LHSHiVT;
4916 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
4918 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
4919 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
4922 std::tie(LHSLo, LHSHi) =
4923 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
4926 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
4929 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
4935 LLVMContext &Ctxt = *DAG.getContext();
4938 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
4939 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
4940 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
4942 EVT ResVT =
N->getValueType(0);
4947 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
4948 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
4954 EVT ResVT =
N->getValueType(0);
4957 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4958 EVT InVT =
Lo.getValueType();
4964 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
4965 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
4972 EVT ResVT =
N->getValueType(0);
4976 GetSplitVector(VecOp,
Lo,
Hi);
4982 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
4984 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
4986 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
4987 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
4992 EVT ResVT =
N->getValueType(0);
4996 GetSplitVector(VecOp,
Lo,
Hi);
4998 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
4999 auto [EVLLo, EVLHi] =
5001 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5007 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5009 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5010 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5013SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5024 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5025 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5026 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5027 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5028 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5029 OpsLo, MMO, IndexType);
5030 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5031 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5035SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5038 "Accumulator should already be a legal type, and shouldn't need "
5039 "further splitting");
5042 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5043 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5044 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5045 unsigned Opcode =
N->getOpcode();
5048 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5049 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5056void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5057 unsigned WidenResNo) {
5058 unsigned NumResults =
N->getNumValues();
5059 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5060 if (ResNo == WidenResNo)
5062 EVT ResVT =
N->getValueType(ResNo);
5068 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5069 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5074void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5075 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5078 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5083 auto unrollExpandedOp = [&]() {
5088 EVT VT =
N->getValueType(0);
5089 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5090 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5091 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5093 if (
N->getNumValues() > 1)
5094 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5100 switch (
N->getOpcode()) {
5103 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5111 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5115 Res = WidenVecRes_ADDRSPACECAST(
N);
5122 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5129 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5133 Res = WidenVecRes_ScalarOp(
N);
5138 case ISD::VP_SELECT:
5140 Res = WidenVecRes_Select(
N);
5144 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5146 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5153 case ISD::VP_LOAD_FF:
5156 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5160 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5168 case ISD::VP_GATHER:
5172 Res = WidenVecRes_VECTOR_REVERSE(
N);
5175 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5185 case ISD::OR:
case ISD::VP_OR:
5196 case ISD::VP_FMINNUM:
5199 case ISD::VP_FMAXNUM:
5201 case ISD::VP_FMINIMUM:
5203 case ISD::VP_FMAXIMUM:
5236 case ISD::VP_FCOPYSIGN:
5237 Res = WidenVecRes_Binary(
N);
5244 Res = WidenVecRes_MaskedBinary(
N);
5249 Res = WidenVecRes_CMP(
N);
5255 if (unrollExpandedOp())
5270 Res = WidenVecRes_BinaryCanTrap(
N);
5279 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5282#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5283 case ISD::STRICT_##DAGN:
5284#include "llvm/IR/ConstrainedOps.def"
5285 Res = WidenVecRes_StrictFP(
N);
5294 Res = WidenVecRes_OverflowOp(
N, ResNo);
5298 Res = WidenVecRes_FCOPYSIGN(
N);
5303 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5308 if (!unrollExpandedOp())
5309 Res = WidenVecRes_ExpOp(
N);
5315 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5320 case ISD::VP_FP_EXTEND:
5322 case ISD::VP_FP_ROUND:
5324 case ISD::VP_FP_TO_SINT:
5326 case ISD::VP_FP_TO_UINT:
5328 case ISD::VP_SIGN_EXTEND:
5330 case ISD::VP_SINT_TO_FP:
5331 case ISD::VP_TRUNCATE:
5334 case ISD::VP_UINT_TO_FP:
5336 case ISD::VP_ZERO_EXTEND:
5338 Res = WidenVecRes_Convert(
N);
5343 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5349 case ISD::VP_LLRINT:
5352 Res = WidenVecRes_XROUND(
N);
5378 if (unrollExpandedOp())
5388 case ISD::VP_BITREVERSE:
5394 case ISD::VP_CTLZ_ZERO_POISON:
5400 case ISD::VP_CTTZ_ZERO_POISON:
5405 case ISD::VP_FFLOOR:
5407 case ISD::VP_FNEARBYINT:
5408 case ISD::VP_FROUND:
5409 case ISD::VP_FROUNDEVEN:
5410 case ISD::VP_FROUNDTOZERO:
5415 Res = WidenVecRes_Unary(
N);
5422 Res = WidenVecRes_Ternary(
N);
5428 if (!unrollExpandedOp())
5429 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5436 SetWidenedVector(
SDValue(
N, ResNo), Res);
5442 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5443 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5444 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5445 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5446 if (
N->getNumOperands() == 3)
5447 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5449 assert(
N->getNumOperands() == 5 &&
"Unexpected number of operands!");
5450 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5454 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5455 {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
5461 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5462 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5463 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5464 if (
N->getNumOperands() == 2)
5465 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5468 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5469 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5473 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5474 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5479 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5480 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5481 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5484 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5485 Mask = ModifyToType(Mask, WideMaskVT,
true);
5486 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5491 LLVMContext &Ctxt = *DAG.getContext();
5496 EVT OpVT =
LHS.getValueType();
5498 LHS = GetWidenedVector(
LHS);
5499 RHS = GetWidenedVector(
RHS);
5500 OpVT =
LHS.getValueType();
5503 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5506 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5512SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5515 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5516 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5517 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5519 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5528 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5531 if (ConcatEnd == 1) {
5532 VT = ConcatOps[0].getValueType();
5534 return ConcatOps[0];
5537 SDLoc dl(ConcatOps[0]);
5544 while (ConcatOps[ConcatEnd-1].
getValueType() != MaxVT) {
5545 int Idx = ConcatEnd - 1;
5546 VT = ConcatOps[Idx--].getValueType();
5547 while (Idx >= 0 && ConcatOps[Idx].
getValueType() == VT)
5560 unsigned NumToInsert = ConcatEnd - Idx - 1;
5561 for (
unsigned i = 0,
OpIdx = Idx + 1; i < NumToInsert; i++,
OpIdx++)
5563 ConcatOps[Idx+1] = VecOp;
5564 ConcatEnd = Idx + 2;
5570 unsigned RealVals = ConcatEnd - Idx - 1;
5571 unsigned SubConcatEnd = 0;
5572 unsigned SubConcatIdx = Idx + 1;
5573 while (SubConcatEnd < RealVals)
5574 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5575 while (SubConcatEnd < OpsToConcat)
5576 SubConcatOps[SubConcatEnd++] = undefVec;
5578 NextVT, SubConcatOps);
5579 ConcatEnd = SubConcatIdx + 1;
5584 if (ConcatEnd == 1) {
5585 VT = ConcatOps[0].getValueType();
5587 return ConcatOps[0];
5592 if (
NumOps != ConcatEnd ) {
5594 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5595 ConcatOps[j] = UndefVal;
5603 unsigned Opcode =
N->getOpcode();
5605 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5609 const SDNodeFlags
Flags =
N->getFlags();
5610 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5611 NumElts = NumElts / 2;
5615 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5617 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5618 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5619 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5627 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5630 TLI.isTypeLegal(WideMaskVT)) {
5631 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5632 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5633 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5635 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5636 N->getValueType(0).getVectorElementCount());
5637 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5651 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5652 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5653 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5656 unsigned ConcatEnd = 0;
5664 while (CurNumElts != 0) {
5665 while (CurNumElts >= NumElts) {
5666 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5667 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5668 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5670 CurNumElts -= NumElts;
5673 NumElts = NumElts / 2;
5675 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5678 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5679 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5680 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5681 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5692 switch (
N->getOpcode()) {
5695 return WidenVecRes_STRICT_FSETCC(
N);
5702 return WidenVecRes_Convert_StrictFP(
N);
5709 unsigned Opcode =
N->getOpcode();
5711 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5715 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5716 NumElts = NumElts / 2;
5727 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5731 unsigned ConcatEnd = 0;
5738 for (
unsigned i = 1; i < NumOpers; ++i) {
5744 Oper = GetWidenedVector(Oper);
5750 DAG.getPOISON(WideOpVT), Oper,
5751 DAG.getVectorIdxConstant(0, dl));
5763 while (CurNumElts != 0) {
5764 while (CurNumElts >= NumElts) {
5767 for (
unsigned i = 0; i < NumOpers; ++i) {
5770 EVT OpVT =
Op.getValueType();
5775 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5781 EVT OperVT[] = {VT, MVT::Other};
5783 ConcatOps[ConcatEnd++] = Oper;
5786 CurNumElts -= NumElts;
5789 NumElts = NumElts / 2;
5791 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5794 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5797 for (
unsigned i = 0; i < NumOpers; ++i) {
5800 EVT OpVT =
Op.getValueType();
5808 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5810 ConcatOps[ConcatEnd++] = Oper;
5819 if (Chains.
size() == 1)
5820 NewChain = Chains[0];
5823 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5828SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5830 EVT ResVT =
N->getValueType(0);
5831 EVT OvVT =
N->getValueType(1);
5832 EVT WideResVT, WideOvVT;
5837 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5842 WideLHS = GetWidenedVector(
N->getOperand(0));
5843 WideRHS = GetWidenedVector(
N->getOperand(1));
5845 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5854 N->getOperand(0), Zero);
5856 N->getOperand(1), Zero);
5859 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5860 SDNode *WideNode = DAG.getNode(
5861 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5864 unsigned OtherNo = 1 - ResNo;
5865 EVT OtherVT =
N->getValueType(OtherNo);
5872 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5875 return SDValue(WideNode, ResNo);
5879 LLVMContext &Ctx = *DAG.getContext();
5883 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
5888 unsigned Opcode =
N->getOpcode();
5889 const SDNodeFlags
Flags =
N->getFlags();
5895 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
5897 InOp = ZExtPromotedInteger(InOp);
5908 InOp = GetWidenedVector(
N->getOperand(0));
5911 if (InVTEC == WidenEC) {
5912 if (
N->getNumOperands() == 1)
5913 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Flags);
5914 if (
N->getNumOperands() == 3) {
5915 assert(
N->isVPOpcode() &&
"Expected VP opcode");
5918 return DAG.getNode(Opcode,
DL, WidenVT, InOp, Mask,
N->getOperand(2));
5920 return DAG.getNode(Opcode,
DL, WidenVT, InOp,
N->getOperand(1), Flags);
5946 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
5950 if (TLI.isTypeLegal(InWidenVT)) {
5958 unsigned NumConcat =
5963 if (
N->getNumOperands() == 1)
5964 return DAG.getNode(Opcode,
DL, WidenVT, InVec, Flags);
5965 return DAG.getNode(Opcode,
DL, WidenVT, InVec,
N->getOperand(1), Flags);
5969 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
5971 if (
N->getNumOperands() == 1)
5972 return DAG.getNode(Opcode,
DL, WidenVT, InVal, Flags);
5973 return DAG.getNode(Opcode,
DL, WidenVT, InVal,
N->getOperand(1), Flags);
5982 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
5983 for (
unsigned i=0; i < MinElts; ++i) {
5984 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
5985 if (
N->getNumOperands() == 1)
5988 Ops[i] = DAG.getNode(Opcode,
DL, EltVT, Val,
N->getOperand(1), Flags);
5991 return DAG.getBuildVector(WidenVT,
DL,
Ops);
5996 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6000 EVT SrcVT = Src.getValueType();
6004 Src = GetWidenedVector(Src);
6005 SrcVT = Src.getValueType();
6012 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6017 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6021 EVT SrcVT = Src.getValueType();
6025 Src = GetWidenedVector(Src);
6026 SrcVT = Src.getValueType();
6033 if (
N->getNumOperands() == 1)
6034 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6036 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6037 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6041 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src, Mask,
N->getOperand(2));
6044SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6049 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6055 unsigned Opcode =
N->getOpcode();
6061 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6066 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6067 for (
unsigned i=0; i < MinElts; ++i) {
6068 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6069 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6073 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6075 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6078SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6079 unsigned Opcode =
N->getOpcode();
6083 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6092 InOp = GetWidenedVector(InOp);
6099 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6106 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6107 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6124 while (
Ops.size() != WidenNumElts)
6125 Ops.push_back(DAG.getPOISON(WidenSVT));
6127 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6133 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6134 return WidenVecRes_BinaryCanTrap(
N);
6137 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6144SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6146 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6149 SDValue Arg = GetWidenedVector(FpValue);
6150 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6155 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6156 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6158 EVT ExpVT =
RHS.getValueType();
6163 ExpOp = ModifyToType(
RHS, WideExpVT);
6166 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6171 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6172 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6173 if (
N->getNumOperands() == 1)
6174 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6176 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
6177 N->getOperand(1),
N->getFlags());
6179 assert(
N->getNumOperands() == 3 &&
"Unexpected number of operands!");
6180 assert(
N->isVPOpcode() &&
"Expected VP opcode");
6184 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
6185 {InOp,
Mask,
N->getOperand(2)});
6189 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6194 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6195 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6196 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6199SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6201 EVT VT0 =
N->getValueType(0);
6202 EVT VT1 =
N->getValueType(1);
6206 "expected both results to be vectors of matching element count");
6208 LLVMContext &Ctx = *DAG.getContext();
6209 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6211 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6218 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6221 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6222 return SDValue(WidenNode, ResNo);
6225SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6226 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6227 return GetWidenedVector(WidenVec);
6231 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6232 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6235 return DAG.getAddrSpaceCast(SDLoc(
N), WidenVT, InOp,
6236 AddrSpaceCastN->getSrcAddressSpace(),
6237 AddrSpaceCastN->getDestAddressSpace());
6243 EVT VT =
N->getValueType(0);
6244 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6247 switch (getTypeAction(InVT)) {
6261 SDValue NInOp = GetPromotedInteger(InOp);
6263 if (WidenVT.
bitsEq(NInVT)) {
6266 if (DAG.getDataLayout().isBigEndian()) {
6269 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6287 InOp = GetWidenedVector(InOp);
6289 if (WidenVT.
bitsEq(InVT))
6299 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6304 unsigned NewNumParts = WidenSize / InSize;
6317 EVT OrigInVT =
N->getOperand(0).getValueType();
6322 if (TLI.isTypeLegal(NewInVT)) {
6330 if (WidenSize % InSize == 0) {
6337 DAG.ExtractVectorElements(InOp,
Ops);
6338 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6350 return CreateStackStoreLoad(InOp, WidenVT);
6353SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6355 N->getOpcode(), SDLoc(
N),
6356 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6357 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6363 EVT VT =
N->getValueType(0);
6367 EVT EltVT =
N->getOperand(0).getValueType();
6370 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6374 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6375 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6377 return DAG.getBuildVector(WidenVT, dl, NewOps);
6381 EVT InVT =
N->getOperand(0).getValueType();
6382 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6384 unsigned NumOperands =
N->getNumOperands();
6386 bool InputWidened =
false;
6390 if (WidenNumElts % NumInElts == 0) {
6392 unsigned NumConcat = WidenNumElts / NumInElts;
6393 SDValue UndefVal = DAG.getPOISON(InVT);
6395 for (
unsigned i=0; i < NumOperands; ++i)
6396 Ops[i] =
N->getOperand(i);
6397 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6402 InputWidened =
true;
6403 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6406 for (i=1; i < NumOperands; ++i)
6407 if (!
N->getOperand(i).isUndef())
6410 if (i == NumOperands)
6413 return GetWidenedVector(
N->getOperand(0));
6415 if (NumOperands == 2) {
6417 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6422 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6423 for (
unsigned i = 0; i < NumInElts; ++i) {
6425 MaskOps[i + NumInElts] = i + WidenNumElts;
6427 return DAG.getVectorShuffle(WidenVT, dl,
6428 GetWidenedVector(
N->getOperand(0)),
6429 GetWidenedVector(
N->getOperand(1)),
6436 "Cannot use build vectors to widen CONCAT_VECTOR result");
6444 for (
unsigned i=0; i < NumOperands; ++i) {
6447 InOp = GetWidenedVector(InOp);
6448 for (
unsigned j = 0;
j < NumInElts; ++
j)
6449 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6451 SDValue UndefVal = DAG.getPOISON(EltVT);
6452 for (; Idx < WidenNumElts; ++Idx)
6453 Ops[Idx] = UndefVal;
6454 return DAG.getBuildVector(WidenVT, dl,
Ops);
6457SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6458 EVT VT =
N->getValueType(0);
6459 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6460 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6467SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6468 EVT VT =
N->getValueType(0);
6470 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6475 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6477 InOp = GetWidenedVector(InOp);
6483 if (IdxVal == 0 && InVT == WidenVT)
6490 assert(IdxVal % VTNumElts == 0 &&
6491 "Expected Idx to be a multiple of subvector minimum vector length");
6492 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6505 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6506 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6507 "down type's element count");
6514 for (;
I < VTNumElts / GCD; ++
I)
6516 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6517 for (;
I < WidenNumElts / GCD; ++
I)
6525 Align Alignment = DAG.getReducedAlign(InVT,
false);
6527 MachineFunction &MF = DAG.getMachineFunction();
6539 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6546 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6547 return DAG.getMaskedLoad(
6548 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6556 for (i = 0; i < VTNumElts; ++i)
6557 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6559 SDValue UndefVal = DAG.getPOISON(EltVT);
6560 for (; i < WidenNumElts; ++i)
6562 return DAG.getBuildVector(WidenVT, dl,
Ops);
6568 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6573SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6574 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6577 N->getOperand(1),
N->getOperand(2));
6586 "Load width must be less than or equal to first value type width");
6595 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6606 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6607 EVT LdVT =
LD->getMemoryVT();
6611 "Must be scalable");
6613 "Expected equivalent element types");
6621 TypeSize WidthDiff = WidenWidth - LdWidth;
6624 std::optional<EVT> FirstVT =
6625 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6632 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6635 Chain, BasePtr,
LD->getMemOperand());
6639 FirstVTWidth, dl, DAG);
6657 if (!
LD->getMemoryVT().isByteSized()) {
6659 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6661 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6670 EVT VT =
LD->getValueType(0);
6671 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6672 EVT WideMaskVT = getSetCCResultType(WideVT);
6675 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6676 TLI.isTypeLegal(WideMaskVT)) {
6679 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6683 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6684 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6696 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6698 Result = GenWidenVectorLoads(LdChain, LD);
6705 if (LdChain.
size() == 1)
6706 NewChain = LdChain[0];
6712 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6723 SDValue NewLoad = DAG.getMaskedLoad(
6724 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6725 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6726 LD->getAddressingMode(),
LD->getExtensionType());
6736 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6738 SDValue EVL =
N->getVectorLength();
6745 "Unable to widen binary VP op");
6746 Mask = GetWidenedVector(Mask);
6747 assert(
Mask.getValueType().getVectorElementCount() ==
6748 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6749 .getVectorElementCount() &&
6750 "Unable to widen vector load");
6753 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6754 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6755 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6763 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6765 SDValue EVL =
N->getVectorLength();
6771 "Unable to widen binary VP op");
6772 Mask = GetWidenedVector(Mask);
6773 assert(
Mask.getValueType().getVectorElementCount() ==
6774 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6775 .getVectorElementCount() &&
6776 "Unable to widen vector load");
6778 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6779 Mask, EVL,
N->getMemOperand());
6792 "Unable to widen VP strided load");
6793 Mask = GetWidenedVector(Mask);
6795 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6796 assert(
Mask.getValueType().getVectorElementCount() ==
6798 "Data and mask vectors should have the same number of elements");
6800 SDValue Res = DAG.getStridedLoadVP(
6801 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6802 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6803 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6804 N->isExpandingLoad());
6812SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6817 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6819 Mask.getValueType().getVectorElementType(),
6822 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6823 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6824 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6826 WideMask, WidePassthru);
6830 EVT VT =
N->getValueType(0);
6831 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6833 EVT MaskVT =
Mask.getValueType();
6834 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6843 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6844 TLI.isTypeLegal(WideMaskVT) &&
6850 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6851 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6855 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6856 N->getMemoryVT(),
N->getMemOperand());
6860 if (!
N->getPassThru()->isUndef()) {
6864 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6865 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6866 DAG.getPOISON(WidenVT), EVL);
6877 Mask = ModifyToType(Mask, WideMaskVT,
true);
6879 SDValue Res = DAG.getMaskedLoad(
6880 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
6881 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
6882 ExtType,
N->isExpandingLoad());
6891 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6893 EVT MaskVT =
Mask.getValueType();
6894 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6903 Mask = ModifyToType(Mask, WideMaskVT,
true);
6908 Index.getValueType().getScalarType(),
6910 Index = ModifyToType(Index, WideIndexVT);
6916 N->getMemoryVT().getScalarType(), NumElts);
6917 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
6918 WideMemVT, dl,
Ops,
N->getMemOperand(),
6919 N->getIndexType(),
N->getExtensionType());
6928 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6936 N->getMemoryVT().getScalarType(), WideEC);
6937 Mask = GetWidenedMask(Mask, WideEC);
6940 Mask,
N->getVectorLength()};
6941 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
6942 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
6951 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6952 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
6980 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
6981 return N->getOperand(OpNo).getValueType();
6989 N =
N.getOperand(0);
6991 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
6992 if (!
N->getOperand(i)->isUndef())
6994 N =
N.getOperand(0);
6998 N =
N.getOperand(0);
7000 N =
N.getOperand(0);
7027 { MaskVT, MVT::Other },
Ops);
7028 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7036 LLVMContext &Ctx = *DAG.getContext();
7039 if (MaskScalarBits < ToMaskScalBits) {
7043 }
else if (MaskScalarBits > ToMaskScalBits) {
7049 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7051 "Mask should have the right element size by now.");
7054 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7056 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7059 EVT SubVT =
Mask->getValueType(0);
7065 assert((
Mask->getValueType(0) == ToMaskVT) &&
7066 "A mask of ToMaskVT should have been produced by now.");
7076 LLVMContext &Ctx = *DAG.getContext();
7087 EVT CondVT =
Cond->getValueType(0);
7091 EVT VSelVT =
N->getValueType(0);
7103 EVT FinalVT = VSelVT;
7114 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7115 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7122 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7130 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7133 EVT ToMaskVT = VSelVT;
7140 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7156 if (ScalarBits0 != ScalarBits1) {
7157 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7158 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7170 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7171 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7172 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7175 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7183 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7188 unsigned Opcode =
N->getOpcode();
7190 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7191 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7192 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7194 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7200 Cond1 = GetWidenedVector(Cond1);
7208 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7209 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7214 Cond1 = ModifyToType(Cond1, CondWidenVT);
7217 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7218 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7220 if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
7221 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7223 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7227 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7228 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7231 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7235 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7236 return DAG.getUNDEF(WidenVT);
7240 EVT VT =
N->getValueType(0);
7243 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7247 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7248 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7251 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7252 for (
unsigned i = 0; i != NumElts; ++i) {
7253 int Idx =
N->getMaskElt(i);
7254 if (Idx < (
int)NumElts)
7257 NewMask[i] = Idx - NumElts + WidenNumElts;
7259 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7263 EVT VT =
N->getValueType(0);
7267 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7268 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7274 unsigned IdxVal = WidenNumElts - VTNumElts;
7287 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7290 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7291 "down type's element count");
7294 for (; i < VTNumElts / GCD; ++i)
7296 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7297 for (; i < WidenNumElts / GCD; ++i)
7305 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7306 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7308 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7312SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7313 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7318 assert(
N->getValueType(0).isVector() &&
7319 N->getOperand(0).getValueType().isVector() &&
7320 "Operands must be vectors");
7321 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7334 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7335 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7342 InOp1 = GetWidenedVector(InOp1);
7343 InOp2 = GetWidenedVector(InOp2);
7346 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7357 "Input not widened to expected type!");
7359 if (
N->getOpcode() == ISD::VP_SETCC) {
7362 return DAG.getNode(ISD::VP_SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7363 N->getOperand(2), Mask,
N->getOperand(4));
7365 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7370 assert(
N->getValueType(0).isVector() &&
7371 N->getOperand(1).getValueType().isVector() &&
7372 "Operands must be vectors");
7373 EVT VT =
N->getValueType(0);
7374 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7384 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7389 for (
unsigned i = 0; i != NumElts; ++i) {
7390 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7391 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7393 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7394 {Chain, LHSElem, RHSElem, CC});
7395 Chains[i] = Scalars[i].getValue(1);
7396 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7397 DAG.getBoolConstant(
true, dl, EltVT, VT),
7398 DAG.getBoolConstant(
false, dl, EltVT, VT));
7402 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7404 return DAG.getBuildVector(WidenVT, dl, Scalars);
7410bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7411 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7415 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7418 switch (
N->getOpcode()) {
7421 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7429 Res = WidenVecOp_FAKE_USE(
N);
7435 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7436 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7437 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7438 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7443 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7445 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7446 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7448 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7449 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7459 Res = WidenVecOp_UnrollVectorOp(
N);
7466 Res = WidenVecOp_EXTEND(
N);
7471 Res = WidenVecOp_CMP(
N);
7488 Res = WidenVecOp_Convert(
N);
7493 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7511 Res = WidenVecOp_VECREDUCE(
N);
7515 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7517 case ISD::VP_REDUCE_FADD:
7518 case ISD::VP_REDUCE_SEQ_FADD:
7519 case ISD::VP_REDUCE_FMUL:
7520 case ISD::VP_REDUCE_SEQ_FMUL:
7521 case ISD::VP_REDUCE_ADD:
7522 case ISD::VP_REDUCE_MUL:
7523 case ISD::VP_REDUCE_AND:
7524 case ISD::VP_REDUCE_OR:
7525 case ISD::VP_REDUCE_XOR:
7526 case ISD::VP_REDUCE_SMAX:
7527 case ISD::VP_REDUCE_SMIN:
7528 case ISD::VP_REDUCE_UMAX:
7529 case ISD::VP_REDUCE_UMIN:
7530 case ISD::VP_REDUCE_FMAX:
7531 case ISD::VP_REDUCE_FMIN:
7532 case ISD::VP_REDUCE_FMAXIMUM:
7533 case ISD::VP_REDUCE_FMINIMUM:
7534 Res = WidenVecOp_VP_REDUCE(
N);
7536 case ISD::VP_CTTZ_ELTS:
7537 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7538 Res = WidenVecOp_VP_CttzElements(
N);
7541 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7546 if (!Res.
getNode())
return false;
7554 if (
N->isStrictFPOpcode())
7556 "Invalid operand expansion");
7559 "Invalid operand expansion");
7561 ReplaceValueWith(
SDValue(
N, 0), Res);
7567 EVT VT =
N->getValueType(0);
7572 "Unexpected type action");
7573 InOp = GetWidenedVector(InOp);
7576 "Input wasn't widened!");
7584 EVT FixedEltVT = FixedVT.getVectorElementType();
7585 if (TLI.isTypeLegal(FixedVT) &&
7587 FixedEltVT == InEltVT) {
7589 "Not enough elements in the fixed type for the operand!");
7591 "We can't have the same type as we started with!");
7593 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7595 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7604 return WidenVecOp_Convert(
N);
7609 switch (
N->getOpcode()) {
7624 EVT OpVT =
N->getOperand(0).getValueType();
7625 EVT ResVT =
N->getValueType(0);
7632 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7633 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7639 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7640 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7642 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7649 return DAG.UnrollVectorOp(
N);
7654 EVT ResultVT =
N->getValueType(0);
7656 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7659 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7665 {WideArg,
Test},
N->getFlags());
7671 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7673 EVT OpVT =
N->getOperand(0).getValueType();
7676 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7681 EVT VT =
N->getValueType(0);
7687 "Unexpected type action");
7688 InOp = GetWidenedVector(InOp);
7690 unsigned Opcode =
N->getOpcode();
7696 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7698 if (
N->isStrictFPOpcode()) {
7700 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7703 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7704 {
N->getOperand(0), InOp });
7710 Res = DAG.
getNode(Opcode, dl, WideVT, InOp,
N->getOperand(1));
7712 Res = DAG.
getNode(Opcode, dl, WideVT, InOp);
7714 return DAG.getExtractSubvector(dl, VT, Res, 0);
7722 if (
N->isStrictFPOpcode()) {
7725 for (
unsigned i=0; i < NumElts; ++i) {
7726 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7727 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7731 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7733 for (
unsigned i = 0; i < NumElts; ++i) {
7734 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7736 Ops[i] = DAG.
getNode(Opcode, dl, EltVT, Elt,
N->getOperand(1));
7738 Ops[i] = DAG.getNode(Opcode, dl, EltVT, Elt);
7742 return DAG.getBuildVector(VT, dl,
Ops);
7746 EVT DstVT =
N->getValueType(0);
7747 SDValue Src = GetWidenedVector(
N->getOperand(0));
7748 EVT SrcVT = Src.getValueType();
7755 if (TLI.isTypeLegal(WideDstVT)) {
7757 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7760 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7764 return DAG.UnrollVectorOp(
N);
7768 EVT VT =
N->getValueType(0);
7769 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7777 if (!VT.
isVector() && VT != MVT::x86mmx &&
7781 if (TLI.isTypeLegal(NewVT)) {
7783 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
7795 ElementCount NewNumElts =
7797 .divideCoefficientBy(EltSize);
7799 if (TLI.isTypeLegal(NewVT)) {
7801 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
7806 return CreateStackStoreLoad(InOp, VT);
7814 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
7815 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
7820 EVT VT =
N->getValueType(0);
7822 EVT InVT =
N->getOperand(0).getValueType();
7827 unsigned NumOperands =
N->getNumOperands();
7828 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
7830 for (i = 1; i < NumOperands; ++i)
7831 if (!
N->getOperand(i).isUndef())
7834 if (i == NumOperands)
7835 return GetWidenedVector(
N->getOperand(0));
7845 for (
unsigned i=0; i < NumOperands; ++i) {
7849 "Unexpected type action");
7850 InOp = GetWidenedVector(InOp);
7851 for (
unsigned j = 0;
j < NumInElts; ++
j)
7852 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
7854 return DAG.getBuildVector(VT, dl,
Ops);
7857SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
7858 EVT VT =
N->getValueType(0);
7863 SubVec = GetWidenedVector(SubVec);
7868 bool IndicesValid =
false;
7871 IndicesValid =
true;
7875 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
7876 Attribute::VScaleRange);
7881 IndicesValid =
true;
7887 "Don't know how to widen the operands for INSERT_SUBVECTOR");
7893 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
7900 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
7907 Align Alignment = DAG.getReducedAlign(VT,
false);
7909 MachineFunction &MF = DAG.getMachineFunction();
7922 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
7930 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
7931 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
7936 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
7941 unsigned Idx =
N->getConstantOperandVal(2);
7947 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
7953SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
7954 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7956 N->getValueType(0), InOp,
N->getOperand(1));
7959SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
7960 SDValue InOp = GetWidenedVector(
N->getOperand(0));
7962 N->getValueType(0), InOp,
N->getOperand(1));
7965SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
7967 EVT ResVT =
N->getValueType(0);
7970 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
7976 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
7984 "Widened input size must be a multiple of result element size");
7987 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
7989 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
7990 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
7998 if (!
ST->getMemoryVT().getScalarType().isByteSized())
7999 return TLI.scalarizeVectorStore(ST, DAG);
8001 if (
ST->isTruncatingStore())
8002 return TLI.scalarizeVectorStore(ST, DAG);
8012 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8013 EVT WideMaskVT = getSetCCResultType(WideVT);
8015 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8016 TLI.isTypeLegal(WideMaskVT)) {
8019 StVal = GetWidenedVector(StVal);
8021 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8023 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8024 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8025 ST->getAddressingMode());
8029 if (GenWidenVectorStores(StChain, ST)) {
8030 if (StChain.
size() == 1)
8039 SDValue WideStVal = GetWidenedVector(StVal);
8043 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8044 ST->getOffset(), Mask,
ST->getMemoryVT(),
8045 ST->getMemOperand(),
ST->getAddressingMode(),
8046 ST->isTruncatingStore());
8052SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8053 assert((OpNo == 1 || OpNo == 3) &&
8054 "Can widen only data or mask operand of vp_store");
8062 StVal = GetWidenedVector(StVal);
8068 "Unable to widen VP store");
8069 Mask = GetWidenedVector(Mask);
8071 Mask = GetWidenedVector(Mask);
8077 "Unable to widen VP store");
8078 StVal = GetWidenedVector(StVal);
8081 assert(
Mask.getValueType().getVectorElementCount() ==
8083 "Mask and data vectors should have the same number of elements");
8084 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8085 ST->getOffset(), Mask,
ST->getVectorLength(),
8086 ST->getMemoryVT(),
ST->getMemOperand(),
8087 ST->getAddressingMode(),
ST->isTruncatingStore(),
8088 ST->isCompressingStore());
8093 assert((OpNo == 1 || OpNo == 4) &&
8094 "Can widen only data or mask operand of vp_strided_store");
8103 "Unable to widen VP strided store");
8107 "Unable to widen VP strided store");
8109 StVal = GetWidenedVector(StVal);
8110 Mask = GetWidenedVector(Mask);
8113 Mask.getValueType().getVectorElementCount() &&
8114 "Data and mask vectors should have the same number of elements");
8116 return DAG.getStridedStoreVP(
8123SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8124 assert((OpNo == 1 || OpNo == 4) &&
8125 "Can widen only data or mask operand of mstore");
8128 EVT MaskVT =
Mask.getValueType();
8133 EVT WideVT, WideMaskVT;
8136 StVal = GetWidenedVector(StVal);
8143 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8150 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8152 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8153 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8162 Mask = ModifyToType(Mask, WideMaskVT,
true);
8165 Mask = ModifyToType(Mask, WideMaskVT,
true);
8167 StVal = ModifyToType(StVal, WideVT);
8170 assert(
Mask.getValueType().getVectorElementCount() ==
8172 "Mask and data vectors should have the same number of elements");
8179SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8180 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8182 SDValue DataOp = MG->getPassThru();
8184 SDValue Scale = MG->getScale();
8192 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8193 MG->getMemOperand(), MG->getIndexType(),
8194 MG->getExtensionType());
8200SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8209 DataOp = GetWidenedVector(DataOp);
8213 EVT IndexVT =
Index.getValueType();
8216 Index = ModifyToType(Index, WideIndexVT);
8219 EVT MaskVT =
Mask.getValueType();
8222 Mask = ModifyToType(Mask, WideMaskVT,
true);
8227 }
else if (OpNo == 4) {
8229 Index = GetWidenedVector(Index);
8235 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8240SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8249 DataOp = GetWidenedVector(DataOp);
8250 Index = GetWidenedVector(Index);
8252 Mask = GetWidenedMask(Mask, WideEC);
8255 }
else if (OpNo == 3) {
8257 Index = GetWidenedVector(Index);
8264 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8269 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8270 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8272 EVT VT =
N->getValueType(0);
8287 SVT, InOp0, InOp1,
N->getOperand(2));
8293 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8295 EVT OpVT =
N->getOperand(0).getValueType();
8298 return DAG.getNode(ExtendCode, dl, VT, CC);
8308 EVT VT =
N->getValueType(0);
8310 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8317 for (
unsigned i = 0; i != NumElts; ++i) {
8318 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8319 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8321 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8322 {Chain, LHSElem, RHSElem, CC});
8323 Chains[i] = Scalars[i].getValue(1);
8324 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8325 DAG.getBoolConstant(
true, dl, EltVT, VT),
8326 DAG.getBoolConstant(
false, dl, EltVT, VT));
8330 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8332 return DAG.getBuildVector(VT, dl, Scalars);
8356 SDValue Op = GetWidenedVector(
N->getOperand(0));
8357 EVT VT =
N->getValueType(0);
8358 EVT OrigVT =
N->getOperand(0).getValueType();
8359 EVT WideVT =
Op.getValueType();
8361 SDNodeFlags
Flags =
N->getFlags();
8363 unsigned Opc =
N->getOpcode();
8365 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8366 assert(NeutralElem &&
"Neutral element must exist");
8376 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8383 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8384 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8390 unsigned GCD = std::gcd(OrigElts, WideElts);
8393 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8394 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8395 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8396 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8399 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8400 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8402 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8411 EVT VT =
N->getValueType(0);
8413 EVT WideVT =
Op.getValueType();
8415 SDNodeFlags
Flags =
N->getFlags();
8417 unsigned Opc =
N->getOpcode();
8419 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8429 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8432 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8433 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8439 unsigned GCD = std::gcd(OrigElts, WideElts);
8442 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8443 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8444 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8445 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8448 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8449 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8451 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8455 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8458 SDValue Op = GetWidenedVector(
N->getOperand(1));
8460 Op.getValueType().getVectorElementCount());
8462 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8463 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8471 EVT VT =
N->getValueType(0);
8475 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8476 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8481 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8487 EVT SrcVT =
Source.getValueType();
8491 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8492 {Source, Mask, N->getOperand(2)},
N->getFlags());
8495SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8498 EVT OrigMaskVT =
Mask.getValueType();
8499 SDValue WideMask = GetWidenedVector(Mask);
8505 if (OrigElts != WideElts) {
8506 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8508 Mask, DAG.getVectorIdxConstant(0,
DL));
8529 unsigned WidenEx = 0) {
8534 unsigned AlignInBits =
Align*8;
8536 EVT RetVT = WidenEltVT;
8541 if (Width == WidenEltWidth)
8552 (WidenWidth % MemVTWidth) == 0 &&
8554 (MemVTWidth <= Width ||
8555 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8556 if (MemVTWidth == WidenWidth)
8575 (WidenWidth % MemVTWidth) == 0 &&
8577 (MemVTWidth <= Width ||
8578 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8587 return std::nullopt;
8598 unsigned Start,
unsigned End) {
8599 SDLoc dl(LdOps[Start]);
8600 EVT LdTy = LdOps[Start].getValueType();
8608 for (
unsigned i = Start + 1; i != End; ++i) {
8609 EVT NewLdTy = LdOps[i].getValueType();
8610 if (NewLdTy != LdTy) {
8629 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8630 EVT LdVT =
LD->getMemoryVT();
8640 AAMDNodes AAInfo =
LD->getAAInfo();
8644 TypeSize WidthDiff = WidenWidth - LdWidth;
8651 std::optional<EVT> FirstVT =
8652 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8659 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8664 std::optional<EVT> NewVT = FirstVT;
8665 TypeSize RemainingWidth = LdWidth;
8666 TypeSize NewVTWidth = FirstVTWidth;
8668 RemainingWidth -= NewVTWidth;
8675 NewVTWidth = NewVT->getSizeInBits();
8681 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
8682 LD->getBaseAlign(), MMOFlags, AAInfo);
8694 uint64_t ScaledOffset = 0;
8695 MachinePointerInfo MPI =
LD->getPointerInfo();
8701 for (EVT MemVT : MemVTs) {
8702 Align NewAlign = ScaledOffset == 0
8703 ?
LD->getBaseAlign()
8706 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
8714 unsigned End = LdOps.
size();
8725 EVT LdTy = LdOps[i].getValueType();
8728 for (--i; i >= 0; --i) {
8729 LdTy = LdOps[i].getValueType();
8736 ConcatOps[--Idx] = LdOps[i];
8737 for (--i; i >= 0; --i) {
8738 EVT NewLdTy = LdOps[i].getValueType();
8739 if (NewLdTy != LdTy) {
8749 for (;
j != End-Idx; ++
j)
8750 WidenOps[j] = ConcatOps[Idx+j];
8752 WidenOps[j] = DAG.getPOISON(LdTy);
8759 ConcatOps[--Idx] = LdOps[i];
8764 ArrayRef(&ConcatOps[Idx], End - Idx));
8770 SDValue UndefVal = DAG.getPOISON(LdTy);
8773 for (; i != End-Idx; ++i)
8774 WidenOps[i] = ConcatOps[Idx+i];
8776 WidenOps[i] = UndefVal;
8787 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8788 EVT LdVT =
LD->getMemoryVT();
8797 AAMDNodes AAInfo =
LD->getAAInfo();
8811 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
8812 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
8818 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
8819 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
8820 LD->getBaseAlign(), MMOFlags, AAInfo);
8825 SDValue UndefVal = DAG.getPOISON(EltVT);
8826 for (; i != WidenNumElts; ++i)
8829 return DAG.getBuildVector(WidenVT, dl,
Ops);
8840 AAMDNodes AAInfo =
ST->getAAInfo();
8841 SDValue ValOp = GetWidenedVector(
ST->getValue());
8844 EVT StVT =
ST->getMemoryVT();
8852 "Mismatch between store and value types");
8856 MachinePointerInfo MPI =
ST->getPointerInfo();
8857 uint64_t ScaledOffset = 0;
8866 std::optional<EVT> NewVT =
8871 TypeSize NewVTWidth = NewVT->getSizeInBits();
8874 StWidth -= NewVTWidth;
8875 MemVTs.
back().second++;
8879 for (
const auto &Pair : MemVTs) {
8880 EVT NewVT = Pair.first;
8881 unsigned Count = Pair.second;
8887 Align NewAlign = ScaledOffset == 0
8888 ?
ST->getBaseAlign()
8890 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
8891 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
8907 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
8908 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
8909 ST->getBaseAlign(), MMOFlags, AAInfo);
8926 bool FillWithZeroes) {
8931 "input and widen element type must match");
8933 "cannot modify scalable vectors in this way");
8946 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
8948 for (
unsigned i = 1; i != NumConcat; ++i)
8955 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
8958 "Scalable vectors should have been handled already.");
8966 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
8968 for (Idx = 0; Idx < MinNumElts; ++Idx)
8969 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
8971 SDValue UndefVal = DAG.getPOISON(EltVT);
8972 for (; Idx < WidenNumElts; ++Idx)
8973 Ops[Idx] = UndefVal;
8975 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
8976 if (!FillWithZeroes)
8980 "We expect to never want to FillWithZeroes for non-integral types.");
8983 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
8984 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
8986 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
8987 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.
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.
@ 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.
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
FunctionAddr VTableAddr uintptr_t uintptr_t Data
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.