35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
47 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
50 switch (
N->getOpcode()) {
53 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
62 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
68 R = ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(
N);
73 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
76 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
82 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
92 R = ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
N);
98 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
100 R = ScalarizeVecRes_VECTOR_MATCH(
N);
103 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
109 R = ScalarizeVecRes_VecInregOp(
N);
161 R = ScalarizeVecRes_UnaryOp(
N);
164 R = ScalarizeVecRes_ADDRSPACECAST(
N);
170 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
228 R = ScalarizeVecRes_BinOp(
N);
235 R = ScalarizeVecRes_MaskedBinOp(
N);
239 R = ScalarizeVecRes_FPOp_MultiType(
N);
244 R = ScalarizeVecRes_CMP(
N);
250 R = ScalarizeVecRes_TernaryOp(
N);
253#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
254 case ISD::STRICT_##DAGN:
255#include "llvm/IR/ConstrainedOps.def"
256 R = ScalarizeVecRes_StrictFPOp(
N);
261 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
270 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
280 R = ScalarizeVecRes_FIX(
N);
286 SetScalarizedVector(
SDValue(
N, ResNo), R);
290 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
291 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
292 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
298 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
299 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
300 SDValue
Mask =
N->getOperand(2);
301 EVT MaskVT =
Mask.getValueType();
306 Mask = GetScalarizedVector(Mask);
314 SDValue Divisor = DAG.getSelect(
DL,
LHS.getValueType(), Mask,
RHS,
315 DAG.getConstant(1,
DL,
LHS.getValueType()));
317 LHS.getValueType(),
LHS, Divisor);
323 SDValue
LHS =
N->getOperand(0);
324 SDValue
RHS =
N->getOperand(1);
325 if (getTypeAction(
LHS.getValueType()) ==
327 LHS = GetScalarizedVector(
LHS);
328 RHS = GetScalarizedVector(
RHS);
330 EVT VT =
LHS.getValueType().getVectorElementType();
331 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
332 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
335 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
336 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
340 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
341 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
342 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
343 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
348 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
349 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
356DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
358 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
359 "Unexpected vector type!");
360 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
362 EVT VT0 =
N->getValueType(0);
363 EVT VT1 =
N->getValueType(1);
367 DAG.getNode(
N->getOpcode(), dl,
368 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
372 unsigned OtherNo = 1 - ResNo;
373 EVT OtherVT =
N->getValueType(OtherNo);
375 SetScalarizedVector(SDValue(
N, OtherNo), SDValue(ScalarNode, OtherNo));
378 SDValue(ScalarNode, OtherNo));
379 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
382 return SDValue(ScalarNode, ResNo);
387 unsigned NumOpers =
N->getNumOperands();
388 SDValue Chain =
N->getOperand(0);
389 EVT ValueVTs[] = {VT, MVT::Other};
398 for (
unsigned i = 1; i < NumOpers; ++i) {
399 SDValue Oper =
N->getOperand(i);
404 Oper = GetScalarizedVector(Oper);
413 SDValue
Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
414 Opers,
N->getFlags());
418 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
425 EVT ResVT =
N->getValueType(0);
426 EVT OvVT =
N->getValueType(1);
428 SDValue ScalarLHS, ScalarRHS;
430 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
431 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
434 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
435 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
436 ScalarLHS = ElemsLHS[0];
437 ScalarRHS = ElemsRHS[0];
440 SDVTList ScalarVTs = DAG.getVTList(
442 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
443 {ScalarLHS, ScalarRHS},
N->getFlags())
447 unsigned OtherNo = 1 - ResNo;
448 EVT OtherVT =
N->getValueType(OtherNo);
450 SetScalarizedVector(SDValue(
N, OtherNo), SDValue(ScalarNode, OtherNo));
452 SDValue OtherVal = DAG.
getNode(
454 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
457 return SDValue(ScalarNode, ResNo);
462 SDValue
Op = DisintegrateMERGE_VALUES(
N, ResNo);
463 return GetScalarizedVector(
Op);
466SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
469 SDValue
Mask = TLI.expandLoopDependenceMask(
N, DAG);
471 N->getValueType(0).getScalarType(), Mask,
472 DAG.getVectorIdxConstant(0,
DL));
476 SDValue
Op =
N->getOperand(0);
478 Op = GetScalarizedVector(
Op);
479 EVT NewVT =
N->getValueType(0).getVectorElementType();
484SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR_OR_SPLAT(
SDNode *
N) {
486 SDValue InOp =
N->getOperand(0);
494SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
496 N->getValueType(0).getVectorElementType(),
497 N->getOperand(0),
N->getOperand(1));
502 SDValue
Op =
N->getOperand(0);
503 EVT OpVT =
Op.getValueType();
507 Op = GetScalarizedVector(
Op);
510 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
513 N->getValueType(0).getVectorElementType(),
Op,
517SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
519 SDValue
Op =
N->getOperand(0);
520 EVT OpVT =
Op.getValueType();
524 Op = GetScalarizedVector(
Op);
527 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
530 N->getValueType(0).getVectorElementType(),
Op,
534SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
536 SDValue
Op =
N->getOperand(0);
537 EVT OpVT =
Op.getValueType();
540 Op = GetScalarizedVector(
Op);
543 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
546 N->getValueType(0).getVectorElementType(),
Op,
547 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
550SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
551 SDValue
Op = GetScalarizedVector(
N->getOperand(0));
552 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
556SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOp_MultiType(
SDNode *
N) {
558 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
559 SDValue
RHS =
N->getOperand(1);
560 EVT RHSVT =
RHS.getValueType();
565 RHS = GetScalarizedVector(
RHS);
569 return DAG.getNode(
N->getOpcode(),
DL,
LHS.getValueType(),
LHS,
RHS,
573SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
576 SDValue
Op =
N->getOperand(1);
578 if (
Op.getValueType() != EltVT)
585 SDValue
Result = DAG.getAtomicLoad(
586 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
587 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
592 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
597 assert(
N->isUnindexed() &&
"Indexed vector load?");
599 SDValue
Result = DAG.getLoad(
601 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
602 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
603 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
604 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
605 N->getMMOMetadataForSubAccess());
609 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
616 SDValue
Op =
N->getOperand(0);
617 EVT OpVT =
Op.getValueType();
627 Op = GetScalarizedVector(
Op);
630 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
632 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
638 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
639 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
640 LHS, DAG.getValueType(ExtVT));
645 SDValue
Op =
N->getOperand(0);
647 EVT OpVT =
Op.getValueType();
652 Op = GetScalarizedVector(
Op);
654 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
657 switch (
N->getOpcode()) {
669SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
671 SDValue
Op =
N->getOperand(0);
672 EVT OpVT =
Op.getValueType();
682 Op = GetScalarizedVector(
Op);
685 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
688 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
689 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
690 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS,
691 AddrSpaceCastN->getFlags());
694SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
705DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
706 assert(
N->getNumValues() ==
N->getNumOperands() &&
707 "Expected one result per operand");
711 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
712 SetScalarizedVector(SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
717 SDValue
Cond =
N->getOperand(0);
718 EVT OpVT =
Cond.getValueType();
727 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
730 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
732 TLI.getBooleanContents(
false,
false);
739 if (TLI.getBooleanContents(
false,
false) !=
740 TLI.getBooleanContents(
false,
true)) {
744 EVT OpVT =
Cond->getOperand(0).getValueType();
746 VecBool = TLI.getBooleanContents(OpVT);
751 EVT CondVT =
Cond.getValueType();
752 if (ScalarBool != VecBool) {
753 switch (ScalarBool) {
761 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
768 Cond, DAG.getValueType(MVT::i1));
774 auto BoolVT = getSetCCResultType(CondVT);
775 if (BoolVT.bitsLT(CondVT))
778 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
779 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
783 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
784 return DAG.getSelect(SDLoc(
N),
785 LHS.getValueType(),
N->getOperand(0),
LHS,
786 GetScalarizedVector(
N->getOperand(2)));
790 SDValue
LHS = GetScalarizedVector(
N->getOperand(2));
792 N->getOperand(0),
N->getOperand(1),
793 LHS, GetScalarizedVector(
N->getOperand(3)),
798 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
801SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
805 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
807 return GetScalarizedVector(
N->getOperand(
Op));
810SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
811 SDValue Src =
N->getOperand(0);
812 EVT SrcVT = Src.getValueType();
817 Src = GetScalarizedVector(Src);
821 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
823 EVT DstVT =
N->getValueType(0).getVectorElementType();
824 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
828 assert(
N->getValueType(0).isVector() &&
829 N->getOperand(0).getValueType().isVector() &&
830 "Operand types must be vectors");
831 SDValue
LHS =
N->getOperand(0);
832 SDValue
RHS =
N->getOperand(1);
833 EVT OpVT =
LHS.getValueType();
834 EVT NVT =
N->getValueType(0).getVectorElementType();
839 LHS = GetScalarizedVector(
LHS);
840 RHS = GetScalarizedVector(
RHS);
843 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
844 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
854 return DAG.getNode(ExtendCode,
DL, NVT, Res);
865 Arg = GetScalarizedVector(Arg);
868 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
877 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
884bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
887 SDValue Res = SDValue();
890 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
893 switch (
N->getOpcode()) {
896 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
903 Res = ScalarizeVecOp_BITCAST(
N);
906 Res = ScalarizeVecOp_FAKE_USE(
N);
920 Res = ScalarizeVecOp_UnaryOp(
N);
925 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
928 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
929 "Unexpected vector type!");
930 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
931 SDValue
Op = DAG.getNode(
932 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
933 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
941 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
944 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
947 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
950 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
953 Res = ScalarizeVecOp_VSELECT(
N);
956 Res = ScalarizeVecOp_VSETCC(
N);
960 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
969 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
972 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
975 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
978 Res = ScalarizeVecOp_FP_EXTEND(
N);
997 Res = ScalarizeVecOp_VECREDUCE(
N);
1001 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
1005 Res = ScalarizeVecOp_CMP(
N);
1008 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
1012 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
1015 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
1021 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
1026 if (!Res.
getNode())
return false;
1034 "Invalid operand expansion");
1036 ReplaceValueWith(SDValue(
N, 0), Res);
1043 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1045 N->getValueType(0), Elt);
1050 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1051 "Fake Use: Unexpected vector type!");
1052 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1053 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1059 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1060 "Unexpected vector type!");
1061 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1062 SDValue
Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1063 N->getValueType(0).getScalarType(), Elt);
1071SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1072 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1073 "Unexpected vector type!");
1074 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1076 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1077 Elt,
N->getOperand(1));
1085SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1086 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1087 "Unexpected vector type!");
1088 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1089 SDValue Res = DAG.
getNode(
N->getOpcode(), SDLoc(
N),
1090 {
N->getValueType(0).getScalarType(), MVT::Other },
1091 {
N->getOperand(0), Elt });
1094 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1101 ReplaceValueWith(SDValue(
N, 0), Res);
1106SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1108 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1109 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1110 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1115SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1119 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1120 SDValue ContainingVec =
N->getOperand(0);
1128SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1129 EVT VT =
N->getValueType(0);
1130 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1142 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1143 EVT VT =
N->getValueType(0);
1145 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1154 assert(
N->getValueType(0).isVector() &&
1155 N->getOperand(0).getValueType().isVector() &&
1156 "Operand types must be vectors");
1157 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1158 "Expected single-element vector type");
1160 EVT VT =
N->getValueType(0);
1161 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
1162 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
1164 EVT OpVT =
N->getOperand(0).getValueType();
1176 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1182SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1184 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1185 assert(
N->getValueType(0).isVector() &&
1186 N->getOperand(1).getValueType().isVector() &&
1187 "Operand types must be vectors");
1188 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1189 "Expected single-element vector type");
1191 EVT VT =
N->getValueType(0);
1192 SDValue Ch =
N->getOperand(0);
1193 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
1194 SDValue
RHS = GetScalarizedVector(
N->getOperand(2));
1195 SDValue CC =
N->getOperand(3);
1197 EVT OpVT =
N->getOperand(1).getValueType();
1200 SDValue Res = DAG.
getNode(
N->getOpcode(),
DL, {MVT::i1, MVT::Other},
1201 {Ch, LHS, RHS, CC});
1205 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1210 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1215 ReplaceValueWith(SDValue(
N, 0), Res);
1222 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1223 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1226 if (
N->isTruncatingStore())
1227 return DAG.getTruncStore(
1228 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1229 N->getBasePtr(),
N->getPointerInfo(),
1230 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1231 N->getMemOperand()->getFlags(),
N->getMMOMetadataForSubAccess());
1233 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1234 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1235 N->getMemOperand()->getFlags(),
1236 N->getMMOMetadataForSubAccess());
1242 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1244 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1245 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1250SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1251 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1252 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1254 N->getValueType(0).getVectorElementType(), Elt,
1259SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1261 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1262 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1265 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1269 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1275 ReplaceValueWith(SDValue(
N, 0), Res);
1282 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1284 N->getValueType(0).getVectorElementType(), Elt);
1290SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1291 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1294 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1295 {
N->getOperand(0), Elt});
1298 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1304 ReplaceValueWith(SDValue(
N, 0), Res);
1309 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1316SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1322 SDValue
Op = GetScalarizedVector(VecOp);
1323 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1324 AccOp,
Op,
N->getFlags());
1328 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
1329 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
1332 SDValue
Cmp = DAG.getNode(
N->getOpcode(), SDLoc(
N), ResVT,
LHS,
RHS);
1336SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1344 EVT VT =
N->getValueType(0);
1345 return DAG.getConstant(0, SDLoc(
N), VT);
1352 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1353 SDValue
Op = GetScalarizedVector(
N->getOperand(0));
1355 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1356 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1357 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1360SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1363 SDValue
Mask = TLI.expandVectorMatch(
N, DAG);
1365 N->getValueType(0).getScalarType(), Mask,
1366 DAG.getVectorIdxConstant(0,
DL));
1371 return TLI.expandVectorMatch(
N, DAG);
1374SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1375 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1378 SDValue
LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1379 SDValue
RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1380 SDValue
Mask = GetScalarizedVector(
N->getOperand(2));
1388 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1400void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1405 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1408 switch (
N->getOpcode()) {
1411 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1420 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1423 SplitVecRes_MASK_BEFOREFIRST(
N,
Lo,
Hi);
1430 case ISD::VP_MERGE: SplitRes_Select(
N,
Lo,
Hi);
break;
1446 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1449 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1461 case ISD::VP_LOAD_FF:
1464 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1471 case ISD::VP_GATHER:
1475 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1478 SplitVecRes_SETCC(
N,
Lo,
Hi);
1481 SplitVecRes_VECTOR_REPEAT(
N,
Lo,
Hi);
1484 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1491 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1494 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1497 SplitVecRes_VECTOR_INTERLEAVE(
N);
1500 SplitVecRes_VAARG(
N,
Lo,
Hi);
1506 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1560 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1563 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1569 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1575 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1631 SplitVecRes_BinOp(
N,
Lo,
Hi);
1637 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1642 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1646 SplitVecRes_CMP(
N,
Lo,
Hi);
1649#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1650 case ISD::STRICT_##DAGN:
1651#include "llvm/IR/ConstrainedOps.def"
1652 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1657 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1666 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1676 SplitVecRes_FIX(
N,
Lo,
Hi);
1678 case ISD::EXPERIMENTAL_VP_SPLICE:
1679 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1681 case ISD::EXPERIMENTAL_VP_REVERSE:
1682 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1688 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1691 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1694 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1700 SetSplitVector(SDValue(
N, ResNo),
Lo,
Hi);
1703void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1710 SDValue BytesIncrement = DAG.getVScale(
1713 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1715 *ScaledOffset += IncrementSize;
1725std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1726 return SplitMask(Mask, SDLoc(Mask));
1729std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1731 SDValue MaskLo, MaskHi;
1732 EVT MaskVT =
Mask.getValueType();
1734 GetSplitVector(Mask, MaskLo, MaskHi);
1736 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1737 return std::make_pair(MaskLo, MaskHi);
1741 SDValue LHSLo, LHSHi;
1742 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1743 SDValue RHSLo, RHSHi;
1744 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1747 const SDNodeFlags
Flags =
N->getFlags();
1748 unsigned Opcode =
N->getOpcode();
1749 if (
N->getNumOperands() == 2) {
1750 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1751 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1755 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1756 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
1757 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
1758 "Expected VP opcode");
1760 SDValue MaskLo, MaskHi;
1761 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1763 SDValue EVLLo, EVLHi;
1764 std::tie(EVLLo, EVLHi) =
1765 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1768 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1770 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1775 SDValue LHSLo, LHSHi;
1776 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1777 SDValue RHSLo, RHSHi;
1778 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1780 SDValue MaskLo, MaskHi,
Mask =
N->getOperand(2);
1782 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1784 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1788 const SDNodeFlags
Flags =
N->getFlags();
1789 unsigned Opcode =
N->getOpcode();
1790 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1792 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1798 SDValue Op0Lo, Op0Hi;
1799 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1800 SDValue Op1Lo, Op1Hi;
1801 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1802 SDValue Op2Lo, Op2Hi;
1803 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1806 const SDNodeFlags
Flags =
N->getFlags();
1807 unsigned Opcode =
N->getOpcode();
1809 DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1811 DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1815 LLVMContext &Ctxt = *DAG.getContext();
1818 SDValue
LHS =
N->getOperand(0);
1819 SDValue
RHS =
N->getOperand(1);
1821 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1823 GetSplitVector(
LHS, LHSLo, LHSHi);
1824 GetSplitVector(
RHS, RHSLo, RHSHi);
1826 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1827 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1831 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1832 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1836 SDValue LHSLo, LHSHi;
1837 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1838 SDValue RHSLo, RHSHi;
1839 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1843 unsigned Opcode =
N->getOpcode();
1844 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1846 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1855 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1862 switch (getTypeAction(InVT)) {
1876 GetExpandedOp(InOp,
Lo,
Hi);
1877 if (DAG.getDataLayout().isBigEndian())
1887 GetSplitVector(InOp,
Lo,
Hi);
1896 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1905 if (DAG.getDataLayout().isBigEndian())
1908 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1910 if (DAG.getDataLayout().isBigEndian())
1916void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1920 SDValue PtrA =
N->getOperand(0);
1921 SDValue PtrB =
N->getOperand(1);
1922 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1925 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1930 unsigned LaneOffset =
1933 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1935 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1942 GetSplitVector(
N->getOperand(0), InLo, InHi);
1948 SDValue
Cond = DAG.getBoolExtOrTrunc(AnyLoActive,
DL,
1949 getSetCCResultType(MVT::i1), MVT::i1);
1958 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1961 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1964 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1969 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1971 unsigned NumSubvectors =
N->getNumOperands() / 2;
1972 if (NumSubvectors == 1) {
1973 Lo =
N->getOperand(0);
1974 Hi =
N->getOperand(1);
1979 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1988void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1990 SDValue Vec =
N->getOperand(0);
1991 SDValue Idx =
N->getOperand(1);
1995 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2010 GetSplitVector(Vec,
Lo,
Hi);
2013 EVT LoVT =
Lo.getValueType();
2023 if (IdxVal + SubElems <= LoElems) {
2031 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
2033 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
2039 SDValue WideSubVec = GetWidenedVector(SubVec);
2041 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2049 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2051 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2052 auto &MF = DAG.getMachineFunction();
2056 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2061 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2062 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2066 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2071 MachinePointerInfo MPI =
Load->getPointerInfo();
2072 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2075 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2083 SDValue LHSLo, LHSHi;
2084 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2087 SDValue RHSLo, RHSHi;
2088 SDValue
RHS =
N->getOperand(1);
2089 EVT RHSVT =
RHS.getValueType();
2092 GetSplitVector(
RHS, RHSLo, RHSHi);
2094 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2107 SDValue ArgLo, ArgHi;
2108 SDValue
Test =
N->getOperand(1);
2109 SDValue FpValue =
N->getOperand(0);
2111 GetSplitVector(FpValue, ArgLo, ArgHi);
2113 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2115 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2123 SDValue LHSLo, LHSHi;
2124 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2128 std::tie(LoVT, HiVT) =
2132 DAG.getValueType(LoVT));
2134 DAG.getValueType(HiVT));
2139 unsigned Opcode =
N->getOpcode();
2140 SDValue N0 =
N->getOperand(0);
2146 GetSplitVector(N0, InLo, InHi);
2148 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2153 EVT OutLoVT, OutHiVT;
2154 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2156 assert((2 * OutNumElements) <= InNumElements &&
2157 "Illegal extend vector in reg split");
2166 SmallVector<int, 8> SplitHi(InNumElements, -1);
2167 for (
unsigned i = 0; i != OutNumElements; ++i)
2168 SplitHi[i] = i + OutNumElements;
2169 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2171 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2172 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2177 unsigned NumOps =
N->getNumOperands();
2181 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2191 for (
unsigned i = 1; i <
NumOps; ++i) {
2192 SDValue
Op =
N->getOperand(i);
2196 EVT InVT =
Op.getValueType();
2201 GetSplitVector(
Op, OpLo, OpHi);
2203 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2210 EVT LoValueVTs[] = {LoVT, MVT::Other};
2211 EVT HiValueVTs[] = {HiVT, MVT::Other};
2212 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2214 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2220 Lo.getValue(1),
Hi.getValue(1));
2224 ReplaceValueWith(SDValue(
N, 1), Chain);
2227SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2229 EVT VT =
N->getValueType(0);
2240 else if (NE > ResNE)
2244 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2248 for (i = 0; i !=
NE; ++i) {
2250 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2251 SDValue Operand =
N->getOperand(j);
2255 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2261 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2269 for (; i < ResNE; ++i)
2270 Scalars.
push_back(DAG.getPOISON(EltVT));
2274 ReplaceValueWith(SDValue(
N, 1), Chain);
2278 return DAG.getBuildVector(VecVT, dl, Scalars);
2281void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2284 EVT ResVT =
N->getValueType(0);
2285 EVT OvVT =
N->getValueType(1);
2286 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2287 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2288 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2290 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2292 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2293 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2295 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2296 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2299 unsigned Opcode =
N->getOpcode();
2300 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2301 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2303 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2305 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2307 Lo = SDValue(LoNode, ResNo);
2308 Hi = SDValue(HiNode, ResNo);
2311 unsigned OtherNo = 1 - ResNo;
2312 EVT OtherVT =
N->getValueType(OtherNo);
2314 SetSplitVector(SDValue(
N, OtherNo),
2315 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2317 SDValue OtherVal = DAG.
getNode(
2319 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2320 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
2324void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2330 GetSplitVector(Vec,
Lo,
Hi);
2333 unsigned IdxVal = CIdx->getZExtValue();
2334 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2335 if (IdxVal < LoNumElts) {
2337 Lo.getValueType(),
Lo, Elt, Idx);
2340 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2360 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2362 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2363 auto &MF = DAG.getMachineFunction();
2367 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2372 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2373 Store = DAG.getTruncStore(
2379 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2382 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2386 MachinePointerInfo MPI =
Load->getPointerInfo();
2387 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2389 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2392 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2393 if (LoVT !=
Lo.getValueType())
2395 if (HiVT !=
Hi.getValueType())
2403 assert(
N->getValueType(0).isScalableVector() &&
2404 "Only scalable vectors are supported for STEP_VECTOR");
2405 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2406 SDValue Step =
N->getOperand(0);
2426 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2427 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2429 Hi = DAG.getPOISON(HiVT);
2439 "Extended load during type legalization!");
2441 EVT VT =
LD->getValueType(0);
2443 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2445 SDValue Ch =
LD->getChain();
2446 SDValue Ptr =
LD->getBasePtr();
2451 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2452 Ch, Ptr,
LD->getMemOperand());
2456 SDValue ExtractLo, ExtractHi;
2457 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2459 Lo = DAG.getBitcast(LoVT, ExtractLo);
2460 Hi = DAG.getBitcast(HiVT, ExtractHi);
2464 ReplaceValueWith(SDValue(LD, 1), ALD.
getValue(1));
2472 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2475 SDValue Ch =
LD->getChain();
2476 SDValue Ptr =
LD->getBasePtr();
2478 EVT MemoryVT =
LD->getMemoryVT();
2480 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
2482 EVT LoMemVT, HiMemVT;
2483 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2486 SDValue
Value, NewChain;
2487 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2488 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2489 ReplaceValueWith(SDValue(LD, 1), NewChain);
2494 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2497 MachinePointerInfo MPI;
2498 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2501 HiMemVT,
LD->getBaseAlign(), MMOFlags,
Metadata);
2510 ReplaceValueWith(SDValue(LD, 1), Ch);
2515 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2518 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2521 SDValue Ch =
LD->getChain();
2522 SDValue Ptr =
LD->getBasePtr();
2524 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2526 SDValue
Mask =
LD->getMask();
2527 SDValue EVL =
LD->getVectorLength();
2528 EVT MemoryVT =
LD->getMemoryVT();
2530 EVT LoMemVT, HiMemVT;
2531 bool HiIsEmpty =
false;
2532 std::tie(LoMemVT, HiMemVT) =
2533 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2536 SDValue MaskLo, MaskHi;
2538 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2541 GetSplitVector(Mask, MaskLo, MaskHi);
2543 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2547 SDValue EVLLo, EVLHi;
2548 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2550 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2553 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2556 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2557 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2565 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2566 LD->isExpandingLoad());
2568 MachinePointerInfo MPI;
2570 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2572 MPI =
LD->getPointerInfo().getWithOffset(
2575 MMO = DAG.getMachineFunction().getMachineMemOperand(
2577 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2579 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2580 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2581 LD->isExpandingLoad());
2591 ReplaceValueWith(SDValue(LD, 1), Ch);
2597 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2599 SDValue Ch =
LD->getChain();
2600 SDValue Ptr =
LD->getBasePtr();
2602 SDValue
Mask =
LD->getMask();
2603 SDValue EVL =
LD->getVectorLength();
2606 SDValue MaskLo, MaskHi;
2608 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2611 GetSplitVector(Mask, MaskLo, MaskHi);
2613 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2617 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2619 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2622 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2624 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2627 Hi = DAG.getPOISON(HiVT);
2629 ReplaceValueWith(SDValue(LD, 1),
Lo.getValue(1));
2630 ReplaceValueWith(SDValue(LD, 2),
Lo.getValue(2));
2636 "Indexed VP strided load during type legalization!");
2638 "Unexpected indexed variable-length load offset");
2643 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2645 EVT LoMemVT, HiMemVT;
2646 bool HiIsEmpty =
false;
2647 std::tie(LoMemVT, HiMemVT) =
2648 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2651 SDValue LoMask, HiMask;
2653 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2656 GetSplitVector(Mask, LoMask, HiMask);
2658 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2661 SDValue LoEVL, HiEVL;
2662 std::tie(LoEVL, HiEVL) =
2666 Lo = DAG.getStridedLoadVP(
2693 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2700 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2711 ReplaceValueWith(SDValue(SLD, 1), Ch);
2719 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2724 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2732 SDValue MaskLo, MaskHi;
2734 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2737 GetSplitVector(Mask, MaskLo, MaskHi);
2739 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2743 EVT LoMemVT, HiMemVT;
2744 bool HiIsEmpty =
false;
2745 std::tie(LoMemVT, HiMemVT) =
2746 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2748 SDValue PassThruLo, PassThruHi;
2750 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2752 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2754 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2759 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2769 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2772 MachinePointerInfo MPI;
2779 MMO = DAG.getMachineFunction().getMachineMemOperand(
2784 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2796 ReplaceValueWith(SDValue(MLD, 1), Ch);
2804 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2806 SDValue Ch =
N->getChain();
2807 SDValue Ptr =
N->getBasePtr();
2814 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2817 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2820 EVT MemoryVT =
N->getMemoryVT();
2824 SDValue MaskLo, MaskHi;
2826 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2828 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2831 EVT LoMemVT, HiMemVT;
2833 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2835 SDValue IndexHi, IndexLo;
2836 if (getTypeAction(
Ops.Index.getValueType()) ==
2838 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2840 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2843 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2845 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2848 SDValue PassThru = MGT->getPassThru();
2849 SDValue PassThruLo, PassThruHi;
2852 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2854 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2859 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2860 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2861 OpsLo, MMO, IndexTy, ExtType);
2863 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2864 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2865 OpsHi, MMO, IndexTy, ExtType);
2868 SDValue EVLLo, EVLHi;
2869 std::tie(EVLLo, EVLHi) =
2870 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2872 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2873 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2874 MMO, VPGT->getIndexType());
2876 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2877 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2878 MMO, VPGT->getIndexType());
2888 ReplaceValueWith(SDValue(
N, 1), Ch);
2902 EVT VecVT =
N->getValueType(0);
2904 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2905 bool HasCustomLowering =
false;
2912 HasCustomLowering =
true;
2918 SDValue Passthru =
N->getOperand(2);
2919 if (!HasCustomLowering) {
2920 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2921 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2926 SDValue
Mask =
N->getOperand(1);
2927 SDValue LoMask, HiMask;
2928 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2929 std::tie(LoMask, HiMask) = SplitMask(Mask);
2931 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2935 SDValue
StackPtr = DAG.CreateStackTemporary(
2936 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2949 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2951 SDValue Chain = DAG.getEntryNode();
2952 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2956 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2960 EVT MaskVT =
Mask.getValueType();
2964 SDValue NumActiveElts =
2967 SDValue StepVector = DAG.getStepVector(
DL, WideMaskVT);
2968 SDValue SplatNumActiveElts = DAG.getSplat(WideMaskVT,
DL, NumActiveElts);
2969 SDValue CompressedMask =
2970 DAG.getSetCC(
DL, MaskVT, StepVector, SplatNumActiveElts,
ISD::SETULT);
2973 Compressed, Passthru);
2975 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2979 assert(
N->getValueType(0).isVector() &&
2980 N->getOperand(0).getValueType().isVector() &&
2981 "Operand types must be vectors");
2985 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2988 SDValue LL, LH, RL, RH;
2989 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2991 GetSplitVector(
N->getOperand(0), LL, LH);
2993 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2995 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2997 GetSplitVector(
N->getOperand(1), RL, RH);
2999 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
3001 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
3002 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
3010 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3014 EVT InVT =
N->getOperand(0).getValueType();
3016 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3018 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3020 const SDNodeFlags
Flags =
N->getFlags();
3021 unsigned Opcode =
N->getOpcode();
3023 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
3024 N->getOperand(3), Flags);
3025 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
3026 N->getOperand(3), Flags);
3032 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
3033 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
3035 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
3036 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
3043 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3047 EVT InVT =
N->getOperand(0).getValueType();
3049 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3051 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3054 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3055 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3056 SDNodeFlags
Flags = AddrSpaceCastN->getFlags();
3057 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS, Flags);
3058 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS, Flags);
3061void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3066 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3067 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3071 EVT InVT =
N->getOperand(0).getValueType();
3073 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3075 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3077 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3078 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3080 SDNode *HiNode =
Hi.getNode();
3081 SDNode *LoNode =
Lo.getNode();
3084 unsigned OtherNo = 1 - ResNo;
3085 EVT OtherVT =
N->getValueType(OtherNo);
3087 SetSplitVector(SDValue(
N, OtherNo), SDValue(LoNode, OtherNo),
3088 SDValue(HiNode, OtherNo));
3092 SDValue(HiNode, OtherNo));
3093 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
3100 EVT SrcVT =
N->getOperand(0).getValueType();
3101 EVT DestVT =
N->getValueType(0);
3103 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3120 LLVMContext &Ctx = *DAG.getContext();
3124 EVT SplitLoVT, SplitHiVT;
3125 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3126 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3127 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3128 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3129 N->dump(&DAG);
dbgs() <<
"\n");
3132 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3134 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3136 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3137 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3142 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3150 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3151 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3157 return N.getResNo() == 0 &&
3161 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](SDValue &Input1,
3163 ArrayRef<int>
Mask) {
3166 "Expected build vector node.");
3169 for (
unsigned I = 0;
I < NewElts; ++
I) {
3172 unsigned Idx =
Mask[
I];
3174 Ops[
I] = Input2.getOperand(Idx - NewElts);
3176 Ops[
I] = Input1.getOperand(Idx);
3181 return DAG.getBuildVector(NewVT,
DL,
Ops);
3187 SmallVector<int> OrigMask(
N->getMask());
3189 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3190 &
DL](SmallVectorImpl<int> &
Mask) {
3192 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3193 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3194 SDValue Input = Inputs[Idx];
3204 for (
auto &
P : ShufflesIdxs) {
3205 if (
P.second.size() < 2)
3209 for (
int &Idx : Mask) {
3212 unsigned SrcRegIdx = Idx / NewElts;
3213 if (Inputs[SrcRegIdx].
isUndef()) {
3221 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3226 Idx = MaskElt % NewElts +
3227 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3233 Inputs[
P.second[0]] =
P.first.first;
3234 Inputs[
P.second[1]] =
P.first.second;
3237 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3240 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3241 for (
int &Idx : Mask) {
3244 unsigned SrcRegIdx = Idx / NewElts;
3245 if (Inputs[SrcRegIdx].
isUndef()) {
3252 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3253 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3256 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3258 if (UsedSubVector.count() > 1) {
3260 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3261 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3263 if (Pairs.
empty() || Pairs.
back().size() == 2)
3265 if (UsedSubVector.test(2 *
I)) {
3266 Pairs.
back().emplace_back(
I, 0);
3268 assert(UsedSubVector.test(2 *
I + 1) &&
3269 "Expected to be used one of the subvectors.");
3270 Pairs.
back().emplace_back(
I, 1);
3273 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3275 for (
int &Idx : Mask) {
3278 unsigned SrcRegIdx = Idx / NewElts;
3280 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3281 return Idxs.front().first == SrcRegIdx ||
3282 Idxs.back().first == SrcRegIdx;
3284 if (It == Pairs.
end())
3286 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3287 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3290 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3291 Inputs[Idxs.front().first] = DAG.
getNode(
3293 Inputs[Idxs.front().first].getValueType(),
3294 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3295 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3304 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3308 if (Shuffle->getOperand(0).getValueType() != NewVT)
3311 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3312 !Shuffle->isSplat()) {
3314 }
else if (!Inputs[
I].hasOneUse() &&
3315 !Shuffle->getOperand(1).isUndef()) {
3317 for (
int &Idx : Mask) {
3320 unsigned SrcRegIdx = Idx / NewElts;
3323 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3328 int OpIdx = MaskElt / NewElts;
3341 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3342 if (Shuffle->getOperand(OpIdx).isUndef())
3344 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3345 if (It == std::end(Inputs))
3347 int FoundOp = std::distance(std::begin(Inputs), It);
3350 for (
int &Idx : Mask) {
3353 unsigned SrcRegIdx = Idx / NewElts;
3356 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3361 int MaskIdx = MaskElt / NewElts;
3362 if (OpIdx == MaskIdx)
3363 Idx = MaskElt % NewElts + FoundOp * NewElts;
3366 Op = (OpIdx + 1) % 2;
3374 for (
int &Idx : Mask) {
3377 unsigned SrcRegIdx = Idx / NewElts;
3380 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3381 int OpIdx = MaskElt / NewElts;
3384 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3390 TryPeekThroughShufflesInputs(OrigMask);
3392 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3393 NewElts](SmallVectorImpl<int> &
Mask) {
3394 SetVector<SDValue> UniqueInputs;
3395 SetVector<SDValue> UniqueConstantInputs;
3396 for (
const auto &
I : Inputs) {
3398 UniqueConstantInputs.
insert(
I);
3399 else if (!
I.isUndef())
3404 if (UniqueInputs.
size() != std::size(Inputs)) {
3405 auto &&UniqueVec = UniqueInputs.
takeVector();
3406 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3407 unsigned ConstNum = UniqueConstantVec.size();
3408 for (
int &Idx : Mask) {
3411 unsigned SrcRegIdx = Idx / NewElts;
3412 if (Inputs[SrcRegIdx].
isUndef()) {
3416 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3417 if (It != UniqueConstantVec.end()) {
3418 Idx = (Idx % NewElts) +
3419 NewElts * std::distance(UniqueConstantVec.begin(), It);
3420 assert(Idx >= 0 &&
"Expected defined mask idx.");
3423 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3424 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3425 Idx = (Idx % NewElts) +
3426 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3427 assert(Idx >= 0 &&
"Expected defined mask idx.");
3429 copy(UniqueConstantVec, std::begin(Inputs));
3430 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3433 MakeUniqueInputs(OrigMask);
3434 SDValue OrigInputs[4];
3435 copy(Inputs, std::begin(OrigInputs));
3441 unsigned FirstMaskIdx =
High * NewElts;
3444 assert(!Output &&
"Expected default initialized initial value.");
3445 TryPeekThroughShufflesInputs(Mask);
3446 MakeUniqueInputs(Mask);
3447 SDValue TmpInputs[4];
3448 copy(Inputs, std::begin(TmpInputs));
3451 bool SecondIteration =
false;
3452 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3457 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3458 SecondIteration =
true;
3459 return SecondIteration;
3462 Mask, std::size(Inputs), std::size(Inputs),
3464 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3465 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3466 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3468 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3470 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3471 DAG.getPOISON(NewVT), Mask);
3472 Inputs[Idx] = Output;
3474 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3475 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3476 unsigned Idx2,
bool ) {
3477 if (AccumulateResults(Idx1)) {
3480 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3482 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3483 Inputs[Idx2], Mask);
3487 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3489 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3490 TmpInputs[Idx2], Mask);
3492 Inputs[Idx1] = Output;
3494 copy(OrigInputs, std::begin(Inputs));
3499 EVT OVT =
N->getValueType(0);
3503 SDValue
SV =
N->getOperand(2);
3507 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3509 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV,
Alignment.value());
3510 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV,
Alignment.value());
3515 ReplaceValueWith(SDValue(
N, 1), Chain);
3520 EVT DstVTLo, DstVTHi;
3521 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3524 SDValue SrcLo, SrcHi;
3525 EVT SrcVT =
N->getOperand(0).getValueType();
3527 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3529 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3531 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3532 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3537 EVT VT =
N->getValueType(0);
3538 SDValue Src =
N->getOperand(0);
3539 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VT);
3540 assert(LoVT == HiVT &&
"Expected equal split types");
3545 auto [SrcLo, SrcHi] = DAG.SplitVector(Src,
DL);
3547 SDValue Deinterleaved =
3549 DAG.getVTList(SplitSrcVT, SplitSrcVT), SrcLo, SrcHi);
3555 DAG.getVTList(LoVT, LoVT), Even, Odd);
3563 GetSplitVector(
N->getOperand(0), InLo, InHi);
3574 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3575 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3580 EVT VT =
N->getValueType(0);
3581 SDValue Val =
N->getOperand(0);
3582 SDValue
Mask =
N->getOperand(1);
3603 EVT PtrVT =
StackPtr.getValueType();
3604 auto &MF = DAG.getMachineFunction();
3608 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3611 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3616 SDValue NumElemMinus1 =
3617 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3618 DAG.getConstant(1,
DL, PtrVT));
3619 SDValue StartOffset = DAG.getNode(
ISD::MUL,
DL, PtrVT, NumElemMinus1,
3620 DAG.getConstant(EltWidth,
DL, PtrVT));
3621 SDValue StorePtr = DAG.getNode(
ISD::ADD,
DL, PtrVT, StackPtr, StartOffset);
3622 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3624 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3625 SDValue
Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3626 DAG.getPOISON(PtrVT), Stride, TrueMask,
3629 SDValue
Load = DAG.getLoadVP(VT,
DL,
Store, StackPtr, Mask, EVL, LoadMMO);
3635 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3640 EVT VT =
N->getValueType(0);
3641 SDValue
V1 =
N->getOperand(0);
3642 SDValue V2 =
N->getOperand(1);
3644 SDValue
Mask =
N->getOperand(3);
3645 SDValue EVL1 =
N->getOperand(4);
3646 SDValue EVL2 =
N->getOperand(5);
3652 EVL1 = ZExtPromotedInteger(EVL1);
3671 EVT PtrVT =
StackPtr.getValueType();
3672 auto &MF = DAG.getMachineFunction();
3676 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3679 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3683 SDValue EltByteSize =
3685 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3686 SDValue EVL1Bytes = DAG.getNode(
ISD::MUL,
DL, PtrVT, EVL1Ptr, EltByteSize);
3690 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3691 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3693 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3695 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3699 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3704 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3705 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3709 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3712 SDValue OffsetToV2 = DAG.getNode(
ISD::SUB,
DL, PtrVT, StackPtr2, StackPtr);
3718 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3726 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3728 DAG.getVectorIdxConstant(0,
DL));
3734void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3737 SDValue Acc =
N->getOperand(0);
3738 SDValue Input1 =
N->getOperand(1);
3739 SDValue Input2 =
N->getOperand(2);
3741 SDValue AccLo, AccHi;
3742 GetSplitVector(Acc, AccLo, AccHi);
3743 unsigned Opcode =
N->getOpcode();
3753 SDValue Input1Lo, Input1Hi;
3754 SDValue Input2Lo, Input2Hi;
3755 GetSplitVector(Input1, Input1Lo, Input1Hi);
3756 GetSplitVector(Input2, Input2Lo, Input2Hi);
3759 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3760 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3763void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3771 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3775 SDValue HiStartVal = DAG.getNode(
ISD::UADDSAT,
DL, OpVT, Op0, LoElts);
3781 SDValue SourceLo, SourceHi;
3782 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3783 SDValue MaskLo, MaskHi;
3784 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3788 N->getOperand(1), MaskLo,
N->getFlags());
3790 N->getOperand(1), MaskHi,
N->getFlags());
3793void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3794 unsigned Factor =
N->getNumOperands();
3797 for (
unsigned i = 0; i != Factor; ++i) {
3799 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3801 Ops[i * 2 + 1] = OpHi;
3812 for (
unsigned i = 0; i != Factor; ++i)
3816void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3817 unsigned Factor =
N->getNumOperands();
3820 for (
unsigned i = 0; i != Factor; ++i) {
3822 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3824 Ops[i + Factor] = OpHi;
3835 for (
unsigned i = 0; i != Factor; ++i) {
3836 unsigned IdxLo = 2 * i;
3837 unsigned IdxHi = 2 * i + 1;
3838 SetSplitVector(SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3839 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3851bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3853 SDValue Res = SDValue();
3856 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3859 switch (
N->getOpcode()) {
3862 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3871 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3878 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3881 Res = SplitVecOp_TruncateHelper(
N);
3887 Res = SplitVecOp_FP_ROUND(
N);
3899 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3906 case ISD::VP_SCATTER:
3910 case ISD::VP_GATHER:
3914 Res = SplitVecOp_VSELECT(
N, OpNo);
3920 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3923 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3929 if (
N->getValueType(0).bitsLT(
3930 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3931 Res = SplitVecOp_TruncateHelper(
N);
3933 Res = SplitVecOp_UnaryOp(
N);
3937 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3953 Res = SplitVecOp_UnaryOp(
N);
3956 Res = SplitVecOp_FPOpDifferentTypes(
N);
3961 Res = SplitVecOp_CMP(
N);
3965 Res = SplitVecOp_FAKE_USE(
N);
3970 Res = SplitVecOp_ExtVecInRegOp(
N);
3990 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3994 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3996 case ISD::VP_REDUCE_FADD:
3997 case ISD::VP_REDUCE_SEQ_FADD:
3998 case ISD::VP_REDUCE_FMUL:
3999 case ISD::VP_REDUCE_SEQ_FMUL:
4000 case ISD::VP_REDUCE_ADD:
4001 case ISD::VP_REDUCE_MUL:
4002 case ISD::VP_REDUCE_AND:
4003 case ISD::VP_REDUCE_OR:
4004 case ISD::VP_REDUCE_XOR:
4005 case ISD::VP_REDUCE_SMAX:
4006 case ISD::VP_REDUCE_SMIN:
4007 case ISD::VP_REDUCE_UMAX:
4008 case ISD::VP_REDUCE_UMIN:
4009 case ISD::VP_REDUCE_FMAX:
4010 case ISD::VP_REDUCE_FMIN:
4011 case ISD::VP_REDUCE_FMAXIMUM:
4012 case ISD::VP_REDUCE_FMINIMUM:
4013 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
4017 Res = SplitVecOp_CttzElts(
N);
4019 case ISD::VP_CTTZ_ELTS:
4020 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
4021 Res = SplitVecOp_VP_CttzElements(
N);
4024 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
4030 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
4033 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
4038 if (!Res.
getNode())
return false;
4045 if (
N->isStrictFPOpcode())
4047 "Invalid operand expansion");
4050 "Invalid operand expansion");
4052 ReplaceValueWith(SDValue(
N, 0), Res);
4056SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
4059 SDValue LoMask, HiMask;
4060 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
4062 EVT VT =
N->getValueType(0);
4074 SDValue
Cond = DAG.getBoolExtOrTrunc(AnyHiActive,
DL,
4075 getSetCCResultType(MVT::i1), MVT::i1);
4080 DAG.getElementCount(
DL, VT, SplitEC)),
4084SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4087 assert(OpNo == 0 &&
"Illegal operand must be mask");
4089 SDValue
Mask =
N->getOperand(0);
4090 SDValue Src0 =
N->getOperand(1);
4091 SDValue Src1 =
N->getOperand(2);
4094 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4097 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4098 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4099 "Lo and Hi have differing types");
4102 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4103 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4105 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4106 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4107 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4108 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4118SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4119 assert(OpNo == 2 &&
"Illegal operand must be mask");
4122 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4123 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4124 SDValue MaskLo, MaskHi;
4125 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4128 RHSLo, MaskLo,
N->getFlags());
4130 RHSHi, MaskHi,
N->getFlags());
4134SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4137 assert(OpNo == 1 &&
"Illegal operand must be mask");
4142 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4144 EVT VecVT =
N->getValueType(0);
4148SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4149 EVT ResVT =
N->getValueType(0);
4155 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4156 GetSplitVector(VecOp,
Lo,
Hi);
4158 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4163 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4164 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4168 EVT ResVT =
N->getValueType(0);
4174 SDNodeFlags
Flags =
N->getFlags();
4177 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4178 GetSplitVector(VecOp,
Lo,
Hi);
4180 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4183 SDValue Partial = DAG.
getNode(
N->getOpcode(), dl, ResVT, AccOp,
Lo, Flags);
4186 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4189SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4190 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4191 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4193 unsigned Opc =
N->getOpcode();
4194 EVT ResVT =
N->getValueType(0);
4200 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4201 GetSplitVector(VecOp,
Lo,
Hi);
4203 SDValue MaskLo, MaskHi;
4204 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4206 SDValue EVLLo, EVLHi;
4207 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4209 const SDNodeFlags
Flags =
N->getFlags();
4213 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4218 EVT ResVT =
N->getValueType(0);
4221 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4222 EVT InVT =
Lo.getValueType();
4227 if (
N->isStrictFPOpcode()) {
4228 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4229 {N->getOperand(0), Lo});
4230 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4231 {N->getOperand(0), Hi});
4240 ReplaceValueWith(SDValue(
N, 1), Ch);
4242 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4243 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4252 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4262 EVT ResVT =
N->getValueType(0);
4264 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4268 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4274 Lo = BitConvertToInteger(
Lo);
4275 Hi = BitConvertToInteger(
Hi);
4277 if (DAG.getDataLayout().isBigEndian())
4285 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4287 EVT ResVT =
N->getValueType(0);
4295 GetSplitVector(SubVec,
Lo,
Hi);
4300 SDValue FirstInsertion =
4302 SDValue SecondInsertion =
4304 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4306 return SecondInsertion;
4309SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4316 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4318 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4320 ElementCount IdxVal =
4324 EVT SrcVT =
N->getOperand(0).getValueType();
4343 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4344 LoEltsMin - IdxValMin);
4345 DAG.ExtractVectorElements(
Hi, Elts, 0,
4348 return DAG.getBuildVector(SubVT, dl, Elts);
4352 ElementCount ExtractIdx = IdxVal - LoElts;
4354 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4357 EVT HiVT =
Hi.getValueType();
4359 "Only fixed-vector extracts are supported in this case");
4369 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4370 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4376 "Extracting scalable subvector from fixed-width unsupported");
4384 "subvector from a scalable predicate vector");
4390 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4392 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4393 auto &MF = DAG.getMachineFunction();
4397 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4401 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4404 SubVT, dl,
Store, StackPtr,
4408SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4417 GetSplitVector(Vec,
Lo,
Hi);
4419 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4421 if (IdxVal < LoElts)
4422 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4424 return SDValue(DAG.UpdateNodeOperands(
N,
Hi,
4425 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4430 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4440 SDValue NewExtract =
4442 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4448 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4450 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4451 auto &MF = DAG.getMachineFunction();
4454 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4458 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4462 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4464 return DAG.getExtLoad(
4475 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4483 SplitVecRes_Gather(
N,
Lo,
Hi);
4486 ReplaceValueWith(SDValue(
N, 0), Res);
4491 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4492 SDValue Ch =
N->getChain();
4493 SDValue Ptr =
N->getBasePtr();
4494 SDValue
Offset =
N->getOffset();
4495 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4496 SDValue
Mask =
N->getMask();
4497 SDValue EVL =
N->getVectorLength();
4498 SDValue
Data =
N->getValue();
4502 SDValue DataLo, DataHi;
4505 GetSplitVector(
Data, DataLo, DataHi);
4507 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4510 SDValue MaskLo, MaskHi;
4512 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4515 GetSplitVector(Mask, MaskLo, MaskHi);
4517 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4520 EVT MemoryVT =
N->getMemoryVT();
4521 EVT LoMemVT, HiMemVT;
4522 bool HiIsEmpty =
false;
4523 std::tie(LoMemVT, HiMemVT) =
4524 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4527 SDValue EVLLo, EVLHi;
4528 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4531 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4534 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4536 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4537 N->getAddressingMode(),
N->isTruncatingStore(),
4538 N->isCompressingStore());
4544 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4545 N->isCompressingStore());
4547 MachinePointerInfo MPI;
4551 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4556 MMO = DAG.getMachineFunction().getMachineMemOperand(
4558 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4560 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4561 N->getAddressingMode(),
N->isTruncatingStore(),
4562 N->isCompressingStore());
4571 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4572 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4576 SDValue
Data =
N->getValue();
4577 SDValue LoData, HiData;
4579 GetSplitVector(
Data, LoData, HiData);
4581 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4583 EVT LoMemVT, HiMemVT;
4584 bool HiIsEmpty =
false;
4585 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4588 SDValue
Mask =
N->getMask();
4589 SDValue LoMask, HiMask;
4591 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4592 else if (getTypeAction(
Mask.getValueType()) ==
4594 GetSplitVector(Mask, LoMask, HiMask);
4596 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4598 SDValue LoEVL, HiEVL;
4599 std::tie(LoEVL, HiEVL) =
4600 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4603 SDValue
Lo = DAG.getStridedStoreVP(
4604 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4605 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4606 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4617 EVT PtrVT =
N->getBasePtr().getValueType();
4620 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4628 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4629 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4631 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4633 SDValue
Hi = DAG.getStridedStoreVP(
4634 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4635 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4636 N->isCompressingStore());
4645 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4646 SDValue Ch =
N->getChain();
4647 SDValue Ptr =
N->getBasePtr();
4648 SDValue
Offset =
N->getOffset();
4649 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4650 SDValue
Mask =
N->getMask();
4651 SDValue
Data =
N->getValue();
4655 SDValue DataLo, DataHi;
4658 GetSplitVector(
Data, DataLo, DataHi);
4660 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4663 SDValue MaskLo, MaskHi;
4665 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4668 GetSplitVector(Mask, MaskLo, MaskHi);
4670 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4673 EVT MemoryVT =
N->getMemoryVT();
4674 EVT LoMemVT, HiMemVT;
4675 bool HiIsEmpty =
false;
4676 std::tie(LoMemVT, HiMemVT) =
4677 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4679 SDValue
Lo,
Hi, Res;
4680 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4683 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4685 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4686 N->getAddressingMode(),
N->isTruncatingStore(),
4687 N->isCompressingStore());
4695 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4696 N->isCompressingStore());
4698 MachinePointerInfo MPI;
4702 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4707 MMO = DAG.getMachineFunction().getMachineMemOperand(
4710 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4712 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4713 N->getAddressingMode(),
N->isTruncatingStore(),
4714 N->isCompressingStore());
4725 SDValue Ch =
N->getChain();
4726 SDValue Ptr =
N->getBasePtr();
4727 EVT MemoryVT =
N->getMemoryVT();
4737 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4741 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4746 EVT LoMemVT, HiMemVT;
4747 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4749 SDValue DataLo, DataHi;
4752 GetSplitVector(
Ops.Data, DataLo, DataHi);
4754 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4757 SDValue MaskLo, MaskHi;
4759 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4761 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4764 SDValue IndexHi, IndexLo;
4765 if (getTypeAction(
Ops.Index.getValueType()) ==
4767 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4769 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4773 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4775 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4778 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4780 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4781 MSC->getIndexType(), MSC->isTruncatingStore());
4786 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4787 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4788 MMO, MSC->getIndexType(),
4789 MSC->isTruncatingStore());
4792 SDValue EVLLo, EVLHi;
4793 std::tie(EVLLo, EVLHi) =
4794 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4796 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4797 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4798 VPSC->getIndexType());
4803 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4804 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4805 VPSC->getIndexType());
4809 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4810 assert(OpNo == 1 &&
"Can only split the stored value");
4813 bool isTruncating =
N->isTruncatingStore();
4814 SDValue Ch =
N->getChain();
4815 SDValue Ptr =
N->getBasePtr();
4816 EVT MemoryVT =
N->getMemoryVT();
4819 MMOMetadata
Metadata =
N->getMMOMetadataForSubAccess();
4821 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4823 EVT LoMemVT, HiMemVT;
4824 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4828 return TLI.scalarizeVectorStore(
N, DAG);
4831 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4834 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4837 MachinePointerInfo MPI;
4838 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4841 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI, HiMemVT, Alignment, MMOFlags,
4844 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags,
Metadata);
4851 LLVMContext &Ctx = *DAG.getContext();
4852 SDValue StVal =
N->getVal();
4869 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4870 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4874 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4877 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4878 DAG.getBitcast(MemVecVT, Wide), 0);
4880 N->getBasePtr(),
N->getMemOperand());
4888 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4890 N->getBasePtr(),
N->getMemOperand());
4903 for (
const SDValue &
Op :
N->op_values()) {
4904 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4910 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4931 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4932 SDValue InVec =
N->getOperand(OpNo);
4934 EVT OutVT =
N->getValueType(0);
4942 EVT LoOutVT, HiOutVT;
4943 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4944 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4949 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4951 return SplitVecOp_UnaryOp(
N);
4960 return SplitVecOp_UnaryOp(
N);
4963 SDValue InLoVec, InHiVec;
4964 GetSplitVector(InVec, InLoVec, InHiVec);
4970 EVT HalfElementVT = IsFloat ?
4972 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4979 if (
N->isStrictFPOpcode()) {
4980 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4981 {N->getOperand(0), InLoVec});
4982 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4983 {N->getOperand(0), InHiVec});
4989 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4990 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4994 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
5002 if (
N->isStrictFPOpcode()) {
5006 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
5008 ReplaceValueWith(SDValue(
N, 1), SDValue(Res.
getNode(), 1));
5014 DAG.getTargetConstant(
5015 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
5022 assert(
N->getValueType(0).isVector() &&
5023 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
5024 "Operand types must be vectors");
5026 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
5028 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
5029 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
5031 EVT VT =
N->getValueType(0);
5032 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
5038 assert(isStrict &&
"unexpected node");
5039 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5040 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
5041 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
5042 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
5045 ReplaceValueWith(SDValue(
N, 1), NewChain);
5053 EVT OpVT =
N->getOperand(0).getValueType();
5056 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
5062 EVT ResVT =
N->getValueType(0);
5065 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
5066 EVT InVT =
Lo.getValueType();
5071 if (
N->isStrictFPOpcode()) {
5072 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5073 {N->getOperand(0), Lo, N->getOperand(2)});
5074 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5075 {N->getOperand(0), Hi, N->getOperand(2)});
5079 Lo.getValue(1),
Hi.getValue(1));
5080 ReplaceValueWith(SDValue(
N, 1), NewChain);
5082 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5083 N->getOperand(2),
N->getOperand(3));
5084 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5085 N->getOperand(2),
N->getOperand(3));
5087 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5088 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5099SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5102 EVT LHSLoVT, LHSHiVT;
5103 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5105 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5106 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5108 SDValue LHSLo, LHSHi;
5109 std::tie(LHSLo, LHSHi) =
5110 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5112 SDValue RHSLo, RHSHi;
5113 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5115 SDValue
Lo = DAG.
getNode(
N->getOpcode(),
DL, LHSLoVT, LHSLo, RHSLo);
5116 SDValue
Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5122 LLVMContext &Ctxt = *DAG.getContext();
5125 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5126 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5127 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5129 EVT ResVT =
N->getValueType(0);
5134 SDValue
Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5135 SDValue
Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5141 EVT ResVT =
N->getValueType(0);
5144 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5145 EVT InVT =
Lo.getValueType();
5151 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5152 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5159 EVT ResVT =
N->getValueType(0);
5163 GetSplitVector(VecOp,
Lo,
Hi);
5169 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5170 SDValue ResLoNotVL =
5171 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5172 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi);
5173 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5174 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5179 EVT ResVT =
N->getValueType(0);
5183 GetSplitVector(VecOp,
Lo,
Hi);
5185 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5186 auto [EVLLo, EVLHi] =
5188 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5192 SDValue ResLo = DAG.
getNode(ISD::VP_CTTZ_ELTS,
DL, ResVT,
Lo, MaskLo, EVLLo);
5193 SDValue ResLoNotEVL =
5194 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5195 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi, MaskHi, EVLHi);
5196 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5197 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5200SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5203 SDValue Inc = HG->
getInc();
5211 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5212 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5213 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5214 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5215 SDValue
Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5216 OpsLo, MMO, IndexType);
5217 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5218 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5222SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5226 EVT LoResVT, HiResVT;
5227 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5228 SDValue SourceLo, SourceHi;
5229 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5230 SDValue MaskLo, MaskHi;
5231 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5234 N->getOperand(1), MaskLo,
N->getFlags());
5236 N->getOperand(1), MaskHi,
N->getFlags());
5242 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5244 SDValue NeedleLo, NeedleHi;
5245 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5249 NeedleLo,
N->getOperand(2),
N->getFlags());
5252 NeedleHi,
N->getOperand(2),
N->getFlags());
5253 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5256SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5259 "Accumulator should already be a legal type, and shouldn't need "
5260 "further splitting");
5263 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5264 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5265 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5266 unsigned Opcode =
N->getOpcode();
5269 SDValue
Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5270 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5277void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5278 unsigned WidenResNo) {
5279 unsigned NumResults =
N->getNumValues();
5280 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5281 if (ResNo == WidenResNo)
5283 EVT ResVT =
N->getValueType(ResNo);
5285 SetWidenedVector(SDValue(
N, ResNo), SDValue(WidenNode, ResNo));
5289 DAG.getExtractSubvector(
DL, ResVT, SDValue(WidenNode, ResNo), 0);
5290 ReplaceValueWith(SDValue(
N, ResNo), ResVal);
5295void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5296 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5299 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5302 SDValue Res = SDValue();
5304 auto unrollExpandedOp = [&]() {
5309 EVT ResVT =
N->getValueType(ResNo);
5310 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5311 EVT VT0 =
N->getValueType(0);
5312 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5313 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT0.
getScalarType())) {
5317 if (
N->getNumValues() > 1)
5318 ReplaceOtherWidenResults(
N, Unrolled.
getNode(), ResNo);
5324 switch (
N->getOpcode()) {
5327 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5335 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5339 Res = WidenVecRes_ADDRSPACECAST(
N);
5346 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5353 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5357 Res = WidenVecRes_ScalarOp(
N);
5363 Res = WidenVecRes_Select(
N);
5366 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5368 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5375 case ISD::VP_LOAD_FF:
5378 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5382 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5390 case ISD::VP_GATHER:
5394 Res = WidenVecRes_VECTOR_REVERSE(
N);
5397 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5400 WidenVecRes_VECTOR_INTERLEAVE(
N);
5403 Res = WidenVecRes_VECTOR_MATCH(
N);
5406 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5460 Res = WidenVecRes_Binary(
N);
5467 Res = WidenVecRes_MaskedBinary(
N);
5472 Res = WidenVecRes_CMP(
N);
5478 if (unrollExpandedOp())
5493 Res = WidenVecRes_BinaryCanTrap(
N);
5502 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5505#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5506 case ISD::STRICT_##DAGN:
5507#include "llvm/IR/ConstrainedOps.def"
5508 Res = WidenVecRes_StrictFP(
N);
5517 Res = WidenVecRes_OverflowOp(
N, ResNo);
5521 Res = WidenVecRes_FCOPYSIGN(
N);
5526 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5531 if (!unrollExpandedOp())
5532 Res = WidenVecRes_ExpOp(
N);
5538 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5553 Res = WidenVecRes_Convert(
N);
5558 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5565 Res = WidenVecRes_XROUND(
N);
5591 if (unrollExpandedOp())
5614 Res = WidenVecRes_Unary(
N);
5619 Res = WidenVecRes_Ternary(
N);
5625 if (!unrollExpandedOp())
5626 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5633 Res = WidenVecRes_PARTIAL_REDUCE_MLA(
N);
5639 SetWidenedVector(SDValue(
N, ResNo), Res);
5645 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5646 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5647 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5648 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5649 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5655 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5656 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5657 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5658 if (
N->getNumOperands() == 2)
5659 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5662 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5663 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5664 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5665 "Expected VP opcode");
5669 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5670 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5675 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5676 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5677 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5678 SDValue
Mask =
N->getOperand(2);
5680 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5681 Mask = ModifyToType(Mask, WideMaskVT,
true);
5682 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5687 LLVMContext &Ctxt = *DAG.getContext();
5690 SDValue
LHS =
N->getOperand(0);
5691 SDValue
RHS =
N->getOperand(1);
5692 EVT OpVT =
LHS.getValueType();
5694 LHS = GetWidenedVector(
LHS);
5695 RHS = GetWidenedVector(
RHS);
5696 OpVT =
LHS.getValueType();
5699 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5702 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5708SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5711 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5712 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5713 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5715 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5724 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5727 if (ConcatEnd == 1) {
5728 VT = ConcatOps[0].getValueType();
5730 return ConcatOps[0];
5733 SDLoc dl(ConcatOps[0]);
5740 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
5741 int Idx = ConcatEnd - 1;
5742 VT = ConcatOps[Idx--].getValueType();
5743 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
5756 unsigned NumToInsert = ConcatEnd - Idx - 1;
5757 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5759 ConcatOps[Idx+1] = VecOp;
5760 ConcatEnd = Idx + 2;
5766 unsigned RealVals = ConcatEnd - Idx - 1;
5767 unsigned SubConcatEnd = 0;
5768 unsigned SubConcatIdx = Idx + 1;
5769 while (SubConcatEnd < RealVals)
5770 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5771 while (SubConcatEnd < OpsToConcat)
5772 SubConcatOps[SubConcatEnd++] = undefVec;
5774 NextVT, SubConcatOps);
5775 ConcatEnd = SubConcatIdx + 1;
5780 if (ConcatEnd == 1) {
5781 VT = ConcatOps[0].getValueType();
5783 return ConcatOps[0];
5788 if (
NumOps != ConcatEnd ) {
5790 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5791 ConcatOps[j] = UndefVal;
5799 unsigned Opcode =
N->getOpcode();
5801 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5805 const SDNodeFlags
Flags =
N->getFlags();
5806 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5807 NumElts = NumElts / 2;
5811 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5813 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5814 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5815 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5823 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5826 TLI.isTypeLegal(WideMaskVT)) {
5827 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5828 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5829 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5831 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5832 N->getValueType(0).getVectorElementCount());
5833 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5847 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5848 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5849 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5852 unsigned ConcatEnd = 0;
5860 while (CurNumElts != 0) {
5861 while (CurNumElts >= NumElts) {
5862 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5863 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5864 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5866 CurNumElts -= NumElts;
5869 NumElts = NumElts / 2;
5871 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5874 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5875 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5876 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5877 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5888 switch (
N->getOpcode()) {
5891 return WidenVecRes_STRICT_FSETCC(
N);
5898 return WidenVecRes_Convert_StrictFP(
N);
5905 unsigned Opcode =
N->getOpcode();
5907 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5911 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5912 NumElts = NumElts / 2;
5923 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5927 unsigned ConcatEnd = 0;
5934 for (
unsigned i = 1; i < NumOpers; ++i) {
5940 Oper = GetWidenedVector(Oper);
5946 DAG.getPOISON(WideOpVT), Oper,
5947 DAG.getVectorIdxConstant(0, dl));
5959 while (CurNumElts != 0) {
5960 while (CurNumElts >= NumElts) {
5963 for (
unsigned i = 0; i < NumOpers; ++i) {
5964 SDValue
Op = InOps[i];
5966 EVT OpVT =
Op.getValueType();
5971 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5977 EVT OperVT[] = {VT, MVT::Other};
5978 SDValue Oper = DAG.
getNode(Opcode, dl, OperVT, EOps);
5979 ConcatOps[ConcatEnd++] = Oper;
5982 CurNumElts -= NumElts;
5985 NumElts = NumElts / 2;
5987 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5990 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5993 for (
unsigned i = 0; i < NumOpers; ++i) {
5994 SDValue
Op = InOps[i];
5996 EVT OpVT =
Op.getValueType();
6004 EVT WidenVT[] = {WidenEltVT, MVT::Other};
6005 SDValue Oper = DAG.
getNode(Opcode, dl, WidenVT, EOps);
6006 ConcatOps[ConcatEnd++] = Oper;
6015 if (Chains.
size() == 1)
6016 NewChain = Chains[0];
6019 ReplaceValueWith(SDValue(
N, 1), NewChain);
6024SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
6026 EVT ResVT =
N->getValueType(0);
6027 EVT OvVT =
N->getValueType(1);
6028 EVT WideResVT, WideOvVT;
6029 SDValue WideLHS, WideRHS;
6033 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
6038 WideLHS = GetWidenedVector(
N->getOperand(0));
6039 WideRHS = GetWidenedVector(
N->getOperand(1));
6041 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
6046 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
6047 SDValue
Poison = DAG.getPOISON(WideResVT);
6050 N->getOperand(0), Zero);
6052 N->getOperand(1), Zero);
6055 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
6056 SDNode *WideNode = DAG.getNode(
6057 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
6060 unsigned OtherNo = 1 - ResNo;
6061 EVT OtherVT =
N->getValueType(OtherNo);
6063 SetWidenedVector(SDValue(
N, OtherNo), SDValue(WideNode, OtherNo));
6065 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
6066 SDValue OtherVal = DAG.
getNode(
6068 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
6071 return SDValue(WideNode, ResNo);
6075 LLVMContext &Ctx = *DAG.getContext();
6079 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6084 unsigned Opcode =
N->getOpcode();
6085 const SDNodeFlags
Flags =
N->getFlags();
6091 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6093 InOp = ZExtPromotedInteger(InOp);
6104 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
6105 if (
N->getNumOperands() == 1)
6106 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6108 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6109 N->getOperand(3), Flags);
6110 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6114 InOp = GetWidenedVector(
N->getOperand(0));
6117 if (InVTEC == WidenEC)
6118 return MakeConvertNode(WidenVT, InOp);
6142 SDValue MidRes = DAG.getNode(
ISD::TRUNCATE,
DL, MidResVT, InOp, Flags);
6143 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6147 if (TLI.isTypeLegal(InWidenVT)) {
6155 unsigned NumConcat =
6160 return MakeConvertNode(WidenVT, InVec);
6164 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6166 return MakeConvertNode(WidenVT, InVal);
6175 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6176 for (
unsigned i=0; i < MinElts; ++i) {
6177 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6178 Ops[i] = MakeConvertNode(EltVT, Val);
6181 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6186 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6189 SDValue Src =
N->getOperand(0);
6190 EVT SrcVT = Src.getValueType();
6194 Src = GetWidenedVector(Src);
6195 SrcVT = Src.getValueType();
6202 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6207 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6210 SDValue Src =
N->getOperand(0);
6211 EVT SrcVT = Src.getValueType();
6215 Src = GetWidenedVector(Src);
6216 SrcVT = Src.getValueType();
6223 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6226SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6231 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6237 unsigned Opcode =
N->getOpcode();
6243 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6248 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6249 for (
unsigned i=0; i < MinElts; ++i) {
6250 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6251 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6255 ReplaceValueWith(SDValue(
N, 1), NewChain);
6257 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6260SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6261 unsigned Opcode =
N->getOpcode();
6265 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6274 InOp = GetWidenedVector(InOp);
6281 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6288 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6289 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6306 while (
Ops.size() != WidenNumElts)
6307 Ops.push_back(DAG.getPOISON(WidenSVT));
6309 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6315 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6316 return WidenVecRes_BinaryCanTrap(
N);
6319 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6326SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6328 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6331 SDValue Arg = GetWidenedVector(FpValue);
6332 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6337 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6338 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6339 SDValue
RHS =
N->getOperand(1);
6340 EVT ExpVT =
RHS.getValueType();
6341 SDValue ExpOp =
RHS;
6345 ExpOp = ModifyToType(
RHS, WideExpVT);
6348 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6353 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6354 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6355 if (
N->getNumOperands() == 1)
6356 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6358 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6363 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6368 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6369 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6370 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6373SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6375 EVT VT0 =
N->getValueType(0);
6376 EVT VT1 =
N->getValueType(1);
6380 "expected both results to be vectors of matching element count");
6382 LLVMContext &Ctx = *DAG.getContext();
6383 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6385 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6392 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6395 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6396 return SDValue(WidenNode, ResNo);
6399SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6400 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6401 return GetWidenedVector(WidenVec);
6406 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6418 InOp = GetWidenedVector(InOp);
6422 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6425 return DAG.getAddrSpaceCast(
6426 DL, WidenVT, InOp, AddrSpaceCastN->getSrcAddressSpace(),
6427 AddrSpaceCastN->getDestAddressSpace(), AddrSpaceCastN->getFlags());
6433 EVT VT =
N->getValueType(0);
6434 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6437 switch (getTypeAction(InVT)) {
6451 SDValue NInOp = GetPromotedInteger(InOp);
6453 if (WidenVT.
bitsEq(NInVT)) {
6456 if (DAG.getDataLayout().isBigEndian()) {
6459 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6477 InOp = GetWidenedVector(InOp);
6479 if (WidenVT.
bitsEq(InVT))
6489 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6494 unsigned NewNumParts = WidenSize / InSize;
6507 EVT OrigInVT =
N->getOperand(0).getValueType();
6512 if (TLI.isTypeLegal(NewInVT)) {
6520 if (WidenSize % InSize == 0) {
6527 DAG.ExtractVectorElements(InOp,
Ops);
6528 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6540 return CreateStackStoreLoad(InOp, WidenVT);
6543SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6545 N->getOpcode(), SDLoc(
N),
6546 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6547 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6553 EVT VT =
N->getValueType(0);
6557 EVT EltVT =
N->getOperand(0).getValueType();
6560 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6564 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6565 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6567 return DAG.getBuildVector(WidenVT, dl, NewOps);
6571 EVT InVT =
N->getOperand(0).getValueType();
6572 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6574 unsigned NumOperands =
N->getNumOperands();
6576 bool InputWidened =
false;
6580 if (WidenNumElts % NumInElts == 0) {
6582 unsigned NumConcat = WidenNumElts / NumInElts;
6583 SDValue UndefVal = DAG.getPOISON(InVT);
6585 for (
unsigned i=0; i < NumOperands; ++i)
6586 Ops[i] =
N->getOperand(i);
6587 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6592 InputWidened =
true;
6593 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6596 for (i=1; i < NumOperands; ++i)
6597 if (!
N->getOperand(i).isUndef())
6600 if (i == NumOperands)
6603 return GetWidenedVector(
N->getOperand(0));
6605 if (NumOperands == 2) {
6607 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6612 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6613 for (
unsigned i = 0; i < NumInElts; ++i) {
6615 MaskOps[i + NumInElts] = i + WidenNumElts;
6617 return DAG.getVectorShuffle(WidenVT, dl,
6618 GetWidenedVector(
N->getOperand(0)),
6619 GetWidenedVector(
N->getOperand(1)),
6626 SDValue WideVec = DAG.getPOISON(WidenVT);
6628 for (
unsigned I = 0;
I < NumOperands; ++
I)
6630 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6641 for (
unsigned i=0; i < NumOperands; ++i) {
6644 InOp = GetWidenedVector(InOp);
6645 for (
unsigned j = 0;
j < NumInElts; ++
j)
6646 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6648 SDValue UndefVal = DAG.getPOISON(EltVT);
6649 for (; Idx < WidenNumElts; ++Idx)
6650 Ops[Idx] = UndefVal;
6651 return DAG.getBuildVector(WidenVT, dl,
Ops);
6654SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6655 EVT VT =
N->getValueType(0);
6656 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6657 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6659 SDValue Idx =
N->getOperand(2);
6664SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6665 EVT VT =
N->getValueType(0);
6667 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6672 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6674 InOp = GetWidenedVector(InOp);
6680 if (IdxVal == 0 && InVT == WidenVT)
6687 assert(IdxVal % VTNumElts == 0 &&
6688 "Expected Idx to be a multiple of subvector minimum vector length");
6689 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6702 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6703 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6704 "down type's element count");
6711 for (;
I < VTNumElts / GCD; ++
I)
6713 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6714 for (;
I < WidenNumElts / GCD; ++
I)
6736 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6743 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6744 return DAG.getMaskedLoad(
6745 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6753 for (i = 0; i < VTNumElts; ++i)
6754 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6756 SDValue UndefVal = DAG.getPOISON(EltVT);
6757 for (; i < WidenNumElts; ++i)
6759 return DAG.getBuildVector(WidenVT, dl,
Ops);
6763 SDValue InOp = ModifyToType(
6765 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6770SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6771 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6774 N->getOperand(1),
N->getOperand(2));
6783 "Load width must be less than or equal to first value type width");
6792 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6809 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6820 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6821 EVT LdVT =
LD->getMemoryVT();
6825 SDValue Chain =
LD->getChain();
6830 TypeSize WidthDiff = WidenWidth - LdWidth;
6833 std::optional<EVT> FirstVT =
6834 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6841 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6844 Chain, BasePtr,
LD->getMemOperand());
6848 FirstVTWidth, dl, DAG);
6852 ReplaceValueWith(SDValue(LD, 1), LdOp.
getValue(1));
6866 if (!
LD->getMemoryVT().isByteSized()) {
6867 SDValue
Value, NewChain;
6868 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6869 ReplaceValueWith(SDValue(LD, 0),
Value);
6870 ReplaceValueWith(SDValue(LD, 1), NewChain);
6879 EVT VT =
LD->getValueType(0);
6880 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6881 EVT WideMaskVT = getSetCCResultType(WideVT);
6884 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6885 TLI.isTypeLegal(WideMaskVT)) {
6887 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
6888 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6892 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6893 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6897 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
6905 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6907 Result = GenWidenVectorLoads(LdChain, LD);
6914 if (LdChain.
size() == 1)
6915 NewChain = LdChain[0];
6921 ReplaceValueWith(SDValue(
N, 1), NewChain);
6932 SDValue NewLoad = DAG.getMaskedLoad(
6933 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6934 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6935 LD->getAddressingMode(),
LD->getExtensionType());
6937 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
6945 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6946 SDValue
Mask =
N->getMask();
6947 SDValue EVL =
N->getVectorLength();
6954 "Unable to widen binary VP op");
6955 Mask = GetWidenedVector(Mask);
6956 assert(
Mask.getValueType().getVectorElementCount() ==
6957 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6958 .getVectorElementCount() &&
6959 "Unable to widen vector load");
6962 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6963 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6964 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6967 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
6972 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6973 SDValue
Mask =
N->getMask();
6974 SDValue EVL =
N->getVectorLength();
6980 "Unable to widen binary VP op");
6981 Mask = GetWidenedVector(Mask);
6982 assert(
Mask.getValueType().getVectorElementCount() ==
6983 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6984 .getVectorElementCount() &&
6985 "Unable to widen vector load");
6987 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6988 Mask, EVL,
N->getMemOperand());
6989 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
6990 ReplaceValueWith(SDValue(
N, 2), Res.
getValue(2));
6998 SDValue
Mask =
N->getMask();
7001 "Unable to widen VP strided load");
7002 Mask = GetWidenedVector(Mask);
7004 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7005 assert(
Mask.getValueType().getVectorElementCount() ==
7007 "Data and mask vectors should have the same number of elements");
7009 SDValue Res = DAG.getStridedLoadVP(
7010 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
7011 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
7012 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
7013 N->isExpandingLoad());
7017 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7021SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
7023 SDValue
Mask =
N->getOperand(1);
7026 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
7028 Mask.getValueType().getVectorElementType(),
7031 SDValue WideVec = ModifyToType(Vec, WideVecVT);
7032 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
7033 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
7035 WideMask, WidePassthru);
7039 EVT VT =
N->getValueType(0);
7040 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7041 SDValue
Mask =
N->getMask();
7042 EVT MaskVT =
Mask.getValueType();
7043 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7052 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
7053 TLI.isTypeLegal(WideMaskVT) &&
7059 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
7060 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
7064 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
7065 N->getMemoryVT(),
N->getMemOperand());
7066 SDValue NewVal = NewLoad;
7069 if (!
N->getPassThru()->isUndef()) {
7073 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
7074 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
7075 DAG.getPOISON(WidenVT), EVL);
7080 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
7086 Mask = ModifyToType(Mask, WideMaskVT,
true);
7088 SDValue Res = DAG.getMaskedLoad(
7089 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7090 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7091 ExtType,
N->isExpandingLoad());
7094 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7100 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7101 SDValue
Mask =
N->getMask();
7102 EVT MaskVT =
Mask.getValueType();
7103 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7104 SDValue Scale =
N->getScale();
7111 Mask = ModifyToType(Mask, WideMaskVT,
true);
7114 SDValue
Index =
N->getIndex();
7116 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7117 Index = ModifyToType(Index, WideIndexVT);
7118 SDValue
Ops[] = {
N->getChain(), PassThru,
Mask,
N->getBasePtr(),
Index,
7123 N->getMemoryVT().getScalarType(), WideEC);
7124 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7125 WideMemVT, dl,
Ops,
N->getMemOperand(),
7126 N->getIndexType(),
N->getExtensionType());
7130 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7135 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7136 SDValue
Mask =
N->getMask();
7137 SDValue Scale =
N->getScale();
7141 SDValue
Index = GetWidenedVector(
N->getIndex());
7143 N->getMemoryVT().getScalarType(), WideEC);
7144 Mask = GetWidenedMask(Mask, WideEC);
7146 SDValue
Ops[] = {
N->getChain(),
N->getBasePtr(),
Index, Scale,
7147 Mask,
N->getVectorLength()};
7148 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7149 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7153 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7158 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7159 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7187 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7188 return N->getOperand(OpNo).getValueType();
7196 N =
N.getOperand(0);
7198 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7199 if (!
N->getOperand(i)->isUndef())
7201 N =
N.getOperand(0);
7205 N =
N.getOperand(0);
7207 N =
N.getOperand(0);
7233 { MaskVT, MVT::Other },
Ops);
7234 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7240 return adjustMaskToType(Mask, ToMaskVT);
7246 LLVMContext &Ctx = *DAG.getContext();
7247 EVT MaskVT =
Mask.getValueType();
7250 if (MaskScalarBits < ToMaskScalBits) {
7254 }
else if (MaskScalarBits > ToMaskScalBits) {
7260 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7262 "Mask should have the right element size by now.");
7265 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7267 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7270 EVT SubVT =
Mask->getValueType(0);
7276 assert((
Mask->getValueType(0) == ToMaskVT) &&
7277 "A mask of ToMaskVT should have been produced by now.");
7284EVT DAGTypeLegalizer::unifyMaskTypes(
SDValue &Op0,
bool IsOpLenient0,
7285 SDValue &Op1,
bool IsOpLenient1,
7289 "unifyMaskTypes only handles scalar width differences");
7301 if (IsOpLenient0 != IsOpLenient1) {
7302 SDValue *LenientOp, *NonLenientOp;
7305 NonLenientOp = &Op1;
7308 NonLenientOp = &Op0;
7311 *LenientOp = adjustMaskToType(*LenientOp, OpVT);
7317 unsigned NarrowBits = std::min(Bits0, Bits1);
7318 unsigned WideBits = std::max(Bits0, Bits1);
7320 unsigned IntBits = NarrowBits == WideBits ? NarrowBits
7321 : ToBits >= WideBits ? WideBits
7322 : ToBits <= NarrowBits ? NarrowBits
7326 Op0 = adjustMaskToType(Op0, OpVT);
7327 Op1 = adjustMaskToType(Op1, OpVT);
7331std::pair<SDValue, bool>
7332DAGTypeLegalizer::convertMaskTreeImpl(
SDValue V,
EVT ToVT,
unsigned Depth) {
7364 if (
Depth >= DAG.MaxRecursionDepth)
7373 unsigned Opcode =
V.getOpcode();
7378 return {convertMask(V, MaskVT, MaskVT),
false};
7386 return {DAG.getConstant(0,
DL, ToVT),
true};
7388 return {DAG.getAllOnesConstant(
DL, ToVT),
true};
7393 auto [Op0, IsLenientOp0] =
7394 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7397 auto [Op1, IsLenientOp1] =
7398 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7401 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7402 return {DAG.getNode(Opcode,
DL, OpVT, Op0, Op1),
7403 IsLenientOp0 && IsLenientOp1};
7408 auto [Inner, IsTypeLenient] =
7409 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7412 return {DAG.getNode(
ISD::FREEZE,
DL, Inner.getValueType(), Inner),
7419 auto [Op0, IsLenientOp0] =
7420 convertMaskTreeImpl(
V.getOperand(0), ToVT,
Depth + 1);
7423 if (
V.getOperand(1).isUndef()) {
7425 return {DAG.getVectorShuffle(OpVT,
DL, Op0, DAG.getUNDEF(OpVT),
7429 auto [Op1, IsLenientOp1] =
7430 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7433 EVT OpVT = unifyMaskTypes(Op0, IsLenientOp0, Op1, IsLenientOp1, ToVT);
7434 return {DAG.getVectorShuffle(OpVT,
DL, Op0, Op1, Shuf->getMask()),
7435 IsLenientOp0 && IsLenientOp1};
7440 auto [Op1, IsLenientOp1] =
7441 convertMaskTreeImpl(
V.getOperand(1), ToVT,
Depth + 1);
7444 auto [Op2, IsLenientOp2] =
7445 convertMaskTreeImpl(
V.getOperand(2), ToVT,
Depth + 1);
7448 EVT OpVT = unifyMaskTypes(Op1, IsLenientOp1, Op2, IsLenientOp2, ToVT);
7457 SDValue
Cond =
V.getOperand(0);
7458 return {DAG.getNode(Opcode,
DL, OpVT,
Cond, Op1, Op2),
7459 IsLenientOp1 && IsLenientOp2};
7473 *DAG.getContext(),
V.getValueType().getVectorElementCount());
7474 auto [
Result,
_] = convertMaskTreeImpl(V, MaskTreeVT);
7477 return adjustMaskToType(Result, ToVT);
7485 LLVMContext &Ctx = *DAG.getContext();
7486 SDValue
Cond =
N->getOperand(0);
7493 EVT CondVT =
Cond->getValueType(0);
7497 EVT VSelVT =
N->getValueType(0);
7509 EVT FinalVT = VSelVT;
7520 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7521 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7528 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7536 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7539 EVT ToMaskVT = VSelVT;
7544 return convertMaskTree(
Cond, ToMaskVT);
7548 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7551 SDValue Cond1 =
N->getOperand(0);
7553 unsigned Opcode =
N->getOpcode();
7555 if (SDValue WideCond = WidenVSELECTMask(
N)) {
7556 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7557 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7559 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7565 Cond1 = GetWidenedVector(Cond1);
7573 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7574 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7579 Cond1 = ModifyToType(Cond1, CondWidenVT);
7582 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7583 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7585 if (Opcode == ISD::VP_MERGE)
7586 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7588 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7592 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7593 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7596 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7600 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7601 return DAG.getUNDEF(WidenVT);
7605 EVT VT =
N->getValueType(0);
7608 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7612 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7613 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7616 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7617 for (
unsigned i = 0; i != NumElts; ++i) {
7618 int Idx =
N->getMaskElt(i);
7619 if (Idx < (
int)NumElts)
7622 NewMask[i] = Idx - NumElts + WidenNumElts;
7624 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7628 EVT VT =
N->getValueType(0);
7632 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7633 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7639 unsigned IdxVal = WidenNumElts - VTNumElts;
7652 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7655 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7656 "down type's element count");
7659 for (; i < VTNumElts / GCD; ++i)
7661 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7662 for (; i < WidenNumElts / GCD; ++i)
7670 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7671 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7673 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7677SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7678 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7682void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7683 EVT VT =
N->getValueType(0);
7686 unsigned Factor =
N->getNumOperands();
7689 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7693 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7694 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7697 SDValue Interleaved =
7703 for (
unsigned Idx = 0; Idx != Factor; ++Idx)
7704 Slices[Idx] = Interleaved.
getValue(Idx);
7708 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7709 SDValue Narrow = DAG.getExtractSubvector(
DL, VT, Packed,
7712 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7713 SetWidenedVector(SDValue(
N, Idx), Wide);
7719 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7720 EVT SourceVT =
N->getOperand(0).getValueType();
7725 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7726 N->getOperand(0), 0);
7727 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7728 N->getOperand(2), 0);
7730 N->getOperand(1), WideMask,
N->getFlags());
7733void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7734 EVT VT =
N->getValueType(0);
7737 unsigned Factor =
N->getNumOperands();
7740 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7750 EVT ConcatVT =
EVT::getVectorVT(*DAG.getContext(), EltVT, OrigEC * Factor);
7752 SDValue PackedWidenVec = DAG.getInsertSubvector(
7753 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7757 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7758 NewOps[Idx] = DAG.getExtractSubvector(
DL, WidenVT, PackedWidenVec,
7765 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7766 SetWidenedVector(SDValue(
N, Idx), NewRes.
getValue(Idx));
7770 assert(
N->getValueType(0).isVector() &&
7771 N->getOperand(0).getValueType().isVector() &&
7772 "Operands must be vectors");
7773 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7786 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7787 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7794 InOp1 = GetWidenedVector(InOp1);
7795 InOp2 = GetWidenedVector(InOp2);
7797 SDValue
Poison = DAG.getPOISON(WidenInVT);
7798 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7809 "Input not widened to expected type!");
7811 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7816 assert(
N->getValueType(0).isVector() &&
7817 N->getOperand(1).getValueType().isVector() &&
7818 "Operands must be vectors");
7819 EVT VT =
N->getValueType(0);
7820 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7827 SDValue
LHS =
N->getOperand(1);
7828 SDValue
RHS =
N->getOperand(2);
7830 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7835 for (
unsigned i = 0; i != NumElts; ++i) {
7836 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7837 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7839 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7840 {Chain, LHSElem, RHSElem, CC});
7841 Chains[i] = Scalars[i].getValue(1);
7842 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7843 DAG.getBoolConstant(
true, dl, EltVT, VT),
7844 DAG.getBoolConstant(
false, dl, EltVT, VT));
7848 ReplaceValueWith(SDValue(
N, 1), NewChain);
7850 return DAG.getBuildVector(WidenVT, dl, Scalars);
7853SDValue DAGTypeLegalizer::WidenVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N) {
7855 EVT VT =
N->getValueType(0);
7858 SDValue Expanded = TLI.expandPartialReduceMLA(
N, DAG);
7859 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7860 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WideVT), Expanded, 0);
7866bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7867 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7868 SDValue Res = SDValue();
7871 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7874 switch (
N->getOpcode()) {
7877 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7885 Res = WidenVecOp_FAKE_USE(
N);
7889 Res = WidenVecOp_VECTOR_REPEAT(
N);
7894 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7898 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7899 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7900 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7905 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7907 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7908 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7910 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7911 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7921 Res = WidenVecOp_UnrollVectorOp(
N);
7928 Res = WidenVecOp_EXTEND(
N);
7933 Res = WidenVecOp_CMP(
N);
7951 Res = WidenVecOp_Convert(
N);
7956 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7976 Res = WidenVecOp_VECREDUCE(
N);
7980 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7982 case ISD::VP_REDUCE_FADD:
7983 case ISD::VP_REDUCE_SEQ_FADD:
7984 case ISD::VP_REDUCE_FMUL:
7985 case ISD::VP_REDUCE_SEQ_FMUL:
7986 case ISD::VP_REDUCE_ADD:
7987 case ISD::VP_REDUCE_MUL:
7988 case ISD::VP_REDUCE_AND:
7989 case ISD::VP_REDUCE_OR:
7990 case ISD::VP_REDUCE_XOR:
7991 case ISD::VP_REDUCE_SMAX:
7992 case ISD::VP_REDUCE_SMIN:
7993 case ISD::VP_REDUCE_UMAX:
7994 case ISD::VP_REDUCE_UMIN:
7995 case ISD::VP_REDUCE_FMAX:
7996 case ISD::VP_REDUCE_FMIN:
7997 case ISD::VP_REDUCE_FMAXIMUM:
7998 case ISD::VP_REDUCE_FMINIMUM:
7999 Res = WidenVecOp_VP_REDUCE(
N);
8003 Res = WidenVecOp_CttzElements(
N);
8005 case ISD::VP_CTTZ_ELTS:
8006 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
8007 Res = WidenVecOp_VP_CttzElements(
N);
8010 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
8013 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
8018 if (!Res.
getNode())
return false;
8026 if (
N->isStrictFPOpcode())
8028 "Invalid operand expansion");
8031 "Invalid operand expansion");
8033 ReplaceValueWith(SDValue(
N, 0), Res);
8039 EVT VT =
N->getValueType(0);
8044 "Unexpected type action");
8045 InOp = GetWidenedVector(InOp);
8048 "Input wasn't widened!");
8056 EVT FixedEltVT = FixedVT.getVectorElementType();
8057 if (TLI.isTypeLegal(FixedVT) &&
8059 FixedEltVT == InEltVT) {
8061 "Not enough elements in the fixed type for the operand!");
8063 "We can't have the same type as we started with!");
8065 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
8067 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
8076 return WidenVecOp_Convert(
N);
8081 switch (
N->getOpcode()) {
8096 EVT OpVT =
N->getOperand(0).getValueType();
8097 EVT ResVT =
N->getValueType(0);
8098 SDValue
LHS = GetWidenedVector(
N->getOperand(0));
8099 SDValue
RHS = GetWidenedVector(
N->getOperand(1));
8104 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
8105 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
8111 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
8112 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
8114 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
8121 return DAG.UnrollVectorOp(
N);
8126 EVT ResultVT =
N->getValueType(0);
8127 SDValue
Test =
N->getOperand(1);
8128 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
8131 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
8137 {WideArg,
Test},
N->getFlags());
8143 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
8145 EVT OpVT =
N->getOperand(0).getValueType();
8148 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
8153 EVT VT =
N->getValueType(0);
8156 SDValue InOp =
N->
getOperand(
N->isStrictFPOpcode() ? 1 : 0);
8159 "Unexpected type action");
8160 InOp = GetWidenedVector(InOp);
8162 unsigned Opcode =
N->getOpcode();
8165 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
8167 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
8170 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
8171 return DAG.getNode(Opcode, dl, VT,
Op);
8178 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
8180 if (
N->isStrictFPOpcode()) {
8182 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8185 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
8186 {
N->getOperand(0), InOp });
8189 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
8191 Res = MakeConvertNode(WideVT, InOp);
8193 return DAG.getExtractSubvector(dl, VT, Res, 0);
8201 if (
N->isStrictFPOpcode()) {
8204 for (
unsigned i=0; i < NumElts; ++i) {
8205 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8206 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
8210 ReplaceValueWith(SDValue(
N, 1), NewChain);
8212 for (
unsigned i = 0; i < NumElts; ++i) {
8213 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
8214 Ops[i] = MakeConvertNode(EltVT, Elt);
8218 return DAG.getBuildVector(VT, dl,
Ops);
8222 EVT DstVT =
N->getValueType(0);
8223 SDValue Src = GetWidenedVector(
N->getOperand(0));
8224 EVT SrcVT = Src.getValueType();
8231 if (TLI.isTypeLegal(WideDstVT)) {
8233 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
8236 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
8240 return DAG.UnrollVectorOp(
N);
8244 EVT VT =
N->getValueType(0);
8245 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8253 if (!VT.
isVector() && VT != MVT::x86mmx &&
8257 if (TLI.isTypeLegal(NewVT)) {
8258 SDValue BitOp = DAG.getNode(
ISD::BITCAST, dl, NewVT, InOp);
8259 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8271 ElementCount NewNumElts =
8273 .divideCoefficientBy(EltSize);
8275 if (TLI.isTypeLegal(NewVT)) {
8277 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8282 return CreateStackStoreLoad(InOp, VT);
8290 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8291 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8296 EVT VT =
N->getValueType(0);
8298 EVT InVT =
N->getOperand(0).getValueType();
8303 unsigned NumOperands =
N->getNumOperands();
8304 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8306 for (i = 1; i < NumOperands; ++i)
8307 if (!
N->getOperand(i).isUndef())
8310 if (i == NumOperands)
8311 return GetWidenedVector(
N->getOperand(0));
8315 SDValue
Result = DAG.getPOISON(VT);
8317 for (
unsigned i = 0; i < NumOperands; ++i) {
8318 SDValue InOp = GetWidenedVector(
N->getOperand(i));
8320 InOp = DAG.getExtractSubvector(dl, InVT, InOp, 0);
8321 Result = DAG.getInsertSubvector(dl, Result, InOp, i * NumInElts);
8333 for (
unsigned i=0; i < NumOperands; ++i) {
8337 "Unexpected type action");
8338 InOp = GetWidenedVector(InOp);
8339 for (
unsigned j = 0;
j < NumInElts; ++
j)
8340 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8342 return DAG.getBuildVector(VT, dl,
Ops);
8347 EVT VT =
N->getValueType(0);
8348 SDValue Src =
N->getOperand(0);
8349 EVT SrcVT = Src.getValueType();
8350 EVT WidenedSrcVT = TLI.getTypeToTransformTo(*DAG.getContext(), SrcVT);
8355 "Cannot widen VECTOR_REPEAT operand to an ElementCount that's not "
8356 "a known scalar multiple of the input ElementCount.");
8360 unsigned NumConcat =
8368 return DAG.getExtractSubvector(
DL, VT, Widened, 0);
8371SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8372 EVT VT =
N->getValueType(0);
8377 SubVec = GetWidenedVector(SubVec);
8382 bool IndicesValid =
false;
8385 IndicesValid =
true;
8389 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8390 Attribute::VScaleRange);
8395 IndicesValid =
true;
8401 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8407 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8414 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8436 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8444 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8445 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8450 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8455 unsigned Idx =
N->getConstantOperandVal(2);
8457 SDValue InsertElt = InVec;
8459 SDValue ExtractElt =
8461 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8467SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8468 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8470 N->getValueType(0), InOp,
N->getOperand(1));
8473SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8474 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8476 N->getValueType(0), InOp,
N->getOperand(1));
8479SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8481 EVT ResVT =
N->getValueType(0);
8484 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8490 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8498 "Widened input size must be a multiple of result element size");
8501 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8503 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8504 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8512 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8513 return TLI.scalarizeVectorStore(ST, DAG);
8515 if (
ST->isTruncatingStore())
8516 return TLI.scalarizeVectorStore(ST, DAG);
8524 SDValue StVal =
ST->getValue();
8526 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8527 EVT WideMaskVT = getSetCCResultType(WideVT);
8529 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8530 TLI.isTypeLegal(WideMaskVT)) {
8533 StVal = GetWidenedVector(StVal);
8534 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
8535 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8537 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8538 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8539 ST->getAddressingMode());
8543 if (GenWidenVectorStores(StChain, ST)) {
8544 if (StChain.
size() == 1)
8553 SDValue WideStVal = GetWidenedVector(StVal);
8557 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8558 ST->getOffset(), Mask,
ST->getMemoryVT(),
8559 ST->getMemOperand(),
ST->getAddressingMode(),
8560 ST->isTruncatingStore());
8567 EVT StVT =
ST->getMemoryVT();
8570 SDValue StVal = GetWidenedVector(
ST->getVal());
8575 TypeSize WidthDiff = WidenWidth - StWidth;
8581 std::optional<EVT> FirstVT =
8582 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8587 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8593 ST->getBasePtr(),
ST->getMemOperand());
8596SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8597 assert((OpNo == 1 || OpNo == 3) &&
8598 "Can widen only data or mask operand of vp_store");
8600 SDValue
Mask =
ST->getMask();
8601 SDValue StVal =
ST->getValue();
8606 StVal = GetWidenedVector(StVal);
8612 "Unable to widen VP store");
8613 Mask = GetWidenedVector(Mask);
8615 Mask = GetWidenedVector(Mask);
8621 "Unable to widen VP store");
8622 StVal = GetWidenedVector(StVal);
8625 assert(
Mask.getValueType().getVectorElementCount() ==
8627 "Mask and data vectors should have the same number of elements");
8628 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8629 ST->getOffset(), Mask,
ST->getVectorLength(),
8630 ST->getMemoryVT(),
ST->getMemOperand(),
8631 ST->getAddressingMode(),
ST->isTruncatingStore(),
8632 ST->isCompressingStore());
8637 assert((OpNo == 1 || OpNo == 4) &&
8638 "Can widen only data or mask operand of vp_strided_store");
8647 "Unable to widen VP strided store");
8651 "Unable to widen VP strided store");
8653 StVal = GetWidenedVector(StVal);
8654 Mask = GetWidenedVector(Mask);
8657 Mask.getValueType().getVectorElementCount() &&
8658 "Data and mask vectors should have the same number of elements");
8660 return DAG.getStridedStoreVP(
8667SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8668 assert((OpNo == 1 || OpNo == 4) &&
8669 "Can widen only data or mask operand of mstore");
8672 EVT MaskVT =
Mask.getValueType();
8677 EVT WideVT, WideMaskVT;
8680 StVal = GetWidenedVector(StVal);
8687 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8694 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8696 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8697 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8706 Mask = ModifyToType(Mask, WideMaskVT,
true);
8709 Mask = ModifyToType(Mask, WideMaskVT,
true);
8711 StVal = ModifyToType(StVal, WideVT);
8714 assert(
Mask.getValueType().getVectorElementCount() ==
8716 "Mask and data vectors should have the same number of elements");
8723SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8724 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8726 SDValue DataOp = MG->getPassThru();
8727 SDValue
Mask = MG->getMask();
8728 SDValue Scale = MG->getScale();
8731 SDValue
Index = GetWidenedVector(MG->getIndex());
8734 SDValue
Ops[] = {MG->getChain(), DataOp,
Mask, MG->getBasePtr(),
Index,
8736 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8737 MG->getMemOperand(), MG->getIndexType(),
8738 MG->getExtensionType());
8739 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
8740 ReplaceValueWith(SDValue(
N, 0), Res.
getValue(0));
8744SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8753 DataOp = GetWidenedVector(DataOp);
8757 EVT IndexVT =
Index.getValueType();
8760 Index = ModifyToType(Index, WideIndexVT);
8763 EVT MaskVT =
Mask.getValueType();
8766 Mask = ModifyToType(Mask, WideMaskVT,
true);
8771 }
else if (OpNo == 4) {
8773 Index = GetWidenedVector(Index);
8779 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8784SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8793 DataOp = GetWidenedVector(DataOp);
8794 Index = GetWidenedVector(Index);
8796 Mask = GetWidenedMask(Mask, WideEC);
8799 }
else if (OpNo == 3) {
8801 Index = GetWidenedVector(Index);
8808 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8813 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8814 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8816 EVT VT =
N->getValueType(0);
8830 SDValue WideSETCC = DAG.getNode(
ISD::SETCC, SDLoc(
N),
8831 SVT, InOp0, InOp1,
N->getOperand(2));
8837 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8839 EVT OpVT =
N->getOperand(0).getValueType();
8842 return DAG.getNode(ExtendCode, dl, VT, CC);
8847 SDValue
LHS = GetWidenedVector(
N->getOperand(1));
8848 SDValue
RHS = GetWidenedVector(
N->getOperand(2));
8852 EVT VT =
N->getValueType(0);
8854 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8861 for (
unsigned i = 0; i != NumElts; ++i) {
8862 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8863 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8865 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8866 {Chain, LHSElem, RHSElem, CC});
8867 Chains[i] = Scalars[i].getValue(1);
8868 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8869 DAG.getBoolConstant(
true, dl, EltVT, VT),
8870 DAG.getBoolConstant(
false, dl, EltVT, VT));
8874 ReplaceValueWith(SDValue(
N, 1), NewChain);
8876 return DAG.getBuildVector(VT, dl, Scalars);
8900 SDValue
Op = GetWidenedVector(
N->getOperand(0));
8901 EVT VT =
N->getValueType(0);
8902 EVT OrigVT =
N->getOperand(0).getValueType();
8903 EVT WideVT =
Op.getValueType();
8905 SDNodeFlags
Flags =
N->getFlags();
8907 unsigned Opc =
N->getOpcode();
8909 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8910 assert(NeutralElem &&
"Neutral element must exist");
8920 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8921 SDValue
Start = NeutralElem;
8927 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8928 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8934 unsigned GCD = std::gcd(OrigElts, WideElts);
8937 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8938 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8939 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8940 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8943 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8944 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8946 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8953 SDValue
Op = GetWidenedVector(VecOp);
8955 EVT VT =
N->getValueType(0);
8957 EVT WideVT =
Op.getValueType();
8959 SDNodeFlags
Flags =
N->getFlags();
8961 unsigned Opc =
N->getOpcode();
8963 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8973 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8976 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8977 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8983 unsigned GCD = std::gcd(OrigElts, WideElts);
8986 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8987 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8988 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8989 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8992 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8993 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8995 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8999 assert(
N->isVPOpcode() &&
"Expected VP opcode");
9002 SDValue
Op = GetWidenedVector(
N->getOperand(1));
9003 SDValue
Mask = GetWidenedMask(
N->getOperand(2),
9004 Op.getValueType().getVectorElementCount());
9006 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
9007 {N->getOperand(0), Op, Mask, N->getOperand(3)},
9015 EVT VT =
N->getValueType(0);
9018 SDValue
Cond = GetWidenedVector(
N->getOperand(0));
9019 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
9020 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
9025 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
9030 SDValue
Source =
N->getOperand(0);
9031 EVT SourceVT =
Source.getValueType();
9032 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9036 WideSource = GetWidenedVector(Source);
9040 SDValue
AllOnes = DAG.getAllOnesConstant(
DL, WideVT);
9043 WideSource = GetWidenedVector(Source);
9045 SmallVector<int>
Mask(WideElts);
9046 std::iota(
Mask.begin(),
Mask.end(), 0);
9048 Mask[
I] += WideElts;
9049 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
9051 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
9055 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
9061 SDValue
Source = GetWidenedVector(
N->getOperand(0));
9062 EVT SrcVT =
Source.getValueType();
9066 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
9067 {Source, Mask, N->getOperand(2)},
N->getFlags());
9070SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
9072 SDValue
Mask =
N->getOperand(0);
9073 EVT OrigMaskVT =
Mask.getValueType();
9074 SDValue WideMask = GetWidenedVector(Mask);
9080 if (OrigElts != WideElts) {
9081 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
9083 Mask, DAG.getVectorIdxConstant(0,
DL));
9090SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
9093 EVT ResVT =
N->getValueType(0);
9094 EVT SourceVT =
N->getOperand(0).getValueType();
9095 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
9100 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
9101 N->getOperand(0), 0);
9102 SDValue WideMask = DAG.getInsertSubvector(
9103 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
9105 N->getOperand(1), WideMask,
N->getFlags());
9106 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
9110 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
9113 SDValue Needle =
N->getOperand(1);
9116 return TLI.expandVectorMatch(
N, DAG);
9118 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
9122 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
9123 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
9126 N->getOperand(0), WideNeedle,
N->getOperand(2),
9144 unsigned WidenEx = 0) {
9149 unsigned AlignInBits =
Align*8;
9151 EVT RetVT = WidenEltVT;
9156 if (Width == WidenEltWidth)
9167 (WidenWidth % MemVTWidth) == 0 &&
9169 (MemVTWidth <= Width ||
9170 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9171 if (MemVTWidth == WidenWidth)
9190 (WidenWidth % MemVTWidth) == 0 &&
9192 (MemVTWidth <= Width ||
9193 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
9202 return std::nullopt;
9213 unsigned Start,
unsigned End) {
9214 SDLoc dl(LdOps[Start]);
9215 EVT LdTy = LdOps[Start].getValueType();
9223 for (
unsigned i = Start + 1; i != End; ++i) {
9224 EVT NewLdTy = LdOps[i].getValueType();
9225 if (NewLdTy != LdTy) {
9244 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9245 EVT LdVT =
LD->getMemoryVT();
9252 SDValue Chain =
LD->getChain();
9255 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9259 TypeSize WidthDiff = WidenWidth - LdWidth;
9266 std::optional<EVT> FirstVT =
9267 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
9274 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
9279 std::optional<EVT> NewVT = FirstVT;
9280 TypeSize RemainingWidth = LdWidth;
9281 TypeSize NewVTWidth = FirstVTWidth;
9283 RemainingWidth -= NewVTWidth;
9290 NewVTWidth = NewVT->getSizeInBits();
9296 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9310 MachinePointerInfo MPI =
LD->getPointerInfo();
9316 for (EVT MemVT : MemVTs) {
9317 Align NewAlign = ScaledOffset == 0
9318 ?
LD->getBaseAlign()
9320 SDValue
L = DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags,
9329 unsigned End = LdOps.
size();
9340 EVT LdTy = LdOps[i].getValueType();
9343 for (--i; i >= 0; --i) {
9344 LdTy = LdOps[i].getValueType();
9351 ConcatOps[--Idx] = LdOps[i];
9352 for (--i; i >= 0; --i) {
9353 EVT NewLdTy = LdOps[i].getValueType();
9354 if (NewLdTy != LdTy) {
9364 for (;
j != End-Idx; ++
j)
9365 WidenOps[j] = ConcatOps[Idx+j];
9367 WidenOps[j] = DAG.getPOISON(LdTy);
9374 ConcatOps[--Idx] = LdOps[i];
9379 ArrayRef(&ConcatOps[Idx], End - Idx));
9385 SDValue UndefVal = DAG.getPOISON(LdTy);
9388 for (; i != End-Idx; ++i)
9389 WidenOps[i] = ConcatOps[Idx+i];
9391 WidenOps[i] = UndefVal;
9402 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9403 EVT LdVT =
LD->getMemoryVT();
9409 SDValue Chain =
LD->getChain();
9412 MMOMetadata
Metadata =
LD->getMMOMetadataForSubAccess();
9426 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9427 LdEltVT,
LD->getBaseAlign(), MMOFlags,
Metadata);
9431 SDValue NewBasePtr =
9433 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9434 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9440 SDValue UndefVal = DAG.getPOISON(EltVT);
9441 for (; i != WidenNumElts; ++i)
9444 return DAG.getBuildVector(WidenVT, dl,
Ops);
9452 SDValue Chain =
ST->getChain();
9455 MMOMetadata
Metadata =
ST->getMMOMetadataForSubAccess();
9456 SDValue ValOp = GetWidenedVector(
ST->getValue());
9459 EVT StVT =
ST->getMemoryVT();
9467 "Mismatch between store and value types");
9471 MachinePointerInfo MPI =
ST->getPointerInfo();
9481 std::optional<EVT> NewVT =
9486 TypeSize NewVTWidth = NewVT->getSizeInBits();
9489 StWidth -= NewVTWidth;
9490 MemVTs.
back().second++;
9494 for (
const auto &Pair : MemVTs) {
9495 EVT NewVT = Pair.first;
9496 unsigned Count = Pair.second;
9502 Align NewAlign = ScaledOffset == 0
9503 ?
ST->getBaseAlign()
9505 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9506 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9522 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9524 DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
ST->getBaseAlign(),
9542 bool FillWithZeroes) {
9547 "input and widen element type must match");
9549 "cannot modify scalable vectors in this way");
9562 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9564 for (
unsigned i = 1; i != NumConcat; ++i)
9571 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9577 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9582 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9583 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9585 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9587 unsigned NumResultParts = NewNumElts / CommonFactor;
9588 if (NumResultParts > NumCopiedParts) {
9589 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9590 : DAG.getPOISON(PartVT);
9591 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9598 "Scalable vectors should have been handled already.");
9606 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9608 for (Idx = 0; Idx < MinNumElts; ++Idx)
9609 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9611 SDValue UndefVal = DAG.getPOISON(EltVT);
9612 for (; Idx < WidenNumElts; ++Idx)
9613 Ops[Idx] = UndefVal;
9615 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9616 if (!FillWithZeroes)
9620 "We expect to never want to FillWithZeroes for non-integral types.");
9623 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9624 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9626 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9627 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
uint64_t getScalarValueSizeInBits() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtractVectorElt(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Extract element at Idx from Vec.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
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
@ MASK_BEFOREFIRST
Has one mask vector operand.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ 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_REPEAT
VECTOR_REPEAT(FIXED_LENGTH_VECTOR) Repeatedly copies the elements of the source fixed-length vector t...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - 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 isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Type * getValueType(Value *V, bool ReVec, bool LookThroughCmp)
Returns the "element type" of the given value/instruction V.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
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.
EVT changeVectorElementCount(LLVMContext &Context, ElementCount EC) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element coun...
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.