35#define DEBUG_TYPE "legalize-types"
41void DAGTypeLegalizer::ScalarizeVectorResult(
SDNode *
N,
unsigned ResNo) {
47 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
50 switch (
N->getOpcode()) {
53 dbgs() <<
"ScalarizeVectorResult #" << ResNo <<
": ";
62 R = ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
N);
70 R = ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
N);
73 R = ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
N);
79 R = ScalarizeVecRes_UnaryOpWithExtraInput(
N);
89 R = ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
N);
95 case ISD::SETCC: R = ScalarizeVecRes_SETCC(
N);
break;
97 R = ScalarizeVecRes_VECTOR_MATCH(
N);
100 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(
N);
break;
106 R = ScalarizeVecRes_VecInregOp(
N);
158 R = ScalarizeVecRes_UnaryOp(
N);
161 R = ScalarizeVecRes_ADDRSPACECAST(
N);
167 R = ScalarizeVecRes_UnaryOpWithTwoResults(
N, ResNo);
226 R = ScalarizeVecRes_BinOp(
N);
233 R = ScalarizeVecRes_MaskedBinOp(
N);
238 R = ScalarizeVecRes_CMP(
N);
244 R = ScalarizeVecRes_TernaryOp(
N);
247#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
248 case ISD::STRICT_##DAGN:
249#include "llvm/IR/ConstrainedOps.def"
250 R = ScalarizeVecRes_StrictFPOp(
N);
255 R = ScalarizeVecRes_FP_TO_XINT_SAT(
N);
264 R = ScalarizeVecRes_OverflowOp(
N, ResNo);
274 R = ScalarizeVecRes_FIX(
N);
280 SetScalarizedVector(
SDValue(
N, ResNo), R);
284 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
285 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
286 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
292 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
293 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
294 SDValue
Mask =
N->getOperand(2);
295 EVT MaskVT =
Mask.getValueType();
300 Mask = GetScalarizedVector(Mask);
308 SDValue Divisor = DAG.getSelect(
DL,
LHS.getValueType(), Mask,
RHS,
309 DAG.getConstant(1,
DL,
LHS.getValueType()));
311 LHS.getValueType(),
LHS, Divisor);
317 SDValue
LHS =
N->getOperand(0);
318 SDValue
RHS =
N->getOperand(1);
319 if (getTypeAction(
LHS.getValueType()) ==
321 LHS = GetScalarizedVector(
LHS);
322 RHS = GetScalarizedVector(
RHS);
324 EVT VT =
LHS.getValueType().getVectorElementType();
325 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
326 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
329 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
330 N->getValueType(0).getVectorElementType(),
LHS,
RHS);
334 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
335 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
336 SDValue Op2 = GetScalarizedVector(
N->getOperand(2));
337 return DAG.getNode(
N->getOpcode(), SDLoc(
N), Op0.
getValueType(), Op0, Op1,
342 SDValue Op0 = GetScalarizedVector(
N->getOperand(0));
343 SDValue Op1 = GetScalarizedVector(
N->getOperand(1));
350DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithTwoResults(
SDNode *
N,
352 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
353 "Unexpected vector type!");
354 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
356 EVT VT0 =
N->getValueType(0);
357 EVT VT1 =
N->getValueType(1);
361 DAG.getNode(
N->getOpcode(), dl,
362 {VT0.getScalarType(), VT1.getScalarType()}, Elt)
366 unsigned OtherNo = 1 - ResNo;
367 EVT OtherVT =
N->getValueType(OtherNo);
369 SetScalarizedVector(SDValue(
N, OtherNo), SDValue(ScalarNode, OtherNo));
372 SDValue(ScalarNode, OtherNo));
373 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
376 return SDValue(ScalarNode, ResNo);
381 unsigned NumOpers =
N->getNumOperands();
382 SDValue Chain =
N->getOperand(0);
383 EVT ValueVTs[] = {VT, MVT::Other};
392 for (
unsigned i = 1; i < NumOpers; ++i) {
393 SDValue Oper =
N->getOperand(i);
398 Oper = GetScalarizedVector(Oper);
407 SDValue
Result = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(ValueVTs),
408 Opers,
N->getFlags());
412 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
419 EVT ResVT =
N->getValueType(0);
420 EVT OvVT =
N->getValueType(1);
422 SDValue ScalarLHS, ScalarRHS;
424 ScalarLHS = GetScalarizedVector(
N->getOperand(0));
425 ScalarRHS = GetScalarizedVector(
N->getOperand(1));
428 DAG.ExtractVectorElements(
N->getOperand(0), ElemsLHS);
429 DAG.ExtractVectorElements(
N->getOperand(1), ElemsRHS);
430 ScalarLHS = ElemsLHS[0];
431 ScalarRHS = ElemsRHS[0];
434 SDVTList ScalarVTs = DAG.getVTList(
436 SDNode *ScalarNode = DAG.getNode(
N->getOpcode(),
DL, ScalarVTs,
437 {ScalarLHS, ScalarRHS},
N->getFlags())
441 unsigned OtherNo = 1 - ResNo;
442 EVT OtherVT =
N->getValueType(OtherNo);
444 SetScalarizedVector(SDValue(
N, OtherNo), SDValue(ScalarNode, OtherNo));
446 SDValue OtherVal = DAG.
getNode(
448 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
451 return SDValue(ScalarNode, ResNo);
456 SDValue
Op = DisintegrateMERGE_VALUES(
N, ResNo);
457 return GetScalarizedVector(
Op);
460SDValue DAGTypeLegalizer::ScalarizeVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
463 SDValue
Mask = TLI.expandLoopDependenceMask(
N, DAG);
465 N->getValueType(0).getScalarType(), Mask,
466 DAG.getVectorIdxConstant(0,
DL));
470 SDValue
Op =
N->getOperand(0);
472 Op = GetScalarizedVector(
Op);
473 EVT NewVT =
N->getValueType(0).getVectorElementType();
478SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(
SDNode *
N) {
480 SDValue InOp =
N->getOperand(0);
488SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
490 N->getValueType(0).getVectorElementType(),
491 N->getOperand(0),
N->getOperand(1));
496 SDValue
Op =
N->getOperand(0);
497 EVT OpVT =
Op.getValueType();
501 Op = GetScalarizedVector(
Op);
504 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
507 N->getValueType(0).getVectorElementType(),
Op,
511SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
513 SDValue
Op =
N->getOperand(0);
514 EVT OpVT =
Op.getValueType();
518 Op = GetScalarizedVector(
Op);
521 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
524 N->getValueType(0).getVectorElementType(),
Op,
528SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
530 SDValue
Op =
N->getOperand(0);
531 EVT OpVT =
Op.getValueType();
534 Op = GetScalarizedVector(
Op);
537 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
540 N->getValueType(0).getVectorElementType(),
Op,
541 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
544SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOpWithExtraInput(
SDNode *
N) {
545 SDValue
Op = GetScalarizedVector(
N->getOperand(0));
546 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
Op.getValueType(),
Op,
550SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
553 SDValue
Op =
N->getOperand(1);
555 if (
Op.getValueType() != EltVT)
562 SDValue
Result = DAG.getAtomicLoad(
563 N->getExtensionType(), SDLoc(
N),
N->getMemoryVT().getVectorElementType(),
564 N->getValueType(0).getVectorElementType(),
N->getChain(),
N->getBasePtr(),
569 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
574 assert(
N->isUnindexed() &&
"Indexed vector load?");
576 SDValue
Result = DAG.getLoad(
578 N->getValueType(0).getVectorElementType(), SDLoc(
N),
N->getChain(),
579 N->getBasePtr(), DAG.getPOISON(
N->getBasePtr().getValueType()),
580 N->getPointerInfo(),
N->getMemoryVT().getVectorElementType(),
581 N->getBaseAlign(),
N->getMemOperand()->getFlags(),
N->getAAInfo());
585 ReplaceValueWith(SDValue(
N, 1),
Result.getValue(1));
592 SDValue
Op =
N->getOperand(0);
593 EVT OpVT =
Op.getValueType();
603 Op = GetScalarizedVector(
Op);
606 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
608 return DAG.getNode(
N->getOpcode(), SDLoc(
N), DestVT,
Op,
N->getFlags());
614 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
615 return DAG.getNode(
N->getOpcode(), SDLoc(
N), EltVT,
616 LHS, DAG.getValueType(ExtVT));
621 SDValue
Op =
N->getOperand(0);
623 EVT OpVT =
Op.getValueType();
628 Op = GetScalarizedVector(
Op);
630 Op = DAG.getExtractVectorElt(
DL, OpEltVT,
Op, 0);
633 switch (
N->getOpcode()) {
645SDValue DAGTypeLegalizer::ScalarizeVecRes_ADDRSPACECAST(
SDNode *
N) {
647 SDValue
Op =
N->getOperand(0);
648 EVT OpVT =
Op.getValueType();
658 Op = GetScalarizedVector(
Op);
661 Op = DAG.getExtractVectorElt(
DL, VT,
Op, 0);
664 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
665 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
666 return DAG.getAddrSpaceCast(
DL, DestVT,
Op, SrcAS, DestAS,
667 AddrSpaceCastN->getFlags());
670SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(
SDNode *
N) {
681DAGTypeLegalizer::ScalarizeVecRes_VECTOR_INTERLEAVE_DEINTERLEAVE(
SDNode *
N) {
682 assert(
N->getNumValues() ==
N->getNumOperands() &&
683 "Expected one result per operand");
687 for (
unsigned I = 0;
I !=
N->getNumValues(); ++
I)
688 SetScalarizedVector(SDValue(
N,
I), GetScalarizedVector(
N->getOperand(
I)));
693 SDValue
Cond =
N->getOperand(0);
694 EVT OpVT =
Cond.getValueType();
703 Cond = DAG.getExtractVectorElt(
DL, VT,
Cond, 0);
706 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
708 TLI.getBooleanContents(
false,
false);
715 if (TLI.getBooleanContents(
false,
false) !=
716 TLI.getBooleanContents(
false,
true)) {
720 EVT OpVT =
Cond->getOperand(0).getValueType();
722 VecBool = TLI.getBooleanContents(OpVT);
727 EVT CondVT =
Cond.getValueType();
728 if (ScalarBool != VecBool) {
729 switch (ScalarBool) {
737 Cond, DAG.getConstant(1, SDLoc(
N), CondVT));
744 Cond, DAG.getValueType(MVT::i1));
750 auto BoolVT = getSetCCResultType(CondVT);
751 if (BoolVT.bitsLT(CondVT))
754 return DAG.getSelect(SDLoc(
N),
LHS.getValueType(),
Cond,
LHS,
755 GetScalarizedVector(
N->getOperand(2)),
N->getFlags());
759 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
760 return DAG.getSelect(SDLoc(
N),
761 LHS.getValueType(),
N->getOperand(0),
LHS,
762 GetScalarizedVector(
N->getOperand(2)));
766 SDValue
LHS = GetScalarizedVector(
N->getOperand(2));
768 N->getOperand(0),
N->getOperand(1),
769 LHS, GetScalarizedVector(
N->getOperand(3)),
774 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
777SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(
SDNode *
N) {
781 return DAG.getUNDEF(
N->getValueType(0).getVectorElementType());
783 return GetScalarizedVector(
N->getOperand(
Op));
786SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(
SDNode *
N) {
787 SDValue Src =
N->getOperand(0);
788 EVT SrcVT = Src.getValueType();
793 Src = GetScalarizedVector(Src);
797 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
799 EVT DstVT =
N->getValueType(0).getVectorElementType();
800 return DAG.getNode(
N->getOpcode(), dl, DstVT, Src,
N->getOperand(1));
804 assert(
N->getValueType(0).isVector() &&
805 N->getOperand(0).getValueType().isVector() &&
806 "Operand types must be vectors");
807 SDValue
LHS =
N->getOperand(0);
808 SDValue
RHS =
N->getOperand(1);
809 EVT OpVT =
LHS.getValueType();
810 EVT NVT =
N->getValueType(0).getVectorElementType();
815 LHS = GetScalarizedVector(
LHS);
816 RHS = GetScalarizedVector(
RHS);
819 LHS = DAG.getExtractVectorElt(
DL, VT,
LHS, 0);
820 RHS = DAG.getExtractVectorElt(
DL, VT,
RHS, 0);
830 return DAG.getNode(ExtendCode,
DL, NVT, Res);
841 Arg = GetScalarizedVector(Arg);
844 Arg = DAG.getExtractVectorElt(
DL, VT, Arg, 0);
853 return DAG.getNode(ExtendCode,
DL, ResultVT, Res);
860bool DAGTypeLegalizer::ScalarizeVectorOperand(
SDNode *
N,
unsigned OpNo) {
863 SDValue Res = SDValue();
866 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
869 switch (
N->getOpcode()) {
872 dbgs() <<
"ScalarizeVectorOperand Op #" << OpNo <<
": ";
879 Res = ScalarizeVecOp_BITCAST(
N);
882 Res = ScalarizeVecOp_FAKE_USE(
N);
896 Res = ScalarizeVecOp_UnaryOp(
N);
901 Res = ScalarizeVecOp_UnaryOpWithExtraInput(
N);
904 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
905 "Unexpected vector type!");
906 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
907 SDValue
Op = DAG.getNode(
908 N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(), Elt,
909 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
917 Res = ScalarizeVecOp_UnaryOp_StrictFP(
N);
920 Res = ScalarizeVecOp_CONCAT_VECTORS(
N);
923 Res = ScalarizeVecOp_INSERT_SUBVECTOR(
N, OpNo);
926 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(
N);
929 Res = ScalarizeVecOp_VSELECT(
N);
932 Res = ScalarizeVecOp_VSETCC(
N);
936 Res = ScalarizeVecOp_VSTRICT_FSETCC(
N, OpNo);
945 Res = ScalarizeVecOp_STRICT_FP_ROUND(
N, OpNo);
948 Res = ScalarizeVecOp_FP_ROUND(
N, OpNo);
951 Res = ScalarizeVecOp_STRICT_FP_EXTEND(
N);
954 Res = ScalarizeVecOp_FP_EXTEND(
N);
973 Res = ScalarizeVecOp_VECREDUCE(
N);
977 Res = ScalarizeVecOp_VECREDUCE_SEQ(
N);
981 Res = ScalarizeVecOp_CMP(
N);
984 Res = ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
988 Res = ScalarizeVecOp_CTTZ_ELTS(
N);
991 Res = ScalarizeVecOp_VECTOR_MATCH(
N, OpNo);
997 Res = ScalarizeVecOp_MaskedBinOp(
N, OpNo);
1002 if (!Res.
getNode())
return false;
1010 "Invalid operand expansion");
1012 ReplaceValueWith(SDValue(
N, 0), Res);
1019 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1021 N->getValueType(0), Elt);
1026 assert(
N->getOperand(1).getValueType().getVectorNumElements() == 1 &&
1027 "Fake Use: Unexpected vector type!");
1028 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1029 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0), Elt);
1035 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1036 "Unexpected vector type!");
1037 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1038 SDValue
Op = DAG.getNode(
N->getOpcode(), SDLoc(
N),
1039 N->getValueType(0).getScalarType(), Elt);
1047SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOpWithExtraInput(
SDNode *
N) {
1048 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1049 "Unexpected vector type!");
1050 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1052 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0).getScalarType(),
1053 Elt,
N->getOperand(1));
1061SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(
SDNode *
N) {
1062 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1063 "Unexpected vector type!");
1064 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1065 SDValue Res = DAG.
getNode(
N->getOpcode(), SDLoc(
N),
1066 {
N->getValueType(0).getScalarType(), MVT::Other },
1067 {
N->getOperand(0), Elt });
1070 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1077 ReplaceValueWith(SDValue(
N, 0), Res);
1082SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(
SDNode *
N) {
1084 for (
unsigned i = 0, e =
N->getNumOperands(); i < e; ++i)
1085 Ops[i] = GetScalarizedVector(
N->getOperand(i));
1086 return DAG.getBuildVector(
N->getValueType(0), SDLoc(
N),
Ops);
1091SDValue DAGTypeLegalizer::ScalarizeVecOp_INSERT_SUBVECTOR(
SDNode *
N,
1095 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1096 SDValue ContainingVec =
N->getOperand(0);
1104SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
1105 EVT VT =
N->getValueType(0);
1106 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1118 SDValue ScalarCond = GetScalarizedVector(
N->getOperand(0));
1119 EVT VT =
N->getValueType(0);
1121 return DAG.getNode(
ISD::SELECT, SDLoc(
N), VT, ScalarCond,
N->getOperand(1),
1130 assert(
N->getValueType(0).isVector() &&
1131 N->getOperand(0).getValueType().isVector() &&
1132 "Operand types must be vectors");
1133 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1134 "Expected single-element vector type");
1136 EVT VT =
N->getValueType(0);
1137 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
1138 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
1140 EVT OpVT =
N->getOperand(0).getValueType();
1152 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1158SDValue DAGTypeLegalizer::ScalarizeVecOp_VSTRICT_FSETCC(
SDNode *
N,
1160 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1161 assert(
N->getValueType(0).isVector() &&
1162 N->getOperand(1).getValueType().isVector() &&
1163 "Operand types must be vectors");
1164 assert(
N->getValueType(0).getVectorNumElements() == 1 &&
1165 "Expected single-element vector type");
1167 EVT VT =
N->getValueType(0);
1168 SDValue Ch =
N->getOperand(0);
1169 SDValue
LHS = GetScalarizedVector(
N->getOperand(1));
1170 SDValue
RHS = GetScalarizedVector(
N->getOperand(2));
1171 SDValue CC =
N->getOperand(3);
1173 EVT OpVT =
N->getOperand(1).getValueType();
1176 SDValue Res = DAG.
getNode(
N->getOpcode(),
DL, {MVT::i1, MVT::Other},
1177 {Ch, LHS, RHS, CC});
1181 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1186 Res = DAG.
getNode(ExtendCode,
DL, NVT, Res);
1191 ReplaceValueWith(SDValue(
N, 0), Res);
1198 assert(
N->isUnindexed() &&
"Indexed store of one-element vector?");
1199 assert(OpNo == 1 &&
"Do not know how to scalarize this operand!");
1202 if (
N->isTruncatingStore())
1203 return DAG.getTruncStore(
1204 N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1205 N->getBasePtr(),
N->getPointerInfo(),
1206 N->getMemoryVT().getVectorElementType(),
N->getBaseAlign(),
1207 N->getMemOperand()->getFlags(),
N->getAAInfo());
1209 return DAG.getStore(
N->getChain(), dl, GetScalarizedVector(
N->getOperand(1)),
1210 N->getBasePtr(),
N->getPointerInfo(),
N->getBaseAlign(),
1211 N->getMemOperand()->getFlags(),
N->getAAInfo());
1217 SDValue ScalarVal = GetScalarizedVector(
N->getVal());
1219 N->getMemoryVT().getVectorElementType(),
N->getChain(),
1220 ScalarVal,
N->getBasePtr(),
N->getMemOperand());
1225SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(
SDNode *
N,
unsigned OpNo) {
1226 assert(OpNo == 0 &&
"Wrong operand for scalarization!");
1227 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1229 N->getValueType(0).getVectorElementType(), Elt,
1234SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(
SDNode *
N,
1236 assert(OpNo == 1 &&
"Wrong operand for scalarization!");
1237 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1240 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1244 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1250 ReplaceValueWith(SDValue(
N, 0), Res);
1257 SDValue Elt = GetScalarizedVector(
N->getOperand(0));
1259 N->getValueType(0).getVectorElementType(), Elt);
1265SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(
SDNode *
N) {
1266 SDValue Elt = GetScalarizedVector(
N->getOperand(1));
1269 {
N->getValueType(0).getVectorElementType(), MVT::Other},
1270 {
N->getOperand(0), Elt});
1273 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
1279 ReplaceValueWith(SDValue(
N, 0), Res);
1284 SDValue Res = GetScalarizedVector(
N->getOperand(0));
1291SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(
SDNode *
N) {
1297 SDValue
Op = GetScalarizedVector(VecOp);
1298 return DAG.getNode(BaseOpc, SDLoc(
N),
N->getValueType(0),
1299 AccOp,
Op,
N->getFlags());
1303 SDValue
LHS = GetScalarizedVector(
N->getOperand(0));
1304 SDValue
RHS = GetScalarizedVector(
N->getOperand(1));
1307 SDValue
Cmp = DAG.getNode(
N->getOpcode(), SDLoc(
N), ResVT,
LHS,
RHS);
1311SDValue DAGTypeLegalizer::ScalarizeVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
1319 EVT VT =
N->getValueType(0);
1320 return DAG.getConstant(0, SDLoc(
N), VT);
1327 return DAG.getConstant(0, SDLoc(
N),
N->getValueType(0));
1328 SDValue
Op = GetScalarizedVector(
N->getOperand(0));
1330 DAG.getSetCC(SDLoc(
N), MVT::i1,
Op,
1331 DAG.getConstant(0, SDLoc(
N),
Op.getValueType()),
ISD::SETEQ);
1332 return DAG.getZExtOrTrunc(SetCC, SDLoc(
N),
N->getValueType(0));
1335SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_MATCH(
SDNode *
N) {
1338 SDValue
Mask = TLI.expandVectorMatch(
N, DAG);
1340 N->getValueType(0).getScalarType(), Mask,
1341 DAG.getVectorIdxConstant(0,
DL));
1346 return TLI.expandVectorMatch(
N, DAG);
1349SDValue DAGTypeLegalizer::ScalarizeVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
1350 assert(OpNo == 2 &&
"Can only scalarize mask operand");
1353 SDValue
LHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(0), 0);
1354 SDValue
RHS = DAG.getExtractVectorElt(
DL, VT,
N->getOperand(1), 0);
1355 SDValue
Mask = GetScalarizedVector(
N->getOperand(2));
1363 DAG.getSelect(
DL, VT, Mask,
RHS, DAG.getConstant(1,
DL, VT)));
1375void DAGTypeLegalizer::SplitVectorResult(
SDNode *
N,
unsigned ResNo) {
1380 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1383 switch (
N->getOpcode()) {
1386 dbgs() <<
"SplitVectorResult #" << ResNo <<
": ";
1395 SplitVecRes_LOOP_DEPENDENCE_MASK(
N,
Lo,
Hi);
1402 case ISD::VP_MERGE: SplitRes_Select(
N,
Lo,
Hi);
break;
1418 SplitVecRes_ScalarOp(
N,
Lo,
Hi);
1421 SplitVecRes_STEP_VECTOR(
N,
Lo,
Hi);
1433 case ISD::VP_LOAD_FF:
1436 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1443 case ISD::VP_GATHER:
1447 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
1450 SplitVecRes_SETCC(
N,
Lo,
Hi);
1453 SplitVecRes_VECTOR_REVERSE(
N,
Lo,
Hi);
1460 SplitVecRes_VECTOR_SPLICE(
N,
Lo,
Hi);
1463 SplitVecRes_VECTOR_DEINTERLEAVE(
N);
1466 SplitVecRes_VECTOR_INTERLEAVE(
N);
1469 SplitVecRes_VAARG(
N,
Lo,
Hi);
1475 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
1529 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
1532 SplitVecRes_ADDRSPACECAST(
N,
Lo,
Hi);
1538 SplitVecRes_UnaryOpWithTwoResults(
N, ResNo,
Lo,
Hi);
1544 SplitVecRes_ExtendOp(
N,
Lo,
Hi);
1600 SplitVecRes_BinOp(
N,
Lo,
Hi);
1606 SplitVecRes_MaskedBinOp(
N,
Lo,
Hi);
1611 SplitVecRes_TernaryOp(
N,
Lo,
Hi);
1615 SplitVecRes_CMP(
N,
Lo,
Hi);
1618#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1619 case ISD::STRICT_##DAGN:
1620#include "llvm/IR/ConstrainedOps.def"
1621 SplitVecRes_StrictFPOp(
N,
Lo,
Hi);
1626 SplitVecRes_FP_TO_XINT_SAT(
N,
Lo,
Hi);
1635 SplitVecRes_OverflowOp(
N, ResNo,
Lo,
Hi);
1645 SplitVecRes_FIX(
N,
Lo,
Hi);
1647 case ISD::EXPERIMENTAL_VP_SPLICE:
1648 SplitVecRes_VP_SPLICE(
N,
Lo,
Hi);
1650 case ISD::EXPERIMENTAL_VP_REVERSE:
1651 SplitVecRes_VP_REVERSE(
N,
Lo,
Hi);
1657 SplitVecRes_PARTIAL_REDUCE_MLA(
N,
Lo,
Hi);
1660 SplitVecRes_GET_ACTIVE_LANE_MASK(
N,
Lo,
Hi);
1663 SplitVecRes_VECTOR_MATCH(
N,
Lo,
Hi);
1669 SetSplitVector(SDValue(
N, ResNo),
Lo,
Hi);
1672void DAGTypeLegalizer::IncrementPointer(
MemSDNode *
N,
EVT MemVT,
1679 SDValue BytesIncrement = DAG.getVScale(
1682 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
1684 *ScaledOffset += IncrementSize;
1694std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask) {
1695 return SplitMask(Mask, SDLoc(Mask));
1698std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(
SDValue Mask,
1700 SDValue MaskLo, MaskHi;
1701 EVT MaskVT =
Mask.getValueType();
1703 GetSplitVector(Mask, MaskLo, MaskHi);
1705 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
1706 return std::make_pair(MaskLo, MaskHi);
1710 SDValue LHSLo, LHSHi;
1711 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1712 SDValue RHSLo, RHSHi;
1713 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1716 const SDNodeFlags
Flags =
N->getFlags();
1717 unsigned Opcode =
N->getOpcode();
1718 if (
N->getNumOperands() == 2) {
1719 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Flags);
1720 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Flags);
1724 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
1725 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
1726 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
1727 "Expected VP opcode");
1729 SDValue MaskLo, MaskHi;
1730 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
1732 SDValue EVLLo, EVLHi;
1733 std::tie(EVLLo, EVLHi) =
1734 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
1737 {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1739 {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1744 SDValue LHSLo, LHSHi;
1745 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1746 SDValue RHSLo, RHSHi;
1747 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1749 SDValue MaskLo, MaskHi,
Mask =
N->getOperand(2);
1751 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
1753 std::tie(MaskLo, MaskHi) = SplitMask(Mask);
1757 const SDNodeFlags
Flags =
N->getFlags();
1758 unsigned Opcode =
N->getOpcode();
1759 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, MaskLo,
1761 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, MaskHi,
1767 SDValue Op0Lo, Op0Hi;
1768 GetSplitVector(
N->getOperand(0), Op0Lo, Op0Hi);
1769 SDValue Op1Lo, Op1Hi;
1770 GetSplitVector(
N->getOperand(1), Op1Lo, Op1Hi);
1771 SDValue Op2Lo, Op2Hi;
1772 GetSplitVector(
N->getOperand(2), Op2Lo, Op2Hi);
1775 const SDNodeFlags
Flags =
N->getFlags();
1776 unsigned Opcode =
N->getOpcode();
1778 DAG.getNode(Opcode, dl, Op0Lo.
getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1780 DAG.getNode(Opcode, dl, Op0Hi.
getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1784 LLVMContext &Ctxt = *DAG.getContext();
1787 SDValue
LHS =
N->getOperand(0);
1788 SDValue
RHS =
N->getOperand(1);
1790 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1792 GetSplitVector(
LHS, LHSLo, LHSHi);
1793 GetSplitVector(
RHS, RHSLo, RHSHi);
1795 std::tie(LHSLo, LHSHi) = DAG.SplitVector(
LHS, dl);
1796 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, dl);
1800 Lo = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSLo, RHSLo);
1801 Hi = DAG.getNode(
N->getOpcode(), dl, SplitResVT, LHSHi, RHSHi);
1805 SDValue LHSLo, LHSHi;
1806 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
1807 SDValue RHSLo, RHSHi;
1808 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
1812 unsigned Opcode =
N->getOpcode();
1813 Lo = DAG.getNode(Opcode, dl, LHSLo.
getValueType(), LHSLo, RHSLo, Op2,
1815 Hi = DAG.getNode(Opcode, dl, LHSHi.
getValueType(), LHSHi, RHSHi, Op2,
1824 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1831 switch (getTypeAction(InVT)) {
1845 GetExpandedOp(InOp,
Lo,
Hi);
1846 if (DAG.getDataLayout().isBigEndian())
1856 GetSplitVector(InOp,
Lo,
Hi);
1865 auto [InLo, InHi] = DAG.SplitVectorOperand(
N, 0);
1874 if (DAG.getDataLayout().isBigEndian())
1877 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT,
Lo,
Hi);
1879 if (DAG.getDataLayout().isBigEndian())
1885void DAGTypeLegalizer::SplitVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N,
SDValue &
Lo,
1889 SDValue PtrA =
N->getOperand(0);
1890 SDValue PtrB =
N->getOperand(1);
1891 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1894 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, PtrA, PtrB,
1899 unsigned LaneOffset =
1902 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, PtrA, PtrB,
1904 DAG.getConstant(LaneOffset,
DL, MVT::i64));
1911 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1914 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1917 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1922 assert(!(
N->getNumOperands() & 1) &&
"Unsupported CONCAT_VECTORS");
1924 unsigned NumSubvectors =
N->getNumOperands() / 2;
1925 if (NumSubvectors == 1) {
1926 Lo =
N->getOperand(0);
1927 Hi =
N->getOperand(1);
1932 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1941void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(
SDNode *
N,
SDValue &
Lo,
1943 SDValue Vec =
N->getOperand(0);
1944 SDValue Idx =
N->getOperand(1);
1948 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
1963 GetSplitVector(Vec,
Lo,
Hi);
1966 EVT LoVT =
Lo.getValueType();
1976 if (IdxVal + SubElems <= LoElems) {
1984 IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1986 DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1992 SDValue WideSubVec = GetWidenedVector(SubVec);
1994 std::tie(
Lo,
Hi) = DAG.SplitVector(WideSubVec, SDLoc(WideSubVec));
2002 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2004 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2005 auto &MF = DAG.getMachineFunction();
2009 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2014 TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
2015 Store = DAG.getStore(
Store, dl, SubVec, SubVecPtr,
2019 Lo = DAG.getLoad(
Lo.getValueType(), dl,
Store, StackPtr, PtrInfo,
2024 MachinePointerInfo MPI =
Load->getPointerInfo();
2025 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2028 Hi = DAG.getLoad(
Hi.getValueType(), dl,
Store, StackPtr, MPI, SmallestAlign);
2036 SDValue LHSLo, LHSHi;
2037 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2040 SDValue RHSLo, RHSHi;
2041 SDValue
RHS =
N->getOperand(1);
2042 EVT RHSVT =
RHS.getValueType();
2045 GetSplitVector(
RHS, RHSLo, RHSHi);
2047 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
RHS, SDLoc(
RHS));
2060 SDValue ArgLo, ArgHi;
2061 SDValue
Test =
N->getOperand(1);
2062 SDValue FpValue =
N->getOperand(0);
2064 GetSplitVector(FpValue, ArgLo, ArgHi);
2066 std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
2068 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2076 SDValue LHSLo, LHSHi;
2077 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
2081 std::tie(LoVT, HiVT) =
2085 DAG.getValueType(LoVT));
2087 DAG.getValueType(HiVT));
2092 unsigned Opcode =
N->getOpcode();
2093 SDValue N0 =
N->getOperand(0);
2099 GetSplitVector(N0, InLo, InHi);
2101 std::tie(InLo, InHi) = DAG.SplitVectorOperand(
N, 0);
2106 EVT OutLoVT, OutHiVT;
2107 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2109 assert((2 * OutNumElements) <= InNumElements &&
2110 "Illegal extend vector in reg split");
2119 SmallVector<int, 8> SplitHi(InNumElements, -1);
2120 for (
unsigned i = 0; i != OutNumElements; ++i)
2121 SplitHi[i] = i + OutNumElements;
2122 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getPOISON(InLoVT), SplitHi);
2124 Lo = DAG.
getNode(Opcode, dl, OutLoVT, InLo);
2125 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
2130 unsigned NumOps =
N->getNumOperands();
2134 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2144 for (
unsigned i = 1; i <
NumOps; ++i) {
2145 SDValue
Op =
N->getOperand(i);
2149 EVT InVT =
Op.getValueType();
2154 GetSplitVector(
Op, OpLo, OpHi);
2156 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(
N, i);
2163 EVT LoValueVTs[] = {LoVT, MVT::Other};
2164 EVT HiValueVTs[] = {HiVT, MVT::Other};
2165 Lo = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
2167 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
2173 Lo.getValue(1),
Hi.getValue(1));
2177 ReplaceValueWith(SDValue(
N, 1), Chain);
2180SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(
SDNode *
N,
unsigned ResNE) {
2182 EVT VT =
N->getValueType(0);
2193 else if (NE > ResNE)
2197 SDVTList ChainVTs = DAG.getVTList(EltVT, MVT::Other);
2201 for (i = 0; i !=
NE; ++i) {
2203 for (
unsigned j = 1, e =
N->getNumOperands(); j != e; ++j) {
2204 SDValue Operand =
N->getOperand(j);
2208 Operands[
j] = DAG.getExtractVectorElt(dl, OperandEltVT, Operand, i);
2214 DAG.getNode(
N->getOpcode(), dl, ChainVTs,
Operands,
N->getFlags());
2222 for (; i < ResNE; ++i)
2223 Scalars.
push_back(DAG.getPOISON(EltVT));
2227 ReplaceValueWith(SDValue(
N, 1), Chain);
2231 return DAG.getBuildVector(VecVT, dl, Scalars);
2234void DAGTypeLegalizer::SplitVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo,
2237 EVT ResVT =
N->getValueType(0);
2238 EVT OvVT =
N->getValueType(1);
2239 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
2240 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
2241 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
2243 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
2245 GetSplitVector(
N->getOperand(0), LoLHS, HiLHS);
2246 GetSplitVector(
N->getOperand(1), LoRHS, HiRHS);
2248 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(
N, 0);
2249 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(
N, 1);
2252 unsigned Opcode =
N->getOpcode();
2253 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
2254 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
2256 DAG.getNode(Opcode, dl, LoVTs, {LoLHS, LoRHS},
N->getFlags()).getNode();
2258 DAG.getNode(Opcode, dl, HiVTs, {HiLHS, HiRHS},
N->getFlags()).getNode();
2260 Lo = SDValue(LoNode, ResNo);
2261 Hi = SDValue(HiNode, ResNo);
2264 unsigned OtherNo = 1 - ResNo;
2265 EVT OtherVT =
N->getValueType(OtherNo);
2267 SetSplitVector(SDValue(
N, OtherNo),
2268 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2270 SDValue OtherVal = DAG.
getNode(
2272 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
2273 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
2277void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(
SDNode *
N,
SDValue &
Lo,
2283 GetSplitVector(Vec,
Lo,
Hi);
2286 unsigned IdxVal = CIdx->getZExtValue();
2287 unsigned LoNumElts =
Lo.getValueType().getVectorMinNumElements();
2288 if (IdxVal < LoNumElts) {
2290 Lo.getValueType(),
Lo, Elt, Idx);
2293 Hi = DAG.getInsertVectorElt(dl,
Hi, Elt, IdxVal - LoNumElts);
2313 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
2315 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
2316 auto &MF = DAG.getMachineFunction();
2320 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
2325 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2326 Store = DAG.getTruncStore(
2332 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
2335 Lo = DAG.getLoad(LoVT, dl,
Store, StackPtr, PtrInfo, SmallestAlign);
2339 MachinePointerInfo MPI =
Load->getPointerInfo();
2340 IncrementPointer(
Load, LoVT, MPI, StackPtr);
2342 Hi = DAG.getLoad(HiVT, dl,
Store, StackPtr, MPI, SmallestAlign);
2345 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2346 if (LoVT !=
Lo.getValueType())
2348 if (HiVT !=
Hi.getValueType())
2356 assert(
N->getValueType(0).isScalableVector() &&
2357 "Only scalable vectors are supported for STEP_VECTOR");
2358 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2359 SDValue Step =
N->getOperand(0);
2379 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2380 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
N->getOperand(0));
2382 Hi = DAG.getPOISON(HiVT);
2392 "Extended load during type legalization!");
2394 EVT VT =
LD->getValueType(0);
2396 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2398 SDValue Ch =
LD->getChain();
2399 SDValue Ptr =
LD->getBasePtr();
2404 SDValue ALD = DAG.getAtomicLoad(
LD->getExtensionType(), dl, MemIntVT, IntVT,
2405 Ch, Ptr,
LD->getMemOperand());
2409 SDValue ExtractLo, ExtractHi;
2410 SplitInteger(ALD, LoIntVT, HiIntVT, ExtractLo, ExtractHi);
2412 Lo = DAG.getBitcast(LoVT, ExtractLo);
2413 Hi = DAG.getBitcast(HiVT, ExtractHi);
2417 ReplaceValueWith(SDValue(LD, 1), ALD.
getValue(1));
2425 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2428 SDValue Ch =
LD->getChain();
2429 SDValue Ptr =
LD->getBasePtr();
2431 EVT MemoryVT =
LD->getMemoryVT();
2433 AAMDNodes AAInfo =
LD->getAAInfo();
2435 EVT LoMemVT, HiMemVT;
2436 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2439 SDValue
Value, NewChain;
2440 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
2441 std::tie(
Lo,
Hi) = DAG.SplitVector(
Value, dl);
2442 ReplaceValueWith(SDValue(LD, 1), NewChain);
2447 LD->getPointerInfo(), LoMemVT,
LD->getBaseAlign(), MMOFlags,
2450 MachinePointerInfo MPI;
2451 IncrementPointer(LD, LoMemVT, MPI, Ptr);
2454 HiMemVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
2463 ReplaceValueWith(SDValue(LD, 1), Ch);
2468 assert(
LD->isUnindexed() &&
"Indexed VP load during type legalization!");
2471 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
LD->getValueType(0));
2474 SDValue Ch =
LD->getChain();
2475 SDValue Ptr =
LD->getBasePtr();
2477 assert(
Offset.isUndef() &&
"Unexpected indexed variable-length load offset");
2479 SDValue
Mask =
LD->getMask();
2480 SDValue EVL =
LD->getVectorLength();
2481 EVT MemoryVT =
LD->getMemoryVT();
2483 EVT LoMemVT, HiMemVT;
2484 bool HiIsEmpty =
false;
2485 std::tie(LoMemVT, HiMemVT) =
2486 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2489 SDValue MaskLo, MaskHi;
2491 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2494 GetSplitVector(Mask, MaskLo, MaskHi);
2496 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2500 SDValue EVLLo, EVLHi;
2501 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2503 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2506 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2509 DAG.getLoadVP(
LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr,
Offset,
2510 MaskLo, EVLLo, LoMemVT, MMO,
LD->isExpandingLoad());
2518 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2519 LD->isExpandingLoad());
2521 MachinePointerInfo MPI;
2523 MPI = MachinePointerInfo(
LD->getPointerInfo().getAddrSpace());
2525 MPI =
LD->getPointerInfo().getWithOffset(
2528 MMO = DAG.getMachineFunction().getMachineMemOperand(
2530 Alignment, MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2532 Hi = DAG.getLoadVP(
LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
2533 Offset, MaskHi, EVLHi, HiMemVT, MMO,
2534 LD->isExpandingLoad());
2544 ReplaceValueWith(SDValue(LD, 1), Ch);
2550 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
LD->getValueType(0));
2552 SDValue Ch =
LD->getChain();
2553 SDValue Ptr =
LD->getBasePtr();
2555 SDValue
Mask =
LD->getMask();
2556 SDValue EVL =
LD->getVectorLength();
2559 SDValue MaskLo, MaskHi;
2561 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2564 GetSplitVector(Mask, MaskLo, MaskHi);
2566 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2570 auto [EVLLo, EVLHi] = DAG.SplitEVL(EVL,
LD->getValueType(0), dl);
2572 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2575 MMOMetadata(
LD->getAAInfo(),
LD->getRanges()));
2577 Lo = DAG.getLoadFFVP(LoVT, dl, Ch, Ptr, MaskLo, EVLLo, MMO);
2580 Hi = DAG.getPOISON(HiVT);
2582 ReplaceValueWith(SDValue(LD, 1),
Lo.getValue(1));
2583 ReplaceValueWith(SDValue(LD, 2),
Lo.getValue(2));
2589 "Indexed VP strided load during type legalization!");
2591 "Unexpected indexed variable-length load offset");
2596 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->
getValueType(0));
2598 EVT LoMemVT, HiMemVT;
2599 bool HiIsEmpty =
false;
2600 std::tie(LoMemVT, HiMemVT) =
2601 DAG.GetDependentSplitDestVTs(SLD->
getMemoryVT(), LoVT, &HiIsEmpty);
2604 SDValue LoMask, HiMask;
2606 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
2609 GetSplitVector(Mask, LoMask, HiMask);
2611 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
2614 SDValue LoEVL, HiEVL;
2615 std::tie(LoEVL, HiEVL) =
2619 Lo = DAG.getStridedLoadVP(
2646 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2653 SLD->
getStride(), HiMask, HiEVL, HiMemVT, MMO,
2664 ReplaceValueWith(SDValue(SLD, 1), Ch);
2672 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->
getValueType(0));
2677 assert(
Offset.isUndef() &&
"Unexpected indexed masked load offset");
2685 SDValue MaskLo, MaskHi;
2687 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
2690 GetSplitVector(Mask, MaskLo, MaskHi);
2692 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2696 EVT LoMemVT, HiMemVT;
2697 bool HiIsEmpty =
false;
2698 std::tie(LoMemVT, HiMemVT) =
2699 DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2701 SDValue PassThruLo, PassThruHi;
2703 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2705 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2707 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2712 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr,
Offset, MaskLo, PassThruLo, LoMemVT,
2722 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2725 MachinePointerInfo MPI;
2732 MMO = DAG.getMachineFunction().getMachineMemOperand(
2737 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr,
Offset, MaskHi, PassThruHi,
2749 ReplaceValueWith(SDValue(MLD, 1), Ch);
2757 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2759 SDValue Ch =
N->getChain();
2760 SDValue Ptr =
N->getBasePtr();
2767 return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2770 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2773 EVT MemoryVT =
N->getMemoryVT();
2777 SDValue MaskLo, MaskHi;
2779 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
2781 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask, dl);
2784 EVT LoMemVT, HiMemVT;
2786 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2788 SDValue IndexHi, IndexLo;
2789 if (getTypeAction(
Ops.Index.getValueType()) ==
2791 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
2793 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index, dl);
2796 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2798 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
2801 SDValue PassThru = MGT->getPassThru();
2802 SDValue PassThruLo, PassThruHi;
2805 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2807 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2812 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
2813 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2814 OpsLo, MMO, IndexTy, ExtType);
2816 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
2817 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2818 OpsHi, MMO, IndexTy, ExtType);
2821 SDValue EVLLo, EVLHi;
2822 std::tie(EVLLo, EVLHi) =
2823 DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2825 SDValue OpsLo[] = {Ch, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
2826 Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2827 MMO, VPGT->getIndexType());
2829 SDValue OpsHi[] = {Ch, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
2830 Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2831 MMO, VPGT->getIndexType());
2841 ReplaceValueWith(SDValue(
N, 1), Ch);
2855 EVT VecVT =
N->getValueType(0);
2857 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(VecVT);
2858 bool HasCustomLowering =
false;
2865 HasCustomLowering =
true;
2871 SDValue Passthru =
N->getOperand(2);
2872 if (!HasCustomLowering) {
2873 SDValue Compressed = TLI.expandVECTOR_COMPRESS(
N, DAG);
2874 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL, LoVT, HiVT);
2879 SDValue
Mask =
N->getOperand(1);
2880 SDValue LoMask, HiMask;
2881 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2882 std::tie(LoMask, HiMask) = SplitMask(Mask);
2884 SDValue UndefPassthru = DAG.getPOISON(LoVT);
2888 SDValue
StackPtr = DAG.CreateStackTemporary(
2889 VecVT.
getStoreSize(), DAG.getReducedAlign(VecVT,
false));
2902 Offset = TLI.getVectorElementPointer(DAG, StackPtr, VecVT,
Offset);
2904 SDValue Chain = DAG.getEntryNode();
2905 Chain = DAG.getStore(Chain,
DL,
Lo, StackPtr, PtrInfo);
2909 SDValue Compressed = DAG.getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
2913 EVT MaskVT =
Mask.getValueType();
2917 SDValue NumActiveElts =
2920 SDValue StepVector = DAG.getStepVector(
DL, WideMaskVT);
2921 SDValue SplatNumActiveElts = DAG.getSplat(WideMaskVT,
DL, NumActiveElts);
2922 SDValue CompressedMask =
2923 DAG.getSetCC(
DL, MaskVT, StepVector, SplatNumActiveElts,
ISD::SETULT);
2926 Compressed, Passthru);
2928 std::tie(
Lo,
Hi) = DAG.SplitVector(Compressed,
DL);
2932 assert(
N->getValueType(0).isVector() &&
2933 N->getOperand(0).getValueType().isVector() &&
2934 "Operand types must be vectors");
2938 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2941 SDValue LL, LH, RL, RH;
2942 if (getTypeAction(
N->getOperand(0).getValueType()) ==
2944 GetSplitVector(
N->getOperand(0), LL, LH);
2946 std::tie(LL, LH) = DAG.SplitVectorOperand(
N, 0);
2948 if (getTypeAction(
N->getOperand(1).getValueType()) ==
2950 GetSplitVector(
N->getOperand(1), RL, RH);
2952 std::tie(RL, RH) = DAG.SplitVectorOperand(
N, 1);
2954 Lo = DAG.getNode(
N->getOpcode(),
DL, LoVT, LL, RL,
N->getOperand(2));
2955 Hi = DAG.getNode(
N->getOpcode(),
DL, HiVT, LH, RH,
N->getOperand(2));
2963 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
2967 EVT InVT =
N->getOperand(0).getValueType();
2969 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
2971 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
2973 const SDNodeFlags
Flags =
N->getFlags();
2974 unsigned Opcode =
N->getOpcode();
2976 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1),
N->getOperand(2),
2977 N->getOperand(3), Flags);
2978 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1),
N->getOperand(2),
2979 N->getOperand(3), Flags);
2985 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo,
N->getOperand(1), Flags);
2986 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi,
N->getOperand(1), Flags);
2988 Lo = DAG.getNode(Opcode, dl, LoVT,
Lo, Flags);
2989 Hi = DAG.getNode(Opcode, dl, HiVT,
Hi, Flags);
2996 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3000 EVT InVT =
N->getOperand(0).getValueType();
3002 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3004 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3007 unsigned SrcAS = AddrSpaceCastN->getSrcAddressSpace();
3008 unsigned DestAS = AddrSpaceCastN->getDestAddressSpace();
3009 SDNodeFlags
Flags = AddrSpaceCastN->getFlags();
3010 Lo = DAG.getAddrSpaceCast(dl, LoVT,
Lo, SrcAS, DestAS, Flags);
3011 Hi = DAG.getAddrSpaceCast(dl, HiVT,
Hi, SrcAS, DestAS, Flags);
3014void DAGTypeLegalizer::SplitVecRes_UnaryOpWithTwoResults(
SDNode *
N,
3019 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(
N->getValueType(0));
3020 auto [LoVT1, HiVT1] = DAG.GetSplitDestVTs(
N->getValueType(1));
3024 EVT InVT =
N->getOperand(0).getValueType();
3026 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
3028 std::tie(
Lo,
Hi) = DAG.SplitVectorOperand(
N, 0);
3030 Lo = DAG.getNode(
N->getOpcode(), dl, {LoVT, LoVT1},
Lo,
N->getFlags());
3031 Hi = DAG.getNode(
N->getOpcode(), dl, {HiVT, HiVT1},
Hi,
N->getFlags());
3033 SDNode *HiNode =
Hi.getNode();
3034 SDNode *LoNode =
Lo.getNode();
3037 unsigned OtherNo = 1 - ResNo;
3038 EVT OtherVT =
N->getValueType(OtherNo);
3040 SetSplitVector(SDValue(
N, OtherNo), SDValue(LoNode, OtherNo),
3041 SDValue(HiNode, OtherNo));
3045 SDValue(HiNode, OtherNo));
3046 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
3053 EVT SrcVT =
N->getOperand(0).getValueType();
3054 EVT DestVT =
N->getValueType(0);
3056 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
3073 LLVMContext &Ctx = *DAG.getContext();
3077 EVT SplitLoVT, SplitHiVT;
3078 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
3079 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
3080 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
3081 LLVM_DEBUG(
dbgs() <<
"Split vector extend via incremental extend:";
3082 N->dump(&DAG);
dbgs() <<
"\n");
3085 DAG.getNode(
N->getOpcode(), dl, NewSrcVT,
N->getOperand(0));
3087 std::tie(
Lo,
Hi) = DAG.SplitVector(NewSrc, dl);
3089 Lo = DAG.getNode(
N->getOpcode(), dl, LoVT,
Lo);
3090 Hi = DAG.getNode(
N->getOpcode(), dl, HiVT,
Hi);
3095 SplitVecRes_UnaryOp(
N,
Lo,
Hi);
3103 GetSplitVector(
N->getOperand(0), Inputs[0], Inputs[1]);
3104 GetSplitVector(
N->getOperand(1), Inputs[2], Inputs[3]);
3110 return N.getResNo() == 0 &&
3114 auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &
DL](SDValue &Input1,
3116 ArrayRef<int>
Mask) {
3119 "Expected build vector node.");
3122 for (
unsigned I = 0;
I < NewElts; ++
I) {
3125 unsigned Idx =
Mask[
I];
3127 Ops[
I] = Input2.getOperand(Idx - NewElts);
3129 Ops[
I] = Input1.getOperand(Idx);
3134 return DAG.getBuildVector(NewVT,
DL,
Ops);
3140 SmallVector<int> OrigMask(
N->getMask());
3142 auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT,
this, NewElts,
3143 &
DL](SmallVectorImpl<int> &
Mask) {
3145 MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
3146 for (
unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
3147 SDValue Input = Inputs[Idx];
3157 for (
auto &
P : ShufflesIdxs) {
3158 if (
P.second.size() < 2)
3162 for (
int &Idx : Mask) {
3165 unsigned SrcRegIdx = Idx / NewElts;
3166 if (Inputs[SrcRegIdx].
isUndef()) {
3174 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3179 Idx = MaskElt % NewElts +
3180 P.second[Shuffle->getOperand(MaskElt / NewElts) ==
P.first.first
3186 Inputs[
P.second[0]] =
P.first.first;
3187 Inputs[
P.second[1]] =
P.first.second;
3190 ShufflesIdxs[std::make_pair(
P.first.second,
P.first.first)].clear();
3193 SmallBitVector UsedSubVector(2 * std::size(Inputs));
3194 for (
int &Idx : Mask) {
3197 unsigned SrcRegIdx = Idx / NewElts;
3198 if (Inputs[SrcRegIdx].
isUndef()) {
3205 Inputs[SrcRegIdx].getNumOperands() == 2 &&
3206 !Inputs[SrcRegIdx].getOperand(1).
isUndef() &&
3209 UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
3211 if (UsedSubVector.count() > 1) {
3213 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3214 if (UsedSubVector.test(2 *
I) == UsedSubVector.test(2 *
I + 1))
3216 if (Pairs.
empty() || Pairs.
back().size() == 2)
3218 if (UsedSubVector.test(2 *
I)) {
3219 Pairs.
back().emplace_back(
I, 0);
3221 assert(UsedSubVector.test(2 *
I + 1) &&
3222 "Expected to be used one of the subvectors.");
3223 Pairs.
back().emplace_back(
I, 1);
3226 if (!Pairs.
empty() && Pairs.
front().size() > 1) {
3228 for (
int &Idx : Mask) {
3231 unsigned SrcRegIdx = Idx / NewElts;
3233 Pairs, [SrcRegIdx](
ArrayRef<std::pair<unsigned, int>> Idxs) {
3234 return Idxs.front().first == SrcRegIdx ||
3235 Idxs.back().first == SrcRegIdx;
3237 if (It == Pairs.
end())
3239 Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
3240 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
3243 for (
ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
3244 Inputs[Idxs.front().first] = DAG.
getNode(
3246 Inputs[Idxs.front().first].getValueType(),
3247 Inputs[Idxs.front().first].getOperand(Idxs.front().second),
3248 Inputs[Idxs.back().first].getOperand(Idxs.back().second));
3257 for (
unsigned I = 0;
I < std::size(Inputs); ++
I) {
3261 if (Shuffle->getOperand(0).getValueType() != NewVT)
3264 if (!Inputs[
I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
3265 !Shuffle->isSplat()) {
3267 }
else if (!Inputs[
I].hasOneUse() &&
3268 !Shuffle->getOperand(1).isUndef()) {
3270 for (
int &Idx : Mask) {
3273 unsigned SrcRegIdx = Idx / NewElts;
3276 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3281 int OpIdx = MaskElt / NewElts;
3294 for (
int OpIdx = 0; OpIdx < 2; ++OpIdx) {
3295 if (Shuffle->getOperand(OpIdx).isUndef())
3297 auto *It =
find(Inputs, Shuffle->getOperand(OpIdx));
3298 if (It == std::end(Inputs))
3300 int FoundOp = std::distance(std::begin(Inputs), It);
3303 for (
int &Idx : Mask) {
3306 unsigned SrcRegIdx = Idx / NewElts;
3309 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3314 int MaskIdx = MaskElt / NewElts;
3315 if (OpIdx == MaskIdx)
3316 Idx = MaskElt % NewElts + FoundOp * NewElts;
3319 Op = (OpIdx + 1) % 2;
3327 for (
int &Idx : Mask) {
3330 unsigned SrcRegIdx = Idx / NewElts;
3333 int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
3334 int OpIdx = MaskElt / NewElts;
3337 Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
3343 TryPeekThroughShufflesInputs(OrigMask);
3345 auto &&MakeUniqueInputs = [&Inputs, &
IsConstant,
3346 NewElts](SmallVectorImpl<int> &
Mask) {
3347 SetVector<SDValue> UniqueInputs;
3348 SetVector<SDValue> UniqueConstantInputs;
3349 for (
const auto &
I : Inputs) {
3351 UniqueConstantInputs.
insert(
I);
3352 else if (!
I.isUndef())
3357 if (UniqueInputs.
size() != std::size(Inputs)) {
3358 auto &&UniqueVec = UniqueInputs.
takeVector();
3359 auto &&UniqueConstantVec = UniqueConstantInputs.
takeVector();
3360 unsigned ConstNum = UniqueConstantVec.size();
3361 for (
int &Idx : Mask) {
3364 unsigned SrcRegIdx = Idx / NewElts;
3365 if (Inputs[SrcRegIdx].
isUndef()) {
3369 const auto It =
find(UniqueConstantVec, Inputs[SrcRegIdx]);
3370 if (It != UniqueConstantVec.end()) {
3371 Idx = (Idx % NewElts) +
3372 NewElts * std::distance(UniqueConstantVec.begin(), It);
3373 assert(Idx >= 0 &&
"Expected defined mask idx.");
3376 const auto RegIt =
find(UniqueVec, Inputs[SrcRegIdx]);
3377 assert(RegIt != UniqueVec.end() &&
"Cannot find non-const value.");
3378 Idx = (Idx % NewElts) +
3379 NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
3380 assert(Idx >= 0 &&
"Expected defined mask idx.");
3382 copy(UniqueConstantVec, std::begin(Inputs));
3383 copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
3386 MakeUniqueInputs(OrigMask);
3387 SDValue OrigInputs[4];
3388 copy(Inputs, std::begin(OrigInputs));
3394 unsigned FirstMaskIdx =
High * NewElts;
3397 assert(!Output &&
"Expected default initialized initial value.");
3398 TryPeekThroughShufflesInputs(Mask);
3399 MakeUniqueInputs(Mask);
3400 SDValue TmpInputs[4];
3401 copy(Inputs, std::begin(TmpInputs));
3404 bool SecondIteration =
false;
3405 auto &&AccumulateResults = [&UsedIdx, &SecondIteration](
unsigned Idx) {
3410 if (UsedIdx >= 0 &&
static_cast<unsigned>(UsedIdx) == Idx)
3411 SecondIteration =
true;
3412 return SecondIteration;
3415 Mask, std::size(Inputs), std::size(Inputs),
3417 [&Output, &DAG = DAG, NewVT]() { Output = DAG.getPOISON(NewVT); },
3418 [&Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3419 &BuildVector](ArrayRef<int>
Mask,
unsigned Idx,
unsigned ) {
3421 Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
3423 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx],
3424 DAG.getPOISON(NewVT), Mask);
3425 Inputs[Idx] = Output;
3427 [&AccumulateResults, &Output, &DAG = DAG, NewVT, &
DL, &Inputs,
3428 &TmpInputs, &BuildVector](ArrayRef<int>
Mask,
unsigned Idx1,
3429 unsigned Idx2,
bool ) {
3430 if (AccumulateResults(Idx1)) {
3433 Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
3435 Output = DAG.getVectorShuffle(NewVT,
DL, Inputs[Idx1],
3436 Inputs[Idx2], Mask);
3440 Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
3442 Output = DAG.getVectorShuffle(NewVT,
DL, TmpInputs[Idx1],
3443 TmpInputs[Idx2], Mask);
3445 Inputs[Idx1] = Output;
3447 copy(OrigInputs, std::begin(Inputs));
3452 EVT OVT =
N->getValueType(0);
3456 SDValue
SV =
N->getOperand(2);
3460 DAG.getDataLayout().getABITypeAlign(NVT.
getTypeForEVT(*DAG.getContext()));
3462 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV,
Alignment.value());
3463 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr, SV,
Alignment.value());
3468 ReplaceValueWith(SDValue(
N, 1), Chain);
3473 EVT DstVTLo, DstVTHi;
3474 std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(
N->getValueType(0));
3477 SDValue SrcLo, SrcHi;
3478 EVT SrcVT =
N->getOperand(0).getValueType();
3480 GetSplitVector(
N->getOperand(0), SrcLo, SrcHi);
3482 std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(
N, 0);
3484 Lo = DAG.getNode(
N->getOpcode(), dl, DstVTLo, SrcLo,
N->getOperand(1));
3485 Hi = DAG.getNode(
N->getOpcode(), dl, DstVTHi, SrcHi,
N->getOperand(1));
3491 GetSplitVector(
N->getOperand(0), InLo, InHi);
3502 SDValue Expanded = TLI.expandVectorSplice(
N, DAG);
3503 std::tie(
Lo,
Hi) = DAG.SplitVector(Expanded,
DL);
3508 EVT VT =
N->getValueType(0);
3509 SDValue Val =
N->getOperand(0);
3510 SDValue
Mask =
N->getOperand(1);
3531 EVT PtrVT =
StackPtr.getValueType();
3532 auto &MF = DAG.getMachineFunction();
3536 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3539 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3544 SDValue NumElemMinus1 =
3545 DAG.getNode(
ISD::SUB,
DL, PtrVT, DAG.getZExtOrTrunc(EVL,
DL, PtrVT),
3546 DAG.getConstant(1,
DL, PtrVT));
3547 SDValue StartOffset = DAG.getNode(
ISD::MUL,
DL, PtrVT, NumElemMinus1,
3548 DAG.getConstant(EltWidth,
DL, PtrVT));
3549 SDValue StorePtr = DAG.getNode(
ISD::ADD,
DL, PtrVT, StackPtr, StartOffset);
3550 SDValue Stride = DAG.getConstant(-(int64_t)EltWidth,
DL, PtrVT);
3552 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3553 SDValue
Store = DAG.getStridedStoreVP(DAG.getEntryNode(),
DL, Val, StorePtr,
3554 DAG.getPOISON(PtrVT), Stride, TrueMask,
3557 SDValue
Load = DAG.getLoadVP(VT,
DL,
Store, StackPtr, Mask, EVL, LoadMMO);
3563 std::tie(
Lo,
Hi) = DAG.SplitVector(
Load,
DL);
3568 EVT VT =
N->getValueType(0);
3569 SDValue
V1 =
N->getOperand(0);
3570 SDValue V2 =
N->getOperand(1);
3572 SDValue
Mask =
N->getOperand(3);
3573 SDValue EVL1 =
N->getOperand(4);
3574 SDValue EVL2 =
N->getOperand(5);
3580 EVL1 = ZExtPromotedInteger(EVL1);
3599 EVT PtrVT =
StackPtr.getValueType();
3600 auto &MF = DAG.getMachineFunction();
3604 MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
3607 MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
3611 SDValue EltByteSize =
3613 SDValue EVL1Ptr = DAG.getZExtOrTrunc(EVL1,
DL, PtrVT);
3614 SDValue EVL1Bytes = DAG.getNode(
ISD::MUL,
DL, PtrVT, EVL1Ptr, EltByteSize);
3618 SDValue StackPtr2 = DAG.getMemBasePlusOffset(StackPtr, EVL1Bytes,
DL);
3619 SDValue PoisonPtr = DAG.getPOISON(PtrVT);
3621 SDValue TrueMask = DAG.getBoolConstant(
true,
DL,
Mask.getValueType(), VT);
3623 DAG.getStoreVP(DAG.getEntryNode(),
DL,
V1, StackPtr, PoisonPtr, TrueMask,
3627 DAG.getStoreVP(StoreV1,
DL, V2, StackPtr2, PoisonPtr, TrueMask, EVL2,
3632 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VT,
N->getOperand(2));
3633 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr, Mask, EVL2, LoadMMO);
3637 SDValue TrailingBytes = DAG.getConstant(TrailingElts * EltWidth,
DL, PtrVT);
3640 SDValue OffsetToV2 = DAG.getNode(
ISD::SUB,
DL, PtrVT, StackPtr2, StackPtr);
3646 Load = DAG.getLoadVP(VT,
DL, StoreV2, StackPtr2, Mask, EVL2, LoadMMO);
3654 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(OrigVT);
3656 DAG.getVectorIdxConstant(0,
DL));
3662void DAGTypeLegalizer::SplitVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N,
SDValue &
Lo,
3665 SDValue Acc =
N->getOperand(0);
3666 SDValue Input1 =
N->getOperand(1);
3667 SDValue Input2 =
N->getOperand(2);
3669 SDValue AccLo, AccHi;
3670 GetSplitVector(Acc, AccLo, AccHi);
3671 unsigned Opcode =
N->getOpcode();
3681 SDValue Input1Lo, Input1Hi;
3682 SDValue Input2Lo, Input2Hi;
3683 GetSplitVector(Input1, Input1Lo, Input1Hi);
3684 GetSplitVector(Input2, Input2Lo, Input2Hi);
3687 Lo = DAG.getNode(Opcode,
DL, ResultVT, AccLo, Input1Lo, Input2Lo);
3688 Hi = DAG.getNode(Opcode,
DL, ResultVT, AccHi, Input1Hi, Input2Hi);
3691void DAGTypeLegalizer::SplitVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N,
SDValue &
Lo,
3699 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
3703 SDValue HiStartVal = DAG.getNode(
ISD::UADDSAT,
DL, OpVT, Op0, LoElts);
3709 SDValue SourceLo, SourceHi;
3710 GetSplitVector(
N->getOperand(0), SourceLo, SourceHi);
3711 SDValue MaskLo, MaskHi;
3712 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
3716 N->getOperand(1), MaskLo,
N->getFlags());
3718 N->getOperand(1), MaskHi,
N->getFlags());
3721void DAGTypeLegalizer::SplitVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
3722 unsigned Factor =
N->getNumOperands();
3725 for (
unsigned i = 0; i != Factor; ++i) {
3727 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3729 Ops[i * 2 + 1] = OpHi;
3740 for (
unsigned i = 0; i != Factor; ++i)
3744void DAGTypeLegalizer::SplitVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
3745 unsigned Factor =
N->getNumOperands();
3748 for (
unsigned i = 0; i != Factor; ++i) {
3750 GetSplitVector(
N->getOperand(i), OpLo, OpHi);
3752 Ops[i + Factor] = OpHi;
3763 for (
unsigned i = 0; i != Factor; ++i) {
3764 unsigned IdxLo = 2 * i;
3765 unsigned IdxHi = 2 * i + 1;
3766 SetSplitVector(SDValue(
N, i), Res[IdxLo / Factor].
getValue(IdxLo % Factor),
3767 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
3779bool DAGTypeLegalizer::SplitVectorOperand(
SDNode *
N,
unsigned OpNo) {
3781 SDValue Res = SDValue();
3784 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
3787 switch (
N->getOpcode()) {
3790 dbgs() <<
"SplitVectorOperand Op #" << OpNo <<
": ";
3799 case ISD::SETCC: Res = SplitVecOp_VSETCC(
N);
break;
3806 Res = SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
3809 Res = SplitVecOp_TruncateHelper(
N);
3815 Res = SplitVecOp_FP_ROUND(
N);
3827 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
3834 case ISD::VP_SCATTER:
3838 case ISD::VP_GATHER:
3842 Res = SplitVecOp_VSELECT(
N, OpNo);
3848 Res = SplitVecOp_MaskedBinOp(
N, OpNo);
3851 Res = SplitVecOp_VECTOR_COMPRESS(
N, OpNo);
3857 if (
N->getValueType(0).bitsLT(
3858 N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType()))
3859 Res = SplitVecOp_TruncateHelper(
N);
3861 Res = SplitVecOp_UnaryOp(
N);
3865 Res = SplitVecOp_FP_TO_XINT_SAT(
N);
3881 Res = SplitVecOp_UnaryOp(
N);
3884 Res = SplitVecOp_FPOpDifferentTypes(
N);
3889 Res = SplitVecOp_CMP(
N);
3893 Res = SplitVecOp_FAKE_USE(
N);
3898 Res = SplitVecOp_ExtVecInRegOp(
N);
3918 Res = SplitVecOp_VECREDUCE(
N, OpNo);
3922 Res = SplitVecOp_VECREDUCE_SEQ(
N);
3924 case ISD::VP_REDUCE_FADD:
3925 case ISD::VP_REDUCE_SEQ_FADD:
3926 case ISD::VP_REDUCE_FMUL:
3927 case ISD::VP_REDUCE_SEQ_FMUL:
3928 case ISD::VP_REDUCE_ADD:
3929 case ISD::VP_REDUCE_MUL:
3930 case ISD::VP_REDUCE_AND:
3931 case ISD::VP_REDUCE_OR:
3932 case ISD::VP_REDUCE_XOR:
3933 case ISD::VP_REDUCE_SMAX:
3934 case ISD::VP_REDUCE_SMIN:
3935 case ISD::VP_REDUCE_UMAX:
3936 case ISD::VP_REDUCE_UMIN:
3937 case ISD::VP_REDUCE_FMAX:
3938 case ISD::VP_REDUCE_FMIN:
3939 case ISD::VP_REDUCE_FMAXIMUM:
3940 case ISD::VP_REDUCE_FMINIMUM:
3941 Res = SplitVecOp_VP_REDUCE(
N, OpNo);
3945 Res = SplitVecOp_CttzElts(
N);
3947 case ISD::VP_CTTZ_ELTS:
3948 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
3949 Res = SplitVecOp_VP_CttzElements(
N);
3952 Res = SplitVecOp_VECTOR_HISTOGRAM(
N);
3958 Res = SplitVecOp_PARTIAL_REDUCE_MLA(
N);
3961 Res = SplitVecOp_VECTOR_MATCH(
N, OpNo);
3966 if (!Res.
getNode())
return false;
3973 if (
N->isStrictFPOpcode())
3975 "Invalid operand expansion");
3978 "Invalid operand expansion");
3980 ReplaceValueWith(SDValue(
N, 0), Res);
3984SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
3987 SDValue LoMask, HiMask;
3988 GetSplitVector(
N->getOperand(0), LoMask, HiMask);
3990 EVT VT =
N->getValueType(0);
4002 SDValue
Cond = DAG.getBoolExtOrTrunc(AnyHiActive,
DL,
4003 getSetCCResultType(MVT::i1), MVT::i1);
4008 DAG.getElementCount(
DL, VT, SplitEC)),
4012SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(
SDNode *
N,
unsigned OpNo) {
4015 assert(OpNo == 0 &&
"Illegal operand must be mask");
4017 SDValue
Mask =
N->getOperand(0);
4018 SDValue Src0 =
N->getOperand(1);
4019 SDValue Src1 =
N->getOperand(2);
4022 assert(
Mask.getValueType().isVector() &&
"VSELECT without a vector mask?");
4025 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4026 assert(
Lo.getValueType() ==
Hi.getValueType() &&
4027 "Lo and Hi have differing types");
4030 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
4031 assert(LoOpVT == HiOpVT &&
"Asymmetric vector split?");
4033 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
4034 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0,
DL);
4035 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1,
DL);
4036 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4046SDValue DAGTypeLegalizer::SplitVecOp_MaskedBinOp(
SDNode *
N,
unsigned OpNo) {
4047 assert(OpNo == 2 &&
"Illegal operand must be mask");
4050 auto [LHSLo, LHSHi] = DAG.SplitVector(
N->getOperand(0),
DL);
4051 auto [RHSLo, RHSHi] = DAG.SplitVector(
N->getOperand(1),
DL);
4052 SDValue MaskLo, MaskHi;
4053 GetSplitVector(
N->getOperand(2), MaskLo, MaskHi);
4056 RHSLo, MaskLo,
N->getFlags());
4058 RHSHi, MaskHi,
N->getFlags());
4062SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_COMPRESS(
SDNode *
N,
unsigned OpNo) {
4065 assert(OpNo == 1 &&
"Illegal operand must be mask");
4070 SplitVecRes_VECTOR_COMPRESS(
N,
Lo,
Hi);
4072 EVT VecVT =
N->getValueType(0);
4076SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(
SDNode *
N,
unsigned OpNo) {
4077 EVT ResVT =
N->getValueType(0);
4083 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4084 GetSplitVector(VecOp,
Lo,
Hi);
4086 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4091 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT,
Lo,
Hi,
N->getFlags());
4092 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
N->getFlags());
4096 EVT ResVT =
N->getValueType(0);
4102 SDNodeFlags
Flags =
N->getFlags();
4105 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4106 GetSplitVector(VecOp,
Lo,
Hi);
4108 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
4111 SDValue Partial = DAG.
getNode(
N->getOpcode(), dl, ResVT, AccOp,
Lo, Flags);
4114 return DAG.getNode(
N->getOpcode(), dl, ResVT, Partial,
Hi, Flags);
4117SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(
SDNode *
N,
unsigned OpNo) {
4118 assert(
N->isVPOpcode() &&
"Expected VP opcode");
4119 assert(OpNo == 1 &&
"Can only split reduce vector operand");
4121 unsigned Opc =
N->getOpcode();
4122 EVT ResVT =
N->getValueType(0);
4128 assert(VecVT.
isVector() &&
"Can only split reduce vector operand");
4129 GetSplitVector(VecOp,
Lo,
Hi);
4131 SDValue MaskLo, MaskHi;
4132 std::tie(MaskLo, MaskHi) = SplitMask(
N->getOperand(2));
4134 SDValue EVLLo, EVLHi;
4135 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(
N->getOperand(3), VecVT, dl);
4137 const SDNodeFlags
Flags =
N->getFlags();
4141 return DAG.getNode(
Opc, dl, ResVT, {ResLo,
Hi, MaskHi, EVLHi},
Flags);
4146 EVT ResVT =
N->getValueType(0);
4149 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4150 EVT InVT =
Lo.getValueType();
4155 if (
N->isStrictFPOpcode()) {
4156 Lo = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4157 {N->getOperand(0), Lo});
4158 Hi = DAG.getNode(
N->getOpcode(), dl, {OutVT, MVT::Other},
4159 {N->getOperand(0), Hi});
4168 ReplaceValueWith(SDValue(
N, 1), Ch);
4170 Lo = DAG.getNode(
N->getOpcode(), dl, OutVT,
Lo);
4171 Hi = DAG.getNode(
N->getOpcode(), dl, OutVT,
Hi);
4180 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4190 EVT ResVT =
N->getValueType(0);
4192 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4196 auto [LoVT, HiVT] = DAG.GetSplitDestVTs(ResVT);
4202 Lo = BitConvertToInteger(
Lo);
4203 Hi = BitConvertToInteger(
Hi);
4205 if (DAG.getDataLayout().isBigEndian())
4213 assert(OpNo == 1 &&
"Invalid OpNo; can only split SubVec.");
4215 EVT ResVT =
N->getValueType(0);
4223 GetSplitVector(SubVec,
Lo,
Hi);
4228 SDValue FirstInsertion =
4230 SDValue SecondInsertion =
4232 DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
4234 return SecondInsertion;
4237SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
4244 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
4246 ElementCount LoElts =
Lo.getValueType().getVectorElementCount();
4248 ElementCount IdxVal =
4252 EVT SrcVT =
N->getOperand(0).getValueType();
4271 DAG.ExtractVectorElements(
Lo, Elts, IdxValMin,
4272 LoEltsMin - IdxValMin);
4273 DAG.ExtractVectorElements(
Hi, Elts, 0,
4276 return DAG.getBuildVector(SubVT, dl, Elts);
4280 ElementCount ExtractIdx = IdxVal - LoElts;
4282 return DAG.getExtractSubvector(dl, SubVT,
Hi,
4285 EVT HiVT =
Hi.getValueType();
4287 "Only fixed-vector extracts are supported in this case");
4297 DAG.getVectorShuffle(HiVT, dl,
Hi, DAG.getPOISON(HiVT), Mask);
4298 return DAG.getExtractSubvector(dl, SubVT, Shuffle, 0);
4304 "Extracting scalable subvector from fixed-width unsupported");
4312 "subvector from a scalable predicate vector");
4318 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4320 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4321 auto &MF = DAG.getMachineFunction();
4325 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4329 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
4332 SubVT, dl,
Store, StackPtr,
4336SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
4345 GetSplitVector(Vec,
Lo,
Hi);
4347 uint64_t LoElts =
Lo.getValueType().getVectorMinNumElements();
4349 if (IdxVal < LoElts)
4350 return SDValue(DAG.UpdateNodeOperands(
N,
Lo, Idx), 0);
4352 return SDValue(DAG.UpdateNodeOperands(
N,
Hi,
4353 DAG.getConstant(IdxVal - LoElts, SDLoc(
N),
4358 if (CustomLowerNode(
N,
N->getValueType(0),
true))
4368 SDValue NewExtract =
4370 return DAG.getAnyExtOrTrunc(NewExtract, dl,
N->getValueType(0));
4376 Align SmallestAlign = DAG.getReducedAlign(VecVT,
false);
4378 DAG.CreateStackTemporary(VecVT.
getStoreSize(), SmallestAlign);
4379 auto &MF = DAG.getMachineFunction();
4382 SDValue
Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
4386 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
4390 assert(
N->getValueType(0).bitsGE(EltVT) &&
"Illegal EXTRACT_VECTOR_ELT.");
4392 return DAG.getExtLoad(
4403 SplitVecRes_ExtVecInRegOp(
N,
Lo,
Hi);
4411 SplitVecRes_Gather(
N,
Lo,
Hi);
4414 ReplaceValueWith(SDValue(
N, 0), Res);
4419 assert(
N->isUnindexed() &&
"Indexed vp_store of vector?");
4420 SDValue Ch =
N->getChain();
4421 SDValue Ptr =
N->getBasePtr();
4422 SDValue
Offset =
N->getOffset();
4423 assert(
Offset.isUndef() &&
"Unexpected VP store offset");
4424 SDValue
Mask =
N->getMask();
4425 SDValue EVL =
N->getVectorLength();
4426 SDValue
Data =
N->getValue();
4430 SDValue DataLo, DataHi;
4433 GetSplitVector(
Data, DataLo, DataHi);
4435 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4438 SDValue MaskLo, MaskHi;
4440 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4443 GetSplitVector(Mask, MaskLo, MaskHi);
4445 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4448 EVT MemoryVT =
N->getMemoryVT();
4449 EVT LoMemVT, HiMemVT;
4450 bool HiIsEmpty =
false;
4451 std::tie(LoMemVT, HiMemVT) =
4452 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4455 SDValue EVLLo, EVLHi;
4456 std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL,
Data.getValueType(),
DL);
4459 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4462 MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4464 Lo = DAG.getStoreVP(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, EVLLo, LoMemVT, MMO,
4465 N->getAddressingMode(),
N->isTruncatingStore(),
4466 N->isCompressingStore());
4472 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4473 N->isCompressingStore());
4475 MachinePointerInfo MPI;
4479 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4484 MMO = DAG.getMachineFunction().getMachineMemOperand(
4486 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4488 Hi = DAG.getStoreVP(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, EVLHi, HiMemVT, MMO,
4489 N->getAddressingMode(),
N->isTruncatingStore(),
4490 N->isCompressingStore());
4499 assert(
N->isUnindexed() &&
"Indexed vp_strided_store of a vector?");
4500 assert(
N->getOffset().isUndef() &&
"Unexpected VP strided store offset");
4504 SDValue
Data =
N->getValue();
4505 SDValue LoData, HiData;
4507 GetSplitVector(
Data, LoData, HiData);
4509 std::tie(LoData, HiData) = DAG.SplitVector(
Data,
DL);
4511 EVT LoMemVT, HiMemVT;
4512 bool HiIsEmpty =
false;
4513 std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
4516 SDValue
Mask =
N->getMask();
4517 SDValue LoMask, HiMask;
4519 SplitVecRes_SETCC(
Mask.getNode(), LoMask, HiMask);
4520 else if (getTypeAction(
Mask.getValueType()) ==
4522 GetSplitVector(Mask, LoMask, HiMask);
4524 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask,
DL);
4526 SDValue LoEVL, HiEVL;
4527 std::tie(LoEVL, HiEVL) =
4528 DAG.SplitEVL(
N->getVectorLength(),
Data.getValueType(),
DL);
4531 SDValue
Lo = DAG.getStridedStoreVP(
4532 N->getChain(),
DL, LoData,
N->getBasePtr(),
N->getOffset(),
4533 N->getStride(), LoMask, LoEVL, LoMemVT,
N->getMemOperand(),
4534 N->getAddressingMode(),
N->isTruncatingStore(),
N->isCompressingStore());
4545 EVT PtrVT =
N->getBasePtr().getValueType();
4548 DAG.getSExtOrTrunc(
N->getStride(),
DL, PtrVT));
4556 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4557 MachinePointerInfo(
N->getPointerInfo().getAddrSpace()),
4559 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4561 SDValue
Hi = DAG.getStridedStoreVP(
4562 N->getChain(),
DL, HiData, Ptr,
N->getOffset(),
N->getStride(), HiMask,
4563 HiEVL, HiMemVT, MMO,
N->getAddressingMode(),
N->isTruncatingStore(),
4564 N->isCompressingStore());
4573 assert(
N->isUnindexed() &&
"Indexed masked store of vector?");
4574 SDValue Ch =
N->getChain();
4575 SDValue Ptr =
N->getBasePtr();
4576 SDValue
Offset =
N->getOffset();
4577 assert(
Offset.isUndef() &&
"Unexpected indexed masked store offset");
4578 SDValue
Mask =
N->getMask();
4579 SDValue
Data =
N->getValue();
4583 SDValue DataLo, DataHi;
4586 GetSplitVector(
Data, DataLo, DataHi);
4588 std::tie(DataLo, DataHi) = DAG.SplitVector(
Data,
DL);
4591 SDValue MaskLo, MaskHi;
4593 SplitVecRes_SETCC(
Mask.getNode(), MaskLo, MaskHi);
4596 GetSplitVector(Mask, MaskLo, MaskHi);
4598 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask,
DL);
4601 EVT MemoryVT =
N->getMemoryVT();
4602 EVT LoMemVT, HiMemVT;
4603 bool HiIsEmpty =
false;
4604 std::tie(LoMemVT, HiMemVT) =
4605 DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.
getValueType(), &HiIsEmpty);
4607 SDValue
Lo,
Hi, Res;
4608 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4611 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4613 Lo = DAG.getMaskedStore(Ch,
DL, DataLo, Ptr,
Offset, MaskLo, LoMemVT, MMO,
4614 N->getAddressingMode(),
N->isTruncatingStore(),
4615 N->isCompressingStore());
4623 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo,
DL, LoMemVT, DAG,
4624 N->isCompressingStore());
4626 MachinePointerInfo MPI;
4630 MPI = MachinePointerInfo(
N->getPointerInfo().getAddrSpace());
4635 MMO = DAG.getMachineFunction().getMachineMemOperand(
4638 MMOMetadata(
N->getAAInfo(),
N->getRanges(),
N->getMemCacheHint()));
4640 Hi = DAG.getMaskedStore(Ch,
DL, DataHi, Ptr,
Offset, MaskHi, HiMemVT, MMO,
4641 N->getAddressingMode(),
N->isTruncatingStore(),
4642 N->isCompressingStore());
4653 SDValue Ch =
N->getChain();
4654 SDValue Ptr =
N->getBasePtr();
4655 EVT MemoryVT =
N->getMemoryVT();
4665 return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
4669 return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
4674 EVT LoMemVT, HiMemVT;
4675 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4677 SDValue DataLo, DataHi;
4680 GetSplitVector(
Ops.Data, DataLo, DataHi);
4682 std::tie(DataLo, DataHi) = DAG.SplitVector(
Ops.Data,
DL);
4685 SDValue MaskLo, MaskHi;
4687 SplitVecRes_SETCC(
Ops.Mask.getNode(), MaskLo, MaskHi);
4689 std::tie(MaskLo, MaskHi) = SplitMask(
Ops.Mask,
DL);
4692 SDValue IndexHi, IndexLo;
4693 if (getTypeAction(
Ops.Index.getValueType()) ==
4695 GetSplitVector(
Ops.Index, IndexLo, IndexHi);
4697 std::tie(IndexLo, IndexHi) = DAG.SplitVector(
Ops.Index,
DL);
4701 MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
4703 Alignment, MMOMetadata(
N->getAAInfo(),
N->getRanges()));
4706 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo,
Ops.Scale};
4708 DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4709 MSC->getIndexType(), MSC->isTruncatingStore());
4714 SDValue OpsHi[] = {
Lo, DataHi, MaskHi, Ptr, IndexHi,
Ops.Scale};
4715 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi,
4716 MMO, MSC->getIndexType(),
4717 MSC->isTruncatingStore());
4720 SDValue EVLLo, EVLHi;
4721 std::tie(EVLLo, EVLHi) =
4722 DAG.SplitEVL(VPSC->getVectorLength(),
Ops.Data.getValueType(),
DL);
4724 SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo,
Ops.Scale, MaskLo, EVLLo};
4725 Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT,
DL, OpsLo, MMO,
4726 VPSC->getIndexType());
4731 SDValue OpsHi[] = {
Lo, DataHi, Ptr, IndexHi,
Ops.Scale, MaskHi, EVLHi};
4732 return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT,
DL, OpsHi, MMO,
4733 VPSC->getIndexType());
4737 assert(
N->isUnindexed() &&
"Indexed store of vector?");
4738 assert(OpNo == 1 &&
"Can only split the stored value");
4741 bool isTruncating =
N->isTruncatingStore();
4742 SDValue Ch =
N->getChain();
4743 SDValue Ptr =
N->getBasePtr();
4744 EVT MemoryVT =
N->getMemoryVT();
4747 AAMDNodes AAInfo =
N->getAAInfo();
4749 GetSplitVector(
N->getOperand(1),
Lo,
Hi);
4751 EVT LoMemVT, HiMemVT;
4752 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
4756 return TLI.scalarizeVectorStore(
N, DAG);
4759 Lo = DAG.getTruncStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), LoMemVT,
4760 Alignment, MMOFlags, AAInfo);
4762 Lo = DAG.getStore(Ch,
DL,
Lo, Ptr,
N->getPointerInfo(), Alignment, MMOFlags,
4765 MachinePointerInfo MPI;
4766 IncrementPointer(
N, LoMemVT, MPI, Ptr);
4769 Hi = DAG.getTruncStore(Ch,
DL,
Hi, Ptr, MPI,
4770 HiMemVT, Alignment, MMOFlags, AAInfo);
4772 Hi = DAG.getStore(Ch,
DL,
Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
4779 LLVMContext &Ctx = *DAG.getContext();
4780 SDValue StVal =
N->getVal();
4797 EVT WideVT = TLI.getLegalTypeToTransformTo(Ctx, IntVecVT);
4798 if (DAG.getDataLayout().isLittleEndian() && TLI.isTypeLegal(MemIntVT) &&
4802 SDValue Wide = ModifyToType(DAG.getBitcast(IntVecVT, StVal), WideVT);
4805 SDValue Elt = DAG.getExtractVectorElt(
DL, MemIntVT,
4806 DAG.getBitcast(MemVecVT, Wide), 0);
4808 N->getBasePtr(),
N->getMemOperand());
4816 SDValue AsInt = DAG.getBitcast(IntVT, StVal);
4818 N->getBasePtr(),
N->getMemOperand());
4831 for (
const SDValue &
Op :
N->op_values()) {
4832 for (
unsigned i = 0, e =
Op.getValueType().getVectorNumElements();
4838 return DAG.getBuildVector(
N->getValueType(0),
DL, Elts);
4859 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
4860 SDValue InVec =
N->getOperand(OpNo);
4862 EVT OutVT =
N->getValueType(0);
4870 EVT LoOutVT, HiOutVT;
4871 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
4872 assert(LoOutVT == HiOutVT &&
"Unequal split?");
4877 if (isTypeLegal(LoOutVT) || InElementSize <= OutElementSize * 2 ||
4879 return SplitVecOp_UnaryOp(
N);
4888 return SplitVecOp_UnaryOp(
N);
4891 SDValue InLoVec, InHiVec;
4892 GetSplitVector(InVec, InLoVec, InHiVec);
4898 EVT HalfElementVT = IsFloat ?
4900 EVT::getIntegerVT(*DAG.
getContext(), InElementSize/2);
4907 if (
N->isStrictFPOpcode()) {
4908 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4909 {N->getOperand(0), InLoVec});
4910 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, {HalfVT, MVT::Other},
4911 {N->getOperand(0), InHiVec});
4917 HalfLo = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InLoVec);
4918 HalfHi = DAG.
getNode(
N->getOpcode(),
DL, HalfVT, InHiVec);
4922 EVT InterVT =
EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
4930 if (
N->isStrictFPOpcode()) {
4934 DAG.getTargetConstant(0,
DL, TLI.getPointerTy(DAG.getDataLayout()))});
4936 ReplaceValueWith(SDValue(
N, 1), SDValue(Res.
getNode(), 1));
4942 DAG.getTargetConstant(
4943 0,
DL, TLI.getPointerTy(DAG.getDataLayout())))
4950 assert(
N->getValueType(0).isVector() &&
4951 N->getOperand(isStrict ? 1 : 0).getValueType().isVector() &&
4952 "Operand types must be vectors");
4954 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
4956 GetSplitVector(
N->getOperand(isStrict ? 1 : 0), Lo0, Hi0);
4957 GetSplitVector(
N->getOperand(isStrict ? 2 : 1), Lo1, Hi1);
4959 EVT VT =
N->getValueType(0);
4960 EVT PartResVT = getSetCCResultType(Lo0.
getValueType());
4966 assert(isStrict &&
"unexpected node");
4967 LoRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4968 N->getOperand(0), Lo0, Lo1,
N->getOperand(3));
4969 HiRes = DAG.
getNode(
Opc,
DL, DAG.getVTList(PartResVT,
N->getValueType(1)),
4970 N->getOperand(0), Hi0, Hi1,
N->getOperand(3));
4973 ReplaceValueWith(SDValue(
N, 1), NewChain);
4981 EVT OpVT =
N->getOperand(0).getValueType();
4984 return DAG.getExtOrTrunc(Con,
DL, VT, ExtendCode);
4990 EVT ResVT =
N->getValueType(0);
4993 GetSplitVector(
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0),
Lo,
Hi);
4994 EVT InVT =
Lo.getValueType();
4999 if (
N->isStrictFPOpcode()) {
5000 Lo = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5001 {N->getOperand(0), Lo, N->getOperand(2)});
5002 Hi = DAG.getNode(
N->getOpcode(),
DL, {OutVT, MVT::Other},
5003 {N->getOperand(0), Hi, N->getOperand(2)});
5007 Lo.getValue(1),
Hi.getValue(1));
5008 ReplaceValueWith(SDValue(
N, 1), NewChain);
5010 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1),
5011 N->getOperand(2),
N->getOperand(3));
5012 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1),
5013 N->getOperand(2),
N->getOperand(3));
5015 Lo = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Lo,
N->getOperand(1));
5016 Hi = DAG.getNode(
N->getOpcode(),
DL, OutVT,
Hi,
N->getOperand(1));
5027SDValue DAGTypeLegalizer::SplitVecOp_FPOpDifferentTypes(
SDNode *
N) {
5030 EVT LHSLoVT, LHSHiVT;
5031 std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5033 if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
5034 return DAG.UnrollVectorOp(
N,
N->getValueType(0).getVectorNumElements());
5036 SDValue LHSLo, LHSHi;
5037 std::tie(LHSLo, LHSHi) =
5038 DAG.SplitVector(
N->getOperand(0),
DL, LHSLoVT, LHSHiVT);
5040 SDValue RHSLo, RHSHi;
5041 std::tie(RHSLo, RHSHi) = DAG.SplitVector(
N->getOperand(1),
DL);
5043 SDValue
Lo = DAG.
getNode(
N->getOpcode(),
DL, LHSLoVT, LHSLo, RHSLo);
5044 SDValue
Hi = DAG.getNode(
N->getOpcode(),
DL, LHSHiVT, LHSHi, RHSHi);
5050 LLVMContext &Ctxt = *DAG.getContext();
5053 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
5054 GetSplitVector(
N->getOperand(0), LHSLo, LHSHi);
5055 GetSplitVector(
N->getOperand(1), RHSLo, RHSHi);
5057 EVT ResVT =
N->getValueType(0);
5062 SDValue
Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSLo, RHSLo);
5063 SDValue
Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT, LHSHi, RHSHi);
5069 EVT ResVT =
N->getValueType(0);
5072 GetSplitVector(
N->getOperand(0),
Lo,
Hi);
5073 EVT InVT =
Lo.getValueType();
5079 Lo = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Lo,
N->getOperand(1));
5080 Hi = DAG.getNode(
N->getOpcode(), dl, NewResVT,
Hi,
N->getOperand(1));
5087 EVT ResVT =
N->getValueType(0);
5091 GetSplitVector(VecOp,
Lo,
Hi);
5097 DAG.getElementCount(
DL, ResVT,
Lo.getValueType().getVectorElementCount());
5098 SDValue ResLoNotVL =
5099 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VL,
ISD::SETNE);
5100 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi);
5101 return DAG.getSelect(
DL, ResVT, ResLoNotVL, ResLo,
5102 DAG.getNode(
ISD::ADD,
DL, ResVT, VL, ResHi));
5107 EVT ResVT =
N->getValueType(0);
5111 GetSplitVector(VecOp,
Lo,
Hi);
5113 auto [MaskLo, MaskHi] = SplitMask(
N->getOperand(1));
5114 auto [EVLLo, EVLHi] =
5116 SDValue VLo = DAG.getZExtOrTrunc(EVLLo,
DL, ResVT);
5120 SDValue ResLo = DAG.
getNode(ISD::VP_CTTZ_ELTS,
DL, ResVT,
Lo, MaskLo, EVLLo);
5121 SDValue ResLoNotEVL =
5122 DAG.getSetCC(
DL, getSetCCResultType(ResVT), ResLo, VLo,
ISD::SETNE);
5123 SDValue ResHi = DAG.
getNode(
N->getOpcode(),
DL, ResVT,
Hi, MaskHi, EVLHi);
5124 return DAG.getSelect(
DL, ResVT, ResLoNotEVL, ResLo,
5125 DAG.getNode(
ISD::ADD,
DL, ResVT, VLo, ResHi));
5128SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_HISTOGRAM(
SDNode *
N) {
5131 SDValue Inc = HG->
getInc();
5139 SDValue IndexLo, IndexHi, MaskLo, MaskHi;
5140 std::tie(IndexLo, IndexHi) = DAG.SplitVector(HG->
getIndex(),
DL);
5141 std::tie(MaskLo, MaskHi) = DAG.SplitVector(HG->
getMask(),
DL);
5142 SDValue OpsLo[] = {HG->
getChain(), Inc, MaskLo, Ptr, IndexLo, Scale, IntID};
5143 SDValue
Lo = DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL,
5144 OpsLo, MMO, IndexType);
5145 SDValue OpsHi[] = {
Lo, Inc, MaskHi, Ptr, IndexHi, Scale, IntID};
5146 return DAG.getMaskedHistogram(DAG.getVTList(MVT::Other), MemVT,
DL, OpsHi,
5150SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
5154 EVT LoResVT, HiResVT;
5155 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
5156 SDValue SourceLo, SourceHi;
5157 std::tie(SourceLo, SourceHi) = DAG.SplitVectorOperand(
N, 0);
5158 SDValue MaskLo, MaskHi;
5159 std::tie(MaskLo, MaskHi) = DAG.SplitVectorOperand(
N, 2);
5162 N->getOperand(1), MaskLo,
N->getFlags());
5164 N->getOperand(1), MaskHi,
N->getFlags());
5170 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
5172 SDValue NeedleLo, NeedleHi;
5173 GetSplitVector(
N->getOperand(1), NeedleLo, NeedleHi);
5177 NeedleLo,
N->getOperand(2),
N->getFlags());
5180 NeedleHi,
N->getOperand(2),
N->getFlags());
5181 return DAG.getNode(
ISD::OR,
DL,
N->getValueType(0), MatchLo, MatchHi);
5184SDValue DAGTypeLegalizer::SplitVecOp_PARTIAL_REDUCE_MLA(
SDNode *
N) {
5187 "Accumulator should already be a legal type, and shouldn't need "
5188 "further splitting");
5191 SDValue Input1Lo, Input1Hi, Input2Lo, Input2Hi;
5192 GetSplitVector(
N->getOperand(1), Input1Lo, Input1Hi);
5193 GetSplitVector(
N->getOperand(2), Input2Lo, Input2Hi);
5194 unsigned Opcode =
N->getOpcode();
5197 SDValue
Lo = DAG.getNode(Opcode,
DL, ResultVT, Acc, Input1Lo, Input2Lo);
5198 return DAG.getNode(Opcode,
DL, ResultVT,
Lo, Input1Hi, Input2Hi);
5205void DAGTypeLegalizer::ReplaceOtherWidenResults(
SDNode *
N,
SDNode *WidenNode,
5206 unsigned WidenResNo) {
5207 unsigned NumResults =
N->getNumValues();
5208 for (
unsigned ResNo = 0; ResNo < NumResults; ResNo++) {
5209 if (ResNo == WidenResNo)
5211 EVT ResVT =
N->getValueType(ResNo);
5213 SetWidenedVector(SDValue(
N, ResNo), SDValue(WidenNode, ResNo));
5217 DAG.getExtractSubvector(
DL, ResVT, SDValue(WidenNode, ResNo), 0);
5218 ReplaceValueWith(SDValue(
N, ResNo), ResVal);
5223void DAGTypeLegalizer::WidenVectorResult(
SDNode *
N,
unsigned ResNo) {
5224 LLVM_DEBUG(
dbgs() <<
"Widen node result " << ResNo <<
": ";
N->dump(&DAG));
5227 if (CustomWidenLowerNode(
N,
N->getValueType(ResNo)))
5230 SDValue Res = SDValue();
5232 auto unrollExpandedOp = [&]() {
5237 EVT VT =
N->getValueType(0);
5238 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5239 if (!TLI.isOperationLegalOrCustomOrPromote(
N->getOpcode(), WideVecVT) &&
5240 TLI.isOperationExpandOrLibCall(
N->getOpcode(), VT.
getScalarType())) {
5242 if (
N->getNumValues() > 1)
5243 ReplaceOtherWidenResults(
N, Res.
getNode(), ResNo);
5249 switch (
N->getOpcode()) {
5252 dbgs() <<
"WidenVectorResult #" << ResNo <<
": ";
5260 Res = WidenVecRes_LOOP_DEPENDENCE_MASK(
N);
5264 Res = WidenVecRes_ADDRSPACECAST(
N);
5271 Res = WidenVecRes_INSERT_SUBVECTOR(
N);
5278 case ISD::LOAD: Res = WidenVecRes_LOAD(
N);
break;
5282 Res = WidenVecRes_ScalarOp(
N);
5288 Res = WidenVecRes_Select(
N);
5291 case ISD::SETCC: Res = WidenVecRes_SETCC(
N);
break;
5293 case ISD::UNDEF: Res = WidenVecRes_UNDEF(
N);
break;
5300 case ISD::VP_LOAD_FF:
5303 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
5307 Res = WidenVecRes_VECTOR_COMPRESS(
N);
5315 case ISD::VP_GATHER:
5319 Res = WidenVecRes_VECTOR_REVERSE(
N);
5322 Res = WidenVecRes_GET_ACTIVE_LANE_MASK(
N);
5325 WidenVecRes_VECTOR_INTERLEAVE(
N);
5328 Res = WidenVecRes_VECTOR_MATCH(
N);
5331 WidenVecRes_VECTOR_DEINTERLEAVE(
N);
5385 Res = WidenVecRes_Binary(
N);
5392 Res = WidenVecRes_MaskedBinary(
N);
5397 Res = WidenVecRes_CMP(
N);
5403 if (unrollExpandedOp())
5418 Res = WidenVecRes_BinaryCanTrap(
N);
5427 Res = WidenVecRes_BinaryWithExtraScalarOp(
N);
5430#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
5431 case ISD::STRICT_##DAGN:
5432#include "llvm/IR/ConstrainedOps.def"
5433 Res = WidenVecRes_StrictFP(
N);
5442 Res = WidenVecRes_OverflowOp(
N, ResNo);
5446 Res = WidenVecRes_FCOPYSIGN(
N);
5451 Res = WidenVecRes_UnarySameEltsWithScalarArg(
N);
5456 if (!unrollExpandedOp())
5457 Res = WidenVecRes_ExpOp(
N);
5463 Res = WidenVecRes_EXTEND_VECTOR_INREG(
N);
5478 Res = WidenVecRes_Convert(
N);
5483 Res = WidenVecRes_FP_TO_XINT_SAT(
N);
5490 Res = WidenVecRes_XROUND(
N);
5516 if (unrollExpandedOp())
5538 Res = WidenVecRes_Unary(
N);
5543 Res = WidenVecRes_Ternary(
N);
5549 if (!unrollExpandedOp())
5550 Res = WidenVecRes_UnaryOpWithTwoResults(
N, ResNo);
5557 Res = WidenVecRes_PARTIAL_REDUCE_MLA(
N);
5563 SetWidenedVector(SDValue(
N, ResNo), Res);
5569 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5570 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5571 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5572 SDValue InOp3 = GetWidenedVector(
N->getOperand(2));
5573 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
5579 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5580 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5581 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5582 if (
N->getNumOperands() == 2)
5583 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2,
5586 assert(
N->getNumOperands() == 4 &&
"Unexpected number of operands!");
5587 assert((
N->getOpcode() == ISD::VP_UDIV ||
N->getOpcode() == ISD::VP_SDIV ||
5588 N->getOpcode() == ISD::VP_UREM ||
N->getOpcode() == ISD::VP_SREM) &&
5589 "Expected VP opcode");
5593 return DAG.getNode(
N->getOpcode(), dl, WidenVT,
5594 {InOp1, InOp2, Mask, N->getOperand(3)},
N->getFlags());
5599 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5600 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5601 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5602 SDValue
Mask =
N->getOperand(2);
5604 *DAG.getContext(),
Mask.getValueType().getVectorElementType());
5605 Mask = ModifyToType(Mask, WideMaskVT,
true);
5606 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Mask,
5611 LLVMContext &Ctxt = *DAG.getContext();
5614 SDValue
LHS =
N->getOperand(0);
5615 SDValue
RHS =
N->getOperand(1);
5616 EVT OpVT =
LHS.getValueType();
5618 LHS = GetWidenedVector(
LHS);
5619 RHS = GetWidenedVector(
RHS);
5620 OpVT =
LHS.getValueType();
5623 EVT WidenResVT = TLI.getTypeToTransformTo(Ctxt,
N->getValueType(0));
5626 return DAG.getNode(
N->getOpcode(), dl, WidenResVT,
LHS,
RHS);
5632SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(
SDNode *
N) {
5635 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5636 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5637 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5639 return DAG.
getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
5648 unsigned ConcatEnd,
EVT VT,
EVT MaxVT,
5651 if (ConcatEnd == 1) {
5652 VT = ConcatOps[0].getValueType();
5654 return ConcatOps[0];
5657 SDLoc dl(ConcatOps[0]);
5664 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
5665 int Idx = ConcatEnd - 1;
5666 VT = ConcatOps[Idx--].getValueType();
5667 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
5680 unsigned NumToInsert = ConcatEnd - Idx - 1;
5681 for (
unsigned i = 0, OpIdx = Idx + 1; i < NumToInsert; i++, OpIdx++)
5683 ConcatOps[Idx+1] = VecOp;
5684 ConcatEnd = Idx + 2;
5690 unsigned RealVals = ConcatEnd - Idx - 1;
5691 unsigned SubConcatEnd = 0;
5692 unsigned SubConcatIdx = Idx + 1;
5693 while (SubConcatEnd < RealVals)
5694 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
5695 while (SubConcatEnd < OpsToConcat)
5696 SubConcatOps[SubConcatEnd++] = undefVec;
5698 NextVT, SubConcatOps);
5699 ConcatEnd = SubConcatIdx + 1;
5704 if (ConcatEnd == 1) {
5705 VT = ConcatOps[0].getValueType();
5707 return ConcatOps[0];
5712 if (
NumOps != ConcatEnd ) {
5714 for (
unsigned j = ConcatEnd; j <
NumOps; ++j)
5715 ConcatOps[j] = UndefVal;
5723 unsigned Opcode =
N->getOpcode();
5725 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5729 const SDNodeFlags
Flags =
N->getFlags();
5730 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5731 NumElts = NumElts / 2;
5735 if (NumElts != 1 && !TLI.canOpTrap(
N->getOpcode(), VT)) {
5737 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5738 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5739 return DAG.getNode(
N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
5747 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WidenVT)) {
5750 TLI.isTypeLegal(WideMaskVT)) {
5751 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5752 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5753 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
5755 DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
5756 N->getValueType(0).getVectorElementCount());
5757 return DAG.
getNode(*VPOpcode, dl, WidenVT, InOp1, InOp2, Mask, EVL,
5771 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
5772 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
5773 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5776 unsigned ConcatEnd = 0;
5784 while (CurNumElts != 0) {
5785 while (CurNumElts >= NumElts) {
5786 SDValue EOp1 = DAG.getExtractSubvector(dl, VT, InOp1, Idx);
5787 SDValue EOp2 = DAG.getExtractSubvector(dl, VT, InOp2, Idx);
5788 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
5790 CurNumElts -= NumElts;
5793 NumElts = NumElts / 2;
5795 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5798 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5799 SDValue EOp1 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp1, Idx);
5800 SDValue EOp2 = DAG.getExtractVectorElt(dl, WidenEltVT, InOp2, Idx);
5801 ConcatOps[ConcatEnd++] = DAG.
getNode(Opcode, dl, WidenEltVT,
5812 switch (
N->getOpcode()) {
5815 return WidenVecRes_STRICT_FSETCC(
N);
5822 return WidenVecRes_Convert_StrictFP(
N);
5829 unsigned Opcode =
N->getOpcode();
5831 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
5835 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
5836 NumElts = NumElts / 2;
5847 unsigned CurNumElts =
N->getValueType(0).getVectorNumElements();
5851 unsigned ConcatEnd = 0;
5858 for (
unsigned i = 1; i < NumOpers; ++i) {
5864 Oper = GetWidenedVector(Oper);
5870 DAG.getPOISON(WideOpVT), Oper,
5871 DAG.getVectorIdxConstant(0, dl));
5883 while (CurNumElts != 0) {
5884 while (CurNumElts >= NumElts) {
5887 for (
unsigned i = 0; i < NumOpers; ++i) {
5888 SDValue
Op = InOps[i];
5890 EVT OpVT =
Op.getValueType();
5895 Op = DAG.getExtractSubvector(dl, OpExtractVT,
Op, Idx);
5901 EVT OperVT[] = {VT, MVT::Other};
5902 SDValue Oper = DAG.
getNode(Opcode, dl, OperVT, EOps);
5903 ConcatOps[ConcatEnd++] = Oper;
5906 CurNumElts -= NumElts;
5909 NumElts = NumElts / 2;
5911 }
while (!TLI.isTypeLegal(VT) && NumElts != 1);
5914 for (
unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
5917 for (
unsigned i = 0; i < NumOpers; ++i) {
5918 SDValue
Op = InOps[i];
5920 EVT OpVT =
Op.getValueType();
5928 EVT WidenVT[] = {WidenEltVT, MVT::Other};
5929 SDValue Oper = DAG.
getNode(Opcode, dl, WidenVT, EOps);
5930 ConcatOps[ConcatEnd++] = Oper;
5939 if (Chains.
size() == 1)
5940 NewChain = Chains[0];
5943 ReplaceValueWith(SDValue(
N, 1), NewChain);
5948SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(
SDNode *
N,
unsigned ResNo) {
5950 EVT ResVT =
N->getValueType(0);
5951 EVT OvVT =
N->getValueType(1);
5952 EVT WideResVT, WideOvVT;
5953 SDValue WideLHS, WideRHS;
5957 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
5962 WideLHS = GetWidenedVector(
N->getOperand(0));
5963 WideRHS = GetWidenedVector(
N->getOperand(1));
5965 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
5970 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
5971 SDValue
Poison = DAG.getPOISON(WideResVT);
5974 N->getOperand(0), Zero);
5976 N->getOperand(1), Zero);
5979 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
5980 SDNode *WideNode = DAG.getNode(
5981 N->getOpcode(),
DL, WideVTs, WideLHS, WideRHS).getNode();
5984 unsigned OtherNo = 1 - ResNo;
5985 EVT OtherVT =
N->getValueType(OtherNo);
5987 SetWidenedVector(SDValue(
N, OtherNo), SDValue(WideNode, OtherNo));
5989 SDValue
Zero = DAG.getVectorIdxConstant(0,
DL);
5990 SDValue OtherVal = DAG.
getNode(
5992 ReplaceValueWith(SDValue(
N, OtherNo), OtherVal);
5995 return SDValue(WideNode, ResNo);
5999 LLVMContext &Ctx = *DAG.getContext();
6003 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(0));
6008 unsigned Opcode =
N->getOpcode();
6009 const SDNodeFlags
Flags =
N->getFlags();
6015 TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
6017 InOp = ZExtPromotedInteger(InOp);
6028 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
6029 if (
N->getNumOperands() == 1)
6030 return DAG.getNode(Opcode,
DL, VT,
Op, Flags);
6032 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1),
N->getOperand(2),
6033 N->getOperand(3), Flags);
6034 return DAG.getNode(Opcode,
DL, VT,
Op,
N->getOperand(1), Flags);
6038 InOp = GetWidenedVector(
N->getOperand(0));
6041 if (InVTEC == WidenEC)
6042 return MakeConvertNode(WidenVT, InOp);
6066 SDValue MidRes = DAG.getNode(
ISD::TRUNCATE,
DL, MidResVT, InOp, Flags);
6067 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), MidRes, 0);
6071 if (TLI.isTypeLegal(InWidenVT)) {
6079 unsigned NumConcat =
6084 return MakeConvertNode(WidenVT, InVec);
6088 SDValue InVal = DAG.getExtractSubvector(
DL, InWidenVT, InOp, 0);
6090 return MakeConvertNode(WidenVT, InVal);
6099 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6100 for (
unsigned i=0; i < MinElts; ++i) {
6101 SDValue Val = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6102 Ops[i] = MakeConvertNode(EltVT, Val);
6105 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6110 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6113 SDValue Src =
N->getOperand(0);
6114 EVT SrcVT = Src.getValueType();
6118 Src = GetWidenedVector(Src);
6119 SrcVT = Src.getValueType();
6126 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src,
N->getOperand(1));
6131 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6134 SDValue Src =
N->getOperand(0);
6135 EVT SrcVT = Src.getValueType();
6139 Src = GetWidenedVector(Src);
6140 SrcVT = Src.getValueType();
6147 return DAG.getNode(
N->getOpcode(), dl, WidenVT, Src);
6150SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(
SDNode *
N) {
6155 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6161 unsigned Opcode =
N->getOpcode();
6167 std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
6172 unsigned MinElts =
N->getValueType(0).getVectorNumElements();
6173 for (
unsigned i=0; i < MinElts; ++i) {
6174 NewOps[1] = DAG.getExtractVectorElt(
DL, InEltVT, InOp, i);
6175 Ops[i] = DAG.getNode(Opcode,
DL, EltVTs, NewOps);
6179 ReplaceValueWith(SDValue(
N, 1), NewChain);
6181 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6184SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(
SDNode *
N) {
6185 unsigned Opcode =
N->getOpcode();
6189 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6198 InOp = GetWidenedVector(InOp);
6205 return DAG.getNode(Opcode,
DL, WidenVT, InOp);
6212 for (
unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i !=
e; ++i) {
6213 SDValue Val = DAG.getExtractVectorElt(
DL, InSVT, InOp, i);
6230 while (
Ops.size() != WidenNumElts)
6231 Ops.push_back(DAG.getPOISON(WidenSVT));
6233 return DAG.getBuildVector(WidenVT,
DL,
Ops);
6239 if (
N->getOperand(0).getValueType() ==
N->getOperand(1).getValueType())
6240 return WidenVecRes_BinaryCanTrap(
N);
6243 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6250SDValue DAGTypeLegalizer::WidenVecRes_UnarySameEltsWithScalarArg(
SDNode *
N) {
6252 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6255 SDValue Arg = GetWidenedVector(FpValue);
6256 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, {Arg,
N->
getOperand(1)},
6261 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6262 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6263 SDValue
RHS =
N->getOperand(1);
6264 EVT ExpVT =
RHS.getValueType();
6265 SDValue ExpOp =
RHS;
6269 ExpOp = ModifyToType(
RHS, WideExpVT);
6272 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp, ExpOp);
6277 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6278 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6279 if (
N->getNumOperands() == 1)
6280 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getFlags());
6282 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT, InOp,
N->getOperand(1),
6287 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6292 SDValue WidenLHS = GetWidenedVector(
N->getOperand(0));
6293 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
6294 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
6297SDValue DAGTypeLegalizer::WidenVecRes_UnaryOpWithTwoResults(
SDNode *
N,
6299 EVT VT0 =
N->getValueType(0);
6300 EVT VT1 =
N->getValueType(1);
6304 "expected both results to be vectors of matching element count");
6306 LLVMContext &Ctx = *DAG.getContext();
6307 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6309 EVT WidenVT = TLI.getTypeToTransformTo(Ctx,
N->getValueType(ResNo));
6316 DAG.getNode(
N->getOpcode(), SDLoc(
N), {WidenVT0, WidenVT1}, InOp)
6319 ReplaceOtherWidenResults(
N, WidenNode, ResNo);
6320 return SDValue(WidenNode, ResNo);
6323SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo) {
6324 SDValue WidenVec = DisintegrateMERGE_VALUES(
N, ResNo);
6325 return GetWidenedVector(WidenVec);
6330 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6340 InOp = GetWidenedVector(InOp);
6344 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(InWidenVT), InOp, 0);
6347 return DAG.getAddrSpaceCast(
6348 DL, WidenVT, InOp, AddrSpaceCastN->getSrcAddressSpace(),
6349 AddrSpaceCastN->getDestAddressSpace(), AddrSpaceCastN->getFlags());
6355 EVT VT =
N->getValueType(0);
6356 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6359 switch (getTypeAction(InVT)) {
6373 SDValue NInOp = GetPromotedInteger(InOp);
6375 if (WidenVT.
bitsEq(NInVT)) {
6378 if (DAG.getDataLayout().isBigEndian()) {
6381 DAG.getShiftAmountConstant(ShiftAmt, NInVT, dl));
6399 InOp = GetWidenedVector(InOp);
6401 if (WidenVT.
bitsEq(InVT))
6411 if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
6416 unsigned NewNumParts = WidenSize / InSize;
6429 EVT OrigInVT =
N->getOperand(0).getValueType();
6434 if (TLI.isTypeLegal(NewInVT)) {
6442 if (WidenSize % InSize == 0) {
6449 DAG.ExtractVectorElements(InOp,
Ops);
6450 Ops.append(WidenSize / InScalarSize -
Ops.size(),
6462 return CreateStackStoreLoad(InOp, WidenVT);
6465SDValue DAGTypeLegalizer::WidenVecRes_LOOP_DEPENDENCE_MASK(
SDNode *
N) {
6467 N->getOpcode(), SDLoc(
N),
6468 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
6469 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
6475 EVT VT =
N->getValueType(0);
6479 EVT EltVT =
N->getOperand(0).getValueType();
6482 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6486 assert(WidenNumElts >= NumElts &&
"Shrinking vector instead of widening!");
6487 NewOps.append(WidenNumElts - NumElts, DAG.getPOISON(EltVT));
6489 return DAG.getBuildVector(WidenVT, dl, NewOps);
6493 EVT InVT =
N->getOperand(0).getValueType();
6494 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6496 unsigned NumOperands =
N->getNumOperands();
6498 bool InputWidened =
false;
6502 if (WidenNumElts % NumInElts == 0) {
6504 unsigned NumConcat = WidenNumElts / NumInElts;
6505 SDValue UndefVal = DAG.getPOISON(InVT);
6507 for (
unsigned i=0; i < NumOperands; ++i)
6508 Ops[i] =
N->getOperand(i);
6509 for (
unsigned i = NumOperands; i != NumConcat; ++i)
6514 InputWidened =
true;
6515 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6518 for (i=1; i < NumOperands; ++i)
6519 if (!
N->getOperand(i).isUndef())
6522 if (i == NumOperands)
6525 return GetWidenedVector(
N->getOperand(0));
6527 if (NumOperands == 2) {
6529 "Cannot use vector shuffles to widen CONCAT_VECTOR result");
6534 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
6535 for (
unsigned i = 0; i < NumInElts; ++i) {
6537 MaskOps[i + NumInElts] = i + WidenNumElts;
6539 return DAG.getVectorShuffle(WidenVT, dl,
6540 GetWidenedVector(
N->getOperand(0)),
6541 GetWidenedVector(
N->getOperand(1)),
6548 SDValue WideVec = DAG.getPOISON(WidenVT);
6550 for (
unsigned I = 0;
I < NumOperands; ++
I)
6552 DAG.getInsertSubvector(dl, WideVec,
N->getOperand(
I),
I * NumInElts);
6563 for (
unsigned i=0; i < NumOperands; ++i) {
6566 InOp = GetWidenedVector(InOp);
6567 for (
unsigned j = 0;
j < NumInElts; ++
j)
6568 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
6570 SDValue UndefVal = DAG.getPOISON(EltVT);
6571 for (; Idx < WidenNumElts; ++Idx)
6572 Ops[Idx] = UndefVal;
6573 return DAG.getBuildVector(WidenVT, dl,
Ops);
6576SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(
SDNode *
N) {
6577 EVT VT =
N->getValueType(0);
6578 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6579 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
6581 SDValue Idx =
N->getOperand(2);
6586SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(
SDNode *
N) {
6587 EVT VT =
N->getValueType(0);
6589 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6594 auto InOpTypeAction = getTypeAction(InOp.
getValueType());
6596 InOp = GetWidenedVector(InOp);
6602 if (IdxVal == 0 && InVT == WidenVT)
6609 assert(IdxVal % VTNumElts == 0 &&
6610 "Expected Idx to be a multiple of subvector minimum vector length");
6611 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
6624 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
6625 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
6626 "down type's element count");
6633 for (;
I < VTNumElts / GCD; ++
I)
6635 DAG.getExtractSubvector(dl, PartVT, InOp, IdxVal +
I * GCD));
6636 for (;
I < WidenNumElts / GCD; ++
I)
6658 SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);
6665 StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
6666 return DAG.getMaskedLoad(
6667 WidenVT, dl, Ch, StackPtr, DAG.getPOISON(
StackPtr.getValueType()), Mask,
6675 for (i = 0; i < VTNumElts; ++i)
6676 Ops[i] = DAG.getExtractVectorElt(dl, EltVT, InOp, IdxVal + i);
6678 SDValue UndefVal = DAG.getPOISON(EltVT);
6679 for (; i < WidenNumElts; ++i)
6681 return DAG.getBuildVector(WidenVT, dl,
Ops);
6685 SDValue InOp = ModifyToType(
6687 TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0)),
true);
6692SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(
SDNode *
N) {
6693 SDValue InOp = GetWidenedVector(
N->getOperand(0));
6696 N->getOperand(1),
N->getOperand(2));
6705 "Load width must be less than or equal to first value type width");
6714 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6731 assert(FirstVT == WidenVT &&
"First value type must equal widen value type");
6742 TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
6743 EVT LdVT =
LD->getMemoryVT();
6747 SDValue Chain =
LD->getChain();
6752 TypeSize WidthDiff = WidenWidth - LdWidth;
6755 std::optional<EVT> FirstVT =
6756 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, 0,
6763 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6766 Chain, BasePtr,
LD->getMemOperand());
6770 FirstVTWidth, dl, DAG);
6774 ReplaceValueWith(SDValue(LD, 1), LdOp.
getValue(1));
6788 if (!
LD->getMemoryVT().isByteSized()) {
6789 SDValue
Value, NewChain;
6790 std::tie(
Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
6791 ReplaceValueWith(SDValue(LD, 0),
Value);
6792 ReplaceValueWith(SDValue(LD, 1), NewChain);
6801 EVT VT =
LD->getValueType(0);
6802 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6803 EVT WideMaskVT = getSetCCResultType(WideVT);
6806 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
6807 TLI.isTypeLegal(WideMaskVT)) {
6809 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
6810 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
6814 LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6815 EVL,
LD->getMemoryVT(),
LD->getMemOperand());
6819 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
6827 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
6829 Result = GenWidenVectorLoads(LdChain, LD);
6836 if (LdChain.
size() == 1)
6837 NewChain = LdChain[0];
6843 ReplaceValueWith(SDValue(
N, 1), NewChain);
6854 SDValue NewLoad = DAG.getMaskedLoad(
6855 WideVT,
DL,
LD->getChain(),
LD->getBasePtr(),
LD->getOffset(), Mask,
6856 DAG.getPOISON(WideVT),
LD->getMemoryVT(),
LD->getMemOperand(),
6857 LD->getAddressingMode(),
LD->getExtensionType());
6859 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
6867 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6868 SDValue
Mask =
N->getMask();
6869 SDValue EVL =
N->getVectorLength();
6876 "Unable to widen binary VP op");
6877 Mask = GetWidenedVector(Mask);
6878 assert(
Mask.getValueType().getVectorElementCount() ==
6879 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6880 .getVectorElementCount() &&
6881 "Unable to widen vector load");
6884 DAG.getLoadVP(
N->getAddressingMode(), ExtType, WidenVT, dl,
N->getChain(),
6885 N->getBasePtr(),
N->getOffset(), Mask, EVL,
6886 N->getMemoryVT(),
N->getMemOperand(),
N->isExpandingLoad());
6889 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
6894 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6895 SDValue
Mask =
N->getMask();
6896 SDValue EVL =
N->getVectorLength();
6902 "Unable to widen binary VP op");
6903 Mask = GetWidenedVector(Mask);
6904 assert(
Mask.getValueType().getVectorElementCount() ==
6905 TLI.getTypeToTransformTo(*DAG.getContext(),
Mask.getValueType())
6906 .getVectorElementCount() &&
6907 "Unable to widen vector load");
6909 SDValue Res = DAG.getLoadFFVP(WidenVT, dl,
N->getChain(),
N->getBasePtr(),
6910 Mask, EVL,
N->getMemOperand());
6911 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
6912 ReplaceValueWith(SDValue(
N, 2), Res.
getValue(2));
6920 SDValue
Mask =
N->getMask();
6923 "Unable to widen VP strided load");
6924 Mask = GetWidenedVector(Mask);
6926 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
6927 assert(
Mask.getValueType().getVectorElementCount() ==
6929 "Data and mask vectors should have the same number of elements");
6931 SDValue Res = DAG.getStridedLoadVP(
6932 N->getAddressingMode(),
N->getExtensionType(), WidenVT,
DL,
N->getChain(),
6933 N->getBasePtr(),
N->getOffset(),
N->getStride(), Mask,
6934 N->getVectorLength(),
N->getMemoryVT(),
N->getMemOperand(),
6935 N->isExpandingLoad());
6939 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
6943SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_COMPRESS(
SDNode *
N) {
6945 SDValue
Mask =
N->getOperand(1);
6948 TLI.getTypeToTransformTo(*DAG.getContext(), Vec.
getValueType());
6950 Mask.getValueType().getVectorElementType(),
6953 SDValue WideVec = ModifyToType(Vec, WideVecVT);
6954 SDValue WideMask = ModifyToType(Mask, WideMaskVT,
true);
6955 SDValue WidePassthru = ModifyToType(Passthru, WideVecVT);
6957 WideMask, WidePassthru);
6961 EVT VT =
N->getValueType(0);
6962 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
6963 SDValue
Mask =
N->getMask();
6964 EVT MaskVT =
Mask.getValueType();
6965 SDValue PassThru = GetWidenedVector(
N->getPassThru());
6974 TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WidenVT) &&
6975 TLI.isTypeLegal(WideMaskVT) &&
6981 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
6982 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
6986 N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask, EVL,
6987 N->getMemoryVT(),
N->getMemOperand());
6988 SDValue NewVal = NewLoad;
6991 if (!
N->getPassThru()->isUndef()) {
6995 NewVal = DAG.
getNode(ISD::VP_MERGE, dl, WidenVT,
6996 DAG.getAllOnesConstant(dl, WideMaskVT), NewVal,
6997 DAG.getPOISON(WidenVT), EVL);
7002 ReplaceValueWith(SDValue(
N, 1), NewLoad.
getValue(1));
7008 Mask = ModifyToType(Mask, WideMaskVT,
true);
7010 SDValue Res = DAG.getMaskedLoad(
7011 WidenVT, dl,
N->getChain(),
N->getBasePtr(),
N->getOffset(), Mask,
7012 PassThru,
N->getMemoryVT(),
N->getMemOperand(),
N->getAddressingMode(),
7013 ExtType,
N->isExpandingLoad());
7016 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7022 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7023 SDValue
Mask =
N->getMask();
7024 EVT MaskVT =
Mask.getValueType();
7025 SDValue PassThru = GetWidenedVector(
N->getPassThru());
7026 SDValue Scale =
N->getScale();
7033 Mask = ModifyToType(Mask, WideMaskVT,
true);
7036 SDValue
Index =
N->getIndex();
7038 *DAG.getContext(),
Index.getValueType().getScalarType(), WideEC);
7039 Index = ModifyToType(Index, WideIndexVT);
7040 SDValue
Ops[] = {
N->getChain(), PassThru,
Mask,
N->getBasePtr(),
Index,
7045 N->getMemoryVT().getScalarType(), WideEC);
7046 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
7047 WideMemVT, dl,
Ops,
N->getMemOperand(),
7048 N->getIndexType(),
N->getExtensionType());
7052 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7057 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7058 SDValue
Mask =
N->getMask();
7059 SDValue Scale =
N->getScale();
7063 SDValue
Index = GetWidenedVector(
N->getIndex());
7065 N->getMemoryVT().getScalarType(), WideEC);
7066 Mask = GetWidenedMask(Mask, WideEC);
7068 SDValue
Ops[] = {
N->getChain(),
N->getBasePtr(),
Index, Scale,
7069 Mask,
N->getVectorLength()};
7070 SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
7071 dl,
Ops,
N->getMemOperand(),
N->getIndexType());
7075 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7080 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7081 return DAG.getNode(
N->getOpcode(), SDLoc(
N), WidenVT,
N->getOperand(0));
7109 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
7110 return N->getOperand(OpNo).getValueType();
7118 N =
N.getOperand(0);
7120 for (
unsigned i = 1; i <
N->getNumOperands(); ++i)
7121 if (!
N->getOperand(i)->isUndef())
7123 N =
N.getOperand(0);
7127 N =
N.getOperand(0);
7129 N =
N.getOperand(0);
7156 { MaskVT, MVT::Other },
Ops);
7157 ReplaceValueWith(InMask.
getValue(1),
Mask.getValue(1));
7165 LLVMContext &Ctx = *DAG.getContext();
7168 if (MaskScalarBits < ToMaskScalBits) {
7172 }
else if (MaskScalarBits > ToMaskScalBits) {
7178 assert(
Mask->getValueType(0).getScalarSizeInBits() ==
7180 "Mask should have the right element size by now.");
7183 unsigned CurrMaskNumEls =
Mask->getValueType(0).getVectorNumElements();
7185 Mask = DAG.getExtractSubvector(SDLoc(Mask), ToMaskVT, Mask, 0);
7188 EVT SubVT =
Mask->getValueType(0);
7194 assert((
Mask->getValueType(0) == ToMaskVT) &&
7195 "A mask of ToMaskVT should have been produced by now.");
7205 LLVMContext &Ctx = *DAG.getContext();
7206 SDValue
Cond =
N->getOperand(0);
7216 EVT CondVT =
Cond->getValueType(0);
7220 EVT VSelVT =
N->getValueType(0);
7232 EVT FinalVT = VSelVT;
7243 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
7244 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
7251 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
7259 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
7262 EVT ToMaskVT = VSelVT;
7269 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7274 SDValue SETCC0 =
Cond->getOperand(0);
7275 SDValue SETCC1 =
Cond->getOperand(1);
7285 if (ScalarBits0 != ScalarBits1) {
7286 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
7287 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
7299 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
7300 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
7301 Cond = DAG.getNode(
Cond->getOpcode(), SDLoc(
Cond), MaskVT, SETCC0, SETCC1);
7304 Mask = convertMask(
Cond, MaskVT, ToMaskVT);
7312 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7315 SDValue Cond1 =
N->getOperand(0);
7317 unsigned Opcode =
N->getOpcode();
7319 if (SDValue WideCond = WidenVSELECTMask(
N)) {
7320 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7321 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7323 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, WideCond, InOp1, InOp2);
7329 Cond1 = GetWidenedVector(Cond1);
7337 SDValue SplitSelect = SplitVecOp_VSELECT(
N, 0);
7338 SDValue Res = ModifyToType(SplitSelect, WidenVT);
7343 Cond1 = ModifyToType(Cond1, CondWidenVT);
7346 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
7347 SDValue InOp2 = GetWidenedVector(
N->getOperand(2));
7349 if (Opcode == ISD::VP_MERGE)
7350 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2,
7352 return DAG.getNode(Opcode, SDLoc(
N), WidenVT, Cond1, InOp1, InOp2);
7356 SDValue InOp1 = GetWidenedVector(
N->getOperand(2));
7357 SDValue InOp2 = GetWidenedVector(
N->getOperand(3));
7360 N->getOperand(1), InOp1, InOp2,
N->getOperand(4));
7364 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7365 return DAG.getUNDEF(WidenVT);
7369 EVT VT =
N->getValueType(0);
7372 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7376 SDValue InOp1 = GetWidenedVector(
N->getOperand(0));
7377 SDValue InOp2 = GetWidenedVector(
N->getOperand(1));
7380 SmallVector<int, 16> NewMask(WidenNumElts, -1);
7381 for (
unsigned i = 0; i != NumElts; ++i) {
7382 int Idx =
N->getMaskElt(i);
7383 if (Idx < (
int)NumElts)
7386 NewMask[i] = Idx - NumElts + WidenNumElts;
7388 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
7392 EVT VT =
N->getValueType(0);
7396 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7397 SDValue OpValue = GetWidenedVector(
N->getOperand(0));
7403 unsigned IdxVal = WidenNumElts - VTNumElts;
7416 unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
7419 assert((IdxVal % GCD) == 0 &&
"Expected Idx to be a multiple of the broken "
7420 "down type's element count");
7423 for (; i < VTNumElts / GCD; ++i)
7425 DAG.getExtractSubvector(dl, PartVT, ReverseVal, IdxVal + i * GCD));
7426 for (; i < WidenNumElts / GCD; ++i)
7434 SmallVector<int, 16>
Mask(WidenNumElts, -1);
7435 std::iota(
Mask.begin(),
Mask.begin() + VTNumElts, IdxVal);
7437 return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getPOISON(WidenVT),
7441SDValue DAGTypeLegalizer::WidenVecRes_GET_ACTIVE_LANE_MASK(
SDNode *
N) {
7442 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7446void DAGTypeLegalizer::WidenVecRes_VECTOR_INTERLEAVE(
SDNode *
N) {
7447 EVT VT =
N->getValueType(0);
7450 unsigned Factor =
N->getNumOperands();
7453 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7457 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7458 WidenOps[Idx] = GetWidenedVector(
N->getOperand(Idx));
7461 SDValue Interleaved =
7467 for (
unsigned Idx = 0; Idx != Factor; ++Idx)
7468 Slices[Idx] = Interleaved.
getValue(Idx);
7472 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7473 SDValue Narrow = DAG.getExtractSubvector(
DL, VT, Packed,
7476 DAG.getInsertSubvector(
DL, DAG.getPOISON(WidenVT), Narrow, 0U);
7477 SetWidenedVector(SDValue(
N, Idx), Wide);
7483 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7484 EVT SourceVT =
N->getOperand(0).getValueType();
7489 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
7490 N->getOperand(0), 0);
7491 SDValue WideMask = DAG.getInsertSubvector(
DL, DAG.getConstant(0,
DL, WidenVT),
7492 N->getOperand(2), 0);
7494 N->getOperand(1), WideMask,
N->getFlags());
7497void DAGTypeLegalizer::WidenVecRes_VECTOR_DEINTERLEAVE(
SDNode *
N) {
7498 EVT VT =
N->getValueType(0);
7501 unsigned Factor =
N->getNumOperands();
7504 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7514 EVT ConcatVT =
EVT::getVectorVT(*DAG.getContext(), EltVT, OrigEC * Factor);
7516 SDValue PackedWidenVec = DAG.getInsertSubvector(
7517 DL, DAG.getUNDEF(PackedWidenVT), ConcatOp, 0U);
7521 for (
unsigned Idx = 0U; Idx < Factor; ++Idx) {
7522 NewOps[Idx] = DAG.getExtractSubvector(
DL, WidenVT, PackedWidenVec,
7529 for (
unsigned Idx = 0U; Idx < Factor; ++Idx)
7530 SetWidenedVector(SDValue(
N, Idx), NewRes.
getValue(Idx));
7534 assert(
N->getValueType(0).isVector() &&
7535 N->getOperand(0).getValueType().isVector() &&
7536 "Operands must be vectors");
7537 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
7550 SDValue SplitVSetCC = SplitVecOp_VSETCC(
N);
7551 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
7558 InOp1 = GetWidenedVector(InOp1);
7559 InOp2 = GetWidenedVector(InOp2);
7561 SDValue
Poison = DAG.getPOISON(WidenInVT);
7562 SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(
N));
7573 "Input not widened to expected type!");
7575 return DAG.getNode(
ISD::SETCC, SDLoc(
N), WidenVT, InOp1, InOp2,
7580 assert(
N->getValueType(0).isVector() &&
7581 N->getOperand(1).getValueType().isVector() &&
7582 "Operands must be vectors");
7583 EVT VT =
N->getValueType(0);
7584 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7591 SDValue
LHS =
N->getOperand(1);
7592 SDValue
RHS =
N->getOperand(2);
7594 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
7599 for (
unsigned i = 0; i != NumElts; ++i) {
7600 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
7601 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
7603 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
7604 {Chain, LHSElem, RHSElem, CC});
7605 Chains[i] = Scalars[i].getValue(1);
7606 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
7607 DAG.getBoolConstant(
true, dl, EltVT, VT),
7608 DAG.getBoolConstant(
false, dl, EltVT, VT));
7612 ReplaceValueWith(SDValue(
N, 1), NewChain);
7614 return DAG.getBuildVector(WidenVT, dl, Scalars);
7617SDValue DAGTypeLegalizer::WidenVecRes_PARTIAL_REDUCE_MLA(
SDNode *
N) {
7619 EVT VT =
N->getValueType(0);
7622 SDValue Expanded = TLI.expandPartialReduceMLA(
N, DAG);
7623 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
7624 return DAG.getInsertSubvector(
DL, DAG.getPOISON(WideVT), Expanded, 0);
7630bool DAGTypeLegalizer::WidenVectorOperand(
SDNode *
N,
unsigned OpNo) {
7631 LLVM_DEBUG(
dbgs() <<
"Widen node operand " << OpNo <<
": ";
N->dump(&DAG));
7632 SDValue Res = SDValue();
7635 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
7638 switch (
N->getOpcode()) {
7641 dbgs() <<
"WidenVectorOperand op #" << OpNo <<
": ";
7649 Res = WidenVecOp_FAKE_USE(
N);
7655 case ISD::STORE: Res = WidenVecOp_STORE(
N);
break;
7659 case ISD::VP_STORE: Res = WidenVecOp_VP_STORE(
N, OpNo);
break;
7660 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7661 Res = WidenVecOp_VP_STRIDED_STORE(
N, OpNo);
7666 Res = WidenVecOp_EXTEND_VECTOR_INREG(
N);
7668 case ISD::MSTORE: Res = WidenVecOp_MSTORE(
N, OpNo);
break;
7669 case ISD::MGATHER: Res = WidenVecOp_MGATHER(
N, OpNo);
break;
7671 case ISD::VP_SCATTER: Res = WidenVecOp_VP_SCATTER(
N, OpNo);
break;
7672 case ISD::SETCC: Res = WidenVecOp_SETCC(
N);
break;
7682 Res = WidenVecOp_UnrollVectorOp(
N);
7689 Res = WidenVecOp_EXTEND(
N);
7694 Res = WidenVecOp_CMP(
N);
7712 Res = WidenVecOp_Convert(
N);
7717 Res = WidenVecOp_FP_TO_XINT_SAT(
N);
7737 Res = WidenVecOp_VECREDUCE(
N);
7741 Res = WidenVecOp_VECREDUCE_SEQ(
N);
7743 case ISD::VP_REDUCE_FADD:
7744 case ISD::VP_REDUCE_SEQ_FADD:
7745 case ISD::VP_REDUCE_FMUL:
7746 case ISD::VP_REDUCE_SEQ_FMUL:
7747 case ISD::VP_REDUCE_ADD:
7748 case ISD::VP_REDUCE_MUL:
7749 case ISD::VP_REDUCE_AND:
7750 case ISD::VP_REDUCE_OR:
7751 case ISD::VP_REDUCE_XOR:
7752 case ISD::VP_REDUCE_SMAX:
7753 case ISD::VP_REDUCE_SMIN:
7754 case ISD::VP_REDUCE_UMAX:
7755 case ISD::VP_REDUCE_UMIN:
7756 case ISD::VP_REDUCE_FMAX:
7757 case ISD::VP_REDUCE_FMIN:
7758 case ISD::VP_REDUCE_FMAXIMUM:
7759 case ISD::VP_REDUCE_FMINIMUM:
7760 Res = WidenVecOp_VP_REDUCE(
N);
7764 Res = WidenVecOp_CttzElements(
N);
7766 case ISD::VP_CTTZ_ELTS:
7767 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
7768 Res = WidenVecOp_VP_CttzElements(
N);
7771 Res = WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
N);
7774 Res = WidenVecOp_VECTOR_MATCH(
N, OpNo);
7779 if (!Res.
getNode())
return false;
7787 if (
N->isStrictFPOpcode())
7789 "Invalid operand expansion");
7792 "Invalid operand expansion");
7794 ReplaceValueWith(SDValue(
N, 0), Res);
7800 EVT VT =
N->getValueType(0);
7805 "Unexpected type action");
7806 InOp = GetWidenedVector(InOp);
7809 "Input wasn't widened!");
7817 EVT FixedEltVT = FixedVT.getVectorElementType();
7818 if (TLI.isTypeLegal(FixedVT) &&
7820 FixedEltVT == InEltVT) {
7822 "Not enough elements in the fixed type for the operand!");
7824 "We can't have the same type as we started with!");
7826 InOp = DAG.getInsertSubvector(
DL, DAG.getPOISON(FixedVT), InOp, 0);
7828 InOp = DAG.getExtractSubvector(
DL, FixedVT, InOp, 0);
7837 return WidenVecOp_Convert(
N);
7842 switch (
N->getOpcode()) {
7857 EVT OpVT =
N->getOperand(0).getValueType();
7858 EVT ResVT =
N->getValueType(0);
7859 SDValue
LHS = GetWidenedVector(
N->getOperand(0));
7860 SDValue
RHS = GetWidenedVector(
N->getOperand(1));
7865 LHS = DAG.getExtractSubvector(dl, OpVT,
LHS, 0);
7866 RHS = DAG.getExtractSubvector(dl, OpVT,
RHS, 0);
7872 LHS = DAG.getNode(ExtendOpcode, dl, ResVT,
LHS);
7873 RHS = DAG.getNode(ExtendOpcode, dl, ResVT,
RHS);
7875 return DAG.getNode(
N->getOpcode(), dl, ResVT,
LHS,
RHS);
7882 return DAG.UnrollVectorOp(
N);
7887 EVT ResultVT =
N->getValueType(0);
7888 SDValue
Test =
N->getOperand(1);
7889 SDValue WideArg = GetWidenedVector(
N->getOperand(0));
7892 EVT WideResultVT = getSetCCResultType(WideArg.
getValueType());
7898 {WideArg,
Test},
N->getFlags());
7904 SDValue CC = DAG.getExtractSubvector(
DL, ResVT, WideNode, 0);
7906 EVT OpVT =
N->getOperand(0).getValueType();
7909 return DAG.getNode(ExtendCode,
DL, ResultVT, CC);
7914 EVT VT =
N->getValueType(0);
7917 SDValue InOp =
N->
getOperand(
N->isStrictFPOpcode() ? 1 : 0);
7920 "Unexpected type action");
7921 InOp = GetWidenedVector(InOp);
7923 unsigned Opcode =
N->getOpcode();
7926 auto MakeConvertNode = [&](EVT VT, SDValue
Op) -> SDValue {
7928 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1),
N->getOperand(2),
7931 return DAG.getNode(Opcode, dl, VT,
Op,
N->getOperand(1));
7932 return DAG.getNode(Opcode, dl, VT,
Op);
7939 if (TLI.isTypeLegal(WideVT) && !
N->isStrictFPOpcode()) {
7941 if (
N->isStrictFPOpcode()) {
7943 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7946 Res = DAG.
getNode(Opcode, dl, { WideVT, MVT::Other },
7947 {
N->getOperand(0), InOp });
7950 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
7952 Res = MakeConvertNode(WideVT, InOp);
7954 return DAG.getExtractSubvector(dl, VT, Res, 0);
7962 if (
N->isStrictFPOpcode()) {
7965 for (
unsigned i=0; i < NumElts; ++i) {
7966 NewOps[1] = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7967 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
7971 ReplaceValueWith(SDValue(
N, 1), NewChain);
7973 for (
unsigned i = 0; i < NumElts; ++i) {
7974 SDValue Elt = DAG.getExtractVectorElt(dl, InEltVT, InOp, i);
7975 Ops[i] = MakeConvertNode(EltVT, Elt);
7979 return DAG.getBuildVector(VT, dl,
Ops);
7983 EVT DstVT =
N->getValueType(0);
7984 SDValue Src = GetWidenedVector(
N->getOperand(0));
7985 EVT SrcVT = Src.getValueType();
7992 if (TLI.isTypeLegal(WideDstVT)) {
7994 DAG.
getNode(
N->getOpcode(), dl, WideDstVT, Src,
N->getOperand(1));
7997 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
8001 return DAG.UnrollVectorOp(
N);
8005 EVT VT =
N->getValueType(0);
8006 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8014 if (!VT.
isVector() && VT != MVT::x86mmx &&
8018 if (TLI.isTypeLegal(NewVT)) {
8019 SDValue BitOp = DAG.getNode(
ISD::BITCAST, dl, NewVT, InOp);
8020 return DAG.getExtractVectorElt(dl, VT, BitOp, 0);
8032 ElementCount NewNumElts =
8034 .divideCoefficientBy(EltSize);
8036 if (TLI.isTypeLegal(NewVT)) {
8038 return DAG.getExtractSubvector(dl, VT, BitOp, 0);
8043 return CreateStackStoreLoad(InOp, VT);
8051 SDValue WidenedOp = GetWidenedVector(
N->getOperand(1));
8052 return DAG.getNode(
ISD::FAKE_USE, SDLoc(), MVT::Other,
N->getOperand(0),
8057 EVT VT =
N->getValueType(0);
8059 EVT InVT =
N->getOperand(0).getValueType();
8064 unsigned NumOperands =
N->getNumOperands();
8065 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
8067 for (i = 1; i < NumOperands; ++i)
8068 if (!
N->getOperand(i).isUndef())
8071 if (i == NumOperands)
8072 return GetWidenedVector(
N->getOperand(0));
8076 SDValue
Result = DAG.getPOISON(VT);
8078 for (
unsigned i = 0; i < NumOperands; ++i) {
8079 SDValue InOp = GetWidenedVector(
N->getOperand(i));
8081 InOp = DAG.getExtractSubvector(dl, InVT, InOp, 0);
8082 Result = DAG.getInsertSubvector(dl, Result, InOp, i * NumInElts);
8094 for (
unsigned i=0; i < NumOperands; ++i) {
8098 "Unexpected type action");
8099 InOp = GetWidenedVector(InOp);
8100 for (
unsigned j = 0;
j < NumInElts; ++
j)
8101 Ops[Idx++] = DAG.getExtractVectorElt(dl, EltVT, InOp, j);
8103 return DAG.getBuildVector(VT, dl,
Ops);
8106SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(
SDNode *
N) {
8107 EVT VT =
N->getValueType(0);
8112 SubVec = GetWidenedVector(SubVec);
8117 bool IndicesValid =
false;
8120 IndicesValid =
true;
8124 Attribute Attr = DAG.getMachineFunction().getFunction().getFnAttribute(
8125 Attribute::VScaleRange);
8130 IndicesValid =
true;
8136 "Don't know how to widen the operands for INSERT_SUBVECTOR");
8142 if (InVec.
isUndef() &&
N->getConstantOperandVal(2) == 0)
8149 if (SubVT == VT &&
N->getConstantOperandVal(2) == 0) {
8171 DAG.getStore(DAG.getEntryNode(),
DL, InVec, StackPtr, StoreMMO);
8179 TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT,
N->getOperand(2));
8180 Ch = DAG.getMaskedStore(Ch,
DL, SubVec, SubVecPtr,
8185 return DAG.getLoad(VT,
DL, Ch, StackPtr, LoadMMO);
8190 unsigned Idx =
N->getConstantOperandVal(2);
8192 SDValue InsertElt = InVec;
8194 SDValue ExtractElt =
8196 InsertElt = DAG.getInsertVectorElt(
DL, InsertElt, ExtractElt,
I + Idx);
8202SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(
SDNode *
N) {
8203 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8205 N->getValueType(0), InOp,
N->getOperand(1));
8208SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(
SDNode *
N) {
8209 SDValue InOp = GetWidenedVector(
N->getOperand(0));
8211 N->getValueType(0), InOp,
N->getOperand(1));
8214SDValue DAGTypeLegalizer::WidenVecOp_EXTEND_VECTOR_INREG(
SDNode *
N) {
8216 EVT ResVT =
N->getValueType(0);
8219 SDValue WideInOp = GetWidenedVector(
N->getOperand(0));
8225 return DAG.getNode(
N->getOpcode(),
DL, ResVT, WideInOp);
8233 "Widened input size must be a multiple of result element size");
8236 EVT WideResVT =
EVT::getVectorVT(*DAG.getContext(), ResEltVT, WideNumElts);
8238 SDValue WideRes = DAG.getNode(
N->getOpcode(),
DL, WideResVT, WideInOp);
8239 return DAG.getExtractSubvector(
DL, ResVT, WideRes, 0);
8247 if (!
ST->getMemoryVT().getScalarType().isByteSized())
8248 return TLI.scalarizeVectorStore(ST, DAG);
8250 if (
ST->isTruncatingStore())
8251 return TLI.scalarizeVectorStore(ST, DAG);
8259 SDValue StVal =
ST->getValue();
8261 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
8262 EVT WideMaskVT = getSetCCResultType(WideVT);
8264 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8265 TLI.isTypeLegal(WideMaskVT)) {
8268 StVal = GetWidenedVector(StVal);
8269 SDValue
Mask = DAG.getAllOnesConstant(
DL, WideMaskVT);
8270 SDValue EVL = DAG.getElementCount(
DL, TLI.getVPExplicitVectorLengthTy(),
8272 return DAG.getStoreVP(
ST->getChain(),
DL, StVal,
ST->getBasePtr(),
8273 ST->getOffset(), Mask, EVL, StVT,
ST->getMemOperand(),
8274 ST->getAddressingMode());
8278 if (GenWidenVectorStores(StChain, ST)) {
8279 if (StChain.
size() == 1)
8288 SDValue WideStVal = GetWidenedVector(StVal);
8292 return DAG.getMaskedStore(
ST->getChain(),
DL, WideStVal,
ST->getBasePtr(),
8293 ST->getOffset(), Mask,
ST->getMemoryVT(),
8294 ST->getMemOperand(),
ST->getAddressingMode(),
8295 ST->isTruncatingStore());
8302 EVT StVT =
ST->getMemoryVT();
8305 SDValue StVal = GetWidenedVector(
ST->getVal());
8310 TypeSize WidthDiff = WidenWidth - StWidth;
8316 std::optional<EVT> FirstVT =
8317 findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, 0,
8322 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
8328 ST->getBasePtr(),
ST->getMemOperand());
8331SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(
SDNode *
N,
unsigned OpNo) {
8332 assert((OpNo == 1 || OpNo == 3) &&
8333 "Can widen only data or mask operand of vp_store");
8335 SDValue
Mask =
ST->getMask();
8336 SDValue StVal =
ST->getValue();
8341 StVal = GetWidenedVector(StVal);
8347 "Unable to widen VP store");
8348 Mask = GetWidenedVector(Mask);
8350 Mask = GetWidenedVector(Mask);
8356 "Unable to widen VP store");
8357 StVal = GetWidenedVector(StVal);
8360 assert(
Mask.getValueType().getVectorElementCount() ==
8362 "Mask and data vectors should have the same number of elements");
8363 return DAG.getStoreVP(
ST->getChain(), dl, StVal,
ST->getBasePtr(),
8364 ST->getOffset(), Mask,
ST->getVectorLength(),
8365 ST->getMemoryVT(),
ST->getMemOperand(),
8366 ST->getAddressingMode(),
ST->isTruncatingStore(),
8367 ST->isCompressingStore());
8372 assert((OpNo == 1 || OpNo == 4) &&
8373 "Can widen only data or mask operand of vp_strided_store");
8382 "Unable to widen VP strided store");
8386 "Unable to widen VP strided store");
8388 StVal = GetWidenedVector(StVal);
8389 Mask = GetWidenedVector(Mask);
8392 Mask.getValueType().getVectorElementCount() &&
8393 "Data and mask vectors should have the same number of elements");
8395 return DAG.getStridedStoreVP(
8402SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(
SDNode *
N,
unsigned OpNo) {
8403 assert((OpNo == 1 || OpNo == 4) &&
8404 "Can widen only data or mask operand of mstore");
8407 EVT MaskVT =
Mask.getValueType();
8412 EVT WideVT, WideMaskVT;
8415 StVal = GetWidenedVector(StVal);
8422 WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
8429 if (TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
8431 Mask = DAG.getInsertSubvector(dl, DAG.getPOISON(WideMaskVT), Mask, 0);
8432 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8441 Mask = ModifyToType(Mask, WideMaskVT,
true);
8444 Mask = ModifyToType(Mask, WideMaskVT,
true);
8446 StVal = ModifyToType(StVal, WideVT);
8449 assert(
Mask.getValueType().getVectorElementCount() ==
8451 "Mask and data vectors should have the same number of elements");
8458SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(
SDNode *
N,
unsigned OpNo) {
8459 assert(OpNo == 4 &&
"Can widen only the index of mgather");
8461 SDValue DataOp = MG->getPassThru();
8462 SDValue
Mask = MG->getMask();
8463 SDValue Scale = MG->getScale();
8466 SDValue
Index = GetWidenedVector(MG->getIndex());
8469 SDValue
Ops[] = {MG->getChain(), DataOp,
Mask, MG->getBasePtr(),
Index,
8471 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl,
Ops,
8472 MG->getMemOperand(), MG->getIndexType(),
8473 MG->getExtensionType());
8474 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
8475 ReplaceValueWith(SDValue(
N, 0), Res.
getValue(0));
8479SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(
SDNode *
N,
unsigned OpNo) {
8488 DataOp = GetWidenedVector(DataOp);
8492 EVT IndexVT =
Index.getValueType();
8495 Index = ModifyToType(Index, WideIndexVT);
8498 EVT MaskVT =
Mask.getValueType();
8501 Mask = ModifyToType(Mask, WideMaskVT,
true);
8506 }
else if (OpNo == 4) {
8508 Index = GetWidenedVector(Index);
8514 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
8519SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(
SDNode *
N,
unsigned OpNo) {
8528 DataOp = GetWidenedVector(DataOp);
8529 Index = GetWidenedVector(Index);
8531 Mask = GetWidenedMask(Mask, WideEC);
8534 }
else if (OpNo == 3) {
8536 Index = GetWidenedVector(Index);
8543 return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(
N),
Ops,
8548 SDValue InOp0 = GetWidenedVector(
N->getOperand(0));
8549 SDValue InOp1 = GetWidenedVector(
N->getOperand(1));
8551 EVT VT =
N->getValueType(0);
8565 SDValue WideSETCC = DAG.getNode(
ISD::SETCC, SDLoc(
N),
8566 SVT, InOp0, InOp1,
N->getOperand(2));
8572 SDValue CC = DAG.getExtractSubvector(dl, ResVT, WideSETCC, 0);
8574 EVT OpVT =
N->getOperand(0).getValueType();
8577 return DAG.getNode(ExtendCode, dl, VT, CC);
8582 SDValue
LHS = GetWidenedVector(
N->getOperand(1));
8583 SDValue
RHS = GetWidenedVector(
N->getOperand(2));
8587 EVT VT =
N->getValueType(0);
8589 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
8596 for (
unsigned i = 0; i != NumElts; ++i) {
8597 SDValue LHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
LHS, i);
8598 SDValue RHSElem = DAG.getExtractVectorElt(dl, TmpEltVT,
RHS, i);
8600 Scalars[i] = DAG.getNode(
N->getOpcode(), dl, {MVT::i1, MVT::Other},
8601 {Chain, LHSElem, RHSElem, CC});
8602 Chains[i] = Scalars[i].getValue(1);
8603 Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
8604 DAG.getBoolConstant(
true, dl, EltVT, VT),
8605 DAG.getBoolConstant(
false, dl, EltVT, VT));
8609 ReplaceValueWith(SDValue(
N, 1), NewChain);
8611 return DAG.getBuildVector(VT, dl, Scalars);
8635 SDValue
Op = GetWidenedVector(
N->getOperand(0));
8636 EVT VT =
N->getValueType(0);
8637 EVT OrigVT =
N->getOperand(0).getValueType();
8638 EVT WideVT =
Op.getValueType();
8640 SDNodeFlags
Flags =
N->getFlags();
8642 unsigned Opc =
N->getOpcode();
8644 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8645 assert(NeutralElem &&
"Neutral element must exist");
8655 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8656 SDValue
Start = NeutralElem;
8662 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8663 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8669 unsigned GCD = std::gcd(OrigElts, WideElts);
8672 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8673 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8674 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8675 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8678 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8679 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8681 return DAG.getNode(
Opc, dl, VT,
Op, Flags);
8688 SDValue
Op = GetWidenedVector(VecOp);
8690 EVT VT =
N->getValueType(0);
8692 EVT WideVT =
Op.getValueType();
8694 SDNodeFlags
Flags =
N->getFlags();
8696 unsigned Opc =
N->getOpcode();
8698 SDValue NeutralElem = DAG.getIdentityElement(BaseOpc, dl, ElemVT, Flags);
8708 VPOpcode && TLI.isOperationLegalOrCustom(*VPOpcode, WideVT)) {
8711 SDValue
Mask = DAG.getAllOnesConstant(dl, WideMaskVT);
8712 SDValue EVL = DAG.getElementCount(dl, TLI.getVPExplicitVectorLengthTy(),
8718 unsigned GCD = std::gcd(OrigElts, WideElts);
8721 SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
8722 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
8723 Op = DAG.getInsertSubvector(dl,
Op, SplatNeutral, Idx);
8724 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8727 for (
unsigned Idx = OrigElts; Idx < WideElts; Idx++)
8728 Op = DAG.getInsertVectorElt(dl,
Op, NeutralElem, Idx);
8730 return DAG.getNode(
Opc, dl, VT, AccOp,
Op, Flags);
8734 assert(
N->isVPOpcode() &&
"Expected VP opcode");
8737 SDValue
Op = GetWidenedVector(
N->getOperand(1));
8738 SDValue
Mask = GetWidenedMask(
N->getOperand(2),
8739 Op.getValueType().getVectorElementCount());
8741 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
8742 {N->getOperand(0), Op, Mask, N->getOperand(3)},
8750 EVT VT =
N->getValueType(0);
8753 SDValue
Cond = GetWidenedVector(
N->getOperand(0));
8754 SDValue LeftIn = DAG.WidenVector(
N->getOperand(1), SDLoc(
N));
8755 SDValue RightIn = DAG.WidenVector(
N->getOperand(2), SDLoc(
N));
8760 return DAG.getExtractSubvector(
DL, VT,
Select, 0);
8765 SDValue
Source =
N->getOperand(0);
8766 EVT SourceVT =
Source.getValueType();
8767 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8771 WideSource = GetWidenedVector(Source);
8775 SDValue
AllOnes = DAG.getAllOnesConstant(
DL, WideVT);
8778 WideSource = GetWidenedVector(Source);
8780 SmallVector<int>
Mask(WideElts);
8781 std::iota(
Mask.begin(),
Mask.end(), 0);
8783 Mask[
I] += WideElts;
8784 WideSource = DAG.getVectorShuffle(WideVT,
DL, WideSource,
AllOnes, Mask);
8786 WideSource = DAG.getInsertSubvector(
DL,
AllOnes, Source, 0);
8790 return DAG.
getNode(
N->getOpcode(),
DL,
N->getValueType(0), WideSource,
8796 SDValue
Source = GetWidenedVector(
N->getOperand(0));
8797 EVT SrcVT =
Source.getValueType();
8801 return DAG.getNode(
N->getOpcode(),
DL,
N->getValueType(0),
8802 {Source, Mask, N->getOperand(2)},
N->getFlags());
8805SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_FIND_LAST_ACTIVE(
SDNode *
N) {
8807 SDValue
Mask =
N->getOperand(0);
8808 EVT OrigMaskVT =
Mask.getValueType();
8809 SDValue WideMask = GetWidenedVector(Mask);
8815 if (OrigElts != WideElts) {
8816 SDValue ZeroMask = DAG.getConstant(0,
DL, WideMaskVT);
8818 Mask, DAG.getVectorIdxConstant(0,
DL));
8825SDValue DAGTypeLegalizer::WidenVecOp_VECTOR_MATCH(
SDNode *
N,
unsigned OpNo) {
8828 EVT ResVT =
N->getValueType(0);
8829 EVT SourceVT =
N->getOperand(0).getValueType();
8830 EVT WideSourceVT = TLI.getTypeToTransformTo(*DAG.getContext(), SourceVT);
8835 SDValue WideSource = DAG.getInsertSubvector(
DL, DAG.getUNDEF(WideSourceVT),
8836 N->getOperand(0), 0);
8837 SDValue WideMask = DAG.getInsertSubvector(
8838 DL, DAG.getConstant(0,
DL, WidenVT),
N->getOperand(2), 0);
8840 N->getOperand(1), WideMask,
N->getFlags());
8841 return DAG.getExtractSubvector(
DL, ResVT, WideMatch, 0);
8845 assert(OpNo == 1 &&
"Unexpected VECTOR_MATCH operand");
8848 SDValue Needle =
N->getOperand(1);
8851 return TLI.expandVectorMatch(
N, DAG);
8853 EVT WidenNeedleVT = TLI.getTypeToTransformTo(*DAG.getContext(), NeedleVT);
8857 SDValue WideNeedle = DAG.getSplatVector(WidenNeedleVT,
DL, Fill);
8858 WideNeedle = DAG.getInsertSubvector(
DL, WideNeedle, Needle, 0);
8861 N->getOperand(0), WideNeedle,
N->getOperand(2),
8879 unsigned WidenEx = 0) {
8884 unsigned AlignInBits =
Align*8;
8886 EVT RetVT = WidenEltVT;
8891 if (Width == WidenEltWidth)
8902 (WidenWidth % MemVTWidth) == 0 &&
8904 (MemVTWidth <= Width ||
8905 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8906 if (MemVTWidth == WidenWidth)
8925 (WidenWidth % MemVTWidth) == 0 &&
8927 (MemVTWidth <= Width ||
8928 (
Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
8937 return std::nullopt;
8948 unsigned Start,
unsigned End) {
8949 SDLoc dl(LdOps[Start]);
8950 EVT LdTy = LdOps[Start].getValueType();
8958 for (
unsigned i = Start + 1; i != End; ++i) {
8959 EVT NewLdTy = LdOps[i].getValueType();
8960 if (NewLdTy != LdTy) {
8979 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
8980 EVT LdVT =
LD->getMemoryVT();
8987 SDValue Chain =
LD->getChain();
8990 AAMDNodes AAInfo =
LD->getAAInfo();
8994 TypeSize WidthDiff = WidenWidth - LdWidth;
9001 std::optional<EVT> FirstVT =
9002 findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
9009 TypeSize FirstVTWidth = FirstVT->getSizeInBits();
9014 std::optional<EVT> NewVT = FirstVT;
9015 TypeSize RemainingWidth = LdWidth;
9016 TypeSize NewVTWidth = FirstVTWidth;
9018 RemainingWidth -= NewVTWidth;
9025 NewVTWidth = NewVT->getSizeInBits();
9031 SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr,
LD->getPointerInfo(),
9032 LD->getBaseAlign(), MMOFlags, AAInfo);
9045 MachinePointerInfo MPI =
LD->getPointerInfo();
9051 for (EVT MemVT : MemVTs) {
9052 Align NewAlign = ScaledOffset == 0
9053 ?
LD->getBaseAlign()
9056 DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
9064 unsigned End = LdOps.
size();
9075 EVT LdTy = LdOps[i].getValueType();
9078 for (--i; i >= 0; --i) {
9079 LdTy = LdOps[i].getValueType();
9086 ConcatOps[--Idx] = LdOps[i];
9087 for (--i; i >= 0; --i) {
9088 EVT NewLdTy = LdOps[i].getValueType();
9089 if (NewLdTy != LdTy) {
9099 for (;
j != End-Idx; ++
j)
9100 WidenOps[j] = ConcatOps[Idx+j];
9102 WidenOps[j] = DAG.getPOISON(LdTy);
9109 ConcatOps[--Idx] = LdOps[i];
9114 ArrayRef(&ConcatOps[Idx], End - Idx));
9120 SDValue UndefVal = DAG.getPOISON(LdTy);
9123 for (; i != End-Idx; ++i)
9124 WidenOps[i] = ConcatOps[Idx+i];
9126 WidenOps[i] = UndefVal;
9137 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
9138 EVT LdVT =
LD->getMemoryVT();
9144 SDValue Chain =
LD->getChain();
9147 AAMDNodes AAInfo =
LD->getAAInfo();
9161 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr,
LD->getPointerInfo(),
9162 LdEltVT,
LD->getBaseAlign(), MMOFlags, AAInfo);
9166 SDValue NewBasePtr =
9168 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
9169 LD->getPointerInfo().getWithOffset(
Offset), LdEltVT,
9170 LD->getBaseAlign(), MMOFlags, AAInfo);
9175 SDValue UndefVal = DAG.getPOISON(EltVT);
9176 for (; i != WidenNumElts; ++i)
9179 return DAG.getBuildVector(WidenVT, dl,
Ops);
9187 SDValue Chain =
ST->getChain();
9190 AAMDNodes AAInfo =
ST->getAAInfo();
9191 SDValue ValOp = GetWidenedVector(
ST->getValue());
9194 EVT StVT =
ST->getMemoryVT();
9202 "Mismatch between store and value types");
9206 MachinePointerInfo MPI =
ST->getPointerInfo();
9216 std::optional<EVT> NewVT =
9221 TypeSize NewVTWidth = NewVT->getSizeInBits();
9224 StWidth -= NewVTWidth;
9225 MemVTs.
back().second++;
9229 for (
const auto &Pair : MemVTs) {
9230 EVT NewVT = Pair.first;
9231 unsigned Count = Pair.second;
9237 Align NewAlign = ScaledOffset == 0
9238 ?
ST->getBaseAlign()
9240 SDValue EOp = DAG.getExtractSubvector(dl, NewVT, ValOp, Idx);
9241 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
9257 SDValue EOp = DAG.getExtractVectorElt(dl, NewVT, VecOp, Idx++);
9258 SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI,
9259 ST->getBaseAlign(), MMOFlags, AAInfo);
9276 bool FillWithZeroes) {
9281 "input and widen element type must match");
9283 "cannot modify scalable vectors in this way");
9296 FillWithZeroes ? DAG.getConstant(0, dl, InVT) : DAG.getPOISON(InVT);
9298 for (
unsigned i = 1; i != NumConcat; ++i)
9305 return DAG.getExtractSubvector(dl, NVT, InOp, 0);
9311 unsigned CommonFactor = std::gcd(InNumElts, NewNumElts);
9316 unsigned NumCopiedParts = std::min(InNumElts, NewNumElts) / CommonFactor;
9317 for (
unsigned I = 0;
I != NumCopiedParts; ++
I)
9319 DAG.getExtractSubvector(dl, PartVT, InOp,
I * CommonFactor));
9321 unsigned NumResultParts = NewNumElts / CommonFactor;
9322 if (NumResultParts > NumCopiedParts) {
9323 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, PartVT)
9324 : DAG.getPOISON(PartVT);
9325 Ops.append(NumResultParts - NumCopiedParts, FillVal);
9332 "Scalable vectors should have been handled already.");
9340 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
9342 for (Idx = 0; Idx < MinNumElts; ++Idx)
9343 Ops[Idx] = DAG.getExtractVectorElt(dl, EltVT, InOp, Idx);
9345 SDValue UndefVal = DAG.getPOISON(EltVT);
9346 for (; Idx < WidenNumElts; ++Idx)
9347 Ops[Idx] = UndefVal;
9349 SDValue Widened = DAG.getBuildVector(NVT, dl,
Ops);
9350 if (!FillWithZeroes)
9354 "We expect to never want to FillWithZeroes for non-integral types.");
9357 MaskOps.
append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
9358 MaskOps.
append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
9360 return DAG.getNode(
ISD::AND, dl, NVT, Widened,
9361 DAG.getBuildVector(NVT, dl, MaskOps));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static unsigned getExtendForIntVecReduction(SDNode *N)
static SDValue BuildVectorFromScalar(SelectionDAG &DAG, EVT VecTy, SmallVectorImpl< SDValue > &LdOps, unsigned Start, unsigned End)
static std::optional< EVT > findMemType(SelectionDAG &DAG, const TargetLowering &TLI, unsigned Width, EVT WidenVT, unsigned Align, unsigned WidenEx)
static EVT getSETCCOperandType(SDValue N)
static bool isSETCCOp(unsigned Opcode)
static bool isLogicalMaskOp(unsigned Opcode)
static bool isSETCCorConvertedSETCC(SDValue N)
static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT, TypeSize FirstVTWidth, const SDLoc &dl, SelectionDAG &DAG)
Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the widened value so it can b...
static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI, SmallVectorImpl< SDValue > &ConcatOps, unsigned ConcatEnd, EVT VT, EVT MaxVT, EVT WidenVT)
static SDValue coerceLoadedValue(SDValue LdOp, EVT FirstVT, EVT WidenVT, TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl, SelectionDAG &DAG)
Either return the same load or provide appropriate casts from the load and return that.
static bool isUndef(const MachineInstr &MI)
This file provides utility analysis objects describing memory locations.
const SmallVectorImpl< MachineOperand > & Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file implements the SmallBitVector class.
This is an SDNode representing atomic operations.
LLVM_ABI unsigned getVScaleRangeMin() const
Returns the minimum value for the vscale_range attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
This class is used to represent ISD::LOAD nodes.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static auto integer_valuetypes()
static auto vector_valuetypes()
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
This class is used to represent an MGATHER node.
const SDValue & getIndex() const
const SDValue & getScale() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
const SDValue & getScale() const
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
const SDValue & getBasePtr() const
bool isExpandingLoad() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
This is an abstract virtual class for memory operations.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
const MDNode * getMemCacheHint() const
Returns the cache hint metadata for this memory access.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtractVectorElt(const SDLoc &DL, EVT VT, SDValue Vec, unsigned Idx)
Extract element at Idx from Vec.
SDValue getInsertVectorElt(const SDLoc &DL, SDValue Vec, SDValue Elt, unsigned Idx)
Insert Elt into Vec at offset Idx.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVMContext * getContext() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
@ TypeScalarizeScalableVector
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
BooleanContent
Enum that describes how the target represents true/false values.
@ ZeroOrOneBooleanContent
@ UndefinedBooleanContent
@ ZeroOrNegativeOneBooleanContent
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
static ISD::NodeType getExtendForContent(BooleanContent Content)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
This class is used to represent an VP_GATHER node.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
bool isExpandingLoad() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getBasePtr() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS*X will result in a value whose quantity matches our ...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isNonZero() const
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS*X will result in a value whose quantity matches our own.
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ LOOP_DEPENDENCE_RAW_MASK
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ CTTZ_ELTS
Returns the number of number of trailing (least significant) zero elements in a vector.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
Finds the index of the last active mask element Operands: Mask.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ CLMUL
Carry-less multiplication operations.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ VECREDUCE_FMAXIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM nodes do not propagate NaNs and order signed zeroes using the llvm....
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ VECTOR_INTERLEAVE
VECTOR_INTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor to...
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ GET_ACTIVE_LANE_MASK
GET_ACTIVE_LANE_MASK - this corrosponds to the llvm.get.active.lane.mask intrinsic.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ VECTOR_SPLICE_LEFT
VECTOR_SPLICE_LEFT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1, VEC2) left by OFFSET elements an...
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ MASKED_UDIV
Masked vector arithmetic that returns poison on disabled lanes.
@ VECTOR_REVERSE
VECTOR_REVERSE(VECTOR) - Returns a vector, of the same type as VECTOR, whose elements are shuffled us...
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ PEXT
Parallel bit extract (compress) and parallel bit deposit (expand).
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ VECTOR_MATCH
VECTOR_MATCH - this corresponds to the llvm.experimental.vector.match intrinsic.
@ VECTOR_SPLICE_RIGHT
VECTOR_SPLICE_RIGHT(VEC1, VEC2, OFFSET) - Shifts CONCAT_VECTORS(VEC1,VEC2) right by OFFSET elements a...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Experimental vector histogram intrinsic Operands: Input Chain, Inc, Mask, Base, Index,...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ VECTOR_DEINTERLEAVE
VECTOR_DEINTERLEAVE(VEC1, VEC2, ...) - Returns N vectors from N input vectors, where N is the factor ...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ABS_MIN_POISON
ABS with a poison result for INT_MIN.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
@ LOOP_DEPENDENCE_WAR_MASK
The llvm.loop.dependence.
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
LLVM_ABI NodeType getUnmaskedBinOpOpcode(unsigned MaskedOpc)
Given a MaskedOpc of ISD::MASKED_(U|S)(DIV|REM), returns the unmasked ISD::(U|S)(DIV|REM).
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
LLVM_ABI std::optional< unsigned > getVPForBaseOpcode(unsigned Opcode)
Translate this non-VP Opcode to its corresponding VP Opcode.
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI NodeType getVecReduceBaseOpcode(unsigned VecReduceOpcode)
Get underlying scalar opcode for VECREDUCE opcode.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Type * getValueType(Value *V, bool ReVec, bool LookThroughCmp)
Returns the "element type" of the given value/instruction V.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr int PoisonMaskElem
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
@ Increment
Incrementally increasing token ID.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
EVT widenIntegerVectorElementType(LLVMContext &Context) const
Return a VT for an integer vector type with the size of the elements doubled.
bool isFixedLengthVector() const
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
EVT getRoundIntegerType(LLVMContext &Context) const
Rounds the bit-width of the given integer EVT up to the nearest power of two (and at least to eight),...
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
bool knownBitsGE(EVT VT) const
Return true if we know at compile time this has more than or the same bits as VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a type whose attributes match ourselves with the exception of the element type that i...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.