35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
47 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
50 switch (
N->getOpcode()) {
53 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
62 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
68 R = ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(
N);
72 R = ScalarizeVecRes_VECTOR_SHUFFLE_VAR(
N);
76 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
79 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
85 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
120 R = ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
N);
126 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
128 R = ScalarizeVecRes_VECTOR_MATCH(
N);
131 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
137 R = ScalarizeVecRes_VecInregOp(
N);
189 R = ScalarizeVecRes_UnaryOp(
N);
192 R = ScalarizeVecRes_ADDRSPACECAST(
N);
198 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
256 R = ScalarizeVecRes_BinOp(
N);
263 R = ScalarizeVecRes_MaskedBinOp(
N);
267 R = ScalarizeVecRes_FPOp_MultiType(
N);
272 R = ScalarizeVecRes_CMP(
N);
278 R = ScalarizeVecRes_TernaryOp(
N);
281#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
282 case ISD::STRICT_##DAGN:
283#include "llvm/IR/ConstrainedOps.def"
284 R = ScalarizeVecRes_StrictFPOp(
N);
289 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
298 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
308 R = ScalarizeVecRes_FIX(
N);
314 R = ScalarizeVecRes_PartialReduction(
N);
320 SetScalarizedVector(
SDValue(
N, ResNo), R);
324 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
325 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
326 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
332 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
333 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
335 EVT MaskVT =
Mask.getValueType();
340 Mask = GetScalarizedVector(Mask);
349 DAG.getConstant(1,
DL,
LHS.getValueType()));
351 LHS.getValueType(),
LHS, Divisor);
359 if (getTypeAction(
LHS.getValueType()) ==
361 LHS = GetScalarizedVector(
LHS);
362 RHS = GetScalarizedVector(
RHS);
364 EVT VT =
LHS.getValueType().getVectorElementType();
365 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
366 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
369 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
370 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
374 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
375 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
376 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
377 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
382 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
383 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
389SDValue DAGTypeLegalizer::ScalarizeVecRes_PartialReduction(
SDNode *
N) {
390 SDValue Acc = GetScalarizedVector(
N->getOperand(0));
394 EVT InVT =
L.getValueType();
409DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
411 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
412 "Unexpected vector type!");
413 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
415 EVT VT0 =
N->getValueType(0);
416 EVT VT1 =
N->getValueType(1);
420 DAG.getNode(
N->getOpcode(), dl,
421 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
425 unsigned OtherNo = 1 - ResNo;
426 EVT OtherVT =
N->getValueType(OtherNo);
428 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
432 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
435 return SDValue(ScalarNode, ResNo);
440 unsigned NumOpers =
N->getNumOperands();
442 EVT ValueVTs[] = {VT, MVT::Other};
451 for (
unsigned i = 1; i < NumOpers; ++i) {
457 Oper = GetScalarizedVector(Oper);
466 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
467 Opers,
N->getFlags());
478 EVT ResVT =
N->getValueType(0);
479 EVT OvVT =
N->getValueType(1);
483 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
484 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
487 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
488 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
489 ScalarLHS = ElemsLHS[0];
490 ScalarRHS = ElemsRHS[0];
493 SDVTList ScalarVTs = DAG.getVTList(
495 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
496 {ScalarLHS, ScalarRHS},
N->getFlags())
500 unsigned OtherNo = 1 - ResNo;
501 EVT OtherVT =
N->getValueType(OtherNo);
503 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
507 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
510 return SDValue(ScalarNode, ResNo);
515 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
516 return GetScalarizedVector(
Op);
519SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
524 N->getValueType(0).getScalarType(), Mask,
525 DAG.getVectorIdxConstant(0,
DL));
531 Op = GetScalarizedVector(
Op);
532 EVT NewVT =
N->getValueType(0).getVectorElementType();
537SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(
SDNode *
N) {
547SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
549 N->getValueType(0).getVectorElementType(),
550 N->getOperand(0),
N->getOperand(1));
553SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE_VAR(
SDNode *
N) {
555 return GetScalarizedVector(
N->getOperand(0));
561 EVT OpVT =
Op.getValueType();
565 Op = GetScalarizedVector(
Op);
568 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
571 N->getValueType(0).getVectorElementType(),
Op,
575SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
578 EVT OpVT =
Op.getValueType();
582 Op = GetScalarizedVector(
Op);
585 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
588 N->getValueType(0).getVectorElementType(),
Op,
592SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
595 EVT OpVT =
Op.getValueType();
598 Op = GetScalarizedVector(
Op);
601 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
604 N->getValueType(0).getVectorElementType(),
Op,
605 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
608SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
609 SDValue Op = GetScalarizedVector(
N->getOperand(0));
610 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
614SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOp_MultiType(
SDNode *
N) {
616 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
618 EVT RHSVT =
RHS.getValueType();
623 RHS = GetScalarizedVector(
RHS);
627 return DAG.getNode(
N->getOpcode(),
DL,
LHS.getValueType(),
LHS,
RHS,
631SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
636 if (
Op.getValueType() != EltVT)
644 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
645 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
656 N->getOpcode(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
657 N->getChain(),
N->getBasePtr(), GetScalarizedVector(
N->getVal()),
665 assert(
N->isUnindexed() &&
"Indexed vector load?");
669 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
670 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
671 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
672 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
673 N->getMMOMetadataForSubAccess());
685 EVT OpVT =
Op.getValueType();
695 Op = GetScalarizedVector(
Op);
698 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
700 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
706 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
707 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
708 LHS, DAG.getValueType(ExtVT));
715 EVT OpVT =
Op.getValueType();
720 Op = GetScalarizedVector(
Op);
722 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
725 switch (
N->getOpcode()) {
737SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
740 EVT OpVT =
Op.getValueType();
750 Op = GetScalarizedVector(
Op);
753 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
756 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
757 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
758 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS,
759 AddrSpaceCastN->getFlags());
762SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
773DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
774 assert(
N->getNumValues() ==
N->getNumOperands() &&
775 "Expected one result per operand");
779 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
780 SetScalarizedVector(
SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
786 EVT OpVT =
Cond.getValueType();
795 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
798 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
800 TLI.getBooleanContents(
false,
false);
807 if (TLI.getBooleanContents(
false,
false) !=
808 TLI.getBooleanContents(
false,
true)) {
812 EVT OpVT =
Cond->getOperand(0).getValueType();
814 VecBool = TLI.getBooleanContents(OpVT);
819 EVT CondVT =
Cond.getValueType();
820 if (ScalarBool != VecBool) {
821 switch (ScalarBool) {
829 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
836 Cond, DAG.getValueType(MVT::i1));
842 auto BoolVT = getSetCCResultType(CondVT);
843 if (BoolVT.bitsLT(CondVT))
846 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
847 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
851 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
852 return DAG.getSelect(SDLoc(
N),
853 LHS.getValueType(),
N->getOperand(0),
LHS,
854 GetScalarizedVector(
N->getOperand(2)));
858 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
860 N->getOperand(0),
N->getOperand(1),
861 LHS, GetScalarizedVector(
N->getOperand(3)),
866 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
869SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
873 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
875 return GetScalarizedVector(
N->getOperand(
Op));
878SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
880 EVT SrcVT = Src.getValueType();
885 Src = GetScalarizedVector(Src);
889 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
891 EVT DstVT =
N->getValueType(0).getVectorElementType();
892 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
896 assert(
N->getValueType(0).isVector() &&
897 N->getOperand(0).getValueType().isVector() &&
898 "Operand types must be vectors");
901 EVT OpVT =
LHS.getValueType();
902 EVT NVT =
N->getValueType(0).getVectorElementType();
907 LHS = GetScalarizedVector(
LHS);
908 RHS = GetScalarizedVector(
RHS);
911 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
912 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
922 return DAG.getNode(ExtendCode,
DL, NVT, Res);
933 Arg = GetScalarizedVector(Arg);
936 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
945 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
952bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
958 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
961 switch (
N->getOpcode()) {
964 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
971 Res = ScalarizeVecOp_BITCAST(
N);
974 Res = ScalarizeVecOp_FAKE_USE(
N);
992 Res = ScalarizeVecOp_UnaryOp(
N);
997 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
1000 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1001 "Unexpected vector type!");
1002 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1004 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
1005 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
1013 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
1016 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
1019 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
1022 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
1025 Res = ScalarizeVecOp_VSELECT(
N);
1028 Res = ScalarizeVecOp_VSETCC(
N);
1032 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
1047 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
1050 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
1053 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
1056 Res = ScalarizeVecOp_FP_EXTEND(
N);
1075 Res = ScalarizeVecOp_VECREDUCE(
N);
1079 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
1083 Res = ScalarizeVecOp_CMP(
N);
1086 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
1090 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
1093 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
1099 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
1104 if (!Res.
getNode())
return false;
1112 "Invalid operand expansion");
1114 ReplaceValueWith(
SDValue(
N, 0), Res);
1121 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1123 N->getValueType(0), Elt);
1128 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1129 "Fake Use: Unexpected vector type!");
1130 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1131 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1137 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1138 "Unexpected vector type!");
1139 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1140 SDValue Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1141 N->getValueType(0).getScalarType(), Elt);
1149SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1150 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1151 "Unexpected vector type!");
1152 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1154 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1155 Elt,
N->getOperand(1));
1163SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1164 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1165 "Unexpected vector type!");
1166 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1168 {
N->getValueType(0).getScalarType(), MVT::Other },
1169 {
N->getOperand(0), Elt });
1179 ReplaceValueWith(
SDValue(
N, 0), Res);
1184SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1186 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1187 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1188 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1193SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1197 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1198 SDValue ContainingVec =
N->getOperand(0);
1206SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1207 EVT VT =
N->getValueType(0);
1208 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1220 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1221 EVT VT =
N->getValueType(0);
1223 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1232 assert(
N->getValueType(0).isVector() &&
1233 N->getOperand(0).getValueType().isVector() &&
1234 "Operand types must be vectors");
1235 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1236 "Expected single-element vector type");
1238 EVT VT =
N->getValueType(0);
1239 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1240 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1242 EVT OpVT =
N->getOperand(0).getValueType();
1254 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1260SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1262 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1263 assert(
N->getValueType(0).isVector() &&
1264 N->getOperand(1).getValueType().isVector() &&
1265 "Operand types must be vectors");
1266 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1267 "Expected single-element vector type");
1269 EVT VT =
N->getValueType(0);
1271 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1272 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1275 EVT OpVT =
N->getOperand(1).getValueType();
1279 {Ch, LHS, RHS, CC});
1288 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1293 ReplaceValueWith(
SDValue(
N, 0), Res);
1300 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1301 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1304 if (
N->isTruncatingStore())
1305 return DAG.getTruncStore(
1306 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1307 N->getBasePtr(),
N->getPointerInfo(),
1308 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1309 N->getMemOperand()->getFlags(),
N->getMMOMetadataForSubAccess());
1311 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1312 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1313 N->getMemOperand()->getFlags(),
1314 N->getMMOMetadataForSubAccess());
1320 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1322 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1323 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1330 assert(OpNo == 3 &&
"Can only scalarize the mask operand!");
1331 EVT DataVT =
N->getValueType(0);
1332 SDValue Mask = PromoteTargetBoolean(
N->getOperand(OpNo), DataVT);
1334 NewOps[OpNo] =
Mask;
1335 SDNode *Res = DAG.UpdateNodeOperands(
N, NewOps);
1349 assert(!
N->isCompressingStore() &&
"CompressingStore not expected");
1352 EVT DataVT =
N->getValue().getValueType();
1354 NewOps[OpNo] = PromoteTargetBoolean(
N->getOperand(OpNo), DataVT);
1355 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1360SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1361 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1362 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1364 N->getValueType(0).getVectorElementType(), Elt,
1369SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1371 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1372 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1375 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1385 ReplaceValueWith(
SDValue(
N, 0), Res);
1392 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1394 N->getValueType(0).getVectorElementType(), Elt);
1400SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1401 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1404 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1405 {
N->getOperand(0), Elt});
1414 ReplaceValueWith(
SDValue(
N, 0), Res);
1419 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1426SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1432 SDValue Op = GetScalarizedVector(VecOp);
1433 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1434 AccOp,
Op,
N->getFlags());
1438 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1439 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1446SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1454 EVT VT =
N->getValueType(0);
1455 return DAG.getConstant(0, SDLoc(
N), VT);
1462 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1463 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1465 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1466 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1467 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1470SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1475 N->getValueType(0).getScalarType(), Mask,
1476 DAG.getVectorIdxConstant(0,
DL));
1481 return TLI.expandVectorMatch(
N, DAG);
1484SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1485 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1488 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1489 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1498 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1510void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1515 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1518 switch (
N->getOpcode()) {
1521 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1530 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1533 SplitVecRes_MASK_BEFOREFIRST(
N,
Lo,
Hi);
1540 case ISD::VP_MERGE: SplitRes_Select(
N,
Lo,
Hi);
break;
1556 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1559 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1571 case ISD::VP_LOAD_FF:
1574 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1581 case ISD::VP_GATHER:
1585 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1588 SplitVecRes_VECTOR_SHUFFLE_VAR(
N,
Lo,
Hi);
1591 SplitVecRes_SETCC(
N,
Lo,
Hi);
1594 SplitVecRes_VECTOR_REPEAT(
N,
Lo,
Hi);
1597 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1604 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1607 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1610 SplitVecRes_VECTOR_INTERLEAVE(
N);
1613 SplitVecRes_VAARG(
N,
Lo,
Hi);
1619 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1673 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1676 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1682 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1688 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1744 SplitVecRes_BinOp(
N,
Lo,
Hi);
1750 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1755 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1759 SplitVecRes_CMP(
N,
Lo,
Hi);
1762#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1763 case ISD::STRICT_##DAGN:
1764#include "llvm/IR/ConstrainedOps.def"
1765 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1770 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1779 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1789 SplitVecRes_FIX(
N,
Lo,
Hi);
1791 case ISD::EXPERIMENTAL_VP_SPLICE:
1792 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1794 case ISD::EXPERIMENTAL_VP_REVERSE:
1795 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1801 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1804 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1807 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1816void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1823 SDValue BytesIncrement = DAG.getVScale(
1826 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1828 *ScaledOffset += IncrementSize;
1838std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1839 return SplitMask(Mask, SDLoc(Mask));
1842std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1845 EVT MaskVT =
Mask.getValueType();
1847 GetSplitVector(Mask, MaskLo, MaskHi);
1849 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1850 return std::make_pair(MaskLo, MaskHi);
1855 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1857 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1860 const SDNodeFlags
Flags =
N->getFlags();
1861 unsigned Opcode =
N->getOpcode();
1862 if (
N->getNumOperands() == 2) {
1863 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1864 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1868 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1869 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
1870 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
1871 "Expected VP opcode");
1874 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1877 std::tie(EVLLo, EVLHi) =
1878 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1881 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1883 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1889 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1891 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1895 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1897 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1901 const SDNodeFlags
Flags =
N->getFlags();
1902 unsigned Opcode =
N->getOpcode();
1903 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1905 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1912 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1914 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1916 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1919 const SDNodeFlags
Flags =
N->getFlags();
1920 unsigned Opcode =
N->getOpcode();
1922 DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1924 DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1928 LLVMContext &Ctxt = *DAG.getContext();
1934 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1936 GetSplitVector(
LHS, LHSLo, LHSHi);
1937 GetSplitVector(
RHS, RHSLo, RHSHi);
1939 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1940 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1944 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1945 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1950 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1952 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1956 unsigned Opcode =
N->getOpcode();
1957 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1959 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1968 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1975 switch (getTypeAction(InVT)) {
1989 GetExpandedOp(InOp,
Lo,
Hi);
1990 if (DAG.getDataLayout().isBigEndian())
2000 GetSplitVector(InOp,
Lo,
Hi);
2009 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
2018 if (DAG.getDataLayout().isBigEndian())
2021 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
2023 if (DAG.getDataLayout().isBigEndian())
2029void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
2035 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2038 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
2043 unsigned LaneOffset =
2046 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
2048 DAG.getConstant(LaneOffset,
DL, MVT::i64));
2055 GetSplitVector(
N->getOperand(0), InLo, InHi);
2062 getSetCCResultType(MVT::i1), MVT::i1);
2071 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2074 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
2077 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
2082 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
2084 unsigned NumSubvectors =
N->getNumOperands() / 2;
2085 if (NumSubvectors == 1) {
2086 Lo =
N->getOperand(0);
2087 Hi =
N->getOperand(1);
2092 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2101void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
2108 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2123 GetSplitVector(Vec,
Lo,
Hi);
2126 EVT LoVT =
Lo.getValueType();
2135 unsigned IdxVal =
Idx->getAsZExtVal();
2136 if (IdxVal + SubElems <= LoElems) {
2144 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
2146 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
2152 SDValue WideSubVec = GetWidenedVector(SubVec);
2154 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2162 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2164 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2165 auto &MF = DAG.getMachineFunction();
2169 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2174 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2175 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2179 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2184 MachinePointerInfo MPI =
Load->getPointerInfo();
2185 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2188 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2197 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2202 EVT RHSVT =
RHS.getValueType();
2205 GetSplitVector(
RHS, RHSLo, RHSHi);
2207 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2222 SDValue FpValue =
N->getOperand(0);
2224 GetSplitVector(FpValue, ArgLo, ArgHi);
2226 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2228 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2237 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2241 std::tie(LoVT, HiVT) =
2245 DAG.getValueType(LoVT));
2247 DAG.getValueType(HiVT));
2252 unsigned Opcode =
N->getOpcode();
2259 GetSplitVector(N0, InLo, InHi);
2261 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2266 EVT OutLoVT, OutHiVT;
2267 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2269 assert((2 * OutNumElements) <= InNumElements &&
2270 "Illegal extend vector in reg split");
2279 SmallVector<int, 8> SplitHi(InNumElements, -1);
2280 for (
unsigned i = 0; i != OutNumElements; ++i)
2281 SplitHi[i] = i + OutNumElements;
2282 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2284 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2285 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2290 unsigned NumOps =
N->getNumOperands();
2294 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2304 for (
unsigned i = 1; i <
NumOps; ++i) {
2309 EVT InVT =
Op.getValueType();
2314 GetSplitVector(
Op, OpLo, OpHi);
2316 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2323 EVT LoValueVTs[] = {LoVT, MVT::Other};
2324 EVT HiValueVTs[] = {HiVT, MVT::Other};
2325 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2327 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2333 Lo.getValue(1),
Hi.getValue(1));
2337 ReplaceValueWith(
SDValue(
N, 1), Chain);
2340SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2341 EVT VT =
N->getValueType(0);
2356 else if (NE > ResNE)
2360 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2364 for (i = 0; i !=
NE; ++i) {
2366 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2367 SDValue Operand =
N->getOperand(j);
2371 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2385 for (; i < ResNE; ++i)
2386 Scalars.
push_back(DAG.getPOISON(EltVT));
2390 ReplaceValueWith(
SDValue(
N, 1), Chain);
2394 return DAG.getBuildVector(VecVT, dl, Scalars);
2397void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2400 EVT ResVT =
N->getValueType(0);
2401 EVT OvVT =
N->getValueType(1);
2402 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2403 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2404 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2406 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2408 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2409 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2411 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2412 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2415 unsigned Opcode =
N->getOpcode();
2416 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2417 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2419 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2421 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2427 unsigned OtherNo = 1 - ResNo;
2428 EVT OtherVT =
N->getValueType(OtherNo);
2430 SetSplitVector(
SDValue(
N, OtherNo),
2436 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2440void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2446 GetSplitVector(Vec,
Lo,
Hi);
2449 unsigned IdxVal = CIdx->getZExtValue();
2450 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2451 if (IdxVal < LoNumElts) {
2453 Lo.getValueType(),
Lo, Elt, Idx);
2456 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2476 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2478 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2479 auto &MF = DAG.getMachineFunction();
2483 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2488 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2489 Store = DAG.getTruncStore(
2495 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2498 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2502 MachinePointerInfo MPI =
Load->getPointerInfo();
2503 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2505 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2508 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2509 if (LoVT !=
Lo.getValueType())
2511 if (HiVT !=
Hi.getValueType())
2519 assert(
N->getValueType(0).isScalableVector() &&
2520 "Only scalable vectors are supported for STEP_VECTOR");
2521 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2542 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2543 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2545 Hi = DAG.getPOISON(HiVT);
2555 "Extended load during type legalization!");
2557 EVT VT =
LD->getValueType(0);
2559 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2567 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2568 Ch, Ptr,
LD->getMemOperand());
2573 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2575 Lo = DAG.getBitcast(LoVT, ExtractLo);
2576 Hi = DAG.getBitcast(HiVT, ExtractHi);
2588 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2594 EVT MemoryVT =
LD->getMemoryVT();
2596 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
2598 EVT LoMemVT, HiMemVT;
2599 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2603 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2604 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2605 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2610 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2613 MachinePointerInfo MPI;
2614 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2617 HiMemVT,
LD->getBaseAlign(), MMOFlags,
Metadata);
2626 ReplaceValueWith(
SDValue(LD, 1), Ch);
2631 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2634 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2640 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2644 EVT MemoryVT =
LD->getMemoryVT();
2646 EVT LoMemVT, HiMemVT;
2647 bool HiIsEmpty =
false;
2648 std::tie(LoMemVT, HiMemVT) =
2649 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2654 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2657 GetSplitVector(Mask, MaskLo, MaskHi);
2659 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2664 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2666 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2669 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2672 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2673 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2681 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2682 LD->isExpandingLoad());
2684 MachinePointerInfo MPI;
2686 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2688 MPI =
LD->getPointerInfo().getWithOffset(
2691 MMO = DAG.getMachineFunction().getMachineMemOperand(
2693 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2695 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2696 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2697 LD->isExpandingLoad());
2707 ReplaceValueWith(
SDValue(LD, 1), Ch);
2713 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2724 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2727 GetSplitVector(Mask, MaskLo, MaskHi);
2729 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2733 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2735 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2738 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2740 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2743 Hi = DAG.getPOISON(HiVT);
2745 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2746 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2752 "Indexed VP strided load during type legalization!");
2754 "Unexpected indexed variable-length load offset");
2759 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2761 EVT LoMemVT, HiMemVT;
2762 bool HiIsEmpty =
false;
2763 std::tie(LoMemVT, HiMemVT) =
2764 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2769 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2772 GetSplitVector(Mask, LoMask, HiMask);
2774 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2778 std::tie(LoEVL, HiEVL) =
2782 Lo = DAG.getStridedLoadVP(
2809 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2816 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2827 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2835 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2840 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2850 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2853 GetSplitVector(Mask, MaskLo, MaskHi);
2855 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2859 EVT LoMemVT, HiMemVT;
2860 bool HiIsEmpty =
false;
2861 std::tie(LoMemVT, HiMemVT) =
2862 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2864 SDValue PassThruLo, PassThruHi;
2866 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2868 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2870 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2875 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2885 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2888 MachinePointerInfo MPI;
2895 MMO = DAG.getMachineFunction().getMachineMemOperand(
2900 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2912 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2920 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2930 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2933 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2936 EVT MemoryVT =
N->getMemoryVT();
2942 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2944 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2947 EVT LoMemVT, HiMemVT;
2949 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2952 if (getTypeAction(
Ops.Index.getValueType()) ==
2954 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2956 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2959 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2961 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2964 SDValue PassThru = MGT->getPassThru();
2965 SDValue PassThruLo, PassThruHi;
2968 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2970 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2975 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2976 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2977 OpsLo, MMO, IndexTy, ExtType);
2979 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2980 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2981 OpsHi, MMO, IndexTy, ExtType);
2985 std::tie(EVLLo, EVLHi) =
2986 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2988 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2989 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2990 MMO, VPGT->getIndexType());
2992 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2993 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2994 MMO, VPGT->getIndexType());
3004 ReplaceValueWith(
SDValue(
N, 1), Ch);
3018 EVT VecVT =
N->getValueType(0);
3020 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
3021 bool HasCustomLowering =
false;
3028 HasCustomLowering =
true;
3034 SDValue Passthru =
N->getOperand(2);
3035 if (!HasCustomLowering) {
3036 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
3037 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
3044 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3045 std::tie(LoMask, HiMask) = SplitMask(Mask);
3047 SDValue UndefPassthru = DAG.getPOISON(LoVT);
3052 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
3065 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
3067 SDValue Chain = DAG.getEntryNode();
3068 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
3072 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
3076 EVT MaskVT =
Mask.getValueType();
3083 SDValue StepVector = DAG.getStepVector(
DL, WideMaskVT);
3084 SDValue SplatNumActiveElts = DAG.getSplat(WideMaskVT,
DL, NumActiveElts);
3086 DAG.getSetCC(
DL, MaskVT, StepVector, SplatNumActiveElts,
ISD::SETULT);
3089 Compressed, Passthru);
3091 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
3094void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE_VAR(
SDNode *
N,
SDValue &
Lo,
3097 SDValue Res = TLI.expandVECTOR_SHUFFLE_VAR(
N, DAG);
3098 std::tie(
Lo,
Hi) = DAG.SplitVector(Res, SDLoc(
N));
3102 assert(
N->getValueType(0).isVector() &&
3103 N->getOperand(0).getValueType().isVector() &&
3104 "Operand types must be vectors");
3108 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3112 if (getTypeAction(
N->getOperand(0).getValueType()) ==
3114 GetSplitVector(
N->getOperand(0), LL, LH);
3116 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
3118 if (getTypeAction(
N->getOperand(1).getValueType()) ==
3120 GetSplitVector(
N->getOperand(1), RL, RH);
3122 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
3124 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
3125 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
3133 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3137 EVT InVT =
N->getOperand(0).getValueType();
3139 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3141 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3143 const SDNodeFlags
Flags =
N->getFlags();
3144 unsigned Opcode =
N->getOpcode();
3146 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
3147 N->getOperand(3), Flags);
3148 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
3149 N->getOperand(3), Flags);
3155 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
3156 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
3158 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
3159 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
3166 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3170 EVT InVT =
N->getOperand(0).getValueType();
3172 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3174 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3177 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3178 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3179 SDNodeFlags
Flags = AddrSpaceCastN->getFlags();
3180 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS, Flags);
3181 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS, Flags);
3184void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3189 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3190 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3194 EVT InVT =
N->getOperand(0).getValueType();
3196 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3198 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3200 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3201 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3203 SDNode *HiNode =
Hi.getNode();
3204 SDNode *LoNode =
Lo.getNode();
3207 unsigned OtherNo = 1 - ResNo;
3208 EVT OtherVT =
N->getValueType(OtherNo);
3216 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3223 EVT SrcVT =
N->getOperand(0).getValueType();
3224 EVT DestVT =
N->getValueType(0);
3226 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3243 LLVMContext &Ctx = *DAG.getContext();
3247 EVT SplitLoVT, SplitHiVT;
3248 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3249 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3250 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3251 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3252 N->dump(&DAG);
dbgs() <<
"\n");
3255 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3257 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3259 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3260 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3265 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3273 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3274 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3280 return N.getResNo() == 0 &&
3284 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3286 ArrayRef<int>
Mask) {
3289 "Expected build vector node.");
3292 for (
unsigned I = 0;
I < NewElts; ++
I) {
3297 Ops[
I] = Input2.getOperand(Idx - NewElts);
3299 Ops[
I] = Input1.getOperand(Idx);
3304 return DAG.getBuildVector(NewVT,
DL,
Ops);
3310 SmallVector<int> OrigMask(
N->getMask());
3312 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3313 &
DL](SmallVectorImpl<int> &
Mask) {
3315 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3316 for (
unsigned Idx = 0;
Idx < std::size(Inputs); ++
Idx) {
3320 Input.getOperand(0).getValueType() !=
Input.getValueType())
3322 ShufflesIdxs[std::make_pair(
Input.getOperand(0),
Input.getOperand(1))]
3324 ShufflesIdxs[std::make_pair(
Input.getOperand(1),
Input.getOperand(0))]
3327 for (
auto &
P : ShufflesIdxs) {
3328 if (
P.second.size() < 2)
3332 for (
int &Idx : Mask) {
3335 unsigned SrcRegIdx =
Idx / NewElts;
3336 if (Inputs[SrcRegIdx].
isUndef()) {
3344 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3349 Idx = MaskElt % NewElts +
3350 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3356 Inputs[
P.second[0]] =
P.first.first;
3357 Inputs[
P.second[1]] =
P.first.second;
3360 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3363 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3364 for (
int &Idx : Mask) {
3367 unsigned SrcRegIdx =
Idx / NewElts;
3368 if (Inputs[SrcRegIdx].
isUndef()) {
3375 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3376 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3379 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3381 if (UsedSubVector.count() > 1) {
3383 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3384 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3386 if (Pairs.
empty() || Pairs.
back().size() == 2)
3388 if (UsedSubVector.test(2 *
I)) {
3389 Pairs.
back().emplace_back(
I, 0);
3391 assert(UsedSubVector.test(2 *
I + 1) &&
3392 "Expected to be used one of the subvectors.");
3393 Pairs.
back().emplace_back(
I, 1);
3396 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3398 for (
int &Idx : Mask) {
3401 unsigned SrcRegIdx =
Idx / NewElts;
3403 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3404 return Idxs.front().first == SrcRegIdx ||
3405 Idxs.back().first == SrcRegIdx;
3407 if (It == Pairs.
end())
3409 Idx = It->front().first * NewElts + (
Idx % NewElts) % (NewElts / 2) +
3410 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3413 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3414 Inputs[Idxs.front().first] = DAG.
getNode(
3416 Inputs[Idxs.front().first].getValueType(),
3417 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3418 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3427 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3431 if (Shuffle->getOperand(0).getValueType() != NewVT)
3434 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3435 !Shuffle->isSplat()) {
3437 }
else if (!Inputs[
I].hasOneUse() &&
3438 !Shuffle->getOperand(1).isUndef()) {
3440 for (
int &Idx : Mask) {
3443 unsigned SrcRegIdx =
Idx / NewElts;
3446 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3451 int OpIdx = MaskElt / NewElts;
3464 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3465 if (Shuffle->getOperand(OpIdx).isUndef())
3467 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3468 if (It == std::end(Inputs))
3470 int FoundOp = std::distance(std::begin(Inputs), It);
3473 for (
int &Idx : Mask) {
3476 unsigned SrcRegIdx =
Idx / NewElts;
3479 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3484 int MaskIdx = MaskElt / NewElts;
3485 if (OpIdx == MaskIdx)
3486 Idx = MaskElt % NewElts + FoundOp * NewElts;
3489 Op = (OpIdx + 1) % 2;
3497 for (
int &Idx : Mask) {
3500 unsigned SrcRegIdx =
Idx / NewElts;
3503 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3504 int OpIdx = MaskElt / NewElts;
3507 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3513 TryPeekThroughShufflesInputs(OrigMask);
3515 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3516 NewElts](SmallVectorImpl<int> &
Mask) {
3517 SetVector<SDValue> UniqueInputs;
3518 SetVector<SDValue> UniqueConstantInputs;
3519 for (
const auto &
I : Inputs) {
3521 UniqueConstantInputs.
insert(
I);
3522 else if (!
I.isUndef())
3527 if (UniqueInputs.
size() != std::size(Inputs)) {
3528 auto &&UniqueVec = UniqueInputs.
takeVector();
3529 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3530 unsigned ConstNum = UniqueConstantVec.size();
3531 for (
int &Idx : Mask) {
3534 unsigned SrcRegIdx =
Idx / NewElts;
3535 if (Inputs[SrcRegIdx].
isUndef()) {
3539 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3540 if (It != UniqueConstantVec.end()) {
3542 NewElts * std::distance(UniqueConstantVec.begin(), It);
3543 assert(Idx >= 0 &&
"Expected defined mask idx.");
3546 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3547 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3549 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3550 assert(Idx >= 0 &&
"Expected defined mask idx.");
3552 copy(UniqueConstantVec, std::begin(Inputs));
3553 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3556 MakeUniqueInputs(OrigMask);
3558 copy(Inputs, std::begin(OrigInputs));
3564 unsigned FirstMaskIdx =
High * NewElts;
3567 assert(!Output &&
"Expected default initialized initial value.");
3568 TryPeekThroughShufflesInputs(Mask);
3569 MakeUniqueInputs(Mask);
3571 copy(Inputs, std::begin(TmpInputs));
3574 bool SecondIteration =
false;
3575 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3580 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3581 SecondIteration =
true;
3582 return SecondIteration;
3585 Mask, std::size(Inputs), std::size(Inputs),
3587 [&Output, &DAG = DAG, NewVT]() {
Output = DAG.getPOISON(NewVT); },
3588 [&
Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3589 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3591 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3593 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3594 DAG.getPOISON(NewVT), Mask);
3597 [&AccumulateResults, &
Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3598 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3599 unsigned Idx2,
bool ) {
3600 if (AccumulateResults(Idx1)) {
3603 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3605 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3606 Inputs[Idx2], Mask);
3610 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3612 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3613 TmpInputs[Idx2], Mask);
3617 copy(OrigInputs, std::begin(Inputs));
3622 EVT OVT =
N->getValueType(0);
3630 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3632 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV,
Alignment.value());
3633 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV,
Alignment.value());
3638 ReplaceValueWith(
SDValue(
N, 1), Chain);
3643 EVT DstVTLo, DstVTHi;
3644 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3648 EVT SrcVT =
N->getOperand(0).getValueType();
3650 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3652 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3654 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3655 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3660 EVT VT =
N->getValueType(0);
3662 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VT);
3663 assert(LoVT == HiVT &&
"Expected equal split types");
3668 auto [SrcLo, SrcHi] = DAG.SplitVector(Src,
DL);
3672 DAG.getVTList(SplitSrcVT, SplitSrcVT), SrcLo, SrcHi);
3678 DAG.getVTList(LoVT, LoVT), Even, Odd);
3686 GetSplitVector(
N->getOperand(0), InLo, InHi);
3697 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3698 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3703 EVT VT =
N->getValueType(0);
3726 EVT PtrVT =
StackPtr.getValueType();
3727 auto &MF = DAG.getMachineFunction();
3731 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3734 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3744 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3745 DAG.getConstant(1,
DL, PtrVT));
3747 DAG.getConstant(EltWidth,
DL, PtrVT));
3749 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3751 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3752 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3753 DAG.getPOISON(PtrVT), Stride, TrueMask,
3762 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3767 EVT VT =
N->getValueType(0);
3779 EVL1 = ZExtPromotedInteger(EVL1);
3798 EVT PtrVT =
StackPtr.getValueType();
3799 auto &MF = DAG.getMachineFunction();
3803 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3806 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3812 SDValue EVL1Ptr = DAG.getZExtOrTrunc(DAG.getFreeze(EVL1),
DL, PtrVT);
3817 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3818 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3820 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3822 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3826 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3831 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3832 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3836 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3845 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3853 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3855 DAG.getVectorIdxConstant(0,
DL));
3861void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3869 GetSplitVector(Acc, AccLo, AccHi);
3870 unsigned Opcode =
N->getOpcode();
3882 GetSplitVector(Input1, Input1Lo, Input1Hi);
3883 GetSplitVector(Input2, Input2Lo, Input2Hi);
3886 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3887 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3890void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3898 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3909 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3911 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3915 N->getOperand(1), MaskLo,
N->getFlags());
3917 N->getOperand(1), MaskHi,
N->getFlags());
3920void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3921 unsigned Factor =
N->getNumOperands();
3924 for (
unsigned i = 0; i != Factor; ++i) {
3926 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3928 Ops[i * 2 + 1] = OpHi;
3939 for (
unsigned i = 0; i != Factor; ++i)
3943void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3944 unsigned Factor =
N->getNumOperands();
3947 for (
unsigned i = 0; i != Factor; ++i) {
3949 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3951 Ops[i + Factor] = OpHi;
3962 for (
unsigned i = 0; i != Factor; ++i) {
3963 unsigned IdxLo = 2 * i;
3964 unsigned IdxHi = 2 * i + 1;
3965 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3966 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3978bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3983 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3986 switch (
N->getOpcode()) {
3989 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3998 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
4005 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
4008 Res = SplitVecOp_TruncateHelper(
N);
4014 Res = SplitVecOp_FP_ROUND(
N);
4026 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
4033 case ISD::VP_SCATTER:
4037 case ISD::VP_GATHER:
4041 Res = SplitVecOp_VSELECT(
N, OpNo);
4047 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
4050 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
4053 Res = SplitVecOp_VECTOR_SHUFFLE_VAR(
N, OpNo);
4059 if (
N->getValueType(0).bitsLT(
4060 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
4061 Res = SplitVecOp_TruncateHelper(
N);
4063 Res = SplitVecOp_UnaryOp(
N);
4067 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
4083 Res = SplitVecOp_UnaryOp(
N);
4086 Res = SplitVecOp_FPOpDifferentTypes(
N);
4091 Res = SplitVecOp_CMP(
N);
4095 Res = SplitVecOp_FAKE_USE(
N);
4100 Res = SplitVecOp_ExtVecInRegOp(
N);
4120 Res = SplitVecOp_VECREDUCE(
N, OpNo);
4124 Res = SplitVecOp_VECREDUCE_SEQ(
N);
4126 case ISD::VP_REDUCE_FADD:
4127 case ISD::VP_REDUCE_SEQ_FADD:
4128 case ISD::VP_REDUCE_FMUL:
4129 case ISD::VP_REDUCE_SEQ_FMUL:
4130 case ISD::VP_REDUCE_ADD:
4131 case ISD::VP_REDUCE_MUL:
4132 case ISD::VP_REDUCE_AND:
4133 case ISD::VP_REDUCE_OR:
4134 case ISD::VP_REDUCE_XOR:
4135 case ISD::VP_REDUCE_SMAX:
4136 case ISD::VP_REDUCE_SMIN:
4137 case ISD::VP_REDUCE_UMAX:
4138 case ISD::VP_REDUCE_UMIN:
4139 case ISD::VP_REDUCE_FMAX:
4140 case ISD::VP_REDUCE_FMIN:
4141 case ISD::VP_REDUCE_FMAXIMUM:
4142 case ISD::VP_REDUCE_FMINIMUM:
4143 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
4147 Res = SplitVecOp_CttzElts(
N);
4149 case ISD::VP_CTTZ_ELTS:
4150 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
4151 Res = SplitVecOp_VP_CttzElements(
N);
4154 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
4160 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
4163 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
4168 if (!Res.
getNode())
return false;
4175 if (
N->isStrictFPOpcode())
4177 "Invalid operand expansion");
4180 "Invalid operand expansion");
4182 ReplaceValueWith(
SDValue(
N, 0), Res);
4186SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4190 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4192 EVT VT =
N->getValueType(0);
4205 getSetCCResultType(MVT::i1), MVT::i1);
4210 DAG.getElementCount(
DL, VT, SplitEC)),
4214SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4217 assert(OpNo == 0 &&
"Illegal operand must be mask");
4222 EVT Src0VT =
Src0.getValueType();
4224 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4227 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4228 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4229 "Lo and Hi have differing types");
4232 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4233 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4236 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4237 std::tie(LoOp1,
HiOp1) = DAG.SplitVector(Src1,
DL);
4238 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4248SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4249 assert(OpNo == 2 &&
"Illegal operand must be mask");
4252 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4253 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4255 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4258 RHSLo, MaskLo,
N->getFlags());
4260 RHSHi, MaskHi,
N->getFlags());
4264SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4267 assert(OpNo == 1 &&
"Illegal operand must be mask");
4272 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4274 EVT VecVT =
N->getValueType(0);
4278SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE_VAR(
SDNode *
N,
4282 assert(OpNo == 1 &&
"Illegal operand must be mask");
4284 return TLI.expandVECTOR_SHUFFLE_VAR(
N, DAG);
4287SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4288 EVT ResVT =
N->getValueType(0);
4294 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4295 GetSplitVector(VecOp,
Lo,
Hi);
4297 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4302 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4303 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4307 EVT ResVT =
N->getValueType(0);
4313 SDNodeFlags
Flags =
N->getFlags();
4316 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4317 GetSplitVector(VecOp,
Lo,
Hi);
4319 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4325 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4328SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4329 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4330 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4332 unsigned Opc =
N->getOpcode();
4333 EVT ResVT =
N->getValueType(0);
4339 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4340 GetSplitVector(VecOp,
Lo,
Hi);
4343 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4346 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4348 const SDNodeFlags
Flags =
N->getFlags();
4352 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4357 EVT ResVT =
N->getValueType(0);
4360 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4361 EVT InVT =
Lo.getValueType();
4366 if (
N->isStrictFPOpcode()) {
4367 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4368 {N->getOperand(0), Lo});
4369 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4370 {N->getOperand(0), Hi});
4379 ReplaceValueWith(
SDValue(
N, 1), Ch);
4381 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4382 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4391 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4401 EVT ResVT =
N->getValueType(0);
4403 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4407 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4413 Lo = BitConvertToInteger(
Lo);
4414 Hi = BitConvertToInteger(
Hi);
4416 if (DAG.getDataLayout().isBigEndian())
4424 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4426 EVT ResVT =
N->getValueType(0);
4434 GetSplitVector(SubVec,
Lo,
Hi);
4443 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4445 return SecondInsertion;
4448SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4455 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4457 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4459 ElementCount IdxVal =
4463 EVT SrcVT =
N->getOperand(0).getValueType();
4482 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4483 LoEltsMin - IdxValMin);
4484 DAG.ExtractVectorElements(
Hi, Elts, 0,
4487 return DAG.getBuildVector(SubVT, dl, Elts);
4491 ElementCount ExtractIdx = IdxVal - LoElts;
4493 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4496 EVT HiVT =
Hi.getValueType();
4498 "Only fixed-vector extracts are supported in this case");
4508 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4509 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4515 "Extracting scalable subvector from fixed-width unsupported");
4523 "subvector from a scalable predicate vector");
4529 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4531 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4532 auto &MF = DAG.getMachineFunction();
4536 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4540 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4543 SubVT, dl,
Store, StackPtr,
4547SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4556 GetSplitVector(Vec,
Lo,
Hi);
4558 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4560 if (IdxVal < LoElts)
4561 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4564 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4565 Idx.getValueType())), 0);
4569 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4581 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4587 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4589 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4590 auto &MF = DAG.getMachineFunction();
4593 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4597 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4601 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4603 return DAG.getExtLoad(
4614 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4622 SplitVecRes_Gather(
N,
Lo,
Hi);
4625 ReplaceValueWith(
SDValue(
N, 0), Res);
4630 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4634 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4636 SDValue EVL =
N->getVectorLength();
4644 GetSplitVector(
Data, DataLo, DataHi);
4646 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4651 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4654 GetSplitVector(Mask, MaskLo, MaskHi);
4656 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4659 EVT MemoryVT =
N->getMemoryVT();
4660 EVT LoMemVT, HiMemVT;
4661 bool HiIsEmpty =
false;
4662 std::tie(LoMemVT, HiMemVT) =
4663 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4667 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4670 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4673 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4675 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4676 N->getAddressingMode(),
N->isTruncatingStore(),
4677 N->isCompressingStore());
4683 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4684 N->isCompressingStore());
4686 MachinePointerInfo MPI;
4690 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4695 MMO = DAG.getMachineFunction().getMachineMemOperand(
4697 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4699 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4700 N->getAddressingMode(),
N->isTruncatingStore(),
4701 N->isCompressingStore());
4710 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4711 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4718 GetSplitVector(
Data, LoData, HiData);
4720 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4722 EVT LoMemVT, HiMemVT;
4723 bool HiIsEmpty =
false;
4724 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4730 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4731 else if (getTypeAction(
Mask.getValueType()) ==
4733 GetSplitVector(Mask, LoMask, HiMask);
4735 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4738 std::tie(LoEVL, HiEVL) =
4739 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4743 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4744 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4745 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4756 EVT PtrVT =
N->getBasePtr().getValueType();
4759 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4767 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4768 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4770 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4773 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4774 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4775 N->isCompressingStore());
4784 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4788 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4797 GetSplitVector(
Data, DataLo, DataHi);
4799 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4804 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4807 GetSplitVector(Mask, MaskLo, MaskHi);
4809 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4812 EVT MemoryVT =
N->getMemoryVT();
4813 EVT LoMemVT, HiMemVT;
4814 bool HiIsEmpty =
false;
4815 std::tie(LoMemVT, HiMemVT) =
4816 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4819 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4822 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4824 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4825 N->getAddressingMode(),
N->isTruncatingStore(),
4826 N->isCompressingStore());
4834 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4835 N->isCompressingStore());
4837 MachinePointerInfo MPI;
4841 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4846 MMO = DAG.getMachineFunction().getMachineMemOperand(
4849 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4851 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4852 N->getAddressingMode(),
N->isTruncatingStore(),
4853 N->isCompressingStore());
4866 EVT MemoryVT =
N->getMemoryVT();
4876 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4880 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4885 EVT LoMemVT, HiMemVT;
4886 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4891 GetSplitVector(
Ops.Data, DataLo, DataHi);
4893 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4898 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4900 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4904 if (getTypeAction(
Ops.Index.getValueType()) ==
4906 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4908 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4912 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4914 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4917 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4919 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4920 MSC->getIndexType(), MSC->isTruncatingStore());
4925 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4926 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4927 MMO, MSC->getIndexType(),
4928 MSC->isTruncatingStore());
4932 std::tie(EVLLo, EVLHi) =
4933 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4935 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4936 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4937 VPSC->getIndexType());
4942 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4943 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4944 VPSC->getIndexType());
4948 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4949 assert(OpNo == 1 &&
"Can only split the stored value");
4952 bool isTruncating =
N->isTruncatingStore();
4955 EVT MemoryVT =
N->getMemoryVT();
4958 MMOMetadata
Metadata =
N->getMMOMetadataForSubAccess();
4960 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4962 EVT LoMemVT, HiMemVT;
4963 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4967 return TLI.scalarizeVectorStore(
N, DAG);
4970 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4973 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4976 MachinePointerInfo MPI;
4977 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4980 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI, HiMemVT, Alignment, MMOFlags,
4983 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags,
Metadata);
4990 LLVMContext &Ctx = *DAG.getContext();
5008 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
5009 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
5013 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
5016 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
5017 DAG.getBitcast(MemVecVT, Wide), 0);
5019 N->getBasePtr(),
N->getMemOperand());
5027 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
5029 N->getBasePtr(),
N->getMemOperand());
5043 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
5049 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
5070 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
5071 SDValue InVec =
N->getOperand(OpNo);
5073 EVT OutVT =
N->getValueType(0);
5081 EVT LoOutVT, HiOutVT;
5082 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
5083 assert(LoOutVT == HiOutVT &&
"Unequal split?");
5088 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
5090 return SplitVecOp_UnaryOp(
N);
5099 return SplitVecOp_UnaryOp(
N);
5103 GetSplitVector(InVec, InLoVec, InHiVec);
5109 EVT HalfElementVT = IsFloat ?
5111 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
5118 if (
N->isStrictFPOpcode()) {
5119 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
5120 {N->getOperand(0), InLoVec});
5121 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
5122 {N->getOperand(0), InHiVec});
5128 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
5129 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
5133 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
5141 if (
N->isStrictFPOpcode()) {
5145 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
5153 DAG.getTargetConstant(
5154 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
5161 assert(
N->getValueType(0).isVector() &&
5162 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
5163 "Operand types must be vectors");
5165 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
5167 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
5168 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
5170 EVT VT =
N->getValueType(0);
5171 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
5177 assert(isStrict &&
"unexpected node");
5178 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5179 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
5180 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5181 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
5184 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5192 EVT OpVT =
N->getOperand(0).getValueType();
5195 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5201 EVT ResVT =
N->getValueType(0);
5204 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5205 EVT InVT =
Lo.getValueType();
5210 if (
N->isStrictFPOpcode()) {
5211 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5212 {N->getOperand(0), Lo, N->getOperand(2)});
5213 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5214 {N->getOperand(0), Hi, N->getOperand(2)});
5218 Lo.getValue(1),
Hi.getValue(1));
5219 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5221 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5222 N->getOperand(2),
N->getOperand(3));
5223 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5224 N->getOperand(2),
N->getOperand(3));
5226 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5227 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5238SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5241 EVT LHSLoVT, LHSHiVT;
5242 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5244 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5245 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5248 std::tie(LHSLo, LHSHi) =
5249 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5252 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5255 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5261 LLVMContext &Ctxt = *DAG.getContext();
5264 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5265 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5266 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5268 EVT ResVT =
N->getValueType(0);
5273 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5274 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5280 EVT ResVT =
N->getValueType(0);
5283 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5284 EVT InVT =
Lo.getValueType();
5290 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5291 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5298 EVT ResVT =
N->getValueType(0);
5302 GetSplitVector(VecOp,
Lo,
Hi);
5308 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5310 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5312 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5313 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5318 EVT ResVT =
N->getValueType(0);
5322 GetSplitVector(VecOp,
Lo,
Hi);
5324 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5325 auto [EVLLo, EVLHi] =
5327 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5333 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5335 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5336 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5339SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5350 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5351 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5352 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5353 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5354 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5355 OpsLo, MMO, IndexType);
5356 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5357 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5361SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5365 EVT LoResVT, HiResVT;
5366 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5368 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5370 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5373 N->getOperand(1), MaskLo,
N->getFlags());
5375 N->getOperand(1), MaskHi,
N->getFlags());
5381 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5384 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5388 NeedleLo,
N->getOperand(2),
N->getFlags());
5391 NeedleHi,
N->getOperand(2),
N->getFlags());
5392 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5395SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5398 "Accumulator should already be a legal type, and shouldn't need "
5399 "further splitting");
5402 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5403 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5404 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5405 unsigned Opcode =
N->getOpcode();
5408 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5409 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5416void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5417 unsigned WidenResNo) {
5418 unsigned NumResults =
N->getNumValues();
5419 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5420 if (ResNo == WidenResNo)
5422 EVT ResVT =
N->getValueType(ResNo);
5428 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5429 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5434void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5435 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5438 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5443 auto unrollExpandedOp = [&]() {
5448 EVT ResVT =
N->getValueType(ResNo);
5449 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5452 EVT VT0 =
N->getValueType(0);
5453 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5454 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT0.
getScalarType())) {
5458 if (
N->getNumValues() > 1)
5459 ReplaceOtherWidenResults(
N, Unrolled.
getNode(), ResNo);
5465 switch (
N->getOpcode()) {
5468 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5476 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5480 Res = WidenVecRes_ADDRSPACECAST(
N);
5487 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5494 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5498 Res = WidenVecRes_ScalarOp(
N);
5504 Res = WidenVecRes_Select(
N);
5507 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5509 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5516 case ISD::VP_LOAD_FF:
5519 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5523 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5526 Res = WidenVecRes_VECTOR_SHUFFLE_VAR(
N);
5534 case ISD::VP_GATHER:
5538 Res = WidenVecRes_VECTOR_REVERSE(
N);
5541 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5544 WidenVecRes_VECTOR_INTERLEAVE(
N);
5547 Res = WidenVecRes_VECTOR_MATCH(
N);
5550 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5606 Res = WidenVecRes_Binary(
N);
5613 Res = WidenVecRes_MaskedBinary(
N);
5618 Res = WidenVecRes_CMP(
N);
5624 if (unrollExpandedOp())
5639 Res = WidenVecRes_BinaryCanTrap(
N);
5648 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5651#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5652 case ISD::STRICT_##DAGN:
5653#include "llvm/IR/ConstrainedOps.def"
5654 Res = WidenVecRes_StrictFP(
N);
5663 Res = WidenVecRes_OverflowOp(
N, ResNo);
5667 Res = WidenVecRes_FCOPYSIGN(
N);
5672 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5677 if (!unrollExpandedOp())
5678 Res = WidenVecRes_ExpOp(
N);
5684 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5699 Res = WidenVecRes_Convert(
N);
5704 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5711 Res = WidenVecRes_XROUND(
N);
5737 if (unrollExpandedOp())
5760 Res = WidenVecRes_Unary(
N);
5765 Res = WidenVecRes_Ternary(
N);
5771 if (!unrollExpandedOp())
5772 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5779 Res = WidenVecRes_PARTIAL_REDUCE_MLA(
N);
5785 SetWidenedVector(
SDValue(
N, ResNo), Res);
5791 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5792 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5793 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5794 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5795 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5801 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5802 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5803 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5804 if (
N->getNumOperands() == 2)
5805 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5808 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5809 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5810 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5811 "Expected VP opcode");
5815 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5816 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5821 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5822 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5823 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5826 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5827 Mask = ModifyToType(Mask, WideMaskVT,
true);
5828 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5833 LLVMContext &Ctxt = *DAG.getContext();
5838 EVT OpVT =
LHS.getValueType();
5840 LHS = GetWidenedVector(
LHS);
5841 RHS = GetWidenedVector(
RHS);
5842 OpVT =
LHS.getValueType();
5845 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5848 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5854SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5857 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5858 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5859 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5861 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5870 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5873 if (ConcatEnd == 1) {
5874 VT = ConcatOps[0].getValueType();
5876 return ConcatOps[0];
5879 SDLoc dl(ConcatOps[0]);
5886 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
5887 int Idx = ConcatEnd - 1;
5888 VT = ConcatOps[Idx--].getValueType();
5889 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
5897 }
while (!
TLI.isTypeLegal(NextVT));
5902 unsigned NumToInsert = ConcatEnd - Idx - 1;
5903 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5905 ConcatOps[Idx+1] = VecOp;
5906 ConcatEnd = Idx + 2;
5912 unsigned RealVals = ConcatEnd - Idx - 1;
5913 unsigned SubConcatEnd = 0;
5914 unsigned SubConcatIdx = Idx + 1;
5915 while (SubConcatEnd < RealVals)
5916 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5917 while (SubConcatEnd < OpsToConcat)
5918 SubConcatOps[SubConcatEnd++] = undefVec;
5920 NextVT, SubConcatOps);
5921 ConcatEnd = SubConcatIdx + 1;
5926 if (ConcatEnd == 1) {
5927 VT = ConcatOps[0].getValueType();
5929 return ConcatOps[0];
5935 if (
NumOps != ConcatEnd ) {
5937 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5938 ConcatOps[j] = UndefVal;
5946 unsigned Opcode =
N->getOpcode();
5948 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5951 const SDNodeFlags
Flags =
N->getFlags();
5957 bool FoundLegalVectorType = TLI.isTypeLegal(VT) && !NumElts.
isScalar();
5958 if (FoundLegalVectorType && DAG.isSafeToSpeculativelyExecute(Opcode)) {
5960 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5961 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5962 return DAG.getNode(Opcode, dl, WidenVT, InOp1, InOp2, Flags);
5970 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5973 TLI.isTypeLegal(WideMaskVT)) {
5974 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5975 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5976 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5978 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5979 N->getValueType(0).getVectorElementCount());
5980 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5989 if (!TLI.isTypeLegal(VT))
5995 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5996 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5997 ElementCount CurNumElts =
N->getValueType(0).getVectorElementCount();
6000 unsigned ConcatEnd = 0;
6010 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
6011 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
6012 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
6015 CurNumElts -= NumElts;
6030 SDValue EOp1 = DAG.getExtractVectorElt(dl, EltVT, InOp1, Idx);
6031 SDValue EOp2 = DAG.getExtractVectorElt(dl, EltVT, InOp2, Idx);
6032 ConcatOps[ConcatEnd++] =
6033 DAG.
getNode(Opcode, dl, EltVT, EOp1, EOp2, Flags);
6039 if (!TLI.isTypeLegal(VT))
6047 switch (
N->getOpcode()) {
6050 return WidenVecRes_STRICT_FSETCC(
N);
6057 return WidenVecRes_Convert_StrictFP(
N);
6064 unsigned Opcode =
N->getOpcode();
6066 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6070 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
6071 NumElts = NumElts / 2;
6082 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
6086 unsigned ConcatEnd = 0;
6093 for (
unsigned i = 1; i < NumOpers; ++i) {
6099 Oper = GetWidenedVector(Oper);
6105 DAG.getPOISON(WideOpVT), Oper,
6106 DAG.getVectorIdxConstant(0, dl));
6118 while (CurNumElts != 0) {
6119 while (CurNumElts >= NumElts) {
6122 for (
unsigned i = 0; i < NumOpers; ++i) {
6125 EVT OpVT =
Op.getValueType();
6130 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
6136 EVT OperVT[] = {VT, MVT::Other};
6138 ConcatOps[ConcatEnd++] = Oper;
6141 CurNumElts -= NumElts;
6144 NumElts = NumElts / 2;
6146 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
6149 for (
unsigned i = 0; i != CurNumElts; ++i, ++
Idx) {
6152 for (
unsigned i = 0; i < NumOpers; ++i) {
6155 EVT OpVT =
Op.getValueType();
6163 EVT WidenVT[] = {WidenEltVT, MVT::Other};
6165 ConcatOps[ConcatEnd++] = Oper;
6174 if (Chains.
size() == 1)
6175 NewChain = Chains[0];
6178 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6183SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
6185 EVT ResVT =
N->getValueType(0);
6186 EVT OvVT =
N->getValueType(1);
6187 EVT WideResVT, WideOvVT;
6192 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6197 WideLHS = GetWidenedVector(
N->getOperand(0));
6198 WideRHS = GetWidenedVector(
N->getOperand(1));
6200 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6209 N->getOperand(0),
Zero);
6211 N->getOperand(1),
Zero);
6214 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6215 SDNode *WideNode = DAG.getNode(
6216 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6219 unsigned OtherNo = 1 - ResNo;
6220 EVT OtherVT =
N->getValueType(OtherNo);
6227 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
6230 return SDValue(WideNode, ResNo);
6234 LLVMContext &Ctx = *DAG.getContext();
6238 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6243 unsigned Opcode =
N->getOpcode();
6244 const SDNodeFlags
Flags =
N->getFlags();
6250 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6252 InOp = ZExtPromotedInteger(InOp);
6264 if (
N->getNumOperands() == 1)
6265 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6267 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6268 N->getOperand(3), Flags);
6269 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6273 InOp = GetWidenedVector(
N->getOperand(0));
6276 if (InVTEC == WidenEC)
6277 return MakeConvertNode(WidenVT, InOp);
6302 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6306 if (TLI.isTypeLegal(InWidenVT)) {
6314 unsigned NumConcat =
6319 return MakeConvertNode(WidenVT, InVec);
6323 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6325 return MakeConvertNode(WidenVT, InVal);
6334 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6335 for (
unsigned i=0; i < MinElts; ++i) {
6336 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6337 Ops[i] = MakeConvertNode(EltVT, Val);
6340 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6345 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6349 EVT SrcVT = Src.getValueType();
6353 Src = GetWidenedVector(Src);
6354 SrcVT = Src.getValueType();
6361 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6366 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6370 EVT SrcVT = Src.getValueType();
6374 Src = GetWidenedVector(Src);
6375 SrcVT = Src.getValueType();
6382 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6385SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6390 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6396 unsigned Opcode =
N->getOpcode();
6402 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6407 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6408 for (
unsigned i=0; i < MinElts; ++i) {
6409 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6410 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6414 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6416 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6419SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6420 unsigned Opcode =
N->getOpcode();
6424 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6433 InOp = GetWidenedVector(InOp);
6440 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6447 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6448 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6465 while (
Ops.size() != WidenNumElts)
6466 Ops.push_back(DAG.getPOISON(WidenSVT));
6468 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6474 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6475 return WidenVecRes_BinaryCanTrap(
N);
6478 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6485SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6487 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6490 SDValue Arg = GetWidenedVector(FpValue);
6491 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6496 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6497 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6499 EVT ExpVT =
RHS.getValueType();
6504 ExpOp = ModifyToType(
RHS, WideExpVT);
6507 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6512 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6513 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6514 if (
N->getNumOperands() == 1)
6515 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6517 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6522 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6527 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6528 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6529 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6532SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6534 EVT VT0 =
N->getValueType(0);
6535 EVT VT1 =
N->getValueType(1);
6539 "expected both results to be vectors of matching element count");
6541 LLVMContext &Ctx = *DAG.getContext();
6542 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6544 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6551 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6554 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6555 return SDValue(WidenNode, ResNo);
6558SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6559 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6560 return GetWidenedVector(WidenVec);
6565 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6577 InOp = GetWidenedVector(InOp);
6581 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6584 return DAG.getAddrSpaceCast(
6585 DL, WidenVT, InOp, AddrSpaceCastN->getSrcAddressSpace(),
6586 AddrSpaceCastN->getDestAddressSpace(), AddrSpaceCastN->getFlags());
6592 EVT VT =
N->getValueType(0);
6593 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6596 switch (getTypeAction(InVT)) {
6610 SDValue NInOp = GetPromotedInteger(InOp);
6612 if (WidenVT.
bitsEq(NInVT)) {
6615 if (DAG.getDataLayout().isBigEndian()) {
6618 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6636 InOp = GetWidenedVector(InOp);
6638 if (WidenVT.
bitsEq(InVT))
6648 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6653 unsigned NewNumParts = WidenSize / InSize;
6666 EVT OrigInVT =
N->getOperand(0).getValueType();
6671 if (TLI.isTypeLegal(NewInVT)) {
6679 if (WidenSize % InSize == 0) {
6686 DAG.ExtractVectorElements(InOp,
Ops);
6687 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6699 return CreateStackStoreLoad(InOp, WidenVT);
6702SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6704 N->getOpcode(), SDLoc(
N),
6705 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6706 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6712 EVT VT =
N->getValueType(0);
6716 EVT EltVT =
N->getOperand(0).getValueType();
6719 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6723 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6724 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6726 return DAG.getBuildVector(WidenVT, dl, NewOps);
6730 EVT InVT =
N->getOperand(0).getValueType();
6731 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6733 unsigned NumOperands =
N->getNumOperands();
6735 bool InputWidened =
false;
6739 if (WidenNumElts % NumInElts == 0) {
6741 unsigned NumConcat = WidenNumElts / NumInElts;
6742 SDValue UndefVal = DAG.getPOISON(InVT);
6744 for (
unsigned i=0; i < NumOperands; ++i)
6745 Ops[i] =
N->getOperand(i);
6746 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6751 InputWidened =
true;
6752 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6755 for (i=1; i < NumOperands; ++i)
6756 if (!
N->getOperand(i).isUndef())
6759 if (i == NumOperands)
6762 return GetWidenedVector(
N->getOperand(0));
6764 if (NumOperands == 2) {
6766 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6771 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6772 for (
unsigned i = 0; i < NumInElts; ++i) {
6774 MaskOps[i + NumInElts] = i + WidenNumElts;
6776 return DAG.getVectorShuffle(WidenVT, dl,
6777 GetWidenedVector(
N->getOperand(0)),
6778 GetWidenedVector(
N->getOperand(1)),
6785 SDValue WideVec = DAG.getPOISON(WidenVT);
6787 for (
unsigned I = 0;
I < NumOperands; ++
I)
6789 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6800 for (
unsigned i=0; i < NumOperands; ++i) {
6803 InOp = GetWidenedVector(InOp);
6804 for (
unsigned j = 0;
j < NumInElts; ++
j)
6805 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6807 SDValue UndefVal = DAG.getPOISON(EltVT);
6808 for (;
Idx < WidenNumElts; ++
Idx)
6809 Ops[Idx] = UndefVal;
6810 return DAG.getBuildVector(WidenVT, dl,
Ops);
6813SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6814 EVT VT =
N->getValueType(0);
6815 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6816 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6823SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6824 EVT VT =
N->getValueType(0);
6826 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6831 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6833 InOp = GetWidenedVector(InOp);
6839 if (IdxVal == 0 && InVT == WidenVT)
6846 assert(IdxVal % VTNumElts == 0 &&
6847 "Expected Idx to be a multiple of subvector minimum vector length");
6848 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6861 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6862 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6863 "down type's element count");
6870 for (;
I < VTNumElts / GCD; ++
I)
6872 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6873 for (;
I < WidenNumElts / GCD; ++
I)
6895 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6902 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6903 return DAG.getMaskedLoad(
6904 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6912 for (i = 0; i < VTNumElts; ++i)
6913 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6915 SDValue UndefVal = DAG.getPOISON(EltVT);
6916 for (; i < WidenNumElts; ++i)
6918 return DAG.getBuildVector(WidenVT, dl,
Ops);
6924 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6929SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6930 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6933 N->getOperand(1),
N->getOperand(2));
6942 "Load width must be less than or equal to first value type width");
6951 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6968 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6979 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6980 EVT LdVT =
LD->getMemoryVT();
6989 TypeSize WidthDiff = WidenWidth - LdWidth;
6992 std::optional<EVT> FirstVT =
6993 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6999 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
7002 Chain, BasePtr,
LD->getMemOperand());
7006 FirstVTWidth, dl, DAG);
7024 if (!
LD->getMemoryVT().isByteSized()) {
7026 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
7028 ReplaceValueWith(
SDValue(LD, 1), NewChain);
7037 EVT VT =
LD->getValueType(0);
7038 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7039 EVT WideMaskVT = getSetCCResultType(WideVT);
7042 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
7043 TLI.isTypeLegal(WideMaskVT)) {
7046 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
7050 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
7051 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
7063 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
7065 Result = GenWidenVectorLoads(LdChain, LD);
7072 if (LdChain.
size() == 1)
7073 NewChain = LdChain[0];
7079 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7090 SDValue NewLoad = DAG.getMaskedLoad(
7091 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
7092 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
7093 LD->getAddressingMode(),
LD->getExtensionType());
7103 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7105 SDValue EVL =
N->getVectorLength();
7112 "Unable to widen binary VP op");
7113 Mask = GetWidenedVector(Mask);
7114 assert(
Mask.getValueType().getVectorElementCount() ==
7115 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7116 .getVectorElementCount() &&
7117 "Unable to widen vector load");
7120 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
7121 N->getBasePtr(),
N->getOffset(), Mask, EVL,
7122 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
7130 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7132 SDValue EVL =
N->getVectorLength();
7138 "Unable to widen binary VP op");
7139 Mask = GetWidenedVector(Mask);
7140 assert(
Mask.getValueType().getVectorElementCount() ==
7141 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
7142 .getVectorElementCount() &&
7143 "Unable to widen vector load");
7145 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
7146 Mask, EVL,
N->getMemOperand());
7159 "Unable to widen VP strided load");
7160 Mask = GetWidenedVector(Mask);
7162 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7163 assert(
Mask.getValueType().getVectorElementCount() ==
7165 "Data and mask vectors should have the same number of elements");
7167 SDValue Res = DAG.getStridedLoadVP(
7168 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
7169 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
7170 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
7171 N->isExpandingLoad());
7179SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
7184 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
7186 Mask.getValueType().getVectorElementType(),
7189 SDValue WideVec = ModifyToType(Vec, WideVecVT);
7190 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
7191 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
7193 WideMask, WidePassthru);
7196SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE_VAR(
SDNode *
N) {
7198 SDValue Src = GetWidenedVector(
N->getOperand(0));
7199 EVT WideVT = Src.getValueType();
7202 N->getOperand(1).getValueType().getVectorElementType());
7203 SDValue Mask = ModifyToType(
N->getOperand(1), WideMaskVT);
7208 EVT VT =
N->getValueType(0);
7209 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7211 EVT MaskVT =
Mask.getValueType();
7212 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7221 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7222 TLI.isTypeLegal(WideMaskVT) &&
7228 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7229 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7233 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7234 N->getMemoryVT(),
N->getMemOperand());
7238 if (!
N->getPassThru()->isUndef()) {
7242 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7243 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7244 DAG.getPOISON(WidenVT), EVL);
7255 Mask = ModifyToType(Mask, WideMaskVT,
true);
7257 SDValue Res = DAG.getMaskedLoad(
7258 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7259 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7260 ExtType,
N->isExpandingLoad());
7269 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7271 EVT MaskVT =
Mask.getValueType();
7272 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7280 Mask = ModifyToType(Mask, WideMaskVT,
true);
7285 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7286 Index = ModifyToType(Index, WideIndexVT);
7292 N->getMemoryVT().getScalarType(), WideEC);
7293 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7294 WideMemVT, dl,
Ops,
N->getMemOperand(),
7295 N->getIndexType(),
N->getExtensionType());
7304 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7312 N->getMemoryVT().getScalarType(), WideEC);
7313 Mask = GetWidenedMask(Mask, WideEC);
7316 Mask,
N->getVectorLength()};
7317 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7318 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7327 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7328 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7356 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7357 return N->getOperand(OpNo).getValueType();
7365 N =
N.getOperand(0);
7367 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7368 if (!
N->getOperand(i)->isUndef())
7370 N =
N.getOperand(0);
7374 N =
N.getOperand(0);
7376 N =
N.getOperand(0);
7402 { MaskVT, MVT::Other },
Ops);
7403 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7409 return adjustMaskToType(Mask, ToMaskVT);
7415 LLVMContext &Ctx = *DAG.getContext();
7416 EVT MaskVT =
Mask.getValueType();
7419 if (MaskScalarBits < ToMaskScalBits) {
7423 }
else if (MaskScalarBits > ToMaskScalBits) {
7429 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7431 "Mask should have the right element size by now.");
7434 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7436 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7439 EVT SubVT =
Mask->getValueType(0);
7445 assert((
Mask->getValueType(0) == ToMaskVT) &&
7446 "A mask of ToMaskVT should have been produced by now.");
7453EVT DAGTypeLegalizer::unifyMaskTypes(
SDValue &Op0,
bool IsOpLenient0,
7454 SDValue &Op1,
bool IsOpLenient1,
7458 "unifyMaskTypes only handles scalar width differences");
7470 if (IsOpLenient0 != IsOpLenient1) {
7471 SDValue *LenientOp, *NonLenientOp;
7474 NonLenientOp = &Op1;
7477 NonLenientOp = &Op0;
7480 *LenientOp = adjustMaskToType(*LenientOp, OpVT);
7486 unsigned NarrowBits = std::min(Bits0, Bits1);
7487 unsigned WideBits = std::max(Bits0, Bits1);
7489 unsigned IntBits = NarrowBits == WideBits ? NarrowBits
7490 : ToBits >= WideBits ? WideBits
7491 : ToBits <= NarrowBits ? NarrowBits
7495 Op0 = adjustMaskToType(Op0, OpVT);
7496 Op1 = adjustMaskToType(Op1, OpVT);
7500std::pair<SDValue, bool>
7501DAGTypeLegalizer::convertMaskTreeImpl(
SDValue V,
EVT ToVT,
unsigned Depth) {
7533 if (
Depth >= DAG.MaxRecursionDepth)
7542 unsigned Opcode =
V.getOpcode();
7547 return {convertMask(
V, MaskVT, MaskVT),
false};
7555 return {DAG.getConstant(0,
DL, ToVT),
true};
7557 return {DAG.getAllOnesConstant(
DL, ToVT),
true};
7562 auto [Op0, IsLenientOp0] =
7563 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7566 auto [Op1, IsLenientOp1] =
7567 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7570 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7571 return {DAG.getNode(Opcode,
DL, OpVT, Op0, Op1),
7572 IsLenientOp0 && IsLenientOp1};
7577 auto [Inner, IsTypeLenient] =
7578 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7581 return {DAG.getNode(
ISD::FREEZE,
DL, Inner.getValueType(), Inner),
7588 auto [Op0, IsLenientOp0] =
7589 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7592 if (
V.getOperand(1).isUndef()) {
7594 return {DAG.getVectorShuffle(OpVT,
DL, Op0, DAG.getUNDEF(OpVT),
7598 auto [Op1, IsLenientOp1] =
7599 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7602 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7603 return {DAG.getVectorShuffle(OpVT,
DL, Op0, Op1, Shuf->getMask()),
7604 IsLenientOp0 && IsLenientOp1};
7609 auto [Op1, IsLenientOp1] =
7610 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7613 auto [Op2, IsLenientOp2] =
7614 convertMaskTreeImpl(
V.getOperand(2), ToVT,
Depth + 1);
7617 EVT OpVT = unifyMaskTypes(Op1, IsLenientOp1, Op2, IsLenientOp2, ToVT);
7627 return {DAG.getNode(Opcode,
DL, OpVT,
Cond, Op1, Op2),
7628 IsLenientOp1 && IsLenientOp2};
7642 *DAG.getContext(),
V.getValueType().getVectorElementCount());
7643 auto [
Result,
_] = convertMaskTreeImpl(
V, MaskTreeVT);
7646 return adjustMaskToType(Result, ToVT);
7654 LLVMContext &Ctx = *DAG.getContext();
7662 EVT CondVT =
Cond->getValueType(0);
7666 EVT VSelVT =
N->getValueType(0);
7678 EVT FinalVT = VSelVT;
7689 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7690 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7697 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7705 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7708 EVT ToMaskVT = VSelVT;
7713 return convertMaskTree(
Cond, ToMaskVT);
7717 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7722 unsigned Opcode =
N->getOpcode();
7724 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7725 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7726 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7728 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7734 Cond1 = GetWidenedVector(Cond1);
7742 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7743 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7748 Cond1 = ModifyToType(Cond1, CondWidenVT);
7751 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7752 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7754 if (Opcode == ISD::VP_MERGE)
7755 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7757 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7761 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7762 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7765 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7769 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7770 return DAG.getUNDEF(WidenVT);
7774 EVT VT =
N->getValueType(0);
7777 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7781 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7782 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7785 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7786 for (
unsigned i = 0; i != NumElts; ++i) {
7787 int Idx =
N->getMaskElt(i);
7788 if (Idx < (
int)NumElts)
7791 NewMask[i] =
Idx - NumElts + WidenNumElts;
7793 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7797 EVT VT =
N->getValueType(0);
7801 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7802 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7808 unsigned IdxVal = WidenNumElts - VTNumElts;
7821 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7824 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7825 "down type's element count");
7828 for (; i < VTNumElts / GCD; ++i)
7830 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7831 for (; i < WidenNumElts / GCD; ++i)
7839 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7840 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7842 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7846SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7847 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7851void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7852 EVT VT =
N->getValueType(0);
7855 unsigned Factor =
N->getNumOperands();
7858 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7862 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx)
7863 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7872 for (
unsigned Idx = 0;
Idx != Factor; ++
Idx)
7873 Slices[Idx] = Interleaved.
getValue(Idx);
7877 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx) {
7878 SDValue Narrow = DAG.getExtractSubvector(
DL, VT, Packed,
7881 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7882 SetWidenedVector(
SDValue(
N, Idx), Wide);
7888 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7889 EVT SourceVT =
N->getOperand(0).getValueType();
7894 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7895 N->getOperand(0), 0);
7896 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7897 N->getOperand(2), 0);
7899 N->getOperand(1), WideMask,
N->getFlags());
7902void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7903 EVT VT =
N->getValueType(0);
7906 unsigned Factor =
N->getNumOperands();
7909 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7919 EVT ConcatVT =
EVT::getVectorVT(*DAG.getContext(), EltVT, OrigEC * Factor);
7921 SDValue PackedWidenVec = DAG.getInsertSubvector(
7922 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7926 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx) {
7927 NewOps[
Idx] = DAG.getExtractSubvector(
DL, WidenVT, PackedWidenVec,
7934 for (
unsigned Idx = 0U;
Idx < Factor; ++
Idx)
7939 assert(
N->getValueType(0).isVector() &&
7940 N->getOperand(0).getValueType().isVector() &&
7941 "Operands must be vectors");
7942 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7955 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7956 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7963 InOp1 = GetWidenedVector(InOp1);
7964 InOp2 = GetWidenedVector(InOp2);
7967 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7978 "Input not widened to expected type!");
7980 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7985 assert(
N->getValueType(0).isVector() &&
7986 N->getOperand(1).getValueType().isVector() &&
7987 "Operands must be vectors");
7988 EVT VT =
N->getValueType(0);
7989 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7999 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8004 for (
unsigned i = 0; i != NumElts; ++i) {
8005 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8006 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8008 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8009 {Chain, LHSElem, RHSElem, CC});
8010 Chains[i] = Scalars[i].getValue(1);
8011 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8012 DAG.getBoolConstant(
true, dl, EltVT, VT),
8013 DAG.getBoolConstant(
false, dl, EltVT, VT));
8017 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8019 return DAG.getBuildVector(WidenVT, dl, Scalars);
8022SDValue DAGTypeLegalizer::WidenVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N) {
8024 EVT VT =
N->getValueType(0);
8027 SDValue Expanded = TLI.expandPartialReduceMLA(
N, DAG);
8028 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
8029 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WideVT), Expanded, 0);
8035bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
8036 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
8040 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
8043 switch (
N->getOpcode()) {
8046 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
8054 Res = WidenVecOp_FAKE_USE(
N);
8058 Res = WidenVecOp_VECTOR_REPEAT(
N);
8063 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
8067 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
8068 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
8069 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
8074 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
8076 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
8077 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
8079 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
8080 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
8090 Res = WidenVecOp_UnrollVectorOp(
N);
8097 Res = WidenVecOp_EXTEND(
N);
8102 Res = WidenVecOp_CMP(
N);
8120 Res = WidenVecOp_Convert(
N);
8125 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
8145 Res = WidenVecOp_VECREDUCE(
N);
8149 Res = WidenVecOp_VECREDUCE_SEQ(
N);
8151 case ISD::VP_REDUCE_FADD:
8152 case ISD::VP_REDUCE_SEQ_FADD:
8153 case ISD::VP_REDUCE_FMUL:
8154 case ISD::VP_REDUCE_SEQ_FMUL:
8155 case ISD::VP_REDUCE_ADD:
8156 case ISD::VP_REDUCE_MUL:
8157 case ISD::VP_REDUCE_AND:
8158 case ISD::VP_REDUCE_OR:
8159 case ISD::VP_REDUCE_XOR:
8160 case ISD::VP_REDUCE_SMAX:
8161 case ISD::VP_REDUCE_SMIN:
8162 case ISD::VP_REDUCE_UMAX:
8163 case ISD::VP_REDUCE_UMIN:
8164 case ISD::VP_REDUCE_FMAX:
8165 case ISD::VP_REDUCE_FMIN:
8166 case ISD::VP_REDUCE_FMAXIMUM:
8167 case ISD::VP_REDUCE_FMINIMUM:
8168 Res = WidenVecOp_VP_REDUCE(
N);
8172 Res = WidenVecOp_CttzElements(
N);
8174 case ISD::VP_CTTZ_ELTS:
8175 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
8176 Res = WidenVecOp_VP_CttzElements(
N);
8179 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
8182 Res = WidenVecOp_VECTOR_SHUFFLE_VAR(
N, OpNo);
8185 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
8190 if (!Res.
getNode())
return false;
8198 if (
N->isStrictFPOpcode())
8200 "Invalid operand expansion");
8203 "Invalid operand expansion");
8205 ReplaceValueWith(
SDValue(
N, 0), Res);
8211 EVT VT =
N->getValueType(0);
8216 "Unexpected type action");
8217 InOp = GetWidenedVector(InOp);
8220 "Input wasn't widened!");
8228 EVT FixedEltVT = FixedVT.getVectorElementType();
8229 if (TLI.isTypeLegal(FixedVT) &&
8231 FixedEltVT == InEltVT) {
8233 "Not enough elements in the fixed type for the operand!");
8235 "We can't have the same type as we started with!");
8237 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
8239 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
8248 return WidenVecOp_Convert(
N);
8253 switch (
N->getOpcode()) {
8268 EVT OpVT =
N->getOperand(0).getValueType();
8269 EVT ResVT =
N->getValueType(0);
8276 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
8277 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
8283 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
8284 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
8286 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
8293 return DAG.UnrollVectorOp(
N);
8298 EVT ResultVT =
N->getValueType(0);
8300 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
8303 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
8309 {WideArg,
Test},
N->getFlags());
8315 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
8317 EVT OpVT =
N->getOperand(0).getValueType();
8320 return DAG.getNode(ExtendCode,
DL, ResultVT,
CC);
8325 EVT VT =
N->getValueType(0);
8331 "Unexpected type action");
8332 InOp = GetWidenedVector(InOp);
8334 unsigned Opcode =
N->getOpcode();
8339 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
8342 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
8343 return DAG.getNode(Opcode, dl, VT,
Op);
8350 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
8352 if (
N->isStrictFPOpcode()) {
8354 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8357 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8358 {
N->getOperand(0), InOp });
8363 Res = MakeConvertNode(WideVT, InOp);
8365 return DAG.getExtractSubvector(dl, VT, Res, 0);
8373 if (
N->isStrictFPOpcode()) {
8376 for (
unsigned i=0; i < NumElts; ++i) {
8377 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8378 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
8382 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8384 for (
unsigned i = 0; i < NumElts; ++i) {
8385 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8386 Ops[i] = MakeConvertNode(EltVT, Elt);
8390 return DAG.getBuildVector(VT, dl,
Ops);
8394 EVT DstVT =
N->getValueType(0);
8395 SDValue Src = GetWidenedVector(
N->getOperand(0));
8396 EVT SrcVT = Src.getValueType();
8403 if (TLI.isTypeLegal(WideDstVT)) {
8405 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
8408 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
8412 return DAG.UnrollVectorOp(
N);
8416 EVT VT =
N->getValueType(0);
8417 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8425 if (!VT.
isVector() && VT != MVT::x86mmx &&
8429 if (TLI.isTypeLegal(NewVT)) {
8431 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8443 ElementCount NewNumElts =
8445 .divideCoefficientBy(EltSize);
8447 if (TLI.isTypeLegal(NewVT)) {
8449 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8454 return CreateStackStoreLoad(InOp, VT);
8462 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8463 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8468 EVT VT =
N->getValueType(0);
8470 EVT InVT =
N->getOperand(0).getValueType();
8475 unsigned NumOperands =
N->getNumOperands();
8476 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8478 for (i = 1; i < NumOperands; ++i)
8479 if (!
N->getOperand(i).isUndef())
8482 if (i == NumOperands)
8483 return GetWidenedVector(
N->getOperand(0));
8489 for (
unsigned i = 0; i < NumOperands; ++i) {
8490 SDValue InOp = GetWidenedVector(
N->getOperand(i));
8492 InOp = DAG.getExtractSubvector(dl, InVT, InOp, 0);
8493 Result = DAG.getInsertSubvector(dl, Result, InOp, i * NumInElts);
8505 for (
unsigned i=0; i < NumOperands; ++i) {
8509 "Unexpected type action");
8510 InOp = GetWidenedVector(InOp);
8511 for (
unsigned j = 0;
j < NumInElts; ++
j)
8512 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8514 return DAG.getBuildVector(VT, dl,
Ops);
8519 EVT VT =
N->getValueType(0);
8521 EVT SrcVT = Src.getValueType();
8522 EVT WidenedSrcVT = TLI.getTypeToTransformTo(*DAG.getContext(), SrcVT);
8527 "Cannot widen VECTOR_REPEAT operand to an ElementCount that's not "
8528 "a known scalar multiple of the input ElementCount.");
8532 unsigned NumConcat =
8540 return DAG.getExtractSubvector(
DL, VT, Widened, 0);
8543SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8544 EVT VT =
N->getValueType(0);
8549 SubVec = GetWidenedVector(SubVec);
8554 bool IndicesValid =
false;
8557 IndicesValid =
true;
8561 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8562 Attribute::VScaleRange);
8567 IndicesValid =
true;
8573 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8579 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8586 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8608 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8616 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8617 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8622 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8627 unsigned Idx =
N->getConstantOperandVal(2);
8633 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8639SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8640 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8642 N->getValueType(0), InOp,
N->getOperand(1));
8645SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8646 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8648 N->getValueType(0), InOp,
N->getOperand(1));
8651SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8653 EVT ResVT =
N->getValueType(0);
8656 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8662 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8670 "Widened input size must be a multiple of result element size");
8673 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8675 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8676 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8684 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8685 return TLI.scalarizeVectorStore(ST, DAG);
8687 if (
ST->isTruncatingStore())
8688 return TLI.scalarizeVectorStore(ST, DAG);
8698 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8699 EVT WideMaskVT = getSetCCResultType(WideVT);
8701 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8702 TLI.isTypeLegal(WideMaskVT)) {
8705 StVal = GetWidenedVector(StVal);
8707 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8709 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8710 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8711 ST->getAddressingMode());
8715 if (GenWidenVectorStores(StChain, ST)) {
8716 if (StChain.
size() == 1)
8725 SDValue WideStVal = GetWidenedVector(StVal);
8729 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8730 ST->getOffset(), Mask,
ST->getMemoryVT(),
8731 ST->getMemOperand(),
ST->getAddressingMode(),
8732 ST->isTruncatingStore());
8739 EVT StVT =
ST->getMemoryVT();
8742 SDValue StVal = GetWidenedVector(
ST->getVal());
8747 TypeSize WidthDiff = WidenWidth - StWidth;
8753 std::optional<EVT> FirstVT =
8754 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8759 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8765 ST->getBasePtr(),
ST->getMemOperand());
8768SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8769 assert((OpNo == 1 || OpNo == 3) &&
8770 "Can widen only data or mask operand of vp_store");
8778 StVal = GetWidenedVector(StVal);
8784 "Unable to widen VP store");
8785 Mask = GetWidenedVector(Mask);
8787 Mask = GetWidenedVector(Mask);
8793 "Unable to widen VP store");
8794 StVal = GetWidenedVector(StVal);
8797 assert(
Mask.getValueType().getVectorElementCount() ==
8799 "Mask and data vectors should have the same number of elements");
8800 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8801 ST->getOffset(), Mask,
ST->getVectorLength(),
8802 ST->getMemoryVT(),
ST->getMemOperand(),
8803 ST->getAddressingMode(),
ST->isTruncatingStore(),
8804 ST->isCompressingStore());
8809 assert((OpNo == 1 || OpNo == 4) &&
8810 "Can widen only data or mask operand of vp_strided_store");
8819 "Unable to widen VP strided store");
8823 "Unable to widen VP strided store");
8825 StVal = GetWidenedVector(StVal);
8826 Mask = GetWidenedVector(Mask);
8829 Mask.getValueType().getVectorElementCount() &&
8830 "Data and mask vectors should have the same number of elements");
8832 return DAG.getStridedStoreVP(
8839SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8840 assert((OpNo == 1 || OpNo == 4) &&
8841 "Can widen only data or mask operand of mstore");
8844 EVT MaskVT =
Mask.getValueType();
8849 EVT WideVT, WideMaskVT;
8852 StVal = GetWidenedVector(StVal);
8859 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8866 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8868 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8869 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8878 Mask = ModifyToType(Mask, WideMaskVT,
true);
8881 Mask = ModifyToType(Mask, WideMaskVT,
true);
8883 StVal = ModifyToType(StVal, WideVT);
8886 assert(
Mask.getValueType().getVectorElementCount() ==
8888 "Mask and data vectors should have the same number of elements");
8895SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8896 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8898 SDValue DataOp = MG->getPassThru();
8900 SDValue Scale = MG->getScale();
8908 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8909 MG->getMemOperand(), MG->getIndexType(),
8910 MG->getExtensionType());
8916SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8925 DataOp = GetWidenedVector(DataOp);
8929 EVT IndexVT =
Index.getValueType();
8932 Index = ModifyToType(Index, WideIndexVT);
8935 EVT MaskVT =
Mask.getValueType();
8938 Mask = ModifyToType(Mask, WideMaskVT,
true);
8943 }
else if (OpNo == 4) {
8945 Index = GetWidenedVector(Index);
8951 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8956SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8965 DataOp = GetWidenedVector(DataOp);
8966 Index = GetWidenedVector(Index);
8968 Mask = GetWidenedMask(Mask, WideEC);
8971 }
else if (OpNo == 3) {
8973 Index = GetWidenedVector(Index);
8980 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8985 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8986 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8988 EVT VT =
N->getValueType(0);
9003 SVT, InOp0, InOp1,
N->getOperand(2));
9009 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
9011 EVT OpVT =
N->getOperand(0).getValueType();
9014 return DAG.getNode(ExtendCode, dl, VT,
CC);
9024 EVT VT =
N->getValueType(0);
9026 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
9033 for (
unsigned i = 0; i != NumElts; ++i) {
9034 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
9035 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
9037 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
9038 {Chain, LHSElem, RHSElem, CC});
9039 Chains[i] = Scalars[i].getValue(1);
9040 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
9041 DAG.getBoolConstant(
true, dl, EltVT, VT),
9042 DAG.getBoolConstant(
false, dl, EltVT, VT));
9046 ReplaceValueWith(
SDValue(
N, 1), NewChain);
9048 return DAG.getBuildVector(VT, dl, Scalars);
9072 SDValue Op = GetWidenedVector(
N->getOperand(0));
9073 EVT VT =
N->getValueType(0);
9074 EVT OrigVT =
N->getOperand(0).getValueType();
9075 EVT WideVT =
Op.getValueType();
9077 SDNodeFlags
Flags =
N->getFlags();
9079 unsigned Opc =
N->getOpcode();
9081 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
9082 assert(NeutralElem &&
"Neutral element must exist");
9092 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
9099 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
9100 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
9106 unsigned GCD = std::gcd(OrigElts, WideElts);
9109 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
9110 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx =
Idx + GCD)
9111 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
9112 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
9115 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx++)
9116 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
9118 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
9127 EVT VT =
N->getValueType(0);
9129 EVT WideVT =
Op.getValueType();
9131 SDNodeFlags
Flags =
N->getFlags();
9133 unsigned Opc =
N->getOpcode();
9135 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
9145 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
9148 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
9149 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
9155 unsigned GCD = std::gcd(OrigElts, WideElts);
9158 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
9159 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx =
Idx + GCD)
9160 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
9161 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
9164 for (
unsigned Idx = OrigElts;
Idx < WideElts;
Idx++)
9165 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
9167 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
9171 assert(
N->isVPOpcode() &&
"Expected VP opcode");
9174 SDValue Op = GetWidenedVector(
N->getOperand(1));
9176 Op.getValueType().getVectorElementCount());
9178 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
9179 {N->getOperand(0), Op, Mask, N->getOperand(3)},
9187 EVT VT =
N->getValueType(0);
9191 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
9192 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
9197 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
9203 EVT SourceVT =
Source.getValueType();
9204 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9208 WideSource = GetWidenedVector(Source);
9215 WideSource = GetWidenedVector(Source);
9217 SmallVector<int>
Mask(WideElts);
9218 std::iota(
Mask.begin(),
Mask.end(), 0);
9220 Mask[
I] += WideElts;
9221 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
9223 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
9227 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
9234 EVT SrcVT =
Source.getValueType();
9238 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
9239 {Source, Mask, N->getOperand(2)},
N->getFlags());
9242SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
9245 EVT OrigMaskVT =
Mask.getValueType();
9246 SDValue WideMask = GetWidenedVector(Mask);
9252 if (OrigElts != WideElts) {
9253 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
9255 Mask, DAG.getVectorIdxConstant(0,
DL));
9262SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_SHUFFLE_VAR(
SDNode *
N,
9266 assert(OpNo == 1 &&
"Illegal operand must be mask");
9268 return TLI.expandVECTOR_SHUFFLE_VAR(
N, DAG);
9271SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
9274 EVT ResVT =
N->getValueType(0);
9275 EVT SourceVT =
N->getOperand(0).getValueType();
9276 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9281 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
9282 N->getOperand(0), 0);
9283 SDValue WideMask = DAG.getInsertSubvector(
9284 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
9286 N->getOperand(1), WideMask,
N->getFlags());
9287 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
9291 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
9297 return TLI.expandVectorMatch(
N, DAG);
9299 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
9303 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
9304 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
9307 N->getOperand(0), WideNeedle,
N->getOperand(2),
9325 unsigned WidenEx = 0) {
9330 unsigned AlignInBits =
Align*8;
9332 EVT RetVT = WidenEltVT;
9337 if (Width == WidenEltWidth)
9348 (WidenWidth % MemVTWidth) == 0 &&
9350 (MemVTWidth <= Width ||
9351 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9352 if (MemVTWidth == WidenWidth)
9371 (WidenWidth % MemVTWidth) == 0 &&
9373 (MemVTWidth <= Width ||
9374 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9383 return std::nullopt;
9394 unsigned Start,
unsigned End) {
9395 SDLoc dl(LdOps[Start]);
9396 EVT LdTy = LdOps[Start].getValueType();
9404 for (
unsigned i = Start + 1; i !=
End; ++i) {
9405 EVT NewLdTy = LdOps[i].getValueType();
9406 if (NewLdTy != LdTy) {
9425 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9426 EVT LdVT =
LD->getMemoryVT();
9436 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9440 TypeSize WidthDiff = WidenWidth - LdWidth;
9447 std::optional<EVT> FirstVT =
9448 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
9455 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
9460 std::optional<EVT> NewVT = FirstVT;
9461 TypeSize RemainingWidth = LdWidth;
9462 TypeSize NewVTWidth = FirstVTWidth;
9464 RemainingWidth -= NewVTWidth;
9471 NewVTWidth = NewVT->getSizeInBits();
9477 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9491 MachinePointerInfo MPI =
LD->getPointerInfo();
9497 for (EVT MemVT : MemVTs) {
9498 Align NewAlign = ScaledOffset == 0
9499 ?
LD->getBaseAlign()
9501 SDValue L = DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags,
9521 EVT LdTy = LdOps[i].getValueType();
9524 for (--i; i >= 0; --i) {
9525 LdTy = LdOps[i].getValueType();
9532 ConcatOps[--
Idx] = LdOps[i];
9533 for (--i; i >= 0; --i) {
9534 EVT NewLdTy = LdOps[i].getValueType();
9535 if (NewLdTy != LdTy) {
9546 WidenOps[j] = ConcatOps[Idx+j];
9548 WidenOps[j] = DAG.getPOISON(LdTy);
9555 ConcatOps[--
Idx] = LdOps[i];
9566 SDValue UndefVal = DAG.getPOISON(LdTy);
9569 for (; i !=
End-
Idx; ++i)
9570 WidenOps[i] = ConcatOps[Idx+i];
9572 WidenOps[i] = UndefVal;
9583 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9584 EVT LdVT =
LD->getMemoryVT();
9593 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9607 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9608 LdEltVT,
LD->getBaseAlign(), MMOFlags,
Metadata);
9614 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9615 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9621 SDValue UndefVal = DAG.getPOISON(EltVT);
9622 for (; i != WidenNumElts; ++i)
9625 return DAG.getBuildVector(WidenVT, dl,
Ops);
9636 MMOMetadata
Metadata =
ST->getMMOMetadataForSubAccess();
9637 SDValue ValOp = GetWidenedVector(
ST->getValue());
9640 EVT StVT =
ST->getMemoryVT();
9648 "Mismatch between store and value types");
9652 MachinePointerInfo MPI =
ST->getPointerInfo();
9662 std::optional<EVT> NewVT =
9667 TypeSize NewVTWidth = NewVT->getSizeInBits();
9670 StWidth -= NewVTWidth;
9671 MemVTs.
back().second++;
9675 for (
const auto &Pair : MemVTs) {
9676 EVT NewVT = Pair.first;
9677 unsigned Count = Pair.second;
9683 Align NewAlign = ScaledOffset == 0
9684 ?
ST->getBaseAlign()
9686 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9687 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9703 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9705 DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
ST->getBaseAlign(),
9723 bool FillWithZeroes) {
9728 "input and widen element type must match");
9730 "cannot modify scalable vectors in this way");
9743 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9745 for (
unsigned i = 1; i != NumConcat; ++i)
9752 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9758 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9763 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9764 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9766 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9768 unsigned NumResultParts = NewNumElts / CommonFactor;
9769 if (NumResultParts > NumCopiedParts) {
9770 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9771 : DAG.getPOISON(PartVT);
9772 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9779 "Scalable vectors should have been handled already.");
9787 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9789 for (Idx = 0;
Idx < MinNumElts; ++
Idx)
9790 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9792 SDValue UndefVal = DAG.getPOISON(EltVT);
9793 for (;
Idx < WidenNumElts; ++
Idx)
9794 Ops[Idx] = UndefVal;
9796 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9797 if (!FillWithZeroes)
9801 "We expect to never want to FillWithZeroes for non-integral types.");
9804 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9805 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9807 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9808 DAG.getBuildVector(NVT, dl, MaskOps));
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT, TypeSize FirstVTWidth, const SDLoc &dl, SelectionDAG &DAG)
Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the widened value so it can b...
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
SmallVector< MachineOperand, 4 > Cond
const MachineOperand & HiOp1
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file implements the SmallBitVector class.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
constexpr bool isScalar() const
Exactly one element.
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
const MDNode * getMemCacheHint() const
Returns the cache hint metadata for this memory access.
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
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtractVectorElt(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Extract element at Idx from Vec.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
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*X will result in a value whose quantity matches our ...
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*X will result in a value whose quantity matches our own.
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.
constexpr bool isZero() const
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 ...
@ ATOMIC_LOAD_FMINIMUMNUM
@ LOOP_DEPENDENCE_RAW_MASK
@ MASK_BEFOREFIRST
Has one mask vector operand.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ AVGSUBFLOORS
AVGSUBFLOORS/AVGSUBFLOORU - Averaging subtract - Subtract two integers using an integer of type i[N+1...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ VECTOR_SHUFFLE_VAR
VECTOR_SHUFFLE_VAR(VEC, MASK) - Returns VEC permuted by MASK, an integer vector with the same number ...
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ VECREDUCE_FMAXIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM nodes do not propagate NaNs and order signed zeroes using the llvm....
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Same as FMINNUM/FMAXNUM, except that a signaling NaN operand deterministi...
@ 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 - Same semantics as the llvm.minnum/maxnum intrinsics.
@ 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...
@ ATOMIC_LOAD_FMAXIMUMNUM
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - Same semantics as the llvm.minimum/maximum intrinsics.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_MATCH
VECTOR_MATCH - this corresponds to the llvm.experimental.vector.match intrinsic.
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_REPEAT
VECTOR_REPEAT(FIXED_LENGTH_VECTOR) Repeatedly copies the elements of the source fixed-length vector t...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - Same semantics as the llvm.minimumnum/maximumnum intrinsics.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
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.
Type * getValueType(Value *V, bool ReVec, bool LookThroughCmp)
Returns the "element type" of the given value/instruction V.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
@ Mul
Product of integers.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
@ End
Run the machine verifier once, at the end of the pipeline.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
EVT changeVectorElementCount(LLVMContext &Context, ElementCount EC) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element coun...
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.