35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
47 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
50 switch (
N->getOpcode()) {
53 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
62 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
70 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
73 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
79 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
89 R = ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
N);
95 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
97 R = ScalarizeVecRes_VECTOR_MATCH(
N);
100 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
106 R = ScalarizeVecRes_VecInregOp(
N);
158 R = ScalarizeVecRes_UnaryOp(
N);
161 R = ScalarizeVecRes_ADDRSPACECAST(
N);
167 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
226 R = ScalarizeVecRes_BinOp(
N);
233 R = ScalarizeVecRes_MaskedBinOp(
N);
238 R = ScalarizeVecRes_CMP(
N);
244 R = ScalarizeVecRes_TernaryOp(
N);
247#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
248 case ISD::STRICT_##DAGN:
249#include "llvm/IR/ConstrainedOps.def"
250 R = ScalarizeVecRes_StrictFPOp(
N);
255 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
264 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
274 R = ScalarizeVecRes_FIX(
N);
280 SetScalarizedVector(
SDValue(
N, ResNo), R);
284 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
285 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
286 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
292 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
293 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
295 EVT MaskVT =
Mask.getValueType();
300 Mask = GetScalarizedVector(Mask);
309 DAG.getConstant(1,
DL,
LHS.getValueType()));
311 LHS.getValueType(),
LHS, Divisor);
319 if (getTypeAction(
LHS.getValueType()) ==
321 LHS = GetScalarizedVector(
LHS);
322 RHS = GetScalarizedVector(
RHS);
324 EVT VT =
LHS.getValueType().getVectorElementType();
325 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
326 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
329 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
330 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
334 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
335 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
336 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
337 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
342 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
343 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
350DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
352 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
353 "Unexpected vector type!");
354 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
356 EVT VT0 =
N->getValueType(0);
357 EVT VT1 =
N->getValueType(1);
361 DAG.getNode(
N->getOpcode(), dl,
362 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
366 unsigned OtherNo = 1 - ResNo;
367 EVT OtherVT =
N->getValueType(OtherNo);
369 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
373 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
376 return SDValue(ScalarNode, ResNo);
381 unsigned NumOpers =
N->getNumOperands();
383 EVT ValueVTs[] = {VT, MVT::Other};
392 for (
unsigned i = 1; i < NumOpers; ++i) {
398 Oper = GetScalarizedVector(Oper);
407 SDValue Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
408 Opers,
N->getFlags());
419 EVT ResVT =
N->getValueType(0);
420 EVT OvVT =
N->getValueType(1);
424 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
425 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
428 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
429 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
430 ScalarLHS = ElemsLHS[0];
431 ScalarRHS = ElemsRHS[0];
434 SDVTList ScalarVTs = DAG.getVTList(
436 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
437 {ScalarLHS, ScalarRHS},
N->getFlags())
441 unsigned OtherNo = 1 - ResNo;
442 EVT OtherVT =
N->getValueType(OtherNo);
444 SetScalarizedVector(
SDValue(
N, OtherNo),
SDValue(ScalarNode, OtherNo));
448 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
451 return SDValue(ScalarNode, ResNo);
456 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
457 return GetScalarizedVector(
Op);
460SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
465 N->getValueType(0).getScalarType(), Mask,
466 DAG.getVectorIdxConstant(0,
DL));
472 Op = GetScalarizedVector(
Op);
473 EVT NewVT =
N->getValueType(0).getVectorElementType();
478SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
488SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
490 N->getValueType(0).getVectorElementType(),
491 N->getOperand(0),
N->getOperand(1));
497 EVT OpVT =
Op.getValueType();
501 Op = GetScalarizedVector(
Op);
504 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
507 N->getValueType(0).getVectorElementType(),
Op,
511SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
514 EVT OpVT =
Op.getValueType();
518 Op = GetScalarizedVector(
Op);
521 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
524 N->getValueType(0).getVectorElementType(),
Op,
528SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
531 EVT OpVT =
Op.getValueType();
534 Op = GetScalarizedVector(
Op);
537 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
540 N->getValueType(0).getVectorElementType(),
Op,
541 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
544SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
545 SDValue Op = GetScalarizedVector(
N->getOperand(0));
546 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
550SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
555 if (
Op.getValueType() != EltVT)
563 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
564 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
574 assert(
N->isUnindexed() &&
"Indexed vector load?");
578 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
579 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
580 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
581 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
593 EVT OpVT =
Op.getValueType();
603 Op = GetScalarizedVector(
Op);
606 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
608 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
614 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
615 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
616 LHS, DAG.getValueType(ExtVT));
623 EVT OpVT =
Op.getValueType();
628 Op = GetScalarizedVector(
Op);
630 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
633 switch (
N->getOpcode()) {
645SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
648 EVT OpVT =
Op.getValueType();
658 Op = GetScalarizedVector(
Op);
661 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
664 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
665 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
666 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS,
667 AddrSpaceCastN->getFlags());
670SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
681DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
682 assert(
N->getNumValues() ==
N->getNumOperands() &&
683 "Expected one result per operand");
687 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
688 SetScalarizedVector(
SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
694 EVT OpVT =
Cond.getValueType();
703 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
706 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
708 TLI.getBooleanContents(
false,
false);
715 if (TLI.getBooleanContents(
false,
false) !=
716 TLI.getBooleanContents(
false,
true)) {
720 EVT OpVT =
Cond->getOperand(0).getValueType();
722 VecBool = TLI.getBooleanContents(OpVT);
727 EVT CondVT =
Cond.getValueType();
728 if (ScalarBool != VecBool) {
729 switch (ScalarBool) {
737 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
744 Cond, DAG.getValueType(MVT::i1));
750 auto BoolVT = getSetCCResultType(CondVT);
751 if (BoolVT.bitsLT(CondVT))
754 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
755 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
759 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
760 return DAG.getSelect(SDLoc(
N),
761 LHS.getValueType(),
N->getOperand(0),
LHS,
762 GetScalarizedVector(
N->getOperand(2)));
766 SDValue LHS = GetScalarizedVector(
N->getOperand(2));
768 N->getOperand(0),
N->getOperand(1),
769 LHS, GetScalarizedVector(
N->getOperand(3)),
774 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
777SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
781 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
783 return GetScalarizedVector(
N->getOperand(
Op));
786SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
788 EVT SrcVT = Src.getValueType();
793 Src = GetScalarizedVector(Src);
797 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
799 EVT DstVT =
N->getValueType(0).getVectorElementType();
800 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
804 assert(
N->getValueType(0).isVector() &&
805 N->getOperand(0).getValueType().isVector() &&
806 "Operand types must be vectors");
809 EVT OpVT =
LHS.getValueType();
810 EVT NVT =
N->getValueType(0).getVectorElementType();
815 LHS = GetScalarizedVector(
LHS);
816 RHS = GetScalarizedVector(
RHS);
819 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
820 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
830 return DAG.getNode(ExtendCode,
DL, NVT, Res);
841 Arg = GetScalarizedVector(Arg);
844 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
853 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
860bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
866 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
869 switch (
N->getOpcode()) {
872 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
879 Res = ScalarizeVecOp_BITCAST(
N);
882 Res = ScalarizeVecOp_FAKE_USE(
N);
896 Res = ScalarizeVecOp_UnaryOp(
N);
901 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
904 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
905 "Unexpected vector type!");
906 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
908 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
909 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
917 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
920 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
923 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
926 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
929 Res = ScalarizeVecOp_VSELECT(
N);
932 Res = ScalarizeVecOp_VSETCC(
N);
936 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
945 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
948 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
951 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
954 Res = ScalarizeVecOp_FP_EXTEND(
N);
973 Res = ScalarizeVecOp_VECREDUCE(
N);
977 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
981 Res = ScalarizeVecOp_CMP(
N);
984 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
988 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
991 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
997 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
1002 if (!Res.
getNode())
return false;
1010 "Invalid operand expansion");
1012 ReplaceValueWith(
SDValue(
N, 0), Res);
1019 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1021 N->getValueType(0), Elt);
1026 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1027 "Fake Use: Unexpected vector type!");
1028 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1029 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1035 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1036 "Unexpected vector type!");
1037 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1038 SDValue Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1039 N->getValueType(0).getScalarType(), Elt);
1047SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1048 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1049 "Unexpected vector type!");
1050 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1052 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1053 Elt,
N->getOperand(1));
1061SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1062 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1063 "Unexpected vector type!");
1064 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1066 {
N->getValueType(0).getScalarType(), MVT::Other },
1067 {
N->getOperand(0), Elt });
1077 ReplaceValueWith(
SDValue(
N, 0), Res);
1082SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1084 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1085 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1086 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1091SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1095 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1096 SDValue ContainingVec =
N->getOperand(0);
1104SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1105 EVT VT =
N->getValueType(0);
1106 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1118 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1119 EVT VT =
N->getValueType(0);
1121 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1130 assert(
N->getValueType(0).isVector() &&
1131 N->getOperand(0).getValueType().isVector() &&
1132 "Operand types must be vectors");
1133 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1134 "Expected single-element vector type");
1136 EVT VT =
N->getValueType(0);
1137 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1138 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1140 EVT OpVT =
N->getOperand(0).getValueType();
1152 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1158SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1160 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1161 assert(
N->getValueType(0).isVector() &&
1162 N->getOperand(1).getValueType().isVector() &&
1163 "Operand types must be vectors");
1164 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1165 "Expected single-element vector type");
1167 EVT VT =
N->getValueType(0);
1169 SDValue LHS = GetScalarizedVector(
N->getOperand(1));
1170 SDValue RHS = GetScalarizedVector(
N->getOperand(2));
1173 EVT OpVT =
N->getOperand(1).getValueType();
1177 {Ch, LHS, RHS, CC});
1186 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1191 ReplaceValueWith(
SDValue(
N, 0), Res);
1198 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1199 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1202 if (
N->isTruncatingStore())
1203 return DAG.getTruncStore(
1204 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1205 N->getBasePtr(),
N->getPointerInfo(),
1206 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1207 N->getMemOperand()->getFlags(),
N->getAAInfo());
1209 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1210 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1211 N->getMemOperand()->getFlags(),
N->getAAInfo());
1217 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1219 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1220 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1225SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1226 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1227 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1229 N->getValueType(0).getVectorElementType(), Elt,
1234SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1236 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1237 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1240 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1250 ReplaceValueWith(
SDValue(
N, 0), Res);
1257 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1259 N->getValueType(0).getVectorElementType(), Elt);
1265SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1266 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1269 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1270 {
N->getOperand(0), Elt});
1279 ReplaceValueWith(
SDValue(
N, 0), Res);
1284 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1291SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1297 SDValue Op = GetScalarizedVector(VecOp);
1298 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1299 AccOp,
Op,
N->getFlags());
1303 SDValue LHS = GetScalarizedVector(
N->getOperand(0));
1304 SDValue RHS = GetScalarizedVector(
N->getOperand(1));
1311SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1319 EVT VT =
N->getValueType(0);
1320 return DAG.getConstant(0, SDLoc(
N), VT);
1327 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1328 SDValue Op = GetScalarizedVector(
N->getOperand(0));
1330 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1331 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1332 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1335SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1340 N->getValueType(0).getScalarType(), Mask,
1341 DAG.getVectorIdxConstant(0,
DL));
1346 return TLI.expandVectorMatch(
N, DAG);
1349SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1350 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1353 SDValue LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1354 SDValue RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1363 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1375void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1380 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1383 switch (
N->getOpcode()) {
1386 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1395 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1402 case ISD::VP_MERGE: SplitRes_Select(
N,
Lo,
Hi);
break;
1418 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1421 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1433 case ISD::VP_LOAD_FF:
1436 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1443 case ISD::VP_GATHER:
1447 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1450 SplitVecRes_SETCC(
N,
Lo,
Hi);
1453 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1460 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1463 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1466 SplitVecRes_VECTOR_INTERLEAVE(
N);
1469 SplitVecRes_VAARG(
N,
Lo,
Hi);
1475 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1529 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1532 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1538 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1544 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1600 SplitVecRes_BinOp(
N,
Lo,
Hi);
1606 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1611 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1615 SplitVecRes_CMP(
N,
Lo,
Hi);
1618#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1619 case ISD::STRICT_##DAGN:
1620#include "llvm/IR/ConstrainedOps.def"
1621 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1626 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1635 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1645 SplitVecRes_FIX(
N,
Lo,
Hi);
1647 case ISD::EXPERIMENTAL_VP_SPLICE:
1648 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1650 case ISD::EXPERIMENTAL_VP_REVERSE:
1651 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1657 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1660 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1663 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1672void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1679 SDValue BytesIncrement = DAG.getVScale(
1682 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1684 *ScaledOffset += IncrementSize;
1694std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1695 return SplitMask(Mask, SDLoc(Mask));
1698std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1701 EVT MaskVT =
Mask.getValueType();
1703 GetSplitVector(Mask, MaskLo, MaskHi);
1705 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1706 return std::make_pair(MaskLo, MaskHi);
1711 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1713 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1716 const SDNodeFlags
Flags =
N->getFlags();
1717 unsigned Opcode =
N->getOpcode();
1718 if (
N->getNumOperands() == 2) {
1719 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1720 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1724 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1725 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
1726 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
1727 "Expected VP opcode");
1730 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1733 std::tie(EVLLo, EVLHi) =
1734 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1737 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1739 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1745 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1747 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1751 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1753 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1757 const SDNodeFlags
Flags =
N->getFlags();
1758 unsigned Opcode =
N->getOpcode();
1759 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1761 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1768 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1770 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1772 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1775 const SDNodeFlags
Flags =
N->getFlags();
1776 unsigned Opcode =
N->getOpcode();
1778 DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1780 DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1784 LLVMContext &Ctxt = *DAG.getContext();
1790 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1792 GetSplitVector(
LHS, LHSLo, LHSHi);
1793 GetSplitVector(
RHS, RHSLo, RHSHi);
1795 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1796 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1800 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1801 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1806 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1808 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1812 unsigned Opcode =
N->getOpcode();
1813 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1815 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1824 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1831 switch (getTypeAction(InVT)) {
1845 GetExpandedOp(InOp,
Lo,
Hi);
1846 if (DAG.getDataLayout().isBigEndian())
1856 GetSplitVector(InOp,
Lo,
Hi);
1865 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1874 if (DAG.getDataLayout().isBigEndian())
1877 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1879 if (DAG.getDataLayout().isBigEndian())
1885void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1891 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1894 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1899 unsigned LaneOffset =
1902 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1904 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1911 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1914 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1917 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1922 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1924 unsigned NumSubvectors =
N->getNumOperands() / 2;
1925 if (NumSubvectors == 1) {
1926 Lo =
N->getOperand(0);
1927 Hi =
N->getOperand(1);
1932 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1941void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1948 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1963 GetSplitVector(Vec,
Lo,
Hi);
1966 EVT LoVT =
Lo.getValueType();
1976 if (IdxVal + SubElems <= LoElems) {
1984 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1986 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1992 SDValue WideSubVec = GetWidenedVector(SubVec);
1994 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2002 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2004 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2005 auto &MF = DAG.getMachineFunction();
2009 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2014 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2015 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2019 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2024 MachinePointerInfo MPI =
Load->getPointerInfo();
2025 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2028 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2037 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2042 EVT RHSVT =
RHS.getValueType();
2045 GetSplitVector(
RHS, RHSLo, RHSHi);
2047 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2062 SDValue FpValue =
N->getOperand(0);
2064 GetSplitVector(FpValue, ArgLo, ArgHi);
2066 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2068 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2077 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2081 std::tie(LoVT, HiVT) =
2085 DAG.getValueType(LoVT));
2087 DAG.getValueType(HiVT));
2092 unsigned Opcode =
N->getOpcode();
2099 GetSplitVector(N0, InLo, InHi);
2101 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2106 EVT OutLoVT, OutHiVT;
2107 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2109 assert((2 * OutNumElements) <= InNumElements &&
2110 "Illegal extend vector in reg split");
2119 SmallVector<int, 8> SplitHi(InNumElements, -1);
2120 for (
unsigned i = 0; i != OutNumElements; ++i)
2121 SplitHi[i] = i + OutNumElements;
2122 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2124 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2125 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2130 unsigned NumOps =
N->getNumOperands();
2134 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2144 for (
unsigned i = 1; i <
NumOps; ++i) {
2149 EVT InVT =
Op.getValueType();
2154 GetSplitVector(
Op, OpLo, OpHi);
2156 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2163 EVT LoValueVTs[] = {LoVT, MVT::Other};
2164 EVT HiValueVTs[] = {HiVT, MVT::Other};
2165 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2167 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2173 Lo.getValue(1),
Hi.getValue(1));
2177 ReplaceValueWith(
SDValue(
N, 1), Chain);
2180SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2182 EVT VT =
N->getValueType(0);
2193 else if (NE > ResNE)
2197 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2201 for (i = 0; i !=
NE; ++i) {
2203 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2204 SDValue Operand =
N->getOperand(j);
2208 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2214 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2222 for (; i < ResNE; ++i)
2223 Scalars.
push_back(DAG.getPOISON(EltVT));
2227 ReplaceValueWith(
SDValue(
N, 1), Chain);
2231 return DAG.getBuildVector(VecVT, dl, Scalars);
2234void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2237 EVT ResVT =
N->getValueType(0);
2238 EVT OvVT =
N->getValueType(1);
2239 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2240 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2241 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2243 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2245 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2246 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2248 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2249 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2252 unsigned Opcode =
N->getOpcode();
2253 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2254 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2256 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2258 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2264 unsigned OtherNo = 1 - ResNo;
2265 EVT OtherVT =
N->getValueType(OtherNo);
2267 SetSplitVector(
SDValue(
N, OtherNo),
2273 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
2277void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2283 GetSplitVector(Vec,
Lo,
Hi);
2286 unsigned IdxVal = CIdx->getZExtValue();
2287 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2288 if (IdxVal < LoNumElts) {
2290 Lo.getValueType(),
Lo, Elt, Idx);
2293 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2313 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2315 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2316 auto &MF = DAG.getMachineFunction();
2320 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2325 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2326 Store = DAG.getTruncStore(
2332 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2335 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2339 MachinePointerInfo MPI =
Load->getPointerInfo();
2340 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2342 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2345 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2346 if (LoVT !=
Lo.getValueType())
2348 if (HiVT !=
Hi.getValueType())
2356 assert(
N->getValueType(0).isScalableVector() &&
2357 "Only scalable vectors are supported for STEP_VECTOR");
2358 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2379 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2380 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2382 Hi = DAG.getPOISON(HiVT);
2392 "Extended load during type legalization!");
2394 EVT VT =
LD->getValueType(0);
2396 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2404 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2405 Ch, Ptr,
LD->getMemOperand());
2410 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2412 Lo = DAG.getBitcast(LoVT, ExtractLo);
2413 Hi = DAG.getBitcast(HiVT, ExtractHi);
2425 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2431 EVT MemoryVT =
LD->getMemoryVT();
2433 AAMDNodes AAInfo =
LD->getAAInfo();
2435 EVT LoMemVT, HiMemVT;
2436 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2440 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2441 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2442 ReplaceValueWith(
SDValue(LD, 1), NewChain);
2447 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2450 MachinePointerInfo MPI;
2451 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2454 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2463 ReplaceValueWith(
SDValue(LD, 1), Ch);
2468 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2471 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2477 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2481 EVT MemoryVT =
LD->getMemoryVT();
2483 EVT LoMemVT, HiMemVT;
2484 bool HiIsEmpty =
false;
2485 std::tie(LoMemVT, HiMemVT) =
2486 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2491 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2494 GetSplitVector(Mask, MaskLo, MaskHi);
2496 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2501 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2503 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2506 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2509 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2510 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2518 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2519 LD->isExpandingLoad());
2521 MachinePointerInfo MPI;
2523 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2525 MPI =
LD->getPointerInfo().getWithOffset(
2528 MMO = DAG.getMachineFunction().getMachineMemOperand(
2530 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2532 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2533 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2534 LD->isExpandingLoad());
2544 ReplaceValueWith(
SDValue(LD, 1), Ch);
2550 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2561 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2564 GetSplitVector(Mask, MaskLo, MaskHi);
2566 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2570 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2572 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2575 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2577 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2580 Hi = DAG.getPOISON(HiVT);
2582 ReplaceValueWith(
SDValue(LD, 1),
Lo.getValue(1));
2583 ReplaceValueWith(
SDValue(LD, 2),
Lo.getValue(2));
2589 "Indexed VP strided load during type legalization!");
2591 "Unexpected indexed variable-length load offset");
2596 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2598 EVT LoMemVT, HiMemVT;
2599 bool HiIsEmpty =
false;
2600 std::tie(LoMemVT, HiMemVT) =
2601 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2606 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2609 GetSplitVector(Mask, LoMask, HiMask);
2611 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2615 std::tie(LoEVL, HiEVL) =
2619 Lo = DAG.getStridedLoadVP(
2646 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2653 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2664 ReplaceValueWith(
SDValue(SLD, 1), Ch);
2672 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2677 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2687 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2690 GetSplitVector(Mask, MaskLo, MaskHi);
2692 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2696 EVT LoMemVT, HiMemVT;
2697 bool HiIsEmpty =
false;
2698 std::tie(LoMemVT, HiMemVT) =
2699 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2701 SDValue PassThruLo, PassThruHi;
2703 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2705 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2707 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2712 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2722 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2725 MachinePointerInfo MPI;
2732 MMO = DAG.getMachineFunction().getMachineMemOperand(
2737 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2749 ReplaceValueWith(
SDValue(MLD, 1), Ch);
2757 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2767 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2770 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2773 EVT MemoryVT =
N->getMemoryVT();
2779 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2781 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2784 EVT LoMemVT, HiMemVT;
2786 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2789 if (getTypeAction(
Ops.Index.getValueType()) ==
2791 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2793 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2796 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2798 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2801 SDValue PassThru = MGT->getPassThru();
2802 SDValue PassThruLo, PassThruHi;
2805 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2807 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2812 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2813 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2814 OpsLo, MMO, IndexTy, ExtType);
2816 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2817 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2818 OpsHi, MMO, IndexTy, ExtType);
2822 std::tie(EVLLo, EVLHi) =
2823 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2825 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2826 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2827 MMO, VPGT->getIndexType());
2829 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2830 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2831 MMO, VPGT->getIndexType());
2841 ReplaceValueWith(
SDValue(
N, 1), Ch);
2855 EVT VecVT =
N->getValueType(0);
2857 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2858 bool HasCustomLowering =
false;
2865 HasCustomLowering =
true;
2871 SDValue Passthru =
N->getOperand(2);
2872 if (!HasCustomLowering) {
2873 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2874 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2881 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2882 std::tie(LoMask, HiMask) = SplitMask(Mask);
2884 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2889 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2902 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2904 SDValue Chain = DAG.getEntryNode();
2905 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2909 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2913 EVT MaskVT =
Mask.getValueType();
2920 SDValue StepVector = DAG.getStepVector(
DL, WideMaskVT);
2921 SDValue SplatNumActiveElts = DAG.getSplat(WideMaskVT,
DL, NumActiveElts);
2923 DAG.getSetCC(
DL, MaskVT, StepVector, SplatNumActiveElts,
ISD::SETULT);
2926 Compressed, Passthru);
2928 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2932 assert(
N->getValueType(0).isVector() &&
2933 N->getOperand(0).getValueType().isVector() &&
2934 "Operand types must be vectors");
2938 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2942 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2944 GetSplitVector(
N->getOperand(0), LL, LH);
2946 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2948 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2950 GetSplitVector(
N->getOperand(1), RL, RH);
2952 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2954 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2955 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2963 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2967 EVT InVT =
N->getOperand(0).getValueType();
2969 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2971 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2973 const SDNodeFlags
Flags =
N->getFlags();
2974 unsigned Opcode =
N->getOpcode();
2976 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
2977 N->getOperand(3), Flags);
2978 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
2979 N->getOperand(3), Flags);
2985 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2986 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2988 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2989 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2996 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3000 EVT InVT =
N->getOperand(0).getValueType();
3002 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3004 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3007 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3008 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3009 SDNodeFlags
Flags = AddrSpaceCastN->getFlags();
3010 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS, Flags);
3011 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS, Flags);
3014void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3019 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3020 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3024 EVT InVT =
N->getOperand(0).getValueType();
3026 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3028 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3030 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3031 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3033 SDNode *HiNode =
Hi.getNode();
3034 SDNode *LoNode =
Lo.getNode();
3037 unsigned OtherNo = 1 - ResNo;
3038 EVT OtherVT =
N->getValueType(OtherNo);
3046 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
3053 EVT SrcVT =
N->getOperand(0).getValueType();
3054 EVT DestVT =
N->getValueType(0);
3056 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3073 LLVMContext &Ctx = *DAG.getContext();
3077 EVT SplitLoVT, SplitHiVT;
3078 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3079 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3080 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3081 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3082 N->dump(&DAG);
dbgs() <<
"\n");
3085 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3087 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3089 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3090 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3095 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3103 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3104 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3110 return N.getResNo() == 0 &&
3114 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](
SDValue &Input1,
3116 ArrayRef<int>
Mask) {
3119 "Expected build vector node.");
3122 for (
unsigned I = 0;
I < NewElts; ++
I) {
3125 unsigned Idx =
Mask[
I];
3127 Ops[
I] = Input2.getOperand(Idx - NewElts);
3129 Ops[
I] = Input1.getOperand(Idx);
3134 return DAG.getBuildVector(NewVT,
DL,
Ops);
3140 SmallVector<int> OrigMask(
N->getMask());
3142 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3143 &
DL](SmallVectorImpl<int> &
Mask) {
3145 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3146 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3157 for (
auto &
P : ShufflesIdxs) {
3158 if (
P.second.size() < 2)
3162 for (
int &Idx : Mask) {
3165 unsigned SrcRegIdx = Idx / NewElts;
3166 if (Inputs[SrcRegIdx].
isUndef()) {
3174 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3179 Idx = MaskElt % NewElts +
3180 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3186 Inputs[
P.second[0]] =
P.first.first;
3187 Inputs[
P.second[1]] =
P.first.second;
3190 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3193 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3194 for (
int &Idx : Mask) {
3197 unsigned SrcRegIdx = Idx / NewElts;
3198 if (Inputs[SrcRegIdx].
isUndef()) {
3205 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3206 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3209 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3211 if (UsedSubVector.count() > 1) {
3213 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3214 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3216 if (Pairs.
empty() || Pairs.
back().size() == 2)
3218 if (UsedSubVector.test(2 *
I)) {
3219 Pairs.
back().emplace_back(
I, 0);
3221 assert(UsedSubVector.test(2 *
I + 1) &&
3222 "Expected to be used one of the subvectors.");
3223 Pairs.
back().emplace_back(
I, 1);
3226 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3228 for (
int &Idx : Mask) {
3231 unsigned SrcRegIdx = Idx / NewElts;
3233 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3234 return Idxs.front().first == SrcRegIdx ||
3235 Idxs.back().first == SrcRegIdx;
3237 if (It == Pairs.
end())
3239 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3240 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3243 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3244 Inputs[Idxs.front().first] = DAG.
getNode(
3246 Inputs[Idxs.front().first].getValueType(),
3247 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3248 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3257 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3261 if (Shuffle->getOperand(0).getValueType() != NewVT)
3264 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3265 !Shuffle->isSplat()) {
3267 }
else if (!Inputs[
I].hasOneUse() &&
3268 !Shuffle->getOperand(1).isUndef()) {
3270 for (
int &Idx : Mask) {
3273 unsigned SrcRegIdx = Idx / NewElts;
3276 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3281 int OpIdx = MaskElt / NewElts;
3294 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3295 if (Shuffle->getOperand(OpIdx).isUndef())
3297 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3298 if (It == std::end(Inputs))
3300 int FoundOp = std::distance(std::begin(Inputs), It);
3303 for (
int &Idx : Mask) {
3306 unsigned SrcRegIdx = Idx / NewElts;
3309 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3314 int MaskIdx = MaskElt / NewElts;
3315 if (OpIdx == MaskIdx)
3316 Idx = MaskElt % NewElts + FoundOp * NewElts;
3319 Op = (OpIdx + 1) % 2;
3327 for (
int &Idx : Mask) {
3330 unsigned SrcRegIdx = Idx / NewElts;
3333 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3334 int OpIdx = MaskElt / NewElts;
3337 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3343 TryPeekThroughShufflesInputs(OrigMask);
3345 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3346 NewElts](SmallVectorImpl<int> &
Mask) {
3347 SetVector<SDValue> UniqueInputs;
3348 SetVector<SDValue> UniqueConstantInputs;
3349 for (
const auto &
I : Inputs) {
3351 UniqueConstantInputs.
insert(
I);
3352 else if (!
I.isUndef())
3357 if (UniqueInputs.
size() != std::size(Inputs)) {
3358 auto &&UniqueVec = UniqueInputs.
takeVector();
3359 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3360 unsigned ConstNum = UniqueConstantVec.size();
3361 for (
int &Idx : Mask) {
3364 unsigned SrcRegIdx = Idx / NewElts;
3365 if (Inputs[SrcRegIdx].
isUndef()) {
3369 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3370 if (It != UniqueConstantVec.end()) {
3371 Idx = (Idx % NewElts) +
3372 NewElts * std::distance(UniqueConstantVec.begin(), It);
3373 assert(Idx >= 0 &&
"Expected defined mask idx.");
3376 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3377 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3378 Idx = (Idx % NewElts) +
3379 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3380 assert(Idx >= 0 &&
"Expected defined mask idx.");
3382 copy(UniqueConstantVec, std::begin(Inputs));
3383 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3386 MakeUniqueInputs(OrigMask);
3388 copy(Inputs, std::begin(OrigInputs));
3394 unsigned FirstMaskIdx =
High * NewElts;
3397 assert(!Output &&
"Expected default initialized initial value.");
3398 TryPeekThroughShufflesInputs(Mask);
3399 MakeUniqueInputs(Mask);
3401 copy(Inputs, std::begin(TmpInputs));
3404 bool SecondIteration =
false;
3405 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3410 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3411 SecondIteration =
true;
3412 return SecondIteration;
3415 Mask, std::size(Inputs), std::size(Inputs),
3417 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3418 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3419 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3421 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3423 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3424 DAG.getPOISON(NewVT), Mask);
3425 Inputs[Idx] = Output;
3427 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3428 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3429 unsigned Idx2,
bool ) {
3430 if (AccumulateResults(Idx1)) {
3433 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3435 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3436 Inputs[Idx2], Mask);
3440 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3442 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3443 TmpInputs[Idx2], Mask);
3445 Inputs[Idx1] = Output;
3447 copy(OrigInputs, std::begin(Inputs));
3452 EVT OVT =
N->getValueType(0);
3460 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3462 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV,
Alignment.value());
3463 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV,
Alignment.value());
3468 ReplaceValueWith(
SDValue(
N, 1), Chain);
3473 EVT DstVTLo, DstVTHi;
3474 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3478 EVT SrcVT =
N->getOperand(0).getValueType();
3480 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3482 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3484 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3485 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3491 GetSplitVector(
N->getOperand(0), InLo, InHi);
3502 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3503 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3508 EVT VT =
N->getValueType(0);
3531 EVT PtrVT =
StackPtr.getValueType();
3532 auto &MF = DAG.getMachineFunction();
3536 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3539 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3545 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3546 DAG.getConstant(1,
DL, PtrVT));
3548 DAG.getConstant(EltWidth,
DL, PtrVT));
3550 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3552 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3553 SDValue Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3554 DAG.getPOISON(PtrVT), Stride, TrueMask,
3563 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3568 EVT VT =
N->getValueType(0);
3580 EVL1 = ZExtPromotedInteger(EVL1);
3599 EVT PtrVT =
StackPtr.getValueType();
3600 auto &MF = DAG.getMachineFunction();
3604 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3607 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3613 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3618 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3619 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3621 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3623 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3627 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3632 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3633 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3637 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3646 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3654 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3656 DAG.getVectorIdxConstant(0,
DL));
3662void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3670 GetSplitVector(Acc, AccLo, AccHi);
3671 unsigned Opcode =
N->getOpcode();
3683 GetSplitVector(Input1, Input1Lo, Input1Hi);
3684 GetSplitVector(Input2, Input2Lo, Input2Hi);
3687 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3688 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3691void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3699 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3710 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3712 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3716 N->getOperand(1), MaskLo,
N->getFlags());
3718 N->getOperand(1), MaskHi,
N->getFlags());
3721void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3722 unsigned Factor =
N->getNumOperands();
3725 for (
unsigned i = 0; i != Factor; ++i) {
3727 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3729 Ops[i * 2 + 1] = OpHi;
3740 for (
unsigned i = 0; i != Factor; ++i)
3744void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3745 unsigned Factor =
N->getNumOperands();
3748 for (
unsigned i = 0; i != Factor; ++i) {
3750 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3752 Ops[i + Factor] = OpHi;
3763 for (
unsigned i = 0; i != Factor; ++i) {
3764 unsigned IdxLo = 2 * i;
3765 unsigned IdxHi = 2 * i + 1;
3766 SetSplitVector(
SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3767 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3779bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3784 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3787 switch (
N->getOpcode()) {
3790 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3799 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3806 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3809 Res = SplitVecOp_TruncateHelper(
N);
3815 Res = SplitVecOp_FP_ROUND(
N);
3827 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3834 case ISD::VP_SCATTER:
3838 case ISD::VP_GATHER:
3842 Res = SplitVecOp_VSELECT(
N, OpNo);
3848 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3851 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3857 if (
N->getValueType(0).bitsLT(
3858 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3859 Res = SplitVecOp_TruncateHelper(
N);
3861 Res = SplitVecOp_UnaryOp(
N);
3865 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3881 Res = SplitVecOp_UnaryOp(
N);
3884 Res = SplitVecOp_FPOpDifferentTypes(
N);
3889 Res = SplitVecOp_CMP(
N);
3893 Res = SplitVecOp_FAKE_USE(
N);
3898 Res = SplitVecOp_ExtVecInRegOp(
N);
3918 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3922 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3924 case ISD::VP_REDUCE_FADD:
3925 case ISD::VP_REDUCE_SEQ_FADD:
3926 case ISD::VP_REDUCE_FMUL:
3927 case ISD::VP_REDUCE_SEQ_FMUL:
3928 case ISD::VP_REDUCE_ADD:
3929 case ISD::VP_REDUCE_MUL:
3930 case ISD::VP_REDUCE_AND:
3931 case ISD::VP_REDUCE_OR:
3932 case ISD::VP_REDUCE_XOR:
3933 case ISD::VP_REDUCE_SMAX:
3934 case ISD::VP_REDUCE_SMIN:
3935 case ISD::VP_REDUCE_UMAX:
3936 case ISD::VP_REDUCE_UMIN:
3937 case ISD::VP_REDUCE_FMAX:
3938 case ISD::VP_REDUCE_FMIN:
3939 case ISD::VP_REDUCE_FMAXIMUM:
3940 case ISD::VP_REDUCE_FMINIMUM:
3941 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3945 Res = SplitVecOp_CttzElts(
N);
3947 case ISD::VP_CTTZ_ELTS:
3948 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3949 Res = SplitVecOp_VP_CttzElements(
N);
3952 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3958 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3961 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
3966 if (!Res.
getNode())
return false;
3973 if (
N->isStrictFPOpcode())
3975 "Invalid operand expansion");
3978 "Invalid operand expansion");
3980 ReplaceValueWith(
SDValue(
N, 0), Res);
3984SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3988 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3990 EVT VT =
N->getValueType(0);
4003 getSetCCResultType(MVT::i1), MVT::i1);
4008 DAG.getElementCount(
DL, VT, SplitEC)),
4012SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4015 assert(OpNo == 0 &&
"Illegal operand must be mask");
4022 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4025 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4026 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4027 "Lo and Hi have differing types");
4030 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4031 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4033 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4034 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4035 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4036 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4046SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4047 assert(OpNo == 2 &&
"Illegal operand must be mask");
4050 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4051 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4053 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4056 RHSLo, MaskLo,
N->getFlags());
4058 RHSHi, MaskHi,
N->getFlags());
4062SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4065 assert(OpNo == 1 &&
"Illegal operand must be mask");
4070 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4072 EVT VecVT =
N->getValueType(0);
4076SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4077 EVT ResVT =
N->getValueType(0);
4083 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4084 GetSplitVector(VecOp,
Lo,
Hi);
4086 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4091 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4092 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4096 EVT ResVT =
N->getValueType(0);
4102 SDNodeFlags
Flags =
N->getFlags();
4105 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4106 GetSplitVector(VecOp,
Lo,
Hi);
4108 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4114 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4117SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4118 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4119 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4121 unsigned Opc =
N->getOpcode();
4122 EVT ResVT =
N->getValueType(0);
4128 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4129 GetSplitVector(VecOp,
Lo,
Hi);
4132 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4135 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4137 const SDNodeFlags
Flags =
N->getFlags();
4141 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4146 EVT ResVT =
N->getValueType(0);
4149 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4150 EVT InVT =
Lo.getValueType();
4155 if (
N->isStrictFPOpcode()) {
4156 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4157 {N->getOperand(0), Lo});
4158 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4159 {N->getOperand(0), Hi});
4168 ReplaceValueWith(
SDValue(
N, 1), Ch);
4170 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4171 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4180 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4190 EVT ResVT =
N->getValueType(0);
4192 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4196 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4202 Lo = BitConvertToInteger(
Lo);
4203 Hi = BitConvertToInteger(
Hi);
4205 if (DAG.getDataLayout().isBigEndian())
4213 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4215 EVT ResVT =
N->getValueType(0);
4223 GetSplitVector(SubVec,
Lo,
Hi);
4232 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4234 return SecondInsertion;
4237SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4244 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4246 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4248 ElementCount IdxVal =
4252 EVT SrcVT =
N->getOperand(0).getValueType();
4271 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4272 LoEltsMin - IdxValMin);
4273 DAG.ExtractVectorElements(
Hi, Elts, 0,
4276 return DAG.getBuildVector(SubVT, dl, Elts);
4280 ElementCount ExtractIdx = IdxVal - LoElts;
4282 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4285 EVT HiVT =
Hi.getValueType();
4287 "Only fixed-vector extracts are supported in this case");
4297 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4298 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4304 "Extracting scalable subvector from fixed-width unsupported");
4312 "subvector from a scalable predicate vector");
4318 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4320 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4321 auto &MF = DAG.getMachineFunction();
4325 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4329 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4332 SubVT, dl,
Store, StackPtr,
4336SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4345 GetSplitVector(Vec,
Lo,
Hi);
4347 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4349 if (IdxVal < LoElts)
4350 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4353 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4358 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4370 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4376 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4378 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4379 auto &MF = DAG.getMachineFunction();
4382 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4386 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4390 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4392 return DAG.getExtLoad(
4403 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4411 SplitVecRes_Gather(
N,
Lo,
Hi);
4414 ReplaceValueWith(
SDValue(
N, 0), Res);
4419 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4423 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4425 SDValue EVL =
N->getVectorLength();
4433 GetSplitVector(
Data, DataLo, DataHi);
4435 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4440 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4443 GetSplitVector(Mask, MaskLo, MaskHi);
4445 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4448 EVT MemoryVT =
N->getMemoryVT();
4449 EVT LoMemVT, HiMemVT;
4450 bool HiIsEmpty =
false;
4451 std::tie(LoMemVT, HiMemVT) =
4452 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4456 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4459 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4462 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4464 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4465 N->getAddressingMode(),
N->isTruncatingStore(),
4466 N->isCompressingStore());
4472 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4473 N->isCompressingStore());
4475 MachinePointerInfo MPI;
4479 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4484 MMO = DAG.getMachineFunction().getMachineMemOperand(
4486 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4488 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4489 N->getAddressingMode(),
N->isTruncatingStore(),
4490 N->isCompressingStore());
4499 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4500 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4507 GetSplitVector(
Data, LoData, HiData);
4509 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4511 EVT LoMemVT, HiMemVT;
4512 bool HiIsEmpty =
false;
4513 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4519 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4520 else if (getTypeAction(
Mask.getValueType()) ==
4522 GetSplitVector(Mask, LoMask, HiMask);
4524 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4527 std::tie(LoEVL, HiEVL) =
4528 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4532 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4533 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4534 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4545 EVT PtrVT =
N->getBasePtr().getValueType();
4548 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4556 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4557 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4559 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4562 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4563 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4564 N->isCompressingStore());
4573 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4577 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4586 GetSplitVector(
Data, DataLo, DataHi);
4588 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4593 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4596 GetSplitVector(Mask, MaskLo, MaskHi);
4598 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4601 EVT MemoryVT =
N->getMemoryVT();
4602 EVT LoMemVT, HiMemVT;
4603 bool HiIsEmpty =
false;
4604 std::tie(LoMemVT, HiMemVT) =
4605 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4608 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4611 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4613 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4614 N->getAddressingMode(),
N->isTruncatingStore(),
4615 N->isCompressingStore());
4623 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4624 N->isCompressingStore());
4626 MachinePointerInfo MPI;
4630 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4635 MMO = DAG.getMachineFunction().getMachineMemOperand(
4638 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4640 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4641 N->getAddressingMode(),
N->isTruncatingStore(),
4642 N->isCompressingStore());
4655 EVT MemoryVT =
N->getMemoryVT();
4665 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4669 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4674 EVT LoMemVT, HiMemVT;
4675 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4680 GetSplitVector(
Ops.Data, DataLo, DataHi);
4682 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4687 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4689 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4693 if (getTypeAction(
Ops.Index.getValueType()) ==
4695 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4697 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4701 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4703 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4706 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4708 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4709 MSC->getIndexType(), MSC->isTruncatingStore());
4714 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4715 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4716 MMO, MSC->getIndexType(),
4717 MSC->isTruncatingStore());
4721 std::tie(EVLLo, EVLHi) =
4722 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4724 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4725 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4726 VPSC->getIndexType());
4731 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4732 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4733 VPSC->getIndexType());
4737 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4738 assert(OpNo == 1 &&
"Can only split the stored value");
4741 bool isTruncating =
N->isTruncatingStore();
4744 EVT MemoryVT =
N->getMemoryVT();
4747 AAMDNodes AAInfo =
N->getAAInfo();
4749 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4751 EVT LoMemVT, HiMemVT;
4752 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4756 return TLI.scalarizeVectorStore(
N, DAG);
4759 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4760 Alignment, MMOFlags, AAInfo);
4762 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4765 MachinePointerInfo MPI;
4766 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4769 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4770 HiMemVT, Alignment, MMOFlags, AAInfo);
4772 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4779 LLVMContext &Ctx = *DAG.getContext();
4797 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4798 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4802 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4805 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4806 DAG.getBitcast(MemVecVT, Wide), 0);
4808 N->getBasePtr(),
N->getMemOperand());
4816 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4818 N->getBasePtr(),
N->getMemOperand());
4832 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4838 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4859 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4860 SDValue InVec =
N->getOperand(OpNo);
4862 EVT OutVT =
N->getValueType(0);
4870 EVT LoOutVT, HiOutVT;
4871 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4872 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4877 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4879 return SplitVecOp_UnaryOp(
N);
4888 return SplitVecOp_UnaryOp(
N);
4892 GetSplitVector(InVec, InLoVec, InHiVec);
4898 EVT HalfElementVT = IsFloat ?
4900 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4907 if (
N->isStrictFPOpcode()) {
4908 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4909 {N->getOperand(0), InLoVec});
4910 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4911 {N->getOperand(0), InHiVec});
4917 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4918 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4922 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4930 if (
N->isStrictFPOpcode()) {
4934 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4942 DAG.getTargetConstant(
4943 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4950 assert(
N->getValueType(0).isVector() &&
4951 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4952 "Operand types must be vectors");
4954 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4956 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4957 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4959 EVT VT =
N->getValueType(0);
4960 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4966 assert(isStrict &&
"unexpected node");
4967 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4968 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4969 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4970 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4973 ReplaceValueWith(
SDValue(
N, 1), NewChain);
4981 EVT OpVT =
N->getOperand(0).getValueType();
4984 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4990 EVT ResVT =
N->getValueType(0);
4993 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4994 EVT InVT =
Lo.getValueType();
4999 if (
N->isStrictFPOpcode()) {
5000 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5001 {N->getOperand(0), Lo, N->getOperand(2)});
5002 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5003 {N->getOperand(0), Hi, N->getOperand(2)});
5007 Lo.getValue(1),
Hi.getValue(1));
5008 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5010 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5011 N->getOperand(2),
N->getOperand(3));
5012 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5013 N->getOperand(2),
N->getOperand(3));
5015 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5016 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5027SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5030 EVT LHSLoVT, LHSHiVT;
5031 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5033 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5034 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5037 std::tie(LHSLo, LHSHi) =
5038 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5041 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5044 SDValue Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5050 LLVMContext &Ctxt = *DAG.getContext();
5053 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5054 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5055 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5057 EVT ResVT =
N->getValueType(0);
5062 SDValue Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5063 SDValue Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5069 EVT ResVT =
N->getValueType(0);
5072 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5073 EVT InVT =
Lo.getValueType();
5079 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5080 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5087 EVT ResVT =
N->getValueType(0);
5091 GetSplitVector(VecOp,
Lo,
Hi);
5097 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5099 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5101 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5102 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5107 EVT ResVT =
N->getValueType(0);
5111 GetSplitVector(VecOp,
Lo,
Hi);
5113 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5114 auto [EVLLo, EVLHi] =
5116 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5122 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5124 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5125 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5128SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5139 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5140 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5141 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5142 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5143 SDValue Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5144 OpsLo, MMO, IndexType);
5145 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5146 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5150SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5154 EVT LoResVT, HiResVT;
5155 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5157 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5159 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5162 N->getOperand(1), MaskLo,
N->getFlags());
5164 N->getOperand(1), MaskHi,
N->getFlags());
5170 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5173 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5177 NeedleLo,
N->getOperand(2),
N->getFlags());
5180 NeedleHi,
N->getOperand(2),
N->getFlags());
5181 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5184SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5187 "Accumulator should already be a legal type, and shouldn't need "
5188 "further splitting");
5191 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5192 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5193 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5194 unsigned Opcode =
N->getOpcode();
5197 SDValue Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5198 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5205void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5206 unsigned WidenResNo) {
5207 unsigned NumResults =
N->getNumValues();
5208 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5209 if (ResNo == WidenResNo)
5211 EVT ResVT =
N->getValueType(ResNo);
5217 DAG.getExtractSubvector(
DL, ResVT,
SDValue(WidenNode, ResNo), 0);
5218 ReplaceValueWith(
SDValue(
N, ResNo), ResVal);
5223void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5224 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5227 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5232 auto unrollExpandedOp = [&]() {
5237 EVT VT =
N->getValueType(0);
5238 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5239 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5240 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5242 if (
N->getNumValues() > 1)
5243 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5249 switch (
N->getOpcode()) {
5252 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5260 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5264 Res = WidenVecRes_ADDRSPACECAST(
N);
5271 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5278 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5282 Res = WidenVecRes_ScalarOp(
N);
5288 Res = WidenVecRes_Select(
N);
5291 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5293 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5300 case ISD::VP_LOAD_FF:
5303 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5307 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5315 case ISD::VP_GATHER:
5319 Res = WidenVecRes_VECTOR_REVERSE(
N);
5322 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5325 WidenVecRes_VECTOR_INTERLEAVE(
N);
5328 Res = WidenVecRes_VECTOR_MATCH(
N);
5331 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5385 Res = WidenVecRes_Binary(
N);
5392 Res = WidenVecRes_MaskedBinary(
N);
5397 Res = WidenVecRes_CMP(
N);
5403 if (unrollExpandedOp())
5418 Res = WidenVecRes_BinaryCanTrap(
N);
5427 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5430#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5431 case ISD::STRICT_##DAGN:
5432#include "llvm/IR/ConstrainedOps.def"
5433 Res = WidenVecRes_StrictFP(
N);
5442 Res = WidenVecRes_OverflowOp(
N, ResNo);
5446 Res = WidenVecRes_FCOPYSIGN(
N);
5451 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5456 if (!unrollExpandedOp())
5457 Res = WidenVecRes_ExpOp(
N);
5463 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5478 Res = WidenVecRes_Convert(
N);
5483 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5490 Res = WidenVecRes_XROUND(
N);
5516 if (unrollExpandedOp())
5538 Res = WidenVecRes_Unary(
N);
5543 Res = WidenVecRes_Ternary(
N);
5549 if (!unrollExpandedOp())
5550 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5554 Res = WidenVecRes_PARTIAL_REDUCE_MLA(
N);
5560 SetWidenedVector(
SDValue(
N, ResNo), Res);
5566 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5567 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5568 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5569 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5570 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5576 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5577 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5578 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5579 if (
N->getNumOperands() == 2)
5580 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5583 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5584 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5585 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5586 "Expected VP opcode");
5590 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5591 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5596 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5597 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5598 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5601 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5602 Mask = ModifyToType(Mask, WideMaskVT,
true);
5603 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5608 LLVMContext &Ctxt = *DAG.getContext();
5613 EVT OpVT =
LHS.getValueType();
5615 LHS = GetWidenedVector(
LHS);
5616 RHS = GetWidenedVector(
RHS);
5617 OpVT =
LHS.getValueType();
5620 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5623 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5629SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5632 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5633 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5634 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5636 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5645 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5648 if (ConcatEnd == 1) {
5649 VT = ConcatOps[0].getValueType();
5651 return ConcatOps[0];
5654 SDLoc dl(ConcatOps[0]);
5661 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
5662 int Idx = ConcatEnd - 1;
5663 VT = ConcatOps[Idx--].getValueType();
5664 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
5677 unsigned NumToInsert = ConcatEnd - Idx - 1;
5678 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5680 ConcatOps[Idx+1] = VecOp;
5681 ConcatEnd = Idx + 2;
5687 unsigned RealVals = ConcatEnd - Idx - 1;
5688 unsigned SubConcatEnd = 0;
5689 unsigned SubConcatIdx = Idx + 1;
5690 while (SubConcatEnd < RealVals)
5691 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5692 while (SubConcatEnd < OpsToConcat)
5693 SubConcatOps[SubConcatEnd++] = undefVec;
5695 NextVT, SubConcatOps);
5696 ConcatEnd = SubConcatIdx + 1;
5701 if (ConcatEnd == 1) {
5702 VT = ConcatOps[0].getValueType();
5704 return ConcatOps[0];
5709 if (
NumOps != ConcatEnd ) {
5711 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5712 ConcatOps[j] = UndefVal;
5720 unsigned Opcode =
N->getOpcode();
5722 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5726 const SDNodeFlags
Flags =
N->getFlags();
5727 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5728 NumElts = NumElts / 2;
5732 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5734 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5735 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5736 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5744 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5747 TLI.isTypeLegal(WideMaskVT)) {
5748 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5749 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5750 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5752 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5753 N->getValueType(0).getVectorElementCount());
5754 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5768 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5769 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5770 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5773 unsigned ConcatEnd = 0;
5781 while (CurNumElts != 0) {
5782 while (CurNumElts >= NumElts) {
5783 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5784 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5785 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5787 CurNumElts -= NumElts;
5790 NumElts = NumElts / 2;
5792 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5795 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5796 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5797 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5798 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5809 switch (
N->getOpcode()) {
5812 return WidenVecRes_STRICT_FSETCC(
N);
5819 return WidenVecRes_Convert_StrictFP(
N);
5826 unsigned Opcode =
N->getOpcode();
5828 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5832 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5833 NumElts = NumElts / 2;
5844 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5848 unsigned ConcatEnd = 0;
5855 for (
unsigned i = 1; i < NumOpers; ++i) {
5861 Oper = GetWidenedVector(Oper);
5867 DAG.getPOISON(WideOpVT), Oper,
5868 DAG.getVectorIdxConstant(0, dl));
5880 while (CurNumElts != 0) {
5881 while (CurNumElts >= NumElts) {
5884 for (
unsigned i = 0; i < NumOpers; ++i) {
5887 EVT OpVT =
Op.getValueType();
5892 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5898 EVT OperVT[] = {VT, MVT::Other};
5900 ConcatOps[ConcatEnd++] = Oper;
5903 CurNumElts -= NumElts;
5906 NumElts = NumElts / 2;
5908 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5911 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5914 for (
unsigned i = 0; i < NumOpers; ++i) {
5917 EVT OpVT =
Op.getValueType();
5925 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5927 ConcatOps[ConcatEnd++] = Oper;
5936 if (Chains.
size() == 1)
5937 NewChain = Chains[0];
5940 ReplaceValueWith(
SDValue(
N, 1), NewChain);
5945SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5947 EVT ResVT =
N->getValueType(0);
5948 EVT OvVT =
N->getValueType(1);
5949 EVT WideResVT, WideOvVT;
5954 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5959 WideLHS = GetWidenedVector(
N->getOperand(0));
5960 WideRHS = GetWidenedVector(
N->getOperand(1));
5962 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5971 N->getOperand(0), Zero);
5973 N->getOperand(1), Zero);
5976 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5977 SDNode *WideNode = DAG.getNode(
5978 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5981 unsigned OtherNo = 1 - ResNo;
5982 EVT OtherVT =
N->getValueType(OtherNo);
5989 ReplaceValueWith(
SDValue(
N, OtherNo), OtherVal);
5992 return SDValue(WideNode, ResNo);
5996 LLVMContext &Ctx = *DAG.getContext();
6000 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6005 unsigned Opcode =
N->getOpcode();
6006 const SDNodeFlags
Flags =
N->getFlags();
6012 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6014 InOp = ZExtPromotedInteger(InOp);
6026 if (
N->getNumOperands() == 1)
6027 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6029 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6030 N->getOperand(3), Flags);
6031 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6035 InOp = GetWidenedVector(
N->getOperand(0));
6038 if (InVTEC == WidenEC)
6039 return MakeConvertNode(WidenVT, InOp);
6064 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6068 if (TLI.isTypeLegal(InWidenVT)) {
6076 unsigned NumConcat =
6081 return MakeConvertNode(WidenVT, InVec);
6085 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6087 return MakeConvertNode(WidenVT, InVal);
6096 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6097 for (
unsigned i=0; i < MinElts; ++i) {
6098 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6099 Ops[i] = MakeConvertNode(EltVT, Val);
6102 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6107 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6111 EVT SrcVT = Src.getValueType();
6115 Src = GetWidenedVector(Src);
6116 SrcVT = Src.getValueType();
6123 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6128 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6132 EVT SrcVT = Src.getValueType();
6136 Src = GetWidenedVector(Src);
6137 SrcVT = Src.getValueType();
6144 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6147SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6152 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6158 unsigned Opcode =
N->getOpcode();
6164 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6169 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6170 for (
unsigned i=0; i < MinElts; ++i) {
6171 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6172 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6176 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6178 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6181SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6182 unsigned Opcode =
N->getOpcode();
6186 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6195 InOp = GetWidenedVector(InOp);
6202 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6209 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6210 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6227 while (
Ops.size() != WidenNumElts)
6228 Ops.push_back(DAG.getPOISON(WidenSVT));
6230 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6236 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6237 return WidenVecRes_BinaryCanTrap(
N);
6240 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6247SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6249 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6252 SDValue Arg = GetWidenedVector(FpValue);
6253 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6258 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6259 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6261 EVT ExpVT =
RHS.getValueType();
6266 ExpOp = ModifyToType(
RHS, WideExpVT);
6269 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6274 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6275 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6276 if (
N->getNumOperands() == 1)
6277 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6279 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6284 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6289 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6290 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6291 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6294SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6296 EVT VT0 =
N->getValueType(0);
6297 EVT VT1 =
N->getValueType(1);
6301 "expected both results to be vectors of matching element count");
6303 LLVMContext &Ctx = *DAG.getContext();
6304 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6306 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6313 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6316 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6317 return SDValue(WidenNode, ResNo);
6320SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6321 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6322 return GetWidenedVector(WidenVec);
6327 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6337 InOp = GetWidenedVector(InOp);
6341 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6344 return DAG.getAddrSpaceCast(
6345 DL, WidenVT, InOp, AddrSpaceCastN->getSrcAddressSpace(),
6346 AddrSpaceCastN->getDestAddressSpace(), AddrSpaceCastN->getFlags());
6352 EVT VT =
N->getValueType(0);
6353 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6356 switch (getTypeAction(InVT)) {
6370 SDValue NInOp = GetPromotedInteger(InOp);
6372 if (WidenVT.
bitsEq(NInVT)) {
6375 if (DAG.getDataLayout().isBigEndian()) {
6378 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6396 InOp = GetWidenedVector(InOp);
6398 if (WidenVT.
bitsEq(InVT))
6408 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6413 unsigned NewNumParts = WidenSize / InSize;
6426 EVT OrigInVT =
N->getOperand(0).getValueType();
6431 if (TLI.isTypeLegal(NewInVT)) {
6439 if (WidenSize % InSize == 0) {
6446 DAG.ExtractVectorElements(InOp,
Ops);
6447 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6459 return CreateStackStoreLoad(InOp, WidenVT);
6462SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6464 N->getOpcode(), SDLoc(
N),
6465 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6466 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6472 EVT VT =
N->getValueType(0);
6476 EVT EltVT =
N->getOperand(0).getValueType();
6479 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6483 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6484 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6486 return DAG.getBuildVector(WidenVT, dl, NewOps);
6490 EVT InVT =
N->getOperand(0).getValueType();
6491 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6493 unsigned NumOperands =
N->getNumOperands();
6495 bool InputWidened =
false;
6499 if (WidenNumElts % NumInElts == 0) {
6501 unsigned NumConcat = WidenNumElts / NumInElts;
6502 SDValue UndefVal = DAG.getPOISON(InVT);
6504 for (
unsigned i=0; i < NumOperands; ++i)
6505 Ops[i] =
N->getOperand(i);
6506 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6511 InputWidened =
true;
6512 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6515 for (i=1; i < NumOperands; ++i)
6516 if (!
N->getOperand(i).isUndef())
6519 if (i == NumOperands)
6522 return GetWidenedVector(
N->getOperand(0));
6524 if (NumOperands == 2) {
6526 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6531 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6532 for (
unsigned i = 0; i < NumInElts; ++i) {
6534 MaskOps[i + NumInElts] = i + WidenNumElts;
6536 return DAG.getVectorShuffle(WidenVT, dl,
6537 GetWidenedVector(
N->getOperand(0)),
6538 GetWidenedVector(
N->getOperand(1)),
6545 SDValue WideVec = DAG.getPOISON(WidenVT);
6547 for (
unsigned I = 0;
I < NumOperands; ++
I)
6549 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6560 for (
unsigned i=0; i < NumOperands; ++i) {
6563 InOp = GetWidenedVector(InOp);
6564 for (
unsigned j = 0;
j < NumInElts; ++
j)
6565 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6567 SDValue UndefVal = DAG.getPOISON(EltVT);
6568 for (; Idx < WidenNumElts; ++Idx)
6569 Ops[Idx] = UndefVal;
6570 return DAG.getBuildVector(WidenVT, dl,
Ops);
6573SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6574 EVT VT =
N->getValueType(0);
6575 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6576 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6583SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6584 EVT VT =
N->getValueType(0);
6586 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6591 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6593 InOp = GetWidenedVector(InOp);
6599 if (IdxVal == 0 && InVT == WidenVT)
6606 assert(IdxVal % VTNumElts == 0 &&
6607 "Expected Idx to be a multiple of subvector minimum vector length");
6608 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6621 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6622 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6623 "down type's element count");
6630 for (;
I < VTNumElts / GCD; ++
I)
6632 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6633 for (;
I < WidenNumElts / GCD; ++
I)
6655 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6662 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6663 return DAG.getMaskedLoad(
6664 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6672 for (i = 0; i < VTNumElts; ++i)
6673 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6675 SDValue UndefVal = DAG.getPOISON(EltVT);
6676 for (; i < WidenNumElts; ++i)
6678 return DAG.getBuildVector(WidenVT, dl,
Ops);
6684 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6689SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6690 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6693 N->getOperand(1),
N->getOperand(2));
6702 "Load width must be less than or equal to first value type width");
6711 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6728 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6739 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6740 EVT LdVT =
LD->getMemoryVT();
6749 TypeSize WidthDiff = WidenWidth - LdWidth;
6752 std::optional<EVT> FirstVT =
6753 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6760 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6763 Chain, BasePtr,
LD->getMemOperand());
6767 FirstVTWidth, dl, DAG);
6785 if (!
LD->getMemoryVT().isByteSized()) {
6787 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6789 ReplaceValueWith(
SDValue(LD, 1), NewChain);
6798 EVT VT =
LD->getValueType(0);
6799 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6800 EVT WideMaskVT = getSetCCResultType(WideVT);
6803 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6804 TLI.isTypeLegal(WideMaskVT)) {
6807 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6811 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6812 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6824 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6826 Result = GenWidenVectorLoads(LdChain, LD);
6833 if (LdChain.
size() == 1)
6834 NewChain = LdChain[0];
6840 ReplaceValueWith(
SDValue(
N, 1), NewChain);
6851 SDValue NewLoad = DAG.getMaskedLoad(
6852 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6853 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6854 LD->getAddressingMode(),
LD->getExtensionType());
6864 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6866 SDValue EVL =
N->getVectorLength();
6873 "Unable to widen binary VP op");
6874 Mask = GetWidenedVector(Mask);
6875 assert(
Mask.getValueType().getVectorElementCount() ==
6876 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6877 .getVectorElementCount() &&
6878 "Unable to widen vector load");
6881 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6882 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6883 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6891 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6893 SDValue EVL =
N->getVectorLength();
6899 "Unable to widen binary VP op");
6900 Mask = GetWidenedVector(Mask);
6901 assert(
Mask.getValueType().getVectorElementCount() ==
6902 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6903 .getVectorElementCount() &&
6904 "Unable to widen vector load");
6906 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6907 Mask, EVL,
N->getMemOperand());
6920 "Unable to widen VP strided load");
6921 Mask = GetWidenedVector(Mask);
6923 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6924 assert(
Mask.getValueType().getVectorElementCount() ==
6926 "Data and mask vectors should have the same number of elements");
6928 SDValue Res = DAG.getStridedLoadVP(
6929 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6930 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6931 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6932 N->isExpandingLoad());
6940SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6945 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6947 Mask.getValueType().getVectorElementType(),
6950 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6951 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6952 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6954 WideMask, WidePassthru);
6958 EVT VT =
N->getValueType(0);
6959 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6961 EVT MaskVT =
Mask.getValueType();
6962 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6971 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6972 TLI.isTypeLegal(WideMaskVT) &&
6978 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6979 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6983 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6984 N->getMemoryVT(),
N->getMemOperand());
6988 if (!
N->getPassThru()->isUndef()) {
6992 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6993 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6994 DAG.getPOISON(WidenVT), EVL);
7005 Mask = ModifyToType(Mask, WideMaskVT,
true);
7007 SDValue Res = DAG.getMaskedLoad(
7008 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7009 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7010 ExtType,
N->isExpandingLoad());
7019 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7021 EVT MaskVT =
Mask.getValueType();
7022 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7030 Mask = ModifyToType(Mask, WideMaskVT,
true);
7035 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7036 Index = ModifyToType(Index, WideIndexVT);
7042 N->getMemoryVT().getScalarType(), WideEC);
7043 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7044 WideMemVT, dl,
Ops,
N->getMemOperand(),
7045 N->getIndexType(),
N->getExtensionType());
7054 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7062 N->getMemoryVT().getScalarType(), WideEC);
7063 Mask = GetWidenedMask(Mask, WideEC);
7066 Mask,
N->getVectorLength()};
7067 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7068 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7077 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7078 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7106 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7107 return N->getOperand(OpNo).getValueType();
7115 N =
N.getOperand(0);
7117 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7118 if (!
N->getOperand(i)->isUndef())
7120 N =
N.getOperand(0);
7124 N =
N.getOperand(0);
7126 N =
N.getOperand(0);
7153 { MaskVT, MVT::Other },
Ops);
7154 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7162 LLVMContext &Ctx = *DAG.getContext();
7165 if (MaskScalarBits < ToMaskScalBits) {
7169 }
else if (MaskScalarBits > ToMaskScalBits) {
7175 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7177 "Mask should have the right element size by now.");
7180 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7182 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7185 EVT SubVT =
Mask->getValueType(0);
7191 assert((
Mask->getValueType(0) == ToMaskVT) &&
7192 "A mask of ToMaskVT should have been produced by now.");
7202 LLVMContext &Ctx = *DAG.getContext();
7213 EVT CondVT =
Cond->getValueType(0);
7217 EVT VSelVT =
N->getValueType(0);
7229 EVT FinalVT = VSelVT;
7240 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7241 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7248 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7256 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7259 EVT ToMaskVT = VSelVT;
7266 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7282 if (ScalarBits0 != ScalarBits1) {
7283 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7284 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7296 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7297 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7298 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7301 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7309 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7314 unsigned Opcode =
N->getOpcode();
7316 if (
SDValue WideCond = WidenVSELECTMask(
N)) {
7317 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7318 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7320 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7326 Cond1 = GetWidenedVector(Cond1);
7334 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7335 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7340 Cond1 = ModifyToType(Cond1, CondWidenVT);
7343 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7344 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7346 if (Opcode == ISD::VP_MERGE)
7347 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7349 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7353 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7354 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7357 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7361 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7362 return DAG.getUNDEF(WidenVT);
7366 EVT VT =
N->getValueType(0);
7369 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7373 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7374 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7377 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7378 for (
unsigned i = 0; i != NumElts; ++i) {
7379 int Idx =
N->getMaskElt(i);
7380 if (Idx < (
int)NumElts)
7383 NewMask[i] = Idx - NumElts + WidenNumElts;
7385 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7389 EVT VT =
N->getValueType(0);
7393 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7394 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7400 unsigned IdxVal = WidenNumElts - VTNumElts;
7413 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7416 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7417 "down type's element count");
7420 for (; i < VTNumElts / GCD; ++i)
7422 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7423 for (; i < WidenNumElts / GCD; ++i)
7431 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7432 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7434 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7438SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7439 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7443void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7444 EVT VT =
N->getValueType(0);
7447 unsigned Factor =
N->getNumOperands();
7450 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7454 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7455 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7464 for (
unsigned Idx = 0; Idx != Factor; ++Idx)
7465 Slices[Idx] = Interleaved.
getValue(Idx);
7469 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7470 SDValue Narrow = DAG.getExtractSubvector(
DL, VT, Packed,
7473 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7474 SetWidenedVector(
SDValue(
N, Idx), Wide);
7480 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7481 EVT SourceVT =
N->getOperand(0).getValueType();
7486 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7487 N->getOperand(0), 0);
7488 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7489 N->getOperand(2), 0);
7491 N->getOperand(1), WideMask,
N->getFlags());
7494void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7495 EVT VT =
N->getValueType(0);
7498 unsigned Factor =
N->getNumOperands();
7501 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7511 EVT ConcatVT =
EVT::getVectorVT(*DAG.getContext(), EltVT, OrigEC * Factor);
7513 SDValue PackedWidenVec = DAG.getInsertSubvector(
7514 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7518 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7519 NewOps[Idx] = DAG.getExtractSubvector(
DL, WidenVT, PackedWidenVec,
7526 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7531 assert(
N->getValueType(0).isVector() &&
7532 N->getOperand(0).getValueType().isVector() &&
7533 "Operands must be vectors");
7534 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7547 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7548 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7555 InOp1 = GetWidenedVector(InOp1);
7556 InOp2 = GetWidenedVector(InOp2);
7559 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7570 "Input not widened to expected type!");
7572 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7577 assert(
N->getValueType(0).isVector() &&
7578 N->getOperand(1).getValueType().isVector() &&
7579 "Operands must be vectors");
7580 EVT VT =
N->getValueType(0);
7581 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7591 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7596 for (
unsigned i = 0; i != NumElts; ++i) {
7597 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7598 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7600 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7601 {Chain, LHSElem, RHSElem, CC});
7602 Chains[i] = Scalars[i].getValue(1);
7603 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7604 DAG.getBoolConstant(
true, dl, EltVT, VT),
7605 DAG.getBoolConstant(
false, dl, EltVT, VT));
7609 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7611 return DAG.getBuildVector(WidenVT, dl, Scalars);
7614SDValue DAGTypeLegalizer::WidenVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N) {
7616 EVT VT =
N->getValueType(0);
7619 SDValue Expanded = TLI.expandPartialReduceMLA(
N, DAG);
7620 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7621 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WideVT), Expanded, 0);
7627bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7628 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7632 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7635 switch (
N->getOpcode()) {
7638 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7646 Res = WidenVecOp_FAKE_USE(
N);
7652 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7656 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7657 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7658 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7663 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7665 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7666 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7668 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7669 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7679 Res = WidenVecOp_UnrollVectorOp(
N);
7686 Res = WidenVecOp_EXTEND(
N);
7691 Res = WidenVecOp_CMP(
N);
7709 Res = WidenVecOp_Convert(
N);
7714 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7734 Res = WidenVecOp_VECREDUCE(
N);
7738 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7740 case ISD::VP_REDUCE_FADD:
7741 case ISD::VP_REDUCE_SEQ_FADD:
7742 case ISD::VP_REDUCE_FMUL:
7743 case ISD::VP_REDUCE_SEQ_FMUL:
7744 case ISD::VP_REDUCE_ADD:
7745 case ISD::VP_REDUCE_MUL:
7746 case ISD::VP_REDUCE_AND:
7747 case ISD::VP_REDUCE_OR:
7748 case ISD::VP_REDUCE_XOR:
7749 case ISD::VP_REDUCE_SMAX:
7750 case ISD::VP_REDUCE_SMIN:
7751 case ISD::VP_REDUCE_UMAX:
7752 case ISD::VP_REDUCE_UMIN:
7753 case ISD::VP_REDUCE_FMAX:
7754 case ISD::VP_REDUCE_FMIN:
7755 case ISD::VP_REDUCE_FMAXIMUM:
7756 case ISD::VP_REDUCE_FMINIMUM:
7757 Res = WidenVecOp_VP_REDUCE(
N);
7761 Res = WidenVecOp_CttzElements(
N);
7763 case ISD::VP_CTTZ_ELTS:
7764 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7765 Res = WidenVecOp_VP_CttzElements(
N);
7768 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7771 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
7776 if (!Res.
getNode())
return false;
7784 if (
N->isStrictFPOpcode())
7786 "Invalid operand expansion");
7789 "Invalid operand expansion");
7791 ReplaceValueWith(
SDValue(
N, 0), Res);
7797 EVT VT =
N->getValueType(0);
7802 "Unexpected type action");
7803 InOp = GetWidenedVector(InOp);
7806 "Input wasn't widened!");
7814 EVT FixedEltVT = FixedVT.getVectorElementType();
7815 if (TLI.isTypeLegal(FixedVT) &&
7817 FixedEltVT == InEltVT) {
7819 "Not enough elements in the fixed type for the operand!");
7821 "We can't have the same type as we started with!");
7823 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7825 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7834 return WidenVecOp_Convert(
N);
7839 switch (
N->getOpcode()) {
7854 EVT OpVT =
N->getOperand(0).getValueType();
7855 EVT ResVT =
N->getValueType(0);
7862 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7863 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7869 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7870 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7872 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7879 return DAG.UnrollVectorOp(
N);
7884 EVT ResultVT =
N->getValueType(0);
7886 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7889 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7895 {WideArg,
Test},
N->getFlags());
7901 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7903 EVT OpVT =
N->getOperand(0).getValueType();
7906 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7911 EVT VT =
N->getValueType(0);
7917 "Unexpected type action");
7918 InOp = GetWidenedVector(InOp);
7920 unsigned Opcode =
N->getOpcode();
7925 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7928 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7929 return DAG.getNode(Opcode, dl, VT,
Op);
7936 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7938 if (
N->isStrictFPOpcode()) {
7940 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7943 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7944 {
N->getOperand(0), InOp });
7949 Res = MakeConvertNode(WideVT, InOp);
7951 return DAG.getExtractSubvector(dl, VT, Res, 0);
7959 if (
N->isStrictFPOpcode()) {
7962 for (
unsigned i=0; i < NumElts; ++i) {
7963 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7964 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7968 ReplaceValueWith(
SDValue(
N, 1), NewChain);
7970 for (
unsigned i = 0; i < NumElts; ++i) {
7971 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7972 Ops[i] = MakeConvertNode(EltVT, Elt);
7976 return DAG.getBuildVector(VT, dl,
Ops);
7980 EVT DstVT =
N->getValueType(0);
7981 SDValue Src = GetWidenedVector(
N->getOperand(0));
7982 EVT SrcVT = Src.getValueType();
7989 if (TLI.isTypeLegal(WideDstVT)) {
7991 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7994 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
7998 return DAG.UnrollVectorOp(
N);
8002 EVT VT =
N->getValueType(0);
8003 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8011 if (!VT.
isVector() && VT != MVT::x86mmx &&
8015 if (TLI.isTypeLegal(NewVT)) {
8017 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8029 ElementCount NewNumElts =
8031 .divideCoefficientBy(EltSize);
8033 if (TLI.isTypeLegal(NewVT)) {
8035 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8040 return CreateStackStoreLoad(InOp, VT);
8048 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8049 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8054 EVT VT =
N->getValueType(0);
8056 EVT InVT =
N->getOperand(0).getValueType();
8061 unsigned NumOperands =
N->getNumOperands();
8062 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8064 for (i = 1; i < NumOperands; ++i)
8065 if (!
N->getOperand(i).isUndef())
8068 if (i == NumOperands)
8069 return GetWidenedVector(
N->getOperand(0));
8079 for (
unsigned i=0; i < NumOperands; ++i) {
8083 "Unexpected type action");
8084 InOp = GetWidenedVector(InOp);
8085 for (
unsigned j = 0;
j < NumInElts; ++
j)
8086 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8088 return DAG.getBuildVector(VT, dl,
Ops);
8091SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8092 EVT VT =
N->getValueType(0);
8097 SubVec = GetWidenedVector(SubVec);
8102 bool IndicesValid =
false;
8105 IndicesValid =
true;
8109 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8110 Attribute::VScaleRange);
8115 IndicesValid =
true;
8121 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8127 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8134 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8156 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8164 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8165 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8170 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8175 unsigned Idx =
N->getConstantOperandVal(2);
8181 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8187SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8188 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8190 N->getValueType(0), InOp,
N->getOperand(1));
8193SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8194 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8196 N->getValueType(0), InOp,
N->getOperand(1));
8199SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8201 EVT ResVT =
N->getValueType(0);
8204 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8210 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8218 "Widened input size must be a multiple of result element size");
8221 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8223 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8224 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8232 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8233 return TLI.scalarizeVectorStore(ST, DAG);
8235 if (
ST->isTruncatingStore())
8236 return TLI.scalarizeVectorStore(ST, DAG);
8246 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8247 EVT WideMaskVT = getSetCCResultType(WideVT);
8249 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8250 TLI.isTypeLegal(WideMaskVT)) {
8253 StVal = GetWidenedVector(StVal);
8255 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8257 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8258 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8259 ST->getAddressingMode());
8263 if (GenWidenVectorStores(StChain, ST)) {
8264 if (StChain.
size() == 1)
8273 SDValue WideStVal = GetWidenedVector(StVal);
8277 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8278 ST->getOffset(), Mask,
ST->getMemoryVT(),
8279 ST->getMemOperand(),
ST->getAddressingMode(),
8280 ST->isTruncatingStore());
8287 EVT StVT =
ST->getMemoryVT();
8290 SDValue StVal = GetWidenedVector(
ST->getVal());
8295 TypeSize WidthDiff = WidenWidth - StWidth;
8301 std::optional<EVT> FirstVT =
8302 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8307 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8313 ST->getBasePtr(),
ST->getMemOperand());
8316SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8317 assert((OpNo == 1 || OpNo == 3) &&
8318 "Can widen only data or mask operand of vp_store");
8326 StVal = GetWidenedVector(StVal);
8332 "Unable to widen VP store");
8333 Mask = GetWidenedVector(Mask);
8335 Mask = GetWidenedVector(Mask);
8341 "Unable to widen VP store");
8342 StVal = GetWidenedVector(StVal);
8345 assert(
Mask.getValueType().getVectorElementCount() ==
8347 "Mask and data vectors should have the same number of elements");
8348 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8349 ST->getOffset(), Mask,
ST->getVectorLength(),
8350 ST->getMemoryVT(),
ST->getMemOperand(),
8351 ST->getAddressingMode(),
ST->isTruncatingStore(),
8352 ST->isCompressingStore());
8357 assert((OpNo == 1 || OpNo == 4) &&
8358 "Can widen only data or mask operand of vp_strided_store");
8367 "Unable to widen VP strided store");
8371 "Unable to widen VP strided store");
8373 StVal = GetWidenedVector(StVal);
8374 Mask = GetWidenedVector(Mask);
8377 Mask.getValueType().getVectorElementCount() &&
8378 "Data and mask vectors should have the same number of elements");
8380 return DAG.getStridedStoreVP(
8387SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8388 assert((OpNo == 1 || OpNo == 4) &&
8389 "Can widen only data or mask operand of mstore");
8392 EVT MaskVT =
Mask.getValueType();
8397 EVT WideVT, WideMaskVT;
8400 StVal = GetWidenedVector(StVal);
8407 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8414 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8416 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8417 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8426 Mask = ModifyToType(Mask, WideMaskVT,
true);
8429 Mask = ModifyToType(Mask, WideMaskVT,
true);
8431 StVal = ModifyToType(StVal, WideVT);
8434 assert(
Mask.getValueType().getVectorElementCount() ==
8436 "Mask and data vectors should have the same number of elements");
8443SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8444 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8446 SDValue DataOp = MG->getPassThru();
8448 SDValue Scale = MG->getScale();
8456 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8457 MG->getMemOperand(), MG->getIndexType(),
8458 MG->getExtensionType());
8464SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8473 DataOp = GetWidenedVector(DataOp);
8477 EVT IndexVT =
Index.getValueType();
8480 Index = ModifyToType(Index, WideIndexVT);
8483 EVT MaskVT =
Mask.getValueType();
8486 Mask = ModifyToType(Mask, WideMaskVT,
true);
8491 }
else if (OpNo == 4) {
8493 Index = GetWidenedVector(Index);
8499 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8504SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8513 DataOp = GetWidenedVector(DataOp);
8514 Index = GetWidenedVector(Index);
8516 Mask = GetWidenedMask(Mask, WideEC);
8519 }
else if (OpNo == 3) {
8521 Index = GetWidenedVector(Index);
8528 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8533 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8534 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8536 EVT VT =
N->getValueType(0);
8551 SVT, InOp0, InOp1,
N->getOperand(2));
8557 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8559 EVT OpVT =
N->getOperand(0).getValueType();
8562 return DAG.getNode(ExtendCode, dl, VT, CC);
8572 EVT VT =
N->getValueType(0);
8574 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8581 for (
unsigned i = 0; i != NumElts; ++i) {
8582 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8583 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8585 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8586 {Chain, LHSElem, RHSElem, CC});
8587 Chains[i] = Scalars[i].getValue(1);
8588 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8589 DAG.getBoolConstant(
true, dl, EltVT, VT),
8590 DAG.getBoolConstant(
false, dl, EltVT, VT));
8594 ReplaceValueWith(
SDValue(
N, 1), NewChain);
8596 return DAG.getBuildVector(VT, dl, Scalars);
8620 SDValue Op = GetWidenedVector(
N->getOperand(0));
8621 EVT VT =
N->getValueType(0);
8622 EVT OrigVT =
N->getOperand(0).getValueType();
8623 EVT WideVT =
Op.getValueType();
8625 SDNodeFlags
Flags =
N->getFlags();
8627 unsigned Opc =
N->getOpcode();
8629 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8630 assert(NeutralElem &&
"Neutral element must exist");
8640 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8647 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8648 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8654 unsigned GCD = std::gcd(OrigElts, WideElts);
8657 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8658 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8659 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8660 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8663 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8664 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8666 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8675 EVT VT =
N->getValueType(0);
8677 EVT WideVT =
Op.getValueType();
8679 SDNodeFlags
Flags =
N->getFlags();
8681 unsigned Opc =
N->getOpcode();
8683 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8693 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8696 SDValue Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8697 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8703 unsigned GCD = std::gcd(OrigElts, WideElts);
8706 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8707 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8708 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8709 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8712 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8713 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8715 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8719 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8722 SDValue Op = GetWidenedVector(
N->getOperand(1));
8724 Op.getValueType().getVectorElementCount());
8726 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8727 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8735 EVT VT =
N->getValueType(0);
8739 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8740 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8745 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8751 EVT SourceVT =
Source.getValueType();
8752 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8756 WideSource = GetWidenedVector(Source);
8763 WideSource = GetWidenedVector(Source);
8765 SmallVector<int>
Mask(WideElts);
8766 std::iota(
Mask.begin(),
Mask.end(), 0);
8768 Mask[
I] += WideElts;
8769 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
8771 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8775 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8782 EVT SrcVT =
Source.getValueType();
8786 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8787 {Source, Mask, N->getOperand(2)},
N->getFlags());
8790SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8793 EVT OrigMaskVT =
Mask.getValueType();
8794 SDValue WideMask = GetWidenedVector(Mask);
8800 if (OrigElts != WideElts) {
8801 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8803 Mask, DAG.getVectorIdxConstant(0,
DL));
8810SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
8813 EVT ResVT =
N->getValueType(0);
8814 EVT SourceVT =
N->getOperand(0).getValueType();
8815 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8820 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
8821 N->getOperand(0), 0);
8822 SDValue WideMask = DAG.getInsertSubvector(
8823 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
8825 N->getOperand(1), WideMask,
N->getFlags());
8826 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
8830 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
8836 return TLI.expandVectorMatch(
N, DAG);
8838 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
8842 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
8843 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
8846 N->getOperand(0), WideNeedle,
N->getOperand(2),
8864 unsigned WidenEx = 0) {
8869 unsigned AlignInBits =
Align*8;
8871 EVT RetVT = WidenEltVT;
8876 if (Width == WidenEltWidth)
8887 (WidenWidth % MemVTWidth) == 0 &&
8889 (MemVTWidth <= Width ||
8890 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8891 if (MemVTWidth == WidenWidth)
8910 (WidenWidth % MemVTWidth) == 0 &&
8912 (MemVTWidth <= Width ||
8913 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8922 return std::nullopt;
8933 unsigned Start,
unsigned End) {
8934 SDLoc dl(LdOps[Start]);
8935 EVT LdTy = LdOps[Start].getValueType();
8943 for (
unsigned i = Start + 1; i != End; ++i) {
8944 EVT NewLdTy = LdOps[i].getValueType();
8945 if (NewLdTy != LdTy) {
8964 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8965 EVT LdVT =
LD->getMemoryVT();
8975 AAMDNodes AAInfo =
LD->getAAInfo();
8979 TypeSize WidthDiff = WidenWidth - LdWidth;
8986 std::optional<EVT> FirstVT =
8987 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
8994 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8999 std::optional<EVT> NewVT = FirstVT;
9000 TypeSize RemainingWidth = LdWidth;
9001 TypeSize NewVTWidth = FirstVTWidth;
9003 RemainingWidth -= NewVTWidth;
9010 NewVTWidth = NewVT->getSizeInBits();
9016 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9017 LD->getBaseAlign(), MMOFlags, AAInfo);
9030 MachinePointerInfo MPI =
LD->getPointerInfo();
9036 for (EVT MemVT : MemVTs) {
9037 Align NewAlign = ScaledOffset == 0
9038 ?
LD->getBaseAlign()
9041 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
9049 unsigned End = LdOps.
size();
9060 EVT LdTy = LdOps[i].getValueType();
9063 for (--i; i >= 0; --i) {
9064 LdTy = LdOps[i].getValueType();
9071 ConcatOps[--Idx] = LdOps[i];
9072 for (--i; i >= 0; --i) {
9073 EVT NewLdTy = LdOps[i].getValueType();
9074 if (NewLdTy != LdTy) {
9084 for (;
j != End-Idx; ++
j)
9085 WidenOps[j] = ConcatOps[Idx+j];
9087 WidenOps[j] = DAG.getPOISON(LdTy);
9094 ConcatOps[--Idx] = LdOps[i];
9099 ArrayRef(&ConcatOps[Idx], End - Idx));
9105 SDValue UndefVal = DAG.getPOISON(LdTy);
9108 for (; i != End-Idx; ++i)
9109 WidenOps[i] = ConcatOps[Idx+i];
9111 WidenOps[i] = UndefVal;
9122 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9123 EVT LdVT =
LD->getMemoryVT();
9132 AAMDNodes AAInfo =
LD->getAAInfo();
9146 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9147 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9153 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9154 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9155 LD->getBaseAlign(), MMOFlags, AAInfo);
9160 SDValue UndefVal = DAG.getPOISON(EltVT);
9161 for (; i != WidenNumElts; ++i)
9164 return DAG.getBuildVector(WidenVT, dl,
Ops);
9175 AAMDNodes AAInfo =
ST->getAAInfo();
9176 SDValue ValOp = GetWidenedVector(
ST->getValue());
9179 EVT StVT =
ST->getMemoryVT();
9187 "Mismatch between store and value types");
9191 MachinePointerInfo MPI =
ST->getPointerInfo();
9201 std::optional<EVT> NewVT =
9206 TypeSize NewVTWidth = NewVT->getSizeInBits();
9209 StWidth -= NewVTWidth;
9210 MemVTs.
back().second++;
9214 for (
const auto &Pair : MemVTs) {
9215 EVT NewVT = Pair.first;
9216 unsigned Count = Pair.second;
9222 Align NewAlign = ScaledOffset == 0
9223 ?
ST->getBaseAlign()
9225 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9226 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9242 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9243 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9244 ST->getBaseAlign(), MMOFlags, AAInfo);
9261 bool FillWithZeroes) {
9266 "input and widen element type must match");
9268 "cannot modify scalable vectors in this way");
9281 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9283 for (
unsigned i = 1; i != NumConcat; ++i)
9290 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9296 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9301 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9302 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9304 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9306 unsigned NumResultParts = NewNumElts / CommonFactor;
9307 if (NumResultParts > NumCopiedParts) {
9308 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9309 : DAG.getPOISON(PartVT);
9310 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9317 "Scalable vectors should have been handled already.");
9325 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9327 for (Idx = 0; Idx < MinNumElts; ++Idx)
9328 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9330 SDValue UndefVal = DAG.getPOISON(EltVT);
9331 for (; Idx < WidenNumElts; ++Idx)
9332 Ops[Idx] = UndefVal;
9334 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9335 if (!FillWithZeroes)
9339 "We expect to never want to FillWithZeroes for non-integral types.");
9342 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9343 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9345 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9346 DAG.getBuildVector(NVT, dl, MaskOps));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT, TypeSize FirstVTWidth, const SDLoc &dl, SelectionDAG &DAG)
Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the widened value so it can b...
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
const SmallVectorImpl< MachineOperand > & Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file implements the SmallBitVector class.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
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
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtractVectorElt(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Extract element at Idx from Vec.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS*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.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ 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 - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by OFFSET elements an...
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ MASKED_UDIV
Masked vector arithmetic that returns poison on disabled lanes.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_MATCH
VECTOR_MATCH - this corresponds to the llvm.experimental.vector.match intrinsic.
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
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.)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.