44#include "llvm/IR/IntrinsicsRISCV.h"
58#define DEBUG_TYPE "riscv-lower"
64 cl::desc(
"Give the maximum size (in number of nodes) of the web of "
65 "instructions that we will consider for VW expansion"),
70 cl::desc(
"Allow the formation of VW_W operations (e.g., "
71 "VWADD_W) with splat constants"),
76 cl::desc(
"Set the minimum number of repetitions of a divisor to allow "
77 "transformation to multiplications by the reciprocal"),
82 cl::desc(
"Give the maximum number of instructions that we will "
83 "use for creating a floating-point immediate value"),
88 cl::desc(
"Swap add and addi in cases where the add may "
89 "be combined with a shift"),
93 "riscv-br-merging-base-cost",
cl::init(2),
95 "Sets the cost threshold for when multiple conditionals will be merged "
96 "into one branch versus be split in multiple branches. Merging "
97 "conditionals saves branches at the cost of additional instructions. "
98 "This value sets the instruction cost limit, below which conditionals "
99 "will be merged, and above which conditionals will be split. Set to -1 "
100 "to never merge branches."),
104 "riscv-br-merging-likely-bias",
cl::init(0),
106 "Increases 'riscv-br-merging-base-cost' in cases that it is "
107 "likely that all conditionals will be executed. For example for "
108 "merging the conditionals (a == b && c > d), if its known that "
109 "a == b is likely, then it is likely that if the conditionals are "
110 "split both sides will be executed, so it may be desirable to "
111 "increase the instruction cost threshold. Set to -1 to never merge "
116 "riscv-br-merging-unlikely-bias",
cl::init(-1),
118 "Decreases 'riscv-br-merging-base-cost' in cases that it is unlikely "
119 "that all conditionals will be executed. For example for merging "
120 "the conditionals (a == b && c > d), if its known that a == b is "
121 "unlikely, then it is unlikely that if the conditionals are split "
122 "both sides will be executed, so it may be desirable to decrease "
123 "the instruction cost threshold. Set to -1 to never merge unlikely "
158 MVT XLenVT = Subtarget.getXLenVT();
163 if (Subtarget.hasStdExtZfhmin())
165 if (Subtarget.hasStdExtZfbfmin() || Subtarget.hasVendorXAndesBFHCvt())
167 if (Subtarget.hasStdExtF())
169 if (Subtarget.hasStdExtD())
171 if (Subtarget.hasStdExtZhinxmin())
173 if (Subtarget.hasStdExtZfinx())
175 if (Subtarget.hasStdExtZdinx()) {
176 if (Subtarget.is64Bit())
183 MVT::nxv1i1, MVT::nxv2i1, MVT::nxv4i1, MVT::nxv8i1,
184 MVT::nxv16i1, MVT::nxv32i1, MVT::nxv64i1};
186 MVT::nxv1i8, MVT::nxv2i8, MVT::nxv4i8, MVT::nxv8i8, MVT::nxv16i8,
187 MVT::nxv32i8, MVT::nxv64i8, MVT::nxv1i16, MVT::nxv2i16, MVT::nxv4i16,
188 MVT::nxv8i16, MVT::nxv16i16, MVT::nxv32i16, MVT::nxv1i32, MVT::nxv2i32,
189 MVT::nxv4i32, MVT::nxv8i32, MVT::nxv16i32, MVT::nxv1i64, MVT::nxv2i64,
190 MVT::nxv4i64, MVT::nxv8i64};
192 MVT::nxv1f16, MVT::nxv2f16, MVT::nxv4f16,
193 MVT::nxv8f16, MVT::nxv16f16, MVT::nxv32f16};
195 MVT::nxv1bf16, MVT::nxv2bf16, MVT::nxv4bf16,
196 MVT::nxv8bf16, MVT::nxv16bf16, MVT::nxv32bf16};
198 MVT::nxv1f32, MVT::nxv2f32, MVT::nxv4f32, MVT::nxv8f32, MVT::nxv16f32};
200 MVT::nxv1f64, MVT::nxv2f64, MVT::nxv4f64, MVT::nxv8f64};
202 MVT::riscv_nxv1i8x2, MVT::riscv_nxv1i8x3, MVT::riscv_nxv1i8x4,
203 MVT::riscv_nxv1i8x5, MVT::riscv_nxv1i8x6, MVT::riscv_nxv1i8x7,
204 MVT::riscv_nxv1i8x8, MVT::riscv_nxv2i8x2, MVT::riscv_nxv2i8x3,
205 MVT::riscv_nxv2i8x4, MVT::riscv_nxv2i8x5, MVT::riscv_nxv2i8x6,
206 MVT::riscv_nxv2i8x7, MVT::riscv_nxv2i8x8, MVT::riscv_nxv4i8x2,
207 MVT::riscv_nxv4i8x3, MVT::riscv_nxv4i8x4, MVT::riscv_nxv4i8x5,
208 MVT::riscv_nxv4i8x6, MVT::riscv_nxv4i8x7, MVT::riscv_nxv4i8x8,
209 MVT::riscv_nxv8i8x2, MVT::riscv_nxv8i8x3, MVT::riscv_nxv8i8x4,
210 MVT::riscv_nxv8i8x5, MVT::riscv_nxv8i8x6, MVT::riscv_nxv8i8x7,
211 MVT::riscv_nxv8i8x8, MVT::riscv_nxv16i8x2, MVT::riscv_nxv16i8x3,
212 MVT::riscv_nxv16i8x4, MVT::riscv_nxv32i8x2};
214 if (Subtarget.hasVInstructions()) {
215 auto addRegClassForRVV = [
this](
MVT VT) {
219 if (VT.getVectorMinNumElements() < MinElts)
222 unsigned Size = VT.getSizeInBits().getKnownMinValue();
225 RC = &RISCV::VRRegClass;
227 RC = &RISCV::VRM2RegClass;
229 RC = &RISCV::VRM4RegClass;
231 RC = &RISCV::VRM8RegClass;
238 for (
MVT VT : BoolVecVTs)
239 addRegClassForRVV(VT);
240 for (
MVT VT : IntVecVTs) {
241 if (VT.getVectorElementType() == MVT::i64 &&
242 !Subtarget.hasVInstructionsI64())
244 addRegClassForRVV(VT);
247 if (Subtarget.hasVInstructionsF16Minimal() ||
248 Subtarget.hasVendorXAndesVPackFPH())
249 for (
MVT VT : F16VecVTs)
250 addRegClassForRVV(VT);
252 if (Subtarget.hasVInstructionsBF16Minimal() ||
253 Subtarget.hasVendorXAndesVBFHCvt())
254 for (
MVT VT : BF16VecVTs)
255 addRegClassForRVV(VT);
257 if (Subtarget.hasVInstructionsF32())
258 for (
MVT VT : F32VecVTs)
259 addRegClassForRVV(VT);
261 if (Subtarget.hasVInstructionsF64())
262 for (
MVT VT : F64VecVTs)
263 addRegClassForRVV(VT);
265 if (Subtarget.useRVVForFixedLengthVectors()) {
266 auto addRegClassForFixedVectors = [
this](
MVT VT) {
273 if (useRVVForFixedLengthVectorVT(VT))
274 addRegClassForFixedVectors(VT);
277 if (useRVVForFixedLengthVectorVT(VT))
278 addRegClassForFixedVectors(VT);
316 if (Subtarget.hasStdExtP()) {
317 if (Subtarget.is64Bit()) {
354 if (!(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
364 if (!Subtarget.hasVendorXTHeadBb() && !Subtarget.hasVendorXqcibm() &&
365 !Subtarget.hasVendorXAndesPerf())
370 if (!Subtarget.hasStdExtZbb() && !Subtarget.hasVendorXTHeadBb() &&
371 !Subtarget.hasVendorXqcibm() && !Subtarget.hasVendorXAndesPerf() &&
372 !(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit()))
375 if (Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit()) {
380 if (Subtarget.is64Bit()) {
388 }
else if (Subtarget.hasStdExtP()) {
393 if (!Subtarget.hasStdExtZmmul()) {
395 }
else if (Subtarget.is64Bit()) {
402 if (!Subtarget.hasStdExtM()) {
405 }
else if (Subtarget.is64Bit()) {
407 {MVT::i8, MVT::i16, MVT::i32},
Custom);
415 if (!Subtarget.hasStdExtP() || !Subtarget.hasStdExtZmmul() ||
422 if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) {
423 if (Subtarget.is64Bit())
425 }
else if (Subtarget.hasVendorXTHeadBb()) {
426 if (Subtarget.is64Bit())
429 }
else if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit()) {
435 if (Subtarget.hasStdExtP())
441 if (Subtarget.hasREVLike()) {
447 if (Subtarget.hasStdExtZbkb())
451 if (Subtarget.hasStdExtZbb() ||
452 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
457 if (Subtarget.hasCTZLike()) {
458 if (Subtarget.is64Bit())
464 if (!Subtarget.hasCPOPLike()) {
467 if (Subtarget.is64Bit())
474 if (Subtarget.hasCLZLike()) {
478 if (Subtarget.is64Bit() &&
479 (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtP()))
482 if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit())
487 if (Subtarget.hasStdExtP()) {
489 if (Subtarget.is64Bit())
493 if (Subtarget.hasStdExtP() ||
494 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
496 if (Subtarget.is64Bit())
498 }
else if (Subtarget.hasShortForwardBranchIALU()) {
501 }
else if (Subtarget.is64Bit()) {
505 if (!Subtarget.useMIPSCCMovInsn() && !Subtarget.hasVendorXTHeadCondMov())
508 if ((Subtarget.hasStdExtP() || Subtarget.hasVendorXqcia()) &&
509 !Subtarget.is64Bit()) {
512 }
else if (Subtarget.hasStdExtP() && Subtarget.is64Bit()) {
515 }
else if (!Subtarget.hasStdExtZbb() && Subtarget.is64Bit()) {
520 if ((Subtarget.hasStdExtP() || Subtarget.hasVendorXqcia()) &&
521 !Subtarget.is64Bit()) {
528 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit()) {
534 if (Subtarget.hasStdExtZbkc()) {
536 if (Subtarget.hasStdExtZbc())
538 }
else if (Subtarget.hasStdExtZvbc() && Subtarget.is64Bit()) {
545 static const unsigned FPLegalNodeTypes[] = {
561 static const unsigned FPOpToLibCall[] = {
ISD::FREM};
563 static const unsigned FPRndMode[] = {
567 static const unsigned ZfhminZfbfminPromoteOps[] = {
579 if (Subtarget.hasStdExtP()) {
580 static const MVT P32VecVTs[] = {MVT::v2i16, MVT::v4i8};
581 static const MVT P64VecVTs[] = {MVT::v2i32, MVT::v4i16, MVT::v8i8};
583 if (Subtarget.is64Bit()) {
590 {MVT::v2i16, MVT::v4i8},
Custom);
623 if (VT != MVT::v2i32)
625 if (VT.getVectorElementType() != MVT::i8) {
648 if (!Subtarget.is64Bit())
654 if (!Subtarget.is64Bit()) {
659 for (
MVT VT : P64VecVTs) {
682 {MVT::v4i16, MVT::v8i8},
Legal);
693 {MVT::v4i16, MVT::v8i8},
Custom);
700 {MVT::v4i16, MVT::v8i8},
Custom);
705 {MVT::v4i16, MVT::v2i32},
Legal);
721 {MVT::v4i16, MVT::v2i32},
Legal);
729 {MVT::v2i8, MVT::v4i8, MVT::v2i16, MVT::v4i16, MVT::v2i32},
Legal);
732 if (Subtarget.hasStdExtZfbfmin()) {
748 if (Subtarget.hasStdExtZfhminOrZhinxmin()) {
749 if (Subtarget.hasStdExtZfhmin())
751 if (Subtarget.hasStdExtZfhOrZhinx()) {
758 if (Subtarget.hasStdExtZfa())
774 if (!Subtarget.hasStdExtD()) {
794 Subtarget.hasStdExtZfh() && Subtarget.hasStdExtZfa() ?
Legal :
Promote);
810 if (Subtarget.is64Bit())
814 if (Subtarget.hasStdExtFOrZfinx()) {
815 if (Subtarget.hasStdExtF())
839 if (Subtarget.hasStdExtZfa()) {
848 if (Subtarget.hasStdExtFOrZfinx() && Subtarget.is64Bit())
851 if (Subtarget.hasStdExtDOrZdinx()) {
852 if (Subtarget.hasStdExtD())
856 if (!Subtarget.is64Bit())
859 if (Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
860 !Subtarget.is64Bit()) {
865 if (Subtarget.hasStdExtZfa()) {
871 if (Subtarget.is64Bit())
901 if (Subtarget.is64Bit()) {
906 }
else if (Subtarget.hasStdExtZfhminOrZhinxmin()) {
915 if (Subtarget.hasStdExtFOrZfinx()) {
941 if (Subtarget.is64Bit())
951 if (Subtarget.is64Bit()) {
958 if (Subtarget.is64Bit())
961 if (Subtarget.hasVendorXMIPSCBOP())
966 if (Subtarget.hasStdExtZalrsc()) {
968 if (Subtarget.hasStdExtZabha() && Subtarget.hasStdExtZacas())
972 }
else if (Subtarget.hasForcedAtomics()) {
987 if (Subtarget.hasVInstructions()) {
996 {MVT::i8, MVT::i16},
Custom);
997 if (Subtarget.is64Bit())
1007 static const unsigned IntegerVPOps[] = {
1008 ISD::VP_SDIV, ISD::VP_UDIV, ISD::VP_SREM,
1009 ISD::VP_UREM, ISD::VP_REDUCE_ADD, ISD::VP_REDUCE_AND,
1010 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR, ISD::VP_REDUCE_SMAX,
1011 ISD::VP_REDUCE_SMIN, ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN,
1013 ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE,
1014 ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_POISON};
1016 static const unsigned FloatingPointVPOps[] = {
1017 ISD::VP_REDUCE_FADD, ISD::VP_REDUCE_SEQ_FADD,
1018 ISD::VP_REDUCE_FMIN, ISD::VP_REDUCE_FMAX, ISD::VP_MERGE,
1019 ISD::VP_REDUCE_FMINIMUM, ISD::VP_REDUCE_FMAXIMUM};
1021 static const unsigned IntegerVecReduceOps[] = {
1026 static const unsigned FloatingPointVecReduceOps[] = {
1030 static const unsigned FloatingPointLibCallOps[] = {
1034 if (!Subtarget.is64Bit()) {
1043 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR,
1044 ISD::VP_REDUCE_SMAX, ISD::VP_REDUCE_SMIN,
1045 ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN},
1049 for (
MVT VT : BoolVecVTs) {
1070 ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_POISON},
1078 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1103 {2, 3, 4, 5, 6, 7, 8}, VT,
Custom);
1115 for (
MVT VT : IntVecVTs) {
1126 if (VT.getVectorElementType() == MVT::i64 && !Subtarget.hasStdExtV())
1132 if (Subtarget.hasStdExtZvabd()) {
1181 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1182 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1203 {2, 3, 4, 5, 6, 7, 8}, VT,
Custom);
1208 if (Subtarget.hasStdExtZvkb()) {
1215 if (Subtarget.hasStdExtZvbb()) {
1231 if (VT.getVectorElementType() == MVT::i64) {
1232 if (Subtarget.hasStdExtZvbc())
1235 if (Subtarget.hasStdExtZvbc32e()) {
1237 }
else if (Subtarget.hasStdExtZvbc()) {
1253 for (
MVT VT : VecTupleVTs) {
1274 static const unsigned ZvfhminZvfbfminPromoteOps[] = {
1310 static const unsigned ZvfbfaPromoteOps[] = {
ISD::FDIV,
1328 static const unsigned ZvfhminZvfbfminPromoteVPOps[] = {
1329 ISD::VP_REDUCE_FMIN,
1330 ISD::VP_REDUCE_FMAX,
1331 ISD::VP_REDUCE_FMINIMUM,
1332 ISD::VP_REDUCE_FMAXIMUM};
1335 const auto SetCommonVFPActions = [&](
MVT VT) {
1375 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1376 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1389 {2, 3, 4, 5, 6, 7, 8}, VT,
Custom);
1415 const auto SetCommonVFPExtLoadTruncStoreActions =
1417 for (
auto SmallVT : SmallerVTs) {
1425 const auto SetCommonPromoteToF32Actions = [&](
MVT VT) {
1441 {2, 3, 4, 5, 6, 7, 8}, VT,
Custom);
1452 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1453 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1480 const auto SetZvfbfaActions = [&](
MVT VT) {
1497 {2, 3, 4, 5, 6, 7, 8}, VT,
Custom);
1515 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1516 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1537 if (Subtarget.hasVInstructionsF16()) {
1538 for (
MVT VT : F16VecVTs) {
1541 SetCommonVFPActions(VT);
1543 }
else if (Subtarget.hasVInstructionsF16Minimal()) {
1544 for (
MVT VT : F16VecVTs) {
1547 SetCommonPromoteToF32Actions(VT);
1551 if (Subtarget.hasVInstructionsBF16()) {
1552 for (
MVT VT : BF16VecVTs) {
1555 SetZvfbfaActions(VT);
1557 }
else if (Subtarget.hasVInstructionsBF16Minimal()) {
1558 for (
MVT VT : BF16VecVTs) {
1561 SetCommonPromoteToF32Actions(VT);
1565 if (Subtarget.hasStdExtZvfofp8min()) {
1566 for (
MVT VT : BF16VecVTs) {
1573 if (Subtarget.hasVInstructionsF32()) {
1574 for (
MVT VT : F32VecVTs) {
1577 SetCommonVFPActions(VT);
1578 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1579 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1583 if (Subtarget.hasVInstructionsF64()) {
1584 for (
MVT VT : F64VecVTs) {
1587 SetCommonVFPActions(VT);
1588 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1589 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1590 SetCommonVFPExtLoadTruncStoreActions(VT, F32VecVTs);
1594 if (Subtarget.useRVVForFixedLengthVectors()) {
1596 if (!useRVVForFixedLengthVectorVT(VT))
1622 {2, 3, 4, 5, 6, 7, 8}, VT,
Custom);
1646 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1697 ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1698 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1736 if (Subtarget.hasStdExtZvkb())
1739 if (Subtarget.hasStdExtZvbb()) {
1754 if (Subtarget.hasStdExtZvbc())
1757 if (Subtarget.hasStdExtZvbc32e()) {
1759 }
else if (Subtarget.hasStdExtZvbc()) {
1763 if (I64VecVT.
isValid() && useRVVForFixedLengthVectorVT(I64VecVT))
1781 if (!useRVVForFixedLengthVectorVT(VT))
1802 {2, 3, 4, 5, 6, 7, 8}, VT,
Custom);
1808 ISD::VP_SCATTER, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1809 ISD::EXPERIMENTAL_VP_STRIDED_STORE},
1820 !Subtarget.hasVInstructionsF16()) {
1826 if (Subtarget.hasStdExtZfhmin()) {
1857 if (Subtarget.hasStdExtZvfofp8min())
1859 if (Subtarget.hasStdExtZfbfmin()) {
1866 if (Subtarget.hasVInstructionsBF16()) {
1887 if (Subtarget.hasVInstructionsBF16())
1931 if (Subtarget.is64Bit())
1933 if (Subtarget.hasStdExtZfhminOrZhinxmin())
1935 if (Subtarget.hasStdExtZfbfmin())
1937 if (Subtarget.hasStdExtFOrZfinx())
1939 if (Subtarget.hasStdExtDOrZdinx())
1944 if (Subtarget.hasStdExtZaamo())
1947 if (Subtarget.hasForcedAtomics()) {
1957 if (Subtarget.hasVendorXTHeadMemIdx()) {
1966 if (Subtarget.is64Bit()) {
1973 if (Subtarget.hasVendorXCVmem() && !Subtarget.is64Bit()) {
1984 if (Subtarget.hasStdExtZvdot4a8i() && Subtarget.getELen() >= 64) {
2001 if (Subtarget.useRVVForFixedLengthVectors()) {
2003 if ((VT.getVectorElementType() != MVT::i32 &&
2004 VT.getVectorElementType() != MVT::i64) ||
2005 !useRVVForFixedLengthVectorVT(VT))
2008 unsigned Scale = VT.getVectorElementType() == MVT::i64 ? 8 : 4;
2016 if (Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh()) {
2022 const Align FunctionAlignment(Subtarget.hasStdExtZca() ? 2 : 4);
2034 if (Subtarget.hasStdExtFOrZfinx())
2038 if (Subtarget.hasVInstructions())
2040 if (Subtarget.hasVInstructions() || Subtarget.hasStdExtP())
2043 if ((Subtarget.hasStdExtZbs() && Subtarget.is64Bit()) ||
2044 Subtarget.hasVInstructions() || Subtarget.hasStdExtP())
2047 if (Subtarget.hasStdExtZbkb())
2050 if (Subtarget.hasStdExtFOrZfinx())
2053 if (Subtarget.hasVInstructions())
2068 ISD::EXPERIMENTAL_VP_REVERSE,
2083 if (Subtarget.hasStdExtZvzip())
2086 if (Subtarget.hasVendorXTHeadMemPair())
2088 if (Subtarget.useRVVForFixedLengthVectors() || Subtarget.hasStdExtP())
2114 Subtarget.getMaxStoresPerMemmove(
true);
2123 if (Subtarget.is64Bit() && Subtarget.hasStdExtP())
2124 if (VT == MVT::v2i16 || VT == MVT::v4i8)
2135 if (Subtarget.hasVInstructions() &&
2146 if (
F->hasOptSize())
2153 int BaseCost = Subtarget.getMispredictionPenalty() / 4;
2164bool RISCVTargetLowering::isProfitableToFoldVScaleAdd(
SDValue N)
const {
2165 return N.hasOneUse();
2169bool RISCVTargetLowering::shouldExpandGetVectorLength(
EVT TripCountVT,
2171 bool IsScalable)
const {
2172 if (!Subtarget.hasVInstructions())
2178 if (TripCountVT != MVT::i32 && TripCountVT != Subtarget.getXLenVT())
2199 auto &
DL =
I.getDataLayout();
2201 auto SetRVVLoadStoreInfo = [&](
unsigned PtrOp,
bool IsStore,
2202 bool IsUnitStrided,
bool UsePtrVal =
false) {
2207 Info.ptrVal =
I.getArgOperand(PtrOp);
2209 Info.fallbackAddressSpace =
2210 I.getArgOperand(PtrOp)->getType()->getPointerAddressSpace();
2214 MemTy =
I.getArgOperand(0)->getType();
2217 MemTy =
I.getType();
2232 Info.align =
DL.getABITypeAlign(MemTy);
2242 if (
I.hasMetadata(LLVMContext::MD_nontemporal))
2249 case Intrinsic::riscv_masked_atomicrmw_xchg:
2250 case Intrinsic::riscv_masked_atomicrmw_add:
2251 case Intrinsic::riscv_masked_atomicrmw_sub:
2252 case Intrinsic::riscv_masked_atomicrmw_nand:
2253 case Intrinsic::riscv_masked_atomicrmw_max:
2254 case Intrinsic::riscv_masked_atomicrmw_min:
2255 case Intrinsic::riscv_masked_atomicrmw_umax:
2256 case Intrinsic::riscv_masked_atomicrmw_umin:
2257 case Intrinsic::riscv_masked_cmpxchg:
2264 Info.memVT = MVT::i32;
2265 Info.ptrVal =
I.getArgOperand(0);
2267 Info.align =
Align(4);
2272 case Intrinsic::riscv_seg2_load_mask:
2273 case Intrinsic::riscv_seg3_load_mask:
2274 case Intrinsic::riscv_seg4_load_mask:
2275 case Intrinsic::riscv_seg5_load_mask:
2276 case Intrinsic::riscv_seg6_load_mask:
2277 case Intrinsic::riscv_seg7_load_mask:
2278 case Intrinsic::riscv_seg8_load_mask:
2279 case Intrinsic::riscv_sseg2_load_mask:
2280 case Intrinsic::riscv_sseg3_load_mask:
2281 case Intrinsic::riscv_sseg4_load_mask:
2282 case Intrinsic::riscv_sseg5_load_mask:
2283 case Intrinsic::riscv_sseg6_load_mask:
2284 case Intrinsic::riscv_sseg7_load_mask:
2285 case Intrinsic::riscv_sseg8_load_mask:
2286 SetRVVLoadStoreInfo( 0,
false,
2289 case Intrinsic::riscv_seg2_store_mask:
2290 case Intrinsic::riscv_seg3_store_mask:
2291 case Intrinsic::riscv_seg4_store_mask:
2292 case Intrinsic::riscv_seg5_store_mask:
2293 case Intrinsic::riscv_seg6_store_mask:
2294 case Intrinsic::riscv_seg7_store_mask:
2295 case Intrinsic::riscv_seg8_store_mask:
2297 SetRVVLoadStoreInfo(
I.arg_size() - 3,
2301 case Intrinsic::riscv_sseg2_store_mask:
2302 case Intrinsic::riscv_sseg3_store_mask:
2303 case Intrinsic::riscv_sseg4_store_mask:
2304 case Intrinsic::riscv_sseg5_store_mask:
2305 case Intrinsic::riscv_sseg6_store_mask:
2306 case Intrinsic::riscv_sseg7_store_mask:
2307 case Intrinsic::riscv_sseg8_store_mask:
2309 SetRVVLoadStoreInfo(
I.arg_size() - 4,
2313 case Intrinsic::riscv_vlm:
2314 SetRVVLoadStoreInfo( 0,
2319 case Intrinsic::riscv_vle:
2320 case Intrinsic::riscv_vle_mask:
2321 case Intrinsic::riscv_vleff:
2322 case Intrinsic::riscv_vleff_mask:
2323 SetRVVLoadStoreInfo( 1,
2328 case Intrinsic::riscv_vsm:
2329 case Intrinsic::riscv_vse:
2330 case Intrinsic::riscv_vse_mask:
2331 SetRVVLoadStoreInfo( 1,
2336 case Intrinsic::riscv_vlse:
2337 case Intrinsic::riscv_vlse_mask:
2338 case Intrinsic::riscv_vloxei:
2339 case Intrinsic::riscv_vloxei_mask:
2340 case Intrinsic::riscv_vluxei:
2341 case Intrinsic::riscv_vluxei_mask:
2342 SetRVVLoadStoreInfo( 1,
2346 case Intrinsic::riscv_vsse:
2347 case Intrinsic::riscv_vsse_mask:
2348 case Intrinsic::riscv_vsoxei:
2349 case Intrinsic::riscv_vsoxei_mask:
2350 case Intrinsic::riscv_vsuxei:
2351 case Intrinsic::riscv_vsuxei_mask:
2352 SetRVVLoadStoreInfo( 1,
2356 case Intrinsic::riscv_vlseg2:
2357 case Intrinsic::riscv_vlseg3:
2358 case Intrinsic::riscv_vlseg4:
2359 case Intrinsic::riscv_vlseg5:
2360 case Intrinsic::riscv_vlseg6:
2361 case Intrinsic::riscv_vlseg7:
2362 case Intrinsic::riscv_vlseg8:
2363 case Intrinsic::riscv_vlseg2ff:
2364 case Intrinsic::riscv_vlseg3ff:
2365 case Intrinsic::riscv_vlseg4ff:
2366 case Intrinsic::riscv_vlseg5ff:
2367 case Intrinsic::riscv_vlseg6ff:
2368 case Intrinsic::riscv_vlseg7ff:
2369 case Intrinsic::riscv_vlseg8ff:
2370 SetRVVLoadStoreInfo(
I.arg_size() - 3,
2374 case Intrinsic::riscv_vlseg2_mask:
2375 case Intrinsic::riscv_vlseg3_mask:
2376 case Intrinsic::riscv_vlseg4_mask:
2377 case Intrinsic::riscv_vlseg5_mask:
2378 case Intrinsic::riscv_vlseg6_mask:
2379 case Intrinsic::riscv_vlseg7_mask:
2380 case Intrinsic::riscv_vlseg8_mask:
2381 case Intrinsic::riscv_vlseg2ff_mask:
2382 case Intrinsic::riscv_vlseg3ff_mask:
2383 case Intrinsic::riscv_vlseg4ff_mask:
2384 case Intrinsic::riscv_vlseg5ff_mask:
2385 case Intrinsic::riscv_vlseg6ff_mask:
2386 case Intrinsic::riscv_vlseg7ff_mask:
2387 case Intrinsic::riscv_vlseg8ff_mask:
2388 SetRVVLoadStoreInfo(
I.arg_size() - 5,
2392 case Intrinsic::riscv_vlsseg2:
2393 case Intrinsic::riscv_vlsseg3:
2394 case Intrinsic::riscv_vlsseg4:
2395 case Intrinsic::riscv_vlsseg5:
2396 case Intrinsic::riscv_vlsseg6:
2397 case Intrinsic::riscv_vlsseg7:
2398 case Intrinsic::riscv_vlsseg8:
2399 case Intrinsic::riscv_vloxseg2:
2400 case Intrinsic::riscv_vloxseg3:
2401 case Intrinsic::riscv_vloxseg4:
2402 case Intrinsic::riscv_vloxseg5:
2403 case Intrinsic::riscv_vloxseg6:
2404 case Intrinsic::riscv_vloxseg7:
2405 case Intrinsic::riscv_vloxseg8:
2406 case Intrinsic::riscv_vluxseg2:
2407 case Intrinsic::riscv_vluxseg3:
2408 case Intrinsic::riscv_vluxseg4:
2409 case Intrinsic::riscv_vluxseg5:
2410 case Intrinsic::riscv_vluxseg6:
2411 case Intrinsic::riscv_vluxseg7:
2412 case Intrinsic::riscv_vluxseg8:
2413 SetRVVLoadStoreInfo(
I.arg_size() - 4,
2417 case Intrinsic::riscv_vlsseg2_mask:
2418 case Intrinsic::riscv_vlsseg3_mask:
2419 case Intrinsic::riscv_vlsseg4_mask:
2420 case Intrinsic::riscv_vlsseg5_mask:
2421 case Intrinsic::riscv_vlsseg6_mask:
2422 case Intrinsic::riscv_vlsseg7_mask:
2423 case Intrinsic::riscv_vlsseg8_mask:
2424 case Intrinsic::riscv_vloxseg2_mask:
2425 case Intrinsic::riscv_vloxseg3_mask:
2426 case Intrinsic::riscv_vloxseg4_mask:
2427 case Intrinsic::riscv_vloxseg5_mask:
2428 case Intrinsic::riscv_vloxseg6_mask:
2429 case Intrinsic::riscv_vloxseg7_mask:
2430 case Intrinsic::riscv_vloxseg8_mask:
2431 case Intrinsic::riscv_vluxseg2_mask:
2432 case Intrinsic::riscv_vluxseg3_mask:
2433 case Intrinsic::riscv_vluxseg4_mask:
2434 case Intrinsic::riscv_vluxseg5_mask:
2435 case Intrinsic::riscv_vluxseg6_mask:
2436 case Intrinsic::riscv_vluxseg7_mask:
2437 case Intrinsic::riscv_vluxseg8_mask:
2438 SetRVVLoadStoreInfo(
I.arg_size() - 6,
2442 case Intrinsic::riscv_vsseg2:
2443 case Intrinsic::riscv_vsseg3:
2444 case Intrinsic::riscv_vsseg4:
2445 case Intrinsic::riscv_vsseg5:
2446 case Intrinsic::riscv_vsseg6:
2447 case Intrinsic::riscv_vsseg7:
2448 case Intrinsic::riscv_vsseg8:
2449 SetRVVLoadStoreInfo(
I.arg_size() - 3,
2453 case Intrinsic::riscv_vsseg2_mask:
2454 case Intrinsic::riscv_vsseg3_mask:
2455 case Intrinsic::riscv_vsseg4_mask:
2456 case Intrinsic::riscv_vsseg5_mask:
2457 case Intrinsic::riscv_vsseg6_mask:
2458 case Intrinsic::riscv_vsseg7_mask:
2459 case Intrinsic::riscv_vsseg8_mask:
2460 SetRVVLoadStoreInfo(
I.arg_size() - 4,
2464 case Intrinsic::riscv_vssseg2:
2465 case Intrinsic::riscv_vssseg3:
2466 case Intrinsic::riscv_vssseg4:
2467 case Intrinsic::riscv_vssseg5:
2468 case Intrinsic::riscv_vssseg6:
2469 case Intrinsic::riscv_vssseg7:
2470 case Intrinsic::riscv_vssseg8:
2471 case Intrinsic::riscv_vsoxseg2:
2472 case Intrinsic::riscv_vsoxseg3:
2473 case Intrinsic::riscv_vsoxseg4:
2474 case Intrinsic::riscv_vsoxseg5:
2475 case Intrinsic::riscv_vsoxseg6:
2476 case Intrinsic::riscv_vsoxseg7:
2477 case Intrinsic::riscv_vsoxseg8:
2478 case Intrinsic::riscv_vsuxseg2:
2479 case Intrinsic::riscv_vsuxseg3:
2480 case Intrinsic::riscv_vsuxseg4:
2481 case Intrinsic::riscv_vsuxseg5:
2482 case Intrinsic::riscv_vsuxseg6:
2483 case Intrinsic::riscv_vsuxseg7:
2484 case Intrinsic::riscv_vsuxseg8:
2485 SetRVVLoadStoreInfo(
I.arg_size() - 4,
2489 case Intrinsic::riscv_vssseg2_mask:
2490 case Intrinsic::riscv_vssseg3_mask:
2491 case Intrinsic::riscv_vssseg4_mask:
2492 case Intrinsic::riscv_vssseg5_mask:
2493 case Intrinsic::riscv_vssseg6_mask:
2494 case Intrinsic::riscv_vssseg7_mask:
2495 case Intrinsic::riscv_vssseg8_mask:
2496 case Intrinsic::riscv_vsoxseg2_mask:
2497 case Intrinsic::riscv_vsoxseg3_mask:
2498 case Intrinsic::riscv_vsoxseg4_mask:
2499 case Intrinsic::riscv_vsoxseg5_mask:
2500 case Intrinsic::riscv_vsoxseg6_mask:
2501 case Intrinsic::riscv_vsoxseg7_mask:
2502 case Intrinsic::riscv_vsoxseg8_mask:
2503 case Intrinsic::riscv_vsuxseg2_mask:
2504 case Intrinsic::riscv_vsuxseg3_mask:
2505 case Intrinsic::riscv_vsuxseg4_mask:
2506 case Intrinsic::riscv_vsuxseg5_mask:
2507 case Intrinsic::riscv_vsuxseg6_mask:
2508 case Intrinsic::riscv_vsuxseg7_mask:
2509 case Intrinsic::riscv_vsuxseg8_mask:
2510 SetRVVLoadStoreInfo(
I.arg_size() - 5,
2514 case Intrinsic::riscv_sf_vlte8:
2515 case Intrinsic::riscv_sf_vlte16:
2516 case Intrinsic::riscv_sf_vlte32:
2517 case Intrinsic::riscv_sf_vlte64:
2519 Info.ptrVal =
I.getArgOperand(1);
2521 case Intrinsic::riscv_sf_vlte8:
2522 Info.memVT = MVT::i8;
2523 Info.align =
Align(1);
2525 case Intrinsic::riscv_sf_vlte16:
2526 Info.memVT = MVT::i16;
2527 Info.align =
Align(2);
2529 case Intrinsic::riscv_sf_vlte32:
2530 Info.memVT = MVT::i32;
2531 Info.align =
Align(4);
2533 case Intrinsic::riscv_sf_vlte64:
2534 Info.memVT = MVT::i64;
2535 Info.align =
Align(8);
2542 case Intrinsic::riscv_sf_vste8:
2543 case Intrinsic::riscv_sf_vste16:
2544 case Intrinsic::riscv_sf_vste32:
2545 case Intrinsic::riscv_sf_vste64:
2547 Info.ptrVal =
I.getArgOperand(1);
2549 case Intrinsic::riscv_sf_vste8:
2550 Info.memVT = MVT::i8;
2551 Info.align =
Align(1);
2553 case Intrinsic::riscv_sf_vste16:
2554 Info.memVT = MVT::i16;
2555 Info.align =
Align(2);
2557 case Intrinsic::riscv_sf_vste32:
2558 Info.memVT = MVT::i32;
2559 Info.align =
Align(4);
2561 case Intrinsic::riscv_sf_vste64:
2562 Info.memVT = MVT::i64;
2563 Info.align =
Align(8);
2591 if (Subtarget.hasVendorXqcilo()) {
2620 if (Subtarget.hasVendorXqcilia())
2631 if (Subtarget.is64Bit() || !SrcTy->isIntegerTy() || !DstTy->
isIntegerTy())
2633 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
2635 return (SrcBits == 64 && DestBits == 32);
2646 return (SrcBits == 64 && DestBits == 32);
2652 if (Subtarget.hasVInstructions() &&
2657 if (SrcBits == DestBits * 2) {
2669 EVT MemVT = LD->getMemoryVT();
2670 if ((MemVT == MVT::i8 || MemVT == MVT::i16) &&
2680 return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
2688 return Subtarget.hasCTZLike();
2692 return Subtarget.hasCLZLike();
2703 if (!Subtarget.hasBEXTILike())
2708 return !Mask->getValue().isSignedIntN(12) && Mask->getValue().isPowerOf2();
2712 EVT VT =
Y.getValueType();
2717 return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
2722 EVT VT =
Y.getValueType();
2729 return Subtarget.hasVInstructions();
2731 return Subtarget.hasStdExtZvkb();
2736 if (Subtarget.hasStdExtZbs())
2737 return X.getValueType().isScalarInteger();
2740 if (Subtarget.hasVendorXTHeadBs())
2741 return C !=
nullptr;
2743 return C &&
C->getAPIntValue().ule(10);
2747 unsigned BinOpcode,
EVT VT,
unsigned SelectOpcode,
SDValue X,
2753 if (!VT.
isVector() || !Subtarget.hasVInstructions())
2764 assert(Ty->isIntegerTy());
2766 unsigned BitSize = Ty->getIntegerBitWidth();
2767 if (BitSize > Subtarget.getXLen())
2771 int64_t Val =
Imm.getSExtValue();
2779 if (!Subtarget.enableUnalignedScalarMem())
2789 return Seq.
size() <= Subtarget.getMaxBuildIntsCost();
2795 unsigned OldShiftOpcode,
unsigned NewShiftOpcode,
2850 if (!Subtarget.hasStdExtZfa())
2853 bool IsSupportedVT =
false;
2854 if (VT == MVT::f16) {
2855 IsSupportedVT = Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZvfh();
2856 }
else if (VT == MVT::f32) {
2857 IsSupportedVT =
true;
2858 }
else if (VT == MVT::f64) {
2859 assert(Subtarget.hasStdExtD() &&
"Expect D extension");
2860 IsSupportedVT =
true;
2870 bool ForCodeSize)
const {
2871 bool IsLegalVT =
false;
2873 IsLegalVT = Subtarget.hasStdExtZfhminOrZhinxmin();
2874 else if (VT == MVT::f32)
2875 IsLegalVT = Subtarget.hasStdExtFOrZfinx();
2876 else if (VT == MVT::f64)
2877 IsLegalVT = Subtarget.hasStdExtDOrZdinx();
2878 else if (VT == MVT::bf16)
2879 IsLegalVT = Subtarget.hasStdExtZfbfmin();
2895 return Imm.isZero();
2899 if (
Imm.isNegZero())
2904 const int FmvCost = Subtarget.hasStdExtZfinx() ? 0 : 1;
2907 Subtarget.getXLen(), Subtarget);
2914 unsigned Index)
const {
2915 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
2916 (ResVT == MVT::v4i8 || ResVT == MVT::v2i16)) {
2922 if (!Subtarget.hasVInstructions())
2940 if (EltVT == MVT::i1)
2946 unsigned MinVLen = Subtarget.getRealMinVLen();
2953 if (Index + ResElts <= MinVLMAX && Index < 31)
2962 if ((ResElts * 2) == SrcElts && Index == ResElts)
2972 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2973 !Subtarget.hasStdExtZfhminOrZhinxmin())
2981 std::optional<MVT> RegisterVT)
const {
2983 if (VT == (Subtarget.is64Bit() ? MVT::i128 : MVT::i64) && RegisterVT &&
2984 *RegisterVT == MVT::Untyped)
2995 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2996 !Subtarget.hasStdExtZfhminOrZhinxmin())
3015 !Subtarget.hasVendorXAndesPerf()) {
3021 ShAmt =
LHS.getValueSizeInBits() - 1 -
Log2_64(Mask);
3035 int64_t
C = RHSC->getSExtValue();
3045 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
3071 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
3106 if (VT.
SimpleTy >= MVT::riscv_nxv1i8x2 &&
3107 VT.
SimpleTy <= MVT::riscv_nxv1i8x8)
3109 if (VT.
SimpleTy >= MVT::riscv_nxv2i8x2 &&
3110 VT.
SimpleTy <= MVT::riscv_nxv2i8x8)
3112 if (VT.
SimpleTy >= MVT::riscv_nxv4i8x2 &&
3113 VT.
SimpleTy <= MVT::riscv_nxv4i8x8)
3115 if (VT.
SimpleTy >= MVT::riscv_nxv8i8x2 &&
3116 VT.
SimpleTy <= MVT::riscv_nxv8i8x8)
3118 if (VT.
SimpleTy >= MVT::riscv_nxv16i8x2 &&
3119 VT.
SimpleTy <= MVT::riscv_nxv16i8x4)
3121 if (VT.
SimpleTy == MVT::riscv_nxv32i8x2)
3131 switch (KnownSize) {
3159 return RISCV::VRRegClassID;
3161 return RISCV::VRM2RegClassID;
3163 return RISCV::VRM4RegClassID;
3165 return RISCV::VRM8RegClassID;
3173 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
3174 "Unexpected subreg numbering");
3175 return RISCV::sub_vrm1_0 + Index;
3178 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
3179 "Unexpected subreg numbering");
3180 return RISCV::sub_vrm2_0 + Index;
3183 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
3184 "Unexpected subreg numbering");
3185 return RISCV::sub_vrm4_0 + Index;
3193 unsigned RegsPerField =
3196 switch (RegsPerField) {
3199 return RISCV::VRN2M1RegClassID;
3201 return RISCV::VRN3M1RegClassID;
3203 return RISCV::VRN4M1RegClassID;
3205 return RISCV::VRN5M1RegClassID;
3207 return RISCV::VRN6M1RegClassID;
3209 return RISCV::VRN7M1RegClassID;
3211 return RISCV::VRN8M1RegClassID;
3215 return RISCV::VRN2M2RegClassID;
3217 return RISCV::VRN3M2RegClassID;
3219 return RISCV::VRN4M2RegClassID;
3223 return RISCV::VRN2M4RegClassID;
3231 return RISCV::VRRegClassID;
3240std::pair<unsigned, unsigned>
3242 MVT VecVT,
MVT SubVecVT,
unsigned InsertExtractIdx,
3244 static_assert((RISCV::VRM8RegClassID > RISCV::VRM4RegClassID &&
3245 RISCV::VRM4RegClassID > RISCV::VRM2RegClassID &&
3246 RISCV::VRM2RegClassID > RISCV::VRRegClassID),
3247 "Register classes not ordered");
3254 if (VecRegClassID == SubRegClassID)
3255 return {RISCV::NoSubRegister, 0};
3258 "Only allow scalable vector subvector.");
3260 "Invalid vector tuple insert/extract for vector and subvector with "
3271 unsigned SubRegIdx = RISCV::NoSubRegister;
3272 for (
const unsigned RCID :
3273 {RISCV::VRM4RegClassID, RISCV::VRM2RegClassID, RISCV::VRRegClassID})
3274 if (VecRegClassID > RCID && SubRegClassID <= RCID) {
3278 SubRegIdx =
TRI->composeSubRegIndices(SubRegIdx,
3283 return {SubRegIdx, InsertExtractIdx};
3288bool RISCVTargetLowering::mergeStoresAfterLegalization(
EVT VT)
const {
3289 if (Subtarget.hasStdExtP() && !Subtarget.
is64Bit() &&
3290 (VT == MVT::i32 || VT == MVT::v2i16 || VT == MVT::v4i8))
3302 return Subtarget.is64Bit() ? Subtarget.hasVInstructionsI64() :
true;
3306 return Subtarget.hasVInstructions();
3308 return Subtarget.hasVInstructionsI64();
3310 return Subtarget.hasVInstructionsF16Minimal();
3312 return Subtarget.hasVInstructionsBF16Minimal();
3314 return Subtarget.hasVInstructionsF32();
3316 return Subtarget.hasVInstructionsF64();
3330 "Unexpected opcode");
3332 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
3334 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
3337 return Op.getOperand(
II->VLOperand + 1 + HasChain);
3411bool RISCVTargetLowering::useRVVForFixedLengthVectorVT(
MVT VT)
const {
3412 return ::useRVVForFixedLengthVectorVT(VT, Subtarget);
3422 "Expected legal fixed length vector!");
3425 unsigned MaxELen = Subtarget.
getELen();
3453 return ::getContainerForFixedLengthVector(VT,
getSubtarget());
3460 "Expected to convert into a scalable vector!");
3461 assert(V.getValueType().isFixedLengthVector() &&
3462 "Expected a fixed length vector operand!");
3471 "Expected to convert into a fixed length vector!");
3472 assert(V.getValueType().isScalableVector() &&
3473 "Expected a scalable vector operand!");
3492 return DAG.
getNode(RISCVISD::VMSET_VL,
DL, MaskVT, VL);
3495static std::pair<SDValue, SDValue>
3504static std::pair<SDValue, SDValue>
3517static std::pair<SDValue, SDValue>
3534std::pair<unsigned, unsigned>
3542 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
3546 unsigned VectorBitsMin = Subtarget.getRealMinVLen();
3550 return std::make_pair(MinVLMAX, MaxVLMAX);
3562 EVT VT,
unsigned DefinedValues)
const {
3571 unsigned DLenFactor = Subtarget.getDLenFactor();
3576 std::tie(LMul, Fractional) =
3579 Cost = LMul <= DLenFactor ? (DLenFactor / LMul) : 1;
3581 Cost = (LMul * DLenFactor);
3595 bool Log2CostModel =
3597 if (Log2CostModel && LMULCost.isValid()) {
3598 unsigned Log =
Log2_64(LMULCost.getValue());
3600 return LMULCost * Log;
3602 return LMULCost * LMULCost;
3633 Op.getValueType() == MVT::bf16) {
3634 bool IsStrict =
Op->isStrictFPOpcode();
3639 {Op.getOperand(0), Op.getOperand(1)});
3641 {
Op.getValueType(), MVT::Other},
3647 DAG.
getNode(
Op.getOpcode(),
DL, MVT::f32,
Op.getOperand(0)),
3662 MVT DstVT =
Op.getSimpleValueType();
3671 Src.getValueType() == MVT::bf16) {
3677 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
3678 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
3679 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
3686 Opc,
DL, DstVT, Src,
3689 if (
Opc == RISCVISD::FCVT_WU_RV64)
3700 MVT SrcVT = Src.getSimpleValueType();
3706 if (SatVT != DstEltVT)
3709 MVT DstContainerVT = DstVT;
3710 MVT SrcContainerVT = SrcVT;
3716 "Expected same element count");
3725 {Src, Src, DAG.getCondCode(ISD::SETNE),
3726 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
3730 if (DstEltSize > (2 * SrcEltSize)) {
3733 Src = DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, InterVT, Src, Mask, VL);
3736 MVT CvtContainerVT = DstContainerVT;
3737 MVT CvtEltVT = DstEltVT;
3738 if (SrcEltSize > (2 * DstEltSize)) {
3744 IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
3747 while (CvtContainerVT != DstContainerVT) {
3751 unsigned ClipOpc = IsSigned ? RISCVISD::TRUNCATE_VECTOR_VL_SSAT
3752 : RISCVISD::TRUNCATE_VECTOR_VL_USAT;
3753 Res = DAG.
getNode(ClipOpc,
DL, CvtContainerVT, Res, Mask, VL);
3757 RISCVISD::VMV_V_X_VL,
DL, DstContainerVT, DAG.
getUNDEF(DstContainerVT),
3759 Res = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, DstContainerVT, IsNan, SplatZero,
3760 Res, DAG.
getUNDEF(DstContainerVT), VL);
3770 bool IsStrict =
Op->isStrictFPOpcode();
3771 SDValue SrcVal =
Op.getOperand(IsStrict ? 1 : 0);
3781 {
Op.getOperand(0), SrcVal});
3782 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
3783 {Ext.getValue(1), Ext.getValue(0)});
3832 MVT VT =
Op.getSimpleValueType();
3842 MVT ContainerVT = VT;
3851 SDValue Abs = DAG.
getNode(RISCVISD::FABS_VL,
DL, ContainerVT, Src, Mask, VL);
3864 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3869 DAG.
getNode(RISCVISD::SETCC_VL,
DL, SetccVT,
3878 switch (
Op.getOpcode()) {
3888 Truncated = DAG.
getNode(RISCVISD::VFCVT_RM_X_F_VL,
DL, IntVT, Src, Mask,
3893 Truncated = DAG.
getNode(RISCVISD::VFCVT_RTZ_X_F_VL,
DL, IntVT, Src,
3897 Truncated = DAG.
getNode(RISCVISD::VFROUND_NOEXCEPT_VL,
DL, ContainerVT, Src,
3903 if (Truncated.
getOpcode() != RISCVISD::VFROUND_NOEXCEPT_VL)
3904 Truncated = DAG.
getNode(RISCVISD::SINT_TO_FP_VL,
DL, ContainerVT, Truncated,
3908 Truncated = DAG.
getNode(RISCVISD::FCOPYSIGN_VL,
DL, ContainerVT, Truncated,
3909 Src, Src, Mask, VL);
3924 MVT VT =
Op.getSimpleValueType();
3928 MVT ContainerVT = VT;
3940 MVT MaskVT = Mask.getSimpleValueType();
3943 {Chain, Src, Src, DAG.getCondCode(ISD::SETUNE),
3944 DAG.getUNDEF(MaskVT), Mask, VL});
3946 Src = DAG.
getNode(RISCVISD::STRICT_FADD_VL,
DL,
3948 {Chain, Src, Src, Src, Unorder, VL});
3952 SDValue Abs = DAG.
getNode(RISCVISD::FABS_VL,
DL, ContainerVT, Src, Mask, VL);
3965 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3969 RISCVISD::SETCC_VL,
DL, MaskVT,
3977 switch (
Op.getOpcode()) {
3987 RISCVISD::STRICT_VFCVT_RM_X_F_VL,
DL, DAG.
getVTList(IntVT, MVT::Other),
3988 {Chain, Src, Mask, DAG.getTargetConstant(FRM, DL, XLenVT), VL});
3993 DAG.
getNode(RISCVISD::STRICT_VFCVT_RTZ_X_F_VL,
DL,
3994 DAG.
getVTList(IntVT, MVT::Other), Chain, Src, Mask, VL);
3997 Truncated = DAG.
getNode(RISCVISD::STRICT_VFROUND_NOEXCEPT_VL,
DL,
3998 DAG.
getVTList(ContainerVT, MVT::Other), Chain, Src,
4006 Truncated = DAG.
getNode(RISCVISD::STRICT_SINT_TO_FP_VL,
DL,
4007 DAG.
getVTList(ContainerVT, MVT::Other), Chain,
4008 Truncated, Mask, VL);
4013 Truncated = DAG.
getNode(RISCVISD::FCOPYSIGN_VL,
DL, ContainerVT, Truncated,
4014 Src, Src, Mask, VL);
4024 MVT VT =
Op.getSimpleValueType();
4045 return DAG.
getNode(RISCVISD::FROUND,
DL, VT, Src, MaxValNode,
4053 MVT DstVT =
Op.getSimpleValueType();
4055 MVT SrcVT = Src.getSimpleValueType();
4060 MVT DstContainerVT = DstVT;
4061 MVT SrcContainerVT = SrcVT;
4073 if (SrcElemType == MVT::f16 || SrcElemType == MVT::bf16) {
4075 Src = DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, F32VT, Src, Mask, VL);
4079 DAG.
getNode(RISCVISD::VFCVT_RM_X_F_VL,
DL, DstContainerVT, Src, Mask,
4099 return DAG.
getNode(RISCVISD::VSLIDEDOWN_VL,
DL, VT,
Ops);
4111 return DAG.
getNode(RISCVISD::VSLIDEUP_VL,
DL, VT,
Ops);
4136 return std::nullopt;
4154 unsigned EltSizeInBits) {
4157 return std::nullopt;
4158 bool IsInteger =
Op.getValueType().isInteger();
4160 std::optional<unsigned> SeqStepDenom;
4161 std::optional<APInt> SeqStepNum;
4162 std::optional<APInt> SeqAddend;
4163 std::optional<std::pair<APInt, unsigned>> PrevElt;
4164 assert(EltSizeInBits >=
Op.getValueType().getScalarSizeInBits());
4169 const unsigned OpSize =
Op.getScalarValueSizeInBits();
4170 for (
auto [Idx, Elt] :
enumerate(
Op->op_values())) {
4171 if (Elt.isUndef()) {
4172 Elts[Idx] = std::nullopt;
4176 Elts[Idx] = Elt->getAsAPIntVal().trunc(OpSize).zext(EltSizeInBits);
4181 return std::nullopt;
4182 Elts[Idx] = *ExactInteger;
4186 for (
auto [Idx, Elt] :
enumerate(Elts)) {
4195 unsigned IdxDiff = Idx - PrevElt->second;
4196 APInt ValDiff = *Elt - PrevElt->first;
4204 int64_t Remainder = ValDiff.
srem(IdxDiff);
4209 return std::nullopt;
4210 ValDiff = ValDiff.
sdiv(IdxDiff);
4215 SeqStepNum = ValDiff;
4216 else if (ValDiff != SeqStepNum)
4217 return std::nullopt;
4220 SeqStepDenom = IdxDiff;
4221 else if (IdxDiff != *SeqStepDenom)
4222 return std::nullopt;
4226 if (!PrevElt || PrevElt->first != *Elt)
4227 PrevElt = std::make_pair(*Elt, Idx);
4231 if (!SeqStepNum || !SeqStepDenom)
4232 return std::nullopt;
4236 for (
auto [Idx, Elt] :
enumerate(Elts)) {
4240 (
APInt(EltSizeInBits, Idx,
false,
true) *
4242 .sdiv(*SeqStepDenom);
4244 APInt Addend = *Elt - ExpectedVal;
4247 else if (Addend != SeqAddend)
4248 return std::nullopt;
4251 assert(SeqAddend &&
"Must have an addend if we have a step");
4253 return VIDSequence{SeqStepNum->getSExtValue(), *SeqStepDenom,
4254 SeqAddend->getSExtValue()};
4269 if (EltTy == MVT::i1 ||
4272 MVT SrcVT = Src.getSimpleValueType();
4288 MVT ContainerVT = VT;
4292 MVT SrcContainerVT = SrcVT;
4307 SDValue Gather = DAG.
getNode(RISCVISD::VRGATHER_VX_VL,
DL, ContainerVT, Src,
4308 Idx, DAG.
getUNDEF(ContainerVT), Mask, VL);
4316 MVT VT =
Op.getSimpleValueType();
4325 int64_t StepNumerator = SimpleVID->StepNumerator;
4326 unsigned StepDenominator = SimpleVID->StepDenominator;
4327 int64_t Addend = SimpleVID->Addend;
4329 assert(StepNumerator != 0 &&
"Invalid step");
4330 bool Negate =
false;
4331 int64_t SplatStepVal = StepNumerator;
4335 if (StepNumerator != 1 && StepNumerator !=
INT64_MIN &&
4337 Negate = StepNumerator < 0;
4339 SplatStepVal =
Log2_64(std::abs(StepNumerator));
4349 (SplatStepVal >= 0 || StepDenominator == 1) &&
isInt<32>(Addend)) {
4359 if ((StepOpcode ==
ISD::MUL && SplatStepVal != 1) ||
4360 (StepOpcode ==
ISD::SHL && SplatStepVal != 0)) {
4362 VID = DAG.
getNode(StepOpcode,
DL, VIDVT, VID, SplatStep);
4364 if (StepDenominator != 1) {
4369 if (Addend != 0 || Negate) {
4395 MVT VT =
Op.getSimpleValueType();
4404 unsigned NumElts =
Op.getNumOperands();
4407 unsigned MostCommonCount = 0;
4409 unsigned NumUndefElts =
4417 unsigned NumScalarLoads = 0;
4423 unsigned &
Count = ValueCounts[V];
4426 NumScalarLoads += !CFP->isPosZero();
4431 if (++
Count >= MostCommonCount) {
4433 MostCommonCount =
Count;
4437 assert(DominantValue &&
"Not expecting an all-undef BUILD_VECTOR");
4438 unsigned NumDefElts = NumElts - NumUndefElts;
4439 unsigned DominantValueCountThreshold = NumDefElts <= 2 ? 0 : NumDefElts - 2;
4445 ((MostCommonCount > DominantValueCountThreshold) ||
4457 if (
SDValue LastOp =
Op->getOperand(
Op->getNumOperands() - 1);
4458 !LastOp.isUndef() && ValueCounts[LastOp] == 1 &&
4459 LastOp != DominantValue) {
4462 VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL;
4468 Processed.
insert(LastOp);
4473 const SDValue &V = OpIdx.value();
4474 if (V.isUndef() || !Processed.
insert(V).second)
4476 if (ValueCounts[V] == 1) {
4484 return DAG.getConstant(V == V1, DL, XLenVT);
4500 MVT VT =
Op.getSimpleValueType();
4509 unsigned NumElts =
Op.getNumOperands();
4530 unsigned NumViaIntegerBits = std::clamp(NumElts, 8u, Subtarget.
getXLen());
4531 NumViaIntegerBits = std::min(NumViaIntegerBits, Subtarget.
getELen());
4539 unsigned IntegerViaVecElts =
divideCeil(NumElts, NumViaIntegerBits);
4540 MVT IntegerViaVecVT =
4545 unsigned BitPos = 0, IntegerEltIdx = 0;
4548 for (
unsigned I = 0;
I < NumElts;) {
4550 bool BitValue = !V.isUndef() && V->getAsZExtVal();
4551 Bits |= ((
uint64_t)BitValue << BitPos);
4557 if (
I % NumViaIntegerBits == 0 ||
I == NumElts) {
4558 if (NumViaIntegerBits <= 32)
4561 Elts[IntegerEltIdx] = Elt;
4570 if (NumElts < NumViaIntegerBits) {
4574 assert(IntegerViaVecVT == MVT::v1i8 &&
"Unexpected mask vector type");
4589 : RISCVISD::VMV_V_X_VL;
4609 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32) &&
4610 "Unexpected sequence type");
4614 unsigned ViaVecLen =
4621 for (
const auto &OpIdx :
enumerate(
Op->op_values())) {
4622 const auto &SeqV = OpIdx.value();
4623 if (!SeqV.isUndef())
4625 ((SeqV->getAsZExtVal() & EltMask) << (OpIdx.index() * EltBitSize));
4631 if (ViaIntVT == MVT::i32)
4654 BV->getRepeatedSequence(Sequence) &&
4655 (Sequence.size() * EltBitSize) <= Subtarget.
getELen()) {
4656 unsigned SeqLen = Sequence.size();
4658 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32 ||
4659 ViaIntVT == MVT::i64) &&
4660 "Unexpected sequence type");
4665 const unsigned RequiredVL = NumElts / SeqLen;
4666 const unsigned ViaVecLen =
4668 NumElts : RequiredVL;
4671 unsigned EltIdx = 0;
4676 for (
const auto &SeqV : Sequence) {
4677 if (!SeqV.isUndef())
4679 ((SeqV->getAsZExtVal() & EltMask) << (EltIdx * EltBitSize));
4686 if (ViaIntVT == MVT::i32)
4693 (!Subtarget.
is64Bit() && ViaIntVT == MVT::i64)) &&
4694 "Unexpected bitcast sequence");
4698 MVT ViaContainerVT =
4701 DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ViaContainerVT,
4705 if (ViaVecLen != RequiredVL)
4724 Source, DAG, Subtarget);
4725 SDValue Res = DAG.
getNode(RISCVISD::VSEXT_VL,
DL, ContainerVT, Source, Mask, VL);
4744 return RISCV::PACKH;
4746 return Subtarget.
is64Bit() ? RISCV::PACKW : RISCV::PACK;
4761 MVT VT =
Op.getSimpleValueType();
4769 if (!Subtarget.hasStdExtZbb() || !Subtarget.hasStdExtZba())
4774 if (ElemSizeInBits >= std::min(Subtarget.
getELen(), Subtarget.
getXLen()) ||
4788 if (Subtarget.hasStdExtZbkb())
4793 ElemDL, XLenVT,
A,
B),
4805 NewOperands.
reserve(NumElts / 2);
4807 NewOperands.
push_back(pack(
Op.getOperand(i),
Op.getOperand(i + 1)));
4817 MVT VT =
Op.getSimpleValueType();
4825 if (!Subtarget.
is64Bit() && Subtarget.hasStdExtP()) {
4826 if (VT == MVT::v2i16) {
4833 return DAG.
getNode(RISCVISD::PPAIRE,
DL, MVT::v2i16,
Lo,
Hi);
4836 if (VT == MVT::v4i8) {
4852 DAG.
getNode(RISCVISD::PPAIRE,
DL, MVT::v8i8, Concat1, Concat2);
4858 DAG.
getNode(RISCVISD::PPAIRE,
DL, MVT::v2i16,
4875 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4876 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin())) {
4886 NewOps[
I] = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Elem);
4938 bool IsScalar =
all_of(
Op->ops().drop_front(),
4939 [](
const SDUse &U) { return U.get().isUndef(); });
4942 ? (IsScalar ? RISCVISD::VFMV_S_F_VL : RISCVISD::VFMV_V_F_VL)
4943 : (IsScalar ? RISCVISD::VMV_S_X_VL : RISCVISD::VMV_V_X_VL);
4971 auto OneVRegOfOps =
ArrayRef(BuildVectorOps).slice(i, ElemsPerVReg);
4975 unsigned InsertIdx = (i / ElemsPerVReg) * NumOpElts;
4997 unsigned NumUndefElts =
4999 unsigned NumDefElts = NumElts - NumUndefElts;
5000 if (NumDefElts >= 8 && NumDefElts > NumElts / 2 &&
5007 for (
const auto &[Idx, U] :
enumerate(
Op->ops())) {
5009 if (Idx < NumElts / 2) {
5016 bool SelectMaskVal = (Idx < NumElts / 2);
5019 assert(SubVecAOps.
size() == NumElts && SubVecBOps.
size() == NumElts &&
5020 MaskVals.
size() == NumElts);
5055 unsigned UndefCount = 0;
5062 LinearBudget -= PerSlideCost;
5065 LinearBudget -= PerSlideCost;
5068 LinearBudget -= PerSlideCost;
5071 if (LinearBudget < 0)
5076 "Illegal type which will result in reserved encoding");
5092 bool SlideUp =
false;
5117 if (EVecEltVT != ContainerEltVT)
5166 Vec = getVSlide(ContainerVT, DAG.
getUNDEF(ContainerVT), Vec,
Offset, Mask,
5173 Opcode = SlideUp ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VFSLIDE1DOWN_VL;
5175 Opcode = SlideUp ? RISCVISD::VSLIDE1UP_VL : RISCVISD::VSLIDE1DOWN_VL;
5184 Vec = getVSlide(ContainerVT, DAG.
getUNDEF(ContainerVT), Vec,
Offset, Mask,
5200 if ((LoC >> 31) == HiC)
5201 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
5213 auto InterVec = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, InterVT,
5222 Hi.getConstantOperandVal(1) == 31)
5223 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
5228 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
5231 return DAG.
getNode(RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL,
DL, VT, Passthru,
Lo,
5241 assert(Scalar.getValueType() == MVT::i64 &&
"Unexpected VT!");
5253 bool HasPassthru = Passthru && !Passthru.
isUndef();
5254 if (!HasPassthru && !Passthru)
5263 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
5264 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
5265 Scalar = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Scalar);
5274 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL, VT, Passthru, Scalar, VL);
5278 if (Scalar.getValueType().bitsLE(XLenVT)) {
5285 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
5286 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru, Scalar, VL);
5289 assert(XLenVT == MVT::i32 && Scalar.getValueType() == MVT::i64 &&
5290 "Unexpected scalar for splat lowering!");
5293 return DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL, VT, Passthru,
5319 MVT ExtractedContainerVT = ExtractedVT;
5321 ExtractedContainerVT =
5324 ExtractedVal, DAG, Subtarget);
5326 if (ExtractedContainerVT.
bitsLE(VT))
5338 if (!Scalar.getValueType().bitsLE(XLenVT))
5341 VT,
DL, DAG, Subtarget);
5349 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
5359 EVT VT =
V1.getValueType();
5373 if (
V1.getConstantOperandVal(1) != 0 ||
5390 Src && Src.
getValueType().getVectorNumElements() == (NumElts * 2))
5406 MVT ContainerVT = VT;
5414 MVT ContainerVT = VT;
5430 return EltBits * 16 <= LMULOctuple * std::min(Subtarget.
getELen(),
5445 if (!Subtarget.hasStdExtZvzip())
5451 int Size = Mask.size();
5453 assert(
Size == (
int)NumElts &&
"Unexpected mask size");
5459 EvenSrc = StartIndexes[0];
5460 OddSrc = StartIndexes[1];
5463 if (EvenSrc != 0 && OddSrc != 0)
5473 int HalfNumElts = NumElts / 2;
5474 return ((EvenSrc % HalfNumElts) == 0) && ((OddSrc % HalfNumElts) == 0);
5479 std::array<std::pair<int, int>, 2> &SrcInfo) {
5484 if (SrcInfo[0].second == 0 && SrcInfo[1].second == 0)
5488 if ((SrcInfo[0].second > 0 && SrcInfo[1].second < 0) ||
5489 SrcInfo[1].second == 0)
5491 assert(SrcInfo[0].first != -1 &&
"Must find one slide");
5499 if (SrcInfo[1].first == -1)
5501 return SrcInfo[0].second < 0 && SrcInfo[1].second > 0 &&
5502 SrcInfo[1].second - SrcInfo[0].second == (int)NumElts;
5514 ElementCount SrcEC = Src.getValueType().getVectorElementCount();
5521 unsigned Shift = Index * EltBits;
5546 std::optional<int> SplatIdx;
5548 if (M == -1 ||
I == (
unsigned)M)
5550 if (SplatIdx && *SplatIdx != M)
5559 for (
int MaskIndex : Mask) {
5560 bool SelectMaskVal = MaskIndex == *SplatIdx;
5563 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
5588 auto findNonEXTRACT_SUBVECTORParent =
5589 [](
SDValue Parent) -> std::pair<SDValue, uint64_t> {
5594 Parent.getOperand(0).getSimpleValueType().isFixedLengthVector()) {
5595 Offset += Parent.getConstantOperandVal(1);
5596 Parent = Parent.getOperand(0);
5598 return std::make_pair(Parent,
Offset);
5601 auto [V1Src, V1IndexOffset] = findNonEXTRACT_SUBVECTORParent(
V1);
5602 auto [V2Src, V2IndexOffset] = findNonEXTRACT_SUBVECTORParent(V2);
5611 for (
size_t i = 0; i != NewMask.
size(); ++i) {
5612 if (NewMask[i] == -1)
5615 if (
static_cast<size_t>(NewMask[i]) < NewMask.
size()) {
5616 NewMask[i] = NewMask[i] + V1IndexOffset;
5620 NewMask[i] = NewMask[i] - NewMask.
size() + V2IndexOffset;
5626 if (NewMask[0] <= 0)
5630 for (
unsigned i = 1; i != NewMask.
size(); ++i)
5631 if (NewMask[i - 1] + 1 != NewMask[i])
5635 MVT SrcVT = Src.getSimpleValueType();
5664 int NumSubElts, Index;
5669 bool OpsSwapped = Mask[Index] < (int)NumElts;
5671 SDValue ToInsert = OpsSwapped ?
V1 : V2;
5682 if (NumSubElts + Index >= (
int)NumElts)
5693 Res = DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, ContainerVT, InPlace, ToInsert,
5696 Res =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, InPlace, ToInsert,
5719 unsigned NumElts = Mask.size();
5722 int Lane = Mask[Idx];
5727 bool SecondOp =
false;
5728 if ((
unsigned)Lane < NumElts) {
5729 OrigLane = V1Mask[Lane];
5731 OrigLane = V2Mask[Lane - NumElts];
5737 if ((
unsigned)OrigLane >= NumElts)
5740 OrigLane += NumElts;
5741 NewMask[Idx] = OrigLane;
5758 bool OpsSwapped =
false;
5773 const unsigned E = Mask.size() - ((
Offset > 0) ?
Offset : 0);
5774 for (
unsigned i = S; i !=
E; ++i)
5775 if (Mask[i] >= 0 && (
unsigned)Mask[i] !=
Base + i +
Offset)
5781 bool IsVSlidedown = isSlideMask(Mask, OpsSwapped ? 0 : NumElts, 1);
5782 if (!IsVSlidedown && !isSlideMask(Mask, OpsSwapped ? 0 : NumElts, -1))
5785 const int InsertIdx = Mask[IsVSlidedown ? (NumElts - 1) : 0];
5787 if (InsertIdx < 0 || InsertIdx / NumElts != (
unsigned)OpsSwapped)
5805 IsVSlidedown ? RISCVISD::VSLIDE1DOWN_VL : RISCVISD::VSLIDE1UP_VL,
DL,
5811 auto OpCode = IsVSlidedown ?
5812 (VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL) :
5813 (VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VSLIDE1UP_VL);
5816 auto Vec = DAG.
getNode(OpCode,
DL, ContainerVT,
5819 Splat, TrueMask, VL);
5831 for (
unsigned i = 0; i < Mask.size(); i++)
5832 LaneIsUndef[i % Factor] &= (Mask[i] == -1);
5835 for (
unsigned i = 0; i < Factor; i++) {
5846 for (
unsigned i = 0; i < Mask.size() / Factor; i++) {
5847 unsigned j = i * Factor + Index;
5848 if (Mask[j] != -1 && (
unsigned)Mask[j] != i)
5857 assert(RISCVISD::VPAIRE_VL ==
Opc || RISCVISD::VPAIRO_VL ==
Opc);
5865 MVT ContainerVT = IntVT;
5872 MVT InnerVT = ContainerVT;
5891 MVT ContainerVT = IntVT;
5902 DAG.
getNode(RISCVISD::VZIP_VL,
DL, ResVT, Op0, Op1, Passthru, Mask, VL);
5913 assert(
Opc == RISCVISD::VUNZIPE_VL ||
Opc == RISCVISD::VUNZIPO_VL);
5914 MVT VT =
Op.getSimpleValueType();
5919 MVT ContainerVT = IntVT;
5951 MVT VT = V.getSimpleValueType();
5984 MVT VecContainerVT = VecVT;
6001 MVT WideContainerVT = WideVT;
6007 EvenV = DAG.
getBitcast(VecContainerVT, EvenV);
6014 if (Subtarget.hasStdExtZvbb()) {
6018 Interleaved = DAG.
getNode(RISCVISD::VWSLL_VL,
DL, WideContainerVT, OddV,
6019 OffsetVec, Passthru, Mask, VL);
6020 Interleaved = DAG.
getNode(RISCVISD::VWADDU_W_VL,
DL, WideContainerVT,
6021 Interleaved, EvenV, Passthru, Mask, VL);
6028 Interleaved = DAG.
getNode(RISCVISD::VWADDU_VL,
DL, WideContainerVT, EvenV,
6029 OddV, Passthru, Mask, VL);
6035 OddV, AllOnesVec, Passthru, Mask, VL);
6042 Interleaved = DAG.
getNode(RISCVISD::ADD_VL,
DL, WideContainerVT,
6043 Interleaved, OddsMul, Passthru, Mask, VL);
6050 Interleaved = DAG.
getBitcast(ResultContainerVT, Interleaved);
6095 if (ViaEltSize > NumElts)
6103 if (ViaEltSize > NumElts)
6109 if (ViaEltSize > NumElts)
6116 MVT &RotateVT,
unsigned &RotateAmt) {
6119 unsigned NumSubElts;
6121 NumElts, NumSubElts, RotateAmt))
6124 NumElts / NumSubElts);
6192 unsigned NumOfSrcRegs = NumElts / NumOpElts;
6193 unsigned NumOfDestRegs = NumElts / NumOpElts;
6202 Mask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs,
6203 [&]() {
Operands.emplace_back(); },
6204 [&](
ArrayRef<int> SrcSubMask,
unsigned SrcVecIdx,
unsigned DstVecIdx) {
6205 Operands.emplace_back().emplace_back(SrcVecIdx, UINT_MAX,
6208 [&](
ArrayRef<int> SrcSubMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
6213 assert(
Operands.size() == NumOfDestRegs &&
"Whole vector must be processed");
6218 unsigned NumShuffles = std::accumulate(
6225 for (const auto &P : Data) {
6226 unsigned Idx2 = std::get<1>(P);
6227 ArrayRef<int> Mask = std::get<2>(P);
6228 if (Idx2 != UINT_MAX)
6230 else if (ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
6235 if ((NumOfDestRegs > 2 && NumShuffles > NumOfDestRegs) ||
6236 (NumOfDestRegs <= 2 && NumShuffles >= 4))
6238 auto ExtractValue = [&, &DAG = DAG](
SDValue SrcVec,
unsigned ExtractIdx) {
6239 SDValue SubVec = DAG.getExtractSubvector(
DL, M1VT, SrcVec, ExtractIdx);
6243 auto PerformShuffle = [&, &DAG = DAG](
SDValue SubVec1,
SDValue SubVec2,
6245 SDValue SubVec = DAG.getVectorShuffle(OneRegVT,
DL, SubVec1, SubVec2, Mask);
6248 SDValue Vec = DAG.getUNDEF(ContainerVT);
6254 const auto &[Idx1, Idx2,
_] =
Data[
I];
6262 V = ExtractValue(Idx1 >= NumOfSrcRegs ? V2 :
V1,
6263 (Idx1 % NumOfSrcRegs) * NumOpElts);
6264 if (Idx2 != UINT_MAX) {
6267 V = ExtractValue(Idx2 >= NumOfSrcRegs ? V2 :
V1,
6268 (Idx2 % NumOfSrcRegs) * NumOpElts);
6272 for (
const auto &[Idx1, Idx2, Mask] :
Data) {
6275 V = PerformShuffle(
V1, V2, Mask);
6279 unsigned InsertIdx =
I * NumOpElts;
6281 Vec = DAG.getInsertSubvector(
DL, Vec, V, InsertIdx);
6291 bool SawUndef =
false;
6292 for (
const auto &[Idx, M] :
enumerate(Mask)) {
6299 if (Idx > (
unsigned)M)
6332 for (
int Idx : Mask) {
6335 unsigned SrcIdx = Idx % Mask.size();
6336 int Src = (
uint32_t)Idx < Mask.size() ? 0 : 1;
6337 if (Srcs[SrcIdx] == -1)
6340 else if (Srcs[SrcIdx] != Src)
6346 for (
int Lane : Srcs) {
6359 for (
unsigned I = 0;
I < Mask.size();
I++) {
6363 NewMask[
I] = Mask[
I] % Mask.size();
6377 if ((M / Span) != (
int)(
I / Span))
6379 int SpanIdx =
I % Span;
6389 return all_of(Mask, [&](
const auto &Idx) {
return Idx == -1 || Idx < Span; });
6401 int SpanIdx =
I % Span;
6402 if (Mask[SpanIdx] != M)
6416 MVT VT =
Op.getSimpleValueType();
6424 if (ElementSize > 32)
6453 if (VT != MVT::v8i8 && VT != MVT::v4i16)
6459 unsigned EvenSrc = StartIndexes[0];
6460 unsigned OddSrc = StartIndexes[1];
6461 if (EvenSrc == 0 && OddSrc == NumElts) {
6463 return DAG.
getNode(RISCVISD::PZIP,
DL, VT,
V1, V2);
6467 return DAG.
getNode(RISCVISD::PWZIP,
DL, VT,
V1, V2);
6469 if (EvenSrc == NumElts && OddSrc == 0) {
6471 return DAG.
getNode(RISCVISD::PZIP,
DL, VT, V2,
V1);
6475 return DAG.
getNode(RISCVISD::PWZIP,
DL, VT, V2,
V1);
6488 if (!IsRV64 || (VT != MVT::v8i8 && VT != MVT::v4i16))
6500 unsigned Opc = Index == 0 ? RISCVISD::PUNZIPE : RISCVISD::PUNZIPO;
6511 if (VT != MVT::v4i8 && VT != MVT::v8i8 && VT != MVT::v2i16 &&
6512 VT != MVT::v4i16 && VT != MVT::v2i32)
6514 if (!Subtarget.
is64Bit() && VT == MVT::v2i32)
6519 unsigned ActiveElts = NumElts;
6521 all_of(Mask.drop_front(NumElts / 2), [](
int M) { return M < 0; }))
6525 bool SlideUp = ActiveMask[0] == (int)NumElts &&
6527 return M.value() == (int)M.index();
6529 bool SlideDown = ActiveMask.
back() == (int)NumElts &&
6531 return M.value() == (int)M.index() + 1;
6533 if (!SlideUp && !SlideDown)
6540 unsigned SlideBits = ActiveElts * EltBits;
6545 if (ActiveElts == 2) {
6547 return DAG.
getNode(SlideUp ? RISCVISD::PPAIRE : RISCVISD::PPAIROE,
DL, VT,
6548 SlideUp ? ScalarVec :
V1, SlideUp ?
V1 : ScalarVec);
6553 if (SlideBits == Subtarget.
getXLen()) {
6569 assert(SlideBits == 32 &&
"Unexpected RV64 packed slide width");
6588 assert(SlideBits == 64 &&
"Unexpected RV32 packed slide width");
6590 MVT HalfVT = LoVec.getSimpleValueType();
6617 unsigned NumElts = Mask.size();
6618 if (NumElts % 2 != 0)
6620 for (
unsigned I = 0;
I != NumElts / 2; ++
I)
6621 if ((Mask[2 *
I] >= 0 && Mask[2 *
I] != (
int)(2 *
I)) ||
6622 (Mask[2 *
I + 1] >= 0 && Mask[2 *
I + 1] < (
int)NumElts))
6634 if (VT != MVT::v4i8)
6644 MVT SrcVT = VT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16;
6649 if (Src.getValueType().getVectorNumElements() != 2 * NumElts)
6657 return DAG.
getNode(RISCVISD::PNSRL,
DL, VT, Src,
6669 if (VT != MVT::v4i8 && VT != MVT::v8i8 && VT != MVT::v2i16 &&
6693 std::optional<bool> Parity[2];
6694 for (
unsigned I = 0;
I != NumElts; ++
I) {
6698 unsigned Lane =
I % 2;
6699 bool FromV1 = (
unsigned)M < NumElts;
6704 else if (Src[Lane] != Cand)
6708 if (FromV1 ? V1IsSplat : V2IsSplat)
6718 else if (*Parity[Lane] !=
P)
6723 if (!Src[0] || !Src[1])
6726 bool EvenIsOdd = Parity[0].value_or(
false);
6727 bool OddIsOdd = Parity[1].value_or(
false);
6729 if (!EvenIsOdd && !OddIsOdd)
6730 Opc = RISCVISD::PPAIRE;
6731 else if (EvenIsOdd && OddIsOdd)
6732 Opc = RISCVISD::PPAIRO;
6733 else if (!EvenIsOdd && OddIsOdd)
6734 Opc = RISCVISD::PPAIREO;
6736 Opc = RISCVISD::PPAIROE;
6743 SDValue
V1 =
Op.getOperand(0);
6744 SDValue V2 =
Op.getOperand(1);
6746 MVT XLenVT = Subtarget.getXLenVT();
6747 MVT VT =
Op.getSimpleValueType();
6753 if (Subtarget.hasStdExtP() && !Subtarget.hasVInstructions()) {
6760 auto IsLowReverse = [&](
unsigned L) {
6763 all_of(
Mask.drop_front(L), [](
int M) { return M < 0; });
6765 if (IsLowReverse(NumElts))
6767 if (Subtarget.is64Bit() && VT == MVT::v4i16 && IsLowReverse(2))
6773 IsLowReverse(NumElts / 2)) {
6820 auto [TrueMask, VL] = TrueMaskVL;
6835 V.getOperand(0).getSimpleValueType().getVectorNumElements();
6836 V =
V.getOperand(
Offset / OpElements);
6849 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
6852 SDValue
Ops[] = {Ld->getChain(),
6866 MVT SplatVT = ContainerVT;
6869 if (SVT == MVT::bf16 ||
6870 (SVT == MVT::f16 && !Subtarget.hasStdExtZfh())) {
6879 V = DAG.
getLoad(SVT,
DL, Ld->getChain(), NewAddr,
6880 Ld->getPointerInfo().getWithOffset(
Offset),
6881 Ld->getBaseAlign(), Ld->getMemOperand()->getFlags());
6884 Ld->getPointerInfo().getWithOffset(
Offset), SVT,
6886 Ld->getMemOperand()->getFlags());
6890 : RISCVISD::VMV_V_X_VL;
6898 assert(Lane < (
int)NumElts &&
"Unexpected lane!");
6899 SDValue Gather = DAG.
getNode(RISCVISD::VRGATHER_VX_VL,
DL, ContainerVT,
6901 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6923 if (Subtarget.hasStdExtZvkb())
6933 if (Subtarget.hasStdExtZvzip() &&
6935 1 <
count_if(Mask, [](
int Idx) {
return Idx != -1; })) {
6936 bool UsesBothSources =
6938 [&Mask](
int Idx) {
return Idx < (int)
Mask.size(); }) &&
6940 [&Mask](
int Idx) {
return Idx >= (int)
Mask.size(); });
6942 unsigned Opc =
Index == 0 ? RISCVISD::VUNZIPE_VL : RISCVISD::VUNZIPO_VL;
6949 }
else if (
auto VLEN = Subtarget.getRealVLen();
6961 if (UsesBothSources &&
6963 V1.getSimpleValueType().getVectorMinNumElements() >= 2 &&
6979 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
6980 for (
unsigned Factor = 2; Factor <= MaxFactor; Factor <<= 1) {
6983 1 <
count_if(Mask, [](
int Idx) {
return Idx != -1; })) {
6987 [&Mask](
int Idx) {
return Idx < (int)
Mask.size(); }) &&
6988 1 <
count_if(Mask, [&Mask](
int Idx) {
6989 return Idx >= (int)
Mask.size();
7022 int EvenSrc, OddSrc;
7032 bool LaneIsUndef[2] = {
true,
true};
7033 for (
const auto &[Idx, M] :
enumerate(Mask))
7034 LaneIsUndef[Idx % 2] &= (
M == -1);
7037 SDValue EvenV, OddV;
7038 if (LaneIsUndef[0]) {
7041 assert(EvenSrc >= 0 &&
"Undef source?");
7042 EvenV = (EvenSrc /
Size) == 0 ?
V1 : V2;
7046 if (LaneIsUndef[1]) {
7049 assert(OddSrc >= 0 &&
"Undef source?");
7050 OddV = (OddSrc /
Size) == 0 ?
V1 : V2;
7056 if (Subtarget.hasStdExtZvzip() &&
7068 std::array<std::pair<int, int>, 2> SrcInfo;
7075 auto GetSourceFor = [&](
const std::pair<int, int> &
Info) {
7076 int SrcIdx =
Info.first;
7077 assert(SrcIdx == 0 || SrcIdx == 1);
7078 SDValue &Src = Sources[SrcIdx];
7080 SDValue SrcV = SrcIdx == 0 ?
V1 : V2;
7085 auto GetSlide = [&](
const std::pair<int, int> &Src, SDValue
Mask,
7087 auto [TrueMask, VL] = TrueMaskVL;
7088 SDValue SrcV = GetSourceFor(Src);
7089 int SlideAmt = Src.second;
7090 if (SlideAmt == 0) {
7092 assert(Mask == TrueMask);
7099 return getVSlideup(DAG, Subtarget,
DL, ContainerVT, Passthru, SrcV,
7104 if (SrcInfo[1].first == -1) {
7105 SDValue Res = DAG.
getUNDEF(ContainerVT);
7106 Res = GetSlide(SrcInfo[0], TrueMask, Res);
7110 if (Subtarget.hasStdExtZvzip()) {
7111 bool TryWiden =
false;
7115 SDValue Src1 = SrcInfo[0].first == 0 ?
V1 : V2;
7116 SDValue Src2 = SrcInfo[1].first == 0 ?
V1 : V2;
7124 SDValue Src1 = SrcInfo[1].first == 0 ?
V1 : V2;
7125 SDValue Src2 = SrcInfo[0].first == 0 ?
V1 : V2;
7144 for (
const auto &[Idx, M] :
enumerate(Mask)) {
7146 (SrcInfo[1].second > 0 && Idx < (
unsigned)SrcInfo[1].second)) {
7150 int Src =
M >= (int)NumElts;
7151 int Diff = (int)Idx - (M % NumElts);
7152 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
7153 assert(
C ^ (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
7154 "Must match exactly one of the two slides");
7157 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
7163 SDValue Res = DAG.
getUNDEF(ContainerVT);
7164 Res = GetSlide(SrcInfo[0], TrueMask, Res);
7165 Res = GetSlide(SrcInfo[1], SelectMask, Res);
7170 assert(!
V1.isUndef() &&
"Unexpected shuffle canonicalization");
7185 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
7186 for (
unsigned Factor = 4; Factor <= MaxFactor; Factor <<= 1) {
7199 unsigned MinVLen = Subtarget.getRealMinVLen();
7201 if (NumElts > MinVLMAX) {
7202 unsigned MaxIdx = 0;
7206 MaxIdx = std::max({(unsigned)
I, (
unsigned)
M, MaxIdx});
7208 unsigned NewNumElts =
7210 if (NewNumElts != NumElts) {
7214 Mask.take_front(NewNumElts));
7231 for (
auto Idx : Mask) {
7234 assert(Idx >= 0 && (
unsigned)Idx < NumElts);
7244 any_of(Mask, [&](
const auto &Idx) {
return Idx > 255; })) {
7254 unsigned GatherVVOpc = RISCVISD::VRGATHER_VV_VL;
7260 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
7268 (IndexVT.
getSizeInBits() / Subtarget.getRealMinVLen()) > 1) {
7269 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
7273 MVT IndexContainerVT =
7278 for (
int MaskIndex : Mask) {
7279 bool IsLHSIndex = MaskIndex < (int)NumElts && MaskIndex >= 0;
7289 if (NumElts <= MinVLMAX) {
7290 SDValue Gather = DAG.
getNode(GatherVVOpc,
DL, ContainerVT,
V1, LHSIndices,
7291 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
7297 auto [InnerTrueMask, InnerVL] =
7308 SDValue Gather = DAG.
getUNDEF(ContainerVT);
7309 for (
int i = 0; i <
N; i++) {
7313 DAG.
getNode(GatherVVOpc,
DL, M1VT, SubV1, SubIndex,
7314 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
7330 SDValue SubVec = DAG.
getNode(GatherVVOpc,
DL, M1VT, SubV1, SubIndex,
7331 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
7332 SDValue Gather = DAG.
getUNDEF(ContainerVT);
7333 for (
int i = 0; i <
N; i++)
7348 SDValue Gather = DAG.
getUNDEF(ContainerVT);
7349 for (
int i = 0; i <
N; i++) {
7352 DAG.
getUNDEF(IndexContainerVT), LHSIndices,
7353 SlideAmt, TrueMask, VL);
7357 DAG.
getNode(GatherVVOpc,
DL, M1VT, SubV1, SubIndex,
7358 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
7367 SDValue Gather = DAG.
getNode(GatherVVOpc,
DL, ContainerVT,
V1, LHSIndices,
7368 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
7374 SmallVector<int> ShuffleMaskLHS, ShuffleMaskRHS;
7378 for (
int MaskIndex : Mask) {
7379 bool IsLHSOrUndefIndex = MaskIndex < (int)NumElts;
7380 ShuffleMaskLHS.
push_back(IsLHSOrUndefIndex && MaskIndex >= 0
7382 ShuffleMaskRHS.
push_back(IsLHSOrUndefIndex ? -1 : (MaskIndex - NumElts));
7413 for (
int MaskIndex : Mask) {
7414 bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ !SwapOps;
7418 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
7434 if (!Subtarget.hasStdExtP() || !VT.
isSimple())
7437 return (SVT == MVT::v4i8 || SVT == MVT::v8i8 || SVT == MVT::v4i16) &&
7443 if (!
isTypeLegal(VT) || !Subtarget.hasVInstructions())
7450 const unsigned NumElts = M.size();
7457 std::array<std::pair<int, int>, 2> SrcInfo;
7468RISCVTargetLowering::lowerCTLZ_CTTZ_ZERO_POISON(
SDValue Op,
7470 MVT VT =
Op.getSimpleValueType();
7474 MVT ContainerVT = VT;
7479 MVT FloatEltVT = (EltSize >= 32) ? MVT::f64 :
MVT::f32;
7481 FloatEltVT = MVT::f32;
7488 "Expected legal float type!");
7499 if (FloatVT.
bitsGT(VT)) {
7510 MVT ContainerFloatVT =
7512 FloatVal = DAG.
getNode(RISCVISD::VFCVT_RM_F_XU_VL,
DL, ContainerFloatVT,
7513 Src, Mask, RTZRM, VL);
7520 unsigned ShiftAmt = FloatEltVT == MVT::f64 ? 52 : 23;
7527 else if (IntVT.
bitsGT(VT))
7531 unsigned ExponentBias = FloatEltVT == MVT::f64 ? 1023 : 127;
7539 unsigned Adjust = ExponentBias + (EltSize - 1);
7554 MVT XLenVT = Subtarget.getXLenVT();
7555 SDValue
Source =
Op->getOperand(0);
7556 MVT SrcVT =
Source.getSimpleValueType();
7557 SDValue
Mask =
Op->getOperand(1);
7558 SDValue EVL =
Op->getOperand(2);
7565 SrcVT = ContainerVT;
7577 SDValue Res = DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Source, Mask, EVL);
7578 if (
Op->getOpcode() == ISD::VP_CTTZ_ELTS_ZERO_POISON)
7596 assert(
Load &&
Load->getMemoryVT().isVector() &&
"Expected vector load");
7599 Load->getMemoryVT(),
7600 *
Load->getMemOperand()))
7604 MVT VT =
Op.getSimpleValueType();
7606 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7607 "Unexpected unaligned RVV load type");
7611 "Expecting equally-sized RVV vector types to be legal");
7613 Load->getPointerInfo(),
Load->getBaseAlign(),
7614 Load->getMemOperand()->getFlags());
7626 "Expected vector store");
7629 Store->getMemoryVT(),
7630 *
Store->getMemOperand()))
7634 SDValue StoredVal =
Store->getValue();
7637 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7638 "Unexpected unaligned RVV store type");
7642 "Expecting equally-sized RVV vector types to be legal");
7643 StoredVal = DAG.
getBitcast(NewVT, StoredVal);
7645 Store->getPointerInfo(),
Store->getBaseAlign(),
7646 Store->getMemOperand()->getFlags());
7656 assert(
Load &&
Load->getMemoryVT().isVector() &&
"Expected vector load");
7659 Load->getMemoryVT(),
7660 *
Load->getMemOperand()))
7670 MVT VT =
Op.getSimpleValueType();
7672 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7673 "Unexpected unaligned RVV load type");
7677 "Expecting equally-sized RVV vector types to be legal");
7679 SDValue VL =
Load->getVectorLength();
7686 Load->getPointerInfo(),
Load->getBaseAlign(),
7699 "Expected vector store");
7702 Store->getMemoryVT(),
7703 *
Store->getMemOperand()))
7713 SDValue StoredVal =
Store->getValue();
7716 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7717 "Unexpected unaligned RVV store type");
7721 "Expecting equally-sized RVV vector types to be legal");
7723 SDValue VL =
Store->getVectorLength();
7727 StoredVal = DAG.
getBitcast(NewVT, StoredVal);
7732 Store->getPointerInfo(),
Store->getMemOperand()->getFlags(),
Size,
7733 Store->getBaseAlign());
7744 assert(
Op.getValueType() == MVT::i64 &&
"Unexpected VT");
7773 unsigned ShiftAmt, AddOpc;
7784 MVT VT =
Op.getSimpleValueType();
7788 bool Negate =
false;
7792 if (Index < 0 &&
Imm.isNegative()) {
7815 unsigned IsData =
Op.getConstantOperandVal(4);
7818 if (Subtarget.hasVendorXMIPSCBOP() && !IsData)
7819 return Op.getOperand(0);
7831 if (Subtarget.hasStdExtZtso()) {
7855 MVT VT =
Op.getSimpleValueType();
7856 MVT XLenVT = Subtarget.getXLenVT();
7857 unsigned Check =
Op.getConstantOperandVal(1);
7858 unsigned TDCMask = 0;
7885 SDValue Op0 =
Op.getOperand(0);
7886 MVT VT0 =
Op.getOperand(0).getSimpleValueType();
7891 SDValue FPCLASS = DAG.
getNode(RISCVISD::FCLASS_VL,
DL, DstVT, Op0, Mask,
7892 VL,
Op->getFlags());
7909 SDValue FPCLASS = DAG.
getNode(RISCVISD::FCLASS_VL,
DL, ContainerDstVT, Op0,
7910 Mask, VL,
Op->getFlags());
7912 TDCMaskV = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerDstVT,
7913 DAG.
getUNDEF(ContainerDstVT), TDCMaskV, VL);
7916 DAG.
getNode(RISCVISD::SETCC_VL,
DL, ContainerVT,
7921 SDValue
AND = DAG.
getNode(RISCVISD::AND_VL,
DL, ContainerDstVT, FPCLASS,
7922 TDCMaskV, DAG.
getUNDEF(ContainerDstVT), Mask, VL);
7925 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerDstVT,
7926 DAG.
getUNDEF(ContainerDstVT), SplatZero, VL);
7928 SDValue VMSNE = DAG.
getNode(RISCVISD::SETCC_VL,
DL, ContainerVT,
7934 SDValue FCLASS = DAG.
getNode(RISCVISD::FCLASS,
DL, XLenVT,
Op.getOperand(0));
7946 MVT VT =
Op.getSimpleValueType();
7980 MVT ContainerVT = VT;
7991 SDValue XIsNonNan = DAG.
getNode(RISCVISD::SETCC_VL,
DL, Mask.getValueType(),
7992 {X, X, DAG.getCondCode(ISD::SETOEQ),
7993 DAG.getUNDEF(ContainerVT), Mask, VL});
7994 NewY = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, XIsNonNan,
Y,
X,
8000 SDValue YIsNonNan = DAG.
getNode(RISCVISD::SETCC_VL,
DL, Mask.getValueType(),
8001 {Y, Y, DAG.getCondCode(ISD::SETOEQ),
8002 DAG.getUNDEF(ContainerVT), Mask, VL});
8003 NewX = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, YIsNonNan,
X,
Y,
8008 Op.getOpcode() ==
ISD::FMAXIMUM ? RISCVISD::VFMAX_VL : RISCVISD::VFMIN_VL;
8010 DAG.
getUNDEF(ContainerVT), Mask, VL);
8020 "Wrong opcode for lowering FABS or FNEG.");
8023 MVT VT =
Op.getSimpleValueType();
8024 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
8028 DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT,
Op.getOperand(0));
8031 Mask = Mask.sext(Subtarget.
getXLen());
8036 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, Logic);
8044 MVT VT =
Op.getSimpleValueType();
8045 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
8055 if (SignSize == Subtarget.
getXLen())
8059 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Sign);
8061 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, XLenVT, Sign);
8063 assert(XLenVT == MVT::i32 &&
"Unexpected type");
8066 return DAG.
getNode(RISCVISD::SplitF64,
DL, {MVT::i32, MVT::i32}, Sign)
8096 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, CopiedSign);
8101#define OP_CASE(NODE) \
8103 return RISCVISD::NODE##_VL;
8104#define VP_CASE(NODE) \
8105 case ISD::VP_##NODE: \
8106 return RISCVISD::NODE##_VL;
8108 switch (
Op.getOpcode()) {
8164 return RISCVISD::CTLZ_VL;
8166 return RISCVISD::CTTZ_VL;
8168 return RISCVISD::VFMADD_VL;
8170 return RISCVISD::STRICT_VFMADD_VL;
8172 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
8173 return RISCVISD::VMAND_VL;
8174 return RISCVISD::AND_VL;
8176 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
8177 return RISCVISD::VMOR_VL;
8178 return RISCVISD::OR_VL;
8180 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
8181 return RISCVISD::VMXOR_VL;
8182 return RISCVISD::XOR_VL;
8185 return RISCVISD::VZEXT_VL;
8187 return RISCVISD::VSEXT_VL;
8189 return RISCVISD::SETCC_VL;
8191 return RISCVISD::VMERGE_VL;
8193 return RISCVISD::VMERGE_VL;
8196 return RISCVISD::VFMIN_VL;
8199 return RISCVISD::VFMAX_VL;
8202 return RISCVISD::VFCVT_RM_X_F_VL;
8204 return RISCVISD::UDIV_VL;
8206 return RISCVISD::UREM_VL;
8208 return RISCVISD::SDIV_VL;
8210 return RISCVISD::SREM_VL;
8220 MVT OpVT =
Op.getSimpleValueType();
8242 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
8243 if (!
Op.getOperand(j).getValueType().isVector()) {
8244 LoOperands[j] =
Op.getOperand(j);
8245 HiOperands[j] =
Op.getOperand(j);
8248 std::tie(LoOperands[j], HiOperands[j]) =
8253 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
8255 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
8267 auto [EVLLo, EVLHi] =
8268 DAG.
SplitEVL(
Op.getOperand(3),
Op.getOperand(1).getValueType(),
DL);
8272 {Op.getOperand(0), Lo, MaskLo, EVLLo},
Op->getFlags());
8274 {ResLo, Hi, MaskHi, EVLHi},
Op->getFlags());
8277 unsigned Opcode =
Op.getOpcode();
8283 Op.getOperand(0),
Lo,
Op->getFlags());
8293 return DAG.
getNode(BaseOpc,
DL,
Op.getValueType(), ResLo, ResHi,
8311 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
8312 if (!
Op.getOperand(j).getValueType().isVector()) {
8313 LoOperands[j] =
Op.getOperand(j);
8314 HiOperands[j] =
Op.getOperand(j);
8317 std::tie(LoOperands[j], HiOperands[j]) =
8322 DAG.
getNode(
Op.getOpcode(),
DL, LoVTs, LoOperands,
Op->getFlags());
8325 DAG.
getNode(
Op.getOpcode(),
DL, HiVTs, HiOperands,
Op->getFlags());
8333RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Load(
SDValue Op,
8335 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
8336 "Unexpected bfloat16 load lowering");
8340 EVT MemVT =
LD->getMemoryVT();
8345 LD->getMemOperand());
8350 SDValue OrSixteenOne =
8352 SDValue ConvertedResult =
8353 DAG.
getNode(RISCVISD::NDS_FMV_BF16_X,
DL, MVT::bf16, OrSixteenOne);
8358RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Store(
SDValue Op,
8360 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
8361 "Unexpected bfloat16 store lowering");
8365 SDValue FMV = DAG.
getNode(RISCVISD::NDS_FMV_X_ANYEXTBF16,
DL,
8366 Subtarget.getXLenVT(),
ST->getValue());
8368 ST->getChain(),
DL, FMV,
ST->getBasePtr(),
8370 ST->getMemOperand());
8381 switch (
Op.getOpcode()) {
8384 "Unimplemented RISCVTargetLowering::LowerOperation Case");
8390 return lowerGlobalAddress(
Op, DAG);
8392 return lowerBlockAddress(
Op, DAG);
8394 return lowerConstantPool(
Op, DAG);
8396 return lowerJumpTable(
Op, DAG);
8398 return lowerGlobalTLSAddress(
Op, DAG);
8402 return lowerConstantFP(
Op, DAG);
8404 return lowerSELECT(
Op, DAG);
8406 return lowerBRCOND(
Op, DAG);
8408 return lowerVASTART(
Op, DAG);
8410 return lowerFRAMEADDR(
Op, DAG);
8412 return lowerRETURNADDR(
Op, DAG);
8414 return lowerShiftLeftParts(
Op, DAG);
8416 return lowerShiftRightParts(
Op, DAG,
true);
8418 return lowerShiftRightParts(
Op, DAG,
false);
8421 if (
Op.getValueType().isFixedLengthVector()) {
8422 assert(Subtarget.hasStdExtZvkb());
8423 return lowerToScalableOp(
Op, DAG);
8425 assert(Subtarget.hasVendorXTHeadBb() &&
8426 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
8427 "Unexpected custom legalization");
8434 EVT VT =
Op.getValueType();
8437 MVT XLenVT = Subtarget.getXLenVT();
8438 if (Op0VT == MVT::i16 &&
8439 ((VT == MVT::f16 && Subtarget.hasStdExtZfhminOrZhinxmin()) ||
8440 (VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
8442 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, NewOp0);
8444 if (VT == MVT::f32 && Op0VT == MVT::i32 && Subtarget.is64Bit() &&
8445 Subtarget.hasStdExtFOrZfinx()) {
8447 return DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32, NewOp0);
8449 if (VT == MVT::f64 && Op0VT == MVT::i64 && !Subtarget.is64Bit() &&
8450 Subtarget.hasStdExtDOrZdinx()) {
8453 return DAG.
getNode(RISCVISD::BuildPairF64,
DL, MVT::f64,
Lo,
Hi);
8460 if (Op0VT.
getSimpleVT() == Subtarget.getXLenVT() &&
8474 "Unexpected types");
8506 return LowerINTRINSIC_WO_CHAIN(
Op, DAG);
8508 return LowerINTRINSIC_W_CHAIN(
Op, DAG);
8510 return LowerINTRINSIC_VOID(
Op, DAG);
8512 return LowerIS_FPCLASS(
Op, DAG);
8514 MVT VT =
Op.getSimpleValueType();
8516 assert(Subtarget.hasStdExtZvbb());
8517 return lowerToScalableOp(
Op, DAG);
8520 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected custom legalization");
8524 return DAG.
getNode(RISCVISD::BREV8,
DL, VT, BSwap);
8530 if (!
Op.getSimpleValueType().isVector())
8532 return lowerVectorTrunc(
Op, DAG);
8535 if (
Op.getOperand(0).getValueType().isVector() &&
8536 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
8537 return lowerVectorMaskExt(
Op, DAG, 1);
8538 if (
Op.getValueType().isScalableVector())
8540 return lowerToScalableOp(
Op, DAG);
8542 if (
Op.getOperand(0).getValueType().isVector() &&
8543 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
8544 return lowerVectorMaskExt(
Op, DAG, -1);
8545 if (
Op.getValueType().isScalableVector())
8547 return lowerToScalableOp(
Op, DAG);
8549 return lowerSPLAT_VECTOR_PARTS(
Op, DAG);
8551 return lowerINSERT_VECTOR_ELT(
Op, DAG);
8553 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
8555 MVT VT =
Op.getSimpleValueType();
8563 MVT ContainerVT = VT;
8570 V = DAG.
getNode(RISCVISD::VFMV_S_F_VL,
DL, ContainerVT,
8571 DAG.
getUNDEF(ContainerVT), Scalar, VL);
8574 V = DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL, ContainerVT,
8575 DAG.
getUNDEF(ContainerVT), Scalar, VL);
8582 MVT XLenVT = Subtarget.getXLenVT();
8583 MVT VT =
Op.getSimpleValueType();
8594 uint64_t Val =
Op.getConstantOperandVal(0);
8602 }
else if (
Log2 > 3) {
8606 }
else if ((Val % 8) == 0) {
8624 if (
Op.getValueType() == MVT::f16 && Subtarget.is64Bit() &&
8625 Op.getOperand(1).getValueType() == MVT::i32) {
8642 return lowerVectorFPExtendOrRound(
Op, DAG);
8645 return lowerStrictFPExtendOrRoundLike(
Op, DAG);
8651 if (
Op.getValueType().isVector() &&
8652 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1) {
8654 EVT VT =
Op.getValueType();
8662 Op.getValueType().isVector() &&
8663 ((
Op.getValueType().getScalarType() == MVT::f16 &&
8664 (Subtarget.hasVInstructionsF16Minimal() &&
8665 !Subtarget.hasVInstructionsF16())) ||
8666 (
Op.getValueType().getScalarType() == MVT::bf16 &&
8667 (Subtarget.hasVInstructionsBF16Minimal() &&
8668 (!Subtarget.hasVInstructionsBF16() ||
8669 Op1.getValueType().getScalarSizeInBits() > 8))))) {
8687 Op1.getValueType().isVector() &&
8688 ((Op1.getValueType().getScalarType() == MVT::f16 &&
8689 (Subtarget.hasVInstructionsF16Minimal() &&
8690 !Subtarget.hasVInstructionsF16())) ||
8691 (Op1.getValueType().getScalarType() == MVT::bf16 &&
8692 (Subtarget.hasVInstructionsBF16Minimal() &&
8693 (!Subtarget.hasVInstructionsBF16() ||
8694 Op.getValueType().getScalarSizeInBits() > 8))))) {
8696 Op1.getValueType().getVectorElementCount());
8703 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), WidenVec);
8713 MVT VT =
Op.getSimpleValueType();
8716 bool IsStrict =
Op->isStrictFPOpcode();
8717 SDValue Src =
Op.getOperand(0 + IsStrict);
8718 MVT SrcVT = Src.getSimpleValueType();
8729 "Unexpected vector element types");
8733 if (EltSize > (2 * SrcEltSize)) {
8745 Op.getOperand(0), Ext);
8749 assert((SrcEltVT == MVT::f16 || SrcEltVT == MVT::bf16) &&
8750 "Unexpected FP_TO_[US]INT lowering");
8755 auto [FExt, Chain] =
8757 return DAG.
getNode(
Op.getOpcode(),
DL,
Op->getVTList(), Chain, FExt);
8764 if (SrcEltSize > (2 * EltSize)) {
8767 assert((EltVT == MVT::f16 || EltVT == MVT::bf16) &&
8768 "Unexpected [US]_TO_FP lowering");
8773 Op.getOperand(0), Src);
8788 Op.getOperand(0), Src);
8806 unsigned RVVOpc = 0;
8807 switch (
Op.getOpcode()) {
8811 RVVOpc = RISCVISD::VFCVT_RTZ_X_F_VL;
8814 RVVOpc = RISCVISD::VFCVT_RTZ_XU_F_VL;
8817 RVVOpc = RISCVISD::SINT_TO_FP_VL;
8820 RVVOpc = RISCVISD::UINT_TO_FP_VL;
8823 RVVOpc = RISCVISD::STRICT_VFCVT_RTZ_X_F_VL;
8826 RVVOpc = RISCVISD::STRICT_VFCVT_RTZ_XU_F_VL;
8829 RVVOpc = RISCVISD::STRICT_SINT_TO_FP_VL;
8832 RVVOpc = RISCVISD::STRICT_UINT_TO_FP_VL;
8839 "Expected same element count");
8846 Op.getOperand(0), Src, Mask, VL);
8850 Src = DAG.
getNode(RVVOpc,
DL, ContainerVT, Src, Mask, VL);
8859 assert(!Subtarget.isSoftFPABI() &&
"Unexpected custom legalization");
8865 makeLibCall(DAG, LC, MVT::f32,
Op.getOperand(0), CallOptions,
DL).first;
8866 if (Subtarget.is64Bit())
8867 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Res);
8871 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalization");
8872 MVT VT =
Op.getSimpleValueType();
8877 SDValue Res = Subtarget.is64Bit()
8878 ? DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32,
Op)
8889 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalisation");
8892 bool IsStrict =
Op->isStrictFPOpcode();
8893 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
8897 std::tie(Res, Chain) =
8898 makeLibCall(DAG, LC, MVT::f32, Op0, CallOptions,
DL, Chain);
8899 if (Subtarget.is64Bit())
8900 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Res);
8910 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalisation");
8913 bool IsStrict =
Op->isStrictFPOpcode();
8914 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
8916 SDValue Arg = Subtarget.is64Bit()
8917 ? DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32, Op0)
8920 std::tie(Res, Chain) =
makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MVT::f32, Arg,
8921 CallOptions,
DL, Chain);
8937 MVT VT =
Op.getSimpleValueType();
8950 if (
Op.getValueType().isVector())
8952 assert(
Op.getOperand(0).getValueType() == MVT::f16 &&
8953 "Unexpected custom legalisation");
8956 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), Ext);
8962 assert(
Op.getOperand(1).getValueType() == MVT::f16 &&
8963 "Unexpected custom legalisation");
8966 {
Op.getOperand(0),
Op.getOperand(1)});
8967 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
8968 {Ext.getValue(1), Ext.getValue(0)});
8975 return lowerVECREDUCE(
Op, DAG);
8979 if (
Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
8980 return lowerVectorMaskVecReduction(
Op, DAG,
false);
8981 return lowerVECREDUCE(
Op, DAG);
8985 return lowerFPVECREDUCE(
Op, DAG);
8993 return lowerFPVECREDUCE(
Op, DAG);
8994 case ISD::VP_REDUCE_ADD:
8995 case ISD::VP_REDUCE_UMAX:
8996 case ISD::VP_REDUCE_SMAX:
8997 case ISD::VP_REDUCE_UMIN:
8998 case ISD::VP_REDUCE_SMIN:
8999 case ISD::VP_REDUCE_FADD:
9000 case ISD::VP_REDUCE_SEQ_FADD:
9001 case ISD::VP_REDUCE_FMIN:
9002 case ISD::VP_REDUCE_FMAX:
9003 case ISD::VP_REDUCE_FMINIMUM:
9004 case ISD::VP_REDUCE_FMAXIMUM:
9007 return lowerVPREDUCE(
Op, DAG);
9008 case ISD::VP_REDUCE_AND:
9009 case ISD::VP_REDUCE_OR:
9010 case ISD::VP_REDUCE_XOR:
9011 if (
Op.getOperand(1).getValueType().getVectorElementType() == MVT::i1)
9012 return lowerVectorMaskVecReduction(
Op, DAG,
true);
9013 return lowerVPREDUCE(
Op, DAG);
9014 case ISD::VP_CTTZ_ELTS:
9015 case ISD::VP_CTTZ_ELTS_ZERO_POISON:
9016 return lowerVPCttzElements(
Op, DAG);
9027 return lowerINSERT_SUBVECTOR(
Op, DAG);
9029 return lowerEXTRACT_SUBVECTOR(
Op, DAG);
9031 return lowerVECTOR_DEINTERLEAVE(
Op, DAG);
9033 return lowerVECTOR_INTERLEAVE(
Op, DAG);
9035 return lowerSTEP_VECTOR(
Op, DAG);
9037 return lowerVECTOR_REVERSE(
Op, DAG);
9040 return lowerVECTOR_SPLICE(
Op, DAG);
9042 MVT VT =
Op.getSimpleValueType();
9044 if (!Subtarget.is64Bit() && EltVT == MVT::i64)
9049 MVT VT =
Op.getSimpleValueType();
9051 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
9052 EltVT == MVT::bf16) {
9055 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
9056 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
9057 Elt = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, Subtarget.getXLenVT(),
9066 if (EltVT == MVT::i1)
9067 return lowerVectorMaskSplat(
Op, DAG);
9071 return lowerVECTOR_SHUFFLE(
Op, DAG);
9076 MVT VT =
Op.getSimpleValueType();
9077 MVT ContainerVT = VT;
9089 if (
Op.getNumOperands() > 2 &&
9093 size_t HalfNumOps =
Op.getNumOperands() / 2;
9095 Op->ops().take_front(HalfNumOps));
9097 Op->ops().drop_front(HalfNumOps));
9101 unsigned NumOpElts =
9102 Op.getOperand(0).getSimpleValueType().getVectorMinNumElements();
9105 SDValue SubVec = OpIdx.value();
9115 EVT VT =
Load->getValueType(0);
9116 if (VT == MVT::f64) {
9117 assert(Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
9118 !Subtarget.is64Bit() &&
"Unexpected custom legalisation");
9126 DAG.
getLoad(MVT::i32,
DL, Chain, BasePtr,
Load->getPointerInfo(),
9127 Load->getBaseAlign(),
Load->getMemOperand()->getFlags());
9130 MVT::i32,
DL, Chain, BasePtr,
Load->getPointerInfo().getWithOffset(4),
9131 Load->getBaseAlign(),
Load->getMemOperand()->getFlags());
9136 if (!Subtarget.isLittleEndian())
9143 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
9144 (VT == MVT::v2i32 || VT == MVT::v4i16 || VT == MVT::v8i8)) {
9145 assert(!Subtarget.is64Bit() &&
"Unexpected custom legalisation");
9149 if (VT == MVT::v2i32)
9151 else if (VT == MVT::v4i16)
9152 HalfVT = MVT::v2i16;
9162 DAG.
getLoad(HalfVT,
DL, Chain, BasePtr,
Load->getPointerInfo(),
9163 Load->getBaseAlign(),
Load->getMemOperand()->getFlags());
9169 Load->getPointerInfo().getWithOffset(HalfSize),
9170 Load->getBaseAlign(),
Load->getMemOperand()->getFlags());
9176 if (VT == MVT::v2i32) {
9187 if (VT == MVT::bf16)
9188 return lowerXAndesBfHCvtBFloat16Load(
Op, DAG);
9193 MVT XLenVT = Subtarget.getXLenVT();
9196 unsigned NumElts = Sz / (NF * 8);
9197 int Log2LMUL =
Log2_64(NumElts) - 3;
9200 Flag.setNoUnsignedWrap(
true);
9210 for (
unsigned i = 0; i < NF; ++i) {
9215 Ret = DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL, VT, Ret, LoadVal,
9223 if (
auto V = expandUnalignedRVVLoad(
Op, DAG))
9225 if (
Op.getValueType().isFixedLengthVector())
9226 return lowerFixedLengthVectorLoadToRVV(
Op, DAG);
9234 if (VT == MVT::f64) {
9235 assert(Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
9236 !Subtarget.is64Bit() &&
"Unexpected custom legalisation");
9243 DAG.
getVTList(MVT::i32, MVT::i32), StoredVal);
9249 if (!Subtarget.isLittleEndian())
9253 Chain,
DL,
Lo, BasePtr,
Store->getPointerInfo(),
9254 Store->getBaseAlign(),
Store->getMemOperand()->getFlags());
9257 Chain,
DL,
Hi, BasePtr,
Store->getPointerInfo().getWithOffset(4),
9258 Store->getBaseAlign(),
Store->getMemOperand()->getFlags());
9261 if (VT == MVT::i64) {
9262 assert(Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit() &&
9263 "Unexpected custom legalisation");
9264 if (
Store->isTruncatingStore())
9267 if (
Store->getAlign() < Subtarget.getZilsdAlign())
9278 {Store->getChain(), Lo, Hi, Store->getBasePtr()}, MVT::i64,
9279 Store->getMemOperand());
9282 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
9283 (VT == MVT::v2i32 || VT == MVT::v4i16 || VT == MVT::v8i8)) {
9284 assert(!Subtarget.is64Bit() &&
"Unexpected custom legalisation");
9291 if (VT == MVT::v2i32)
9293 else if (VT == MVT::v4i16)
9294 HalfVT = MVT::v2i16;
9304 if (VT == MVT::v2i32) {
9321 Chain,
DL,
Lo, BasePtr,
Store->getPointerInfo(),
9322 Store->getBaseAlign(),
Store->getMemOperand()->getFlags());
9327 Chain,
DL,
Hi, BasePtr,
9328 Store->getPointerInfo().getWithOffset(HalfSize),
9329 Store->getBaseAlign(),
Store->getMemOperand()->getFlags());
9334 if (VT == MVT::bf16)
9335 return lowerXAndesBfHCvtBFloat16Store(
Op, DAG);
9340 MVT XLenVT = Subtarget.getXLenVT();
9343 unsigned NumElts = Sz / (NF * 8);
9344 int Log2LMUL =
Log2_64(NumElts) - 3;
9347 Flag.setNoUnsignedWrap(
true);
9357 for (
unsigned i = 0; i < NF; ++i) {
9359 DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL,
9362 Ret = DAG.
getStore(Chain,
DL, Extract, BasePtr,
9364 Store->getBaseAlign(),
9365 Store->getMemOperand()->getFlags());
9372 if (
auto V = expandUnalignedRVVStore(
Op, DAG))
9374 if (
Op.getOperand(1).getValueType().isFixedLengthVector())
9375 return lowerFixedLengthVectorStoreToRVV(
Op, DAG);
9379 if (
SDValue V = expandUnalignedVPLoad(
Op, DAG))
9383 return lowerMaskedLoad(
Op, DAG);
9384 case ISD::VP_LOAD_FF:
9385 return lowerLoadFF(
Op, DAG);
9387 if (
SDValue V = expandUnalignedVPStore(
Op, DAG))
9391 return lowerMaskedStore(
Op, DAG);
9393 return lowerVectorCompress(
Op, DAG);
9402 EVT VT =
Op.getValueType();
9413 MVT OpVT =
Op.getOperand(0).getSimpleValueType();
9415 MVT VT =
Op.getSimpleValueType();
9420 "Unexpected CondCode");
9453 return DAG.
getSetCC(
DL, VT, RHS, LHS, CCVal);
9456 MVT VT =
Op.getSimpleValueType();
9483 return DAG.
getSetCC(
DL, VT, RHS, LHS, CCVal);
9492 return lowerToScalableOp(
Op, DAG);
9502 return lowerToScalableOp(
Op, DAG);
9504 EVT VT =
Op.getValueType();
9506 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
9507 (VT == MVT::v4i16 || VT == MVT::v8i8)) {
9520 MaskLo, TrueLo, FalseLo);
9522 MaskHi, TrueHi, FalseHi);
9526 return lowerToScalableOp(
Op, DAG);
9534 EVT VT =
Op.getValueType();
9535 unsigned Opc =
Op.getOpcode();
9537 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
9538 (VT == MVT::v4i16 || VT == MVT::v8i8)) {
9544 MVT HalfVT = (VT == MVT::v4i16) ? MVT::v2i16 : MVT::v4i8;
9547 auto [LHSLo, LHSHi] = DAG.
SplitVector(LHS,
DL, HalfVT, HalfVT);
9550 auto [RHSLo, RHSHi] = DAG.
SplitVector(RHS,
DL, HalfVT, HalfVT);
9559 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
9561 (VT == MVT::v4i8 || VT == MVT::v2i16)) {
9563 "Unexpected custom legalisation");
9565 MVT WideVT = (VT == MVT::v4i8) ? MVT::v4i16 : MVT::v2i32;
9569 DAG.
getNode(WMulOpc,
DL, WideVT,
Op.getOperand(0),
Op.getOperand(1));
9579 if (Subtarget.hasStdExtP() && Subtarget.is64Bit() && VT == MVT::v8i8 &&
9584 unsigned LoOpc =
Opc ==
ISD::MULHU ? RISCVISD::PMULU_HALVES_00
9585 : RISCVISD::PMUL_HALVES_00;
9586 unsigned HiOpc =
Opc ==
ISD::MULHU ? RISCVISD::PMULU_HALVES_11
9587 : RISCVISD::PMUL_HALVES_11;
9593 return lowerToScalableOp(
Op, DAG);
9596 EVT VT =
Op.getValueType();
9597 assert(Subtarget.hasStdExtP() && Subtarget.is64Bit() &&
9598 (VT == MVT::v2i32 || VT == MVT::v4i16) &&
9599 "Unexpected custom legalisation");
9607 if (
Op.getSimpleValueType().isFixedLengthVector()) {
9608 if (Subtarget.hasStdExtP()) {
9620 switch (
Op.getOpcode()) {
9624 Opc = RISCVISD::PSLL;
9627 Opc = RISCVISD::PSRL;
9630 Opc = RISCVISD::PSRA;
9633 Opc = RISCVISD::PSSHA;
9639 return lowerToScalableOp(
Op, DAG);
9643 assert(
Op.getOperand(1).getValueType() == MVT::i32 && Subtarget.is64Bit() &&
9644 "Unexpected custom legalisation");
9651 MVT VT =
Op.getSimpleValueType();
9666 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
9694 return lowerToScalableOp(
Op, DAG);
9697 EVT VT =
Op->getValueType(0);
9698 if (Subtarget.hasStdExtZvabd() && VT.
isVector())
9699 return lowerToScalableOp(
Op, DAG);
9716 return lowerABS(
Op, DAG);
9721 if (Subtarget.hasStdExtZvbb())
9722 return lowerToScalableOp(
Op, DAG);
9724 return lowerCTLZ_CTTZ_ZERO_POISON(
Op, DAG);
9728 MVT VT =
Op.getSimpleValueType();
9729 MVT XLenVT = Subtarget.getXLenVT();
9733 assert(Subtarget.hasStdExtZvbc() && Subtarget.is64Bit() && VT == XLenVT &&
9734 "Unexpected custom legalisation");
9737 Attribute::NoImplicitFloat))
9746 return DAG.
getNode(RISCVISD::VMV_X_S,
DL, XLenVT, Res);
9752 return lowerToScalableOp(
Op, DAG);
9755 "Unexpected custom legalisation");
9764 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
9768 return lowerToScalableOp(
Op, DAG);
9777 return lowerToScalableOp(
Op, DAG);
9780 return lowerVectorStrictFSetcc(
Op, DAG);
9790 case ISD::VP_GATHER:
9791 return lowerMaskedGather(
Op, DAG);
9793 case ISD::VP_SCATTER:
9794 return lowerMaskedScatter(
Op, DAG);
9796 return lowerGET_ROUNDING(
Op, DAG);
9798 return lowerSET_ROUNDING(
Op, DAG);
9800 return lowerGET_FPENV(
Op, DAG);
9802 return lowerSET_FPENV(
Op, DAG);
9804 return lowerRESET_FPENV(
Op, DAG);
9806 return lowerGET_FPMODE(
Op, DAG);
9808 return lowerSET_FPMODE(
Op, DAG);
9810 return lowerRESET_FPMODE(
Op, DAG);
9812 return lowerEH_DWARF_CFA(
Op, DAG);
9814 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
9815 return lowerVPMergeMask(
Op, DAG);
9821 return lowerVPOp(
Op, DAG);
9822 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
9823 return lowerVPStridedLoad(
Op, DAG);
9824 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
9825 return lowerVPStridedStore(
Op, DAG);
9826 case ISD::EXPERIMENTAL_VP_SPLICE:
9827 return lowerVPSpliceExperimental(
Op, DAG);
9828 case ISD::EXPERIMENTAL_VP_REVERSE:
9829 return lowerVPReverseExperimental(
Op, DAG);
9832 "llvm.clear_cache only needs custom lower on Linux targets");
9835 return emitFlushICache(DAG,
Op.getOperand(0),
Op.getOperand(1),
9836 Op.getOperand(2), Flags,
DL);
9839 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
9841 return lowerINIT_TRAMPOLINE(
Op, DAG);
9843 return lowerADJUST_TRAMPOLINE(
Op, DAG);
9847 return lowerPARTIAL_REDUCE_MLA(
Op, DAG);
9859 MakeLibCallOptions CallOptions;
9860 std::pair<SDValue, SDValue> CallResult =
9861 makeLibCall(DAG, RTLIB::RISCV_FLUSH_ICACHE, MVT::isVoid,
9862 {Start, End, Flags}, CallOptions,
DL, InChain);
9865 return CallResult.second;
9870 if (!Subtarget.is64Bit())
9878 std::unique_ptr<MCCodeEmitter> CodeEmitter(
9881 SDValue Root =
Op.getOperand(0);
9882 SDValue Trmp =
Op.getOperand(1);
9907 const bool HasCFBranch =
9908 MF.
getInfo<RISCVMachineFunctionInfo>()->hasCFProtectionBranch();
9909 const unsigned StaticChainIdx = HasCFBranch ? 5 : 4;
9910 const unsigned StaticChainOffset = StaticChainIdx * 4;
9911 const unsigned FunctionAddressOffset = StaticChainOffset + 8;
9914 auto GetEncoding = [&](
const MCInst &MC) {
9917 CodeEmitter->encodeInstruction(MC, CB, Fixups, STI);
9924 SmallVector<uint32_t> Encodings;
9929 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)),
9933 GetEncoding(MCInstBuilder(RISCV::LD)
9936 .addImm(FunctionAddressOffset)),
9939 GetEncoding(MCInstBuilder(RISCV::LD)
9942 .addImm(StaticChainOffset)),
9945 GetEncoding(MCInstBuilder(RISCV::JALR)
9953 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X0).addImm(0)),
9956 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X28).addImm(0)),
9960 GetEncoding(MCInstBuilder(RISCV::LD)
9963 .addImm(FunctionAddressOffset - 4)),
9966 GetEncoding(MCInstBuilder(RISCV::LD)
9969 .addImm(StaticChainOffset - 4)),
9972 GetEncoding(MCInstBuilder(RISCV::JALR)
9984 Root, dl, DAG.
getConstant(Encoding, dl, MVT::i64), Addr,
9985 MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32));
9989 SDValue FunctionAddress =
Op.getOperand(2);
9990 SDValue StaticChain =
Op.getOperand(3);
9993 struct OffsetValuePair {
9995 const SDValue
Value;
9996 SDValue Addr = SDValue();
9997 } OffsetValues[] = {
9998 {StaticChainOffset, StaticChain},
9999 {FunctionAddressOffset, FunctionAddress},
10001 for (
auto &OffsetValue : OffsetValues) {
10004 DAG.
getConstant(OffsetValue.Offset, dl, MVT::i64));
10005 OffsetValue.Addr = Addr;
10007 DAG.
getStore(Root, dl, OffsetValue.Value, Addr,
10008 MachinePointerInfo(TrmpAddr, OffsetValue.Offset)));
10011 assert(OutChains.
size() == StaticChainIdx + 2 &&
10012 "Size of OutChains mismatch");
10017 SDValue EndOfTrmp = OffsetValues[0].Addr;
10028 if (!Subtarget.is64Bit())
10031 return Op.getOperand(0);
10041 MVT VT =
Op.getSimpleValueType();
10042 SDValue Accum =
Op.getOperand(0);
10043 SDValue
A =
Op.getOperand(1);
10044 SDValue
B =
Op.getOperand(2);
10045 MVT ArgVT =
A.getSimpleValueType();
10046 assert(ArgVT ==
B.getSimpleValueType() &&
10062 SDValue Dot = DAG.
getNode(
Op.getOpcode(),
DL, DotVT,
10063 {DAG.getConstant(0, DL, DotVT), A, B});
10078 SDValue Wide = DAG.
getNode(ExtOpc,
DL, WideVT, Dot);
10110 MVT ContainerVT = VT;
10119 switch (
Op.getOpcode()) {
10121 Opc = RISCVISD::VDOT4A_VL;
10124 Opc = RISCVISD::VDOT4AU_VL;
10127 Opc = RISCVISD::VDOT4ASU_VL;
10153 N->getOffset(), Flags);
10182template <
class NodeTy>
10184 bool IsLocal,
bool IsExternWeak)
const {
10194 if (IsLocal && !Subtarget.allowTaggedGlobals())
10198 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
10221 if (Subtarget.hasVendorXqcili()) {
10225 return DAG.
getNode(RISCVISD::QC_E_LI,
DL, Ty, Addr);
10231 SDValue MNHi = DAG.
getNode(RISCVISD::HI,
DL, Ty, AddrHi);
10232 return DAG.
getNode(RISCVISD::ADD_LO,
DL, Ty, MNHi, AddrLo);
10236 if (IsExternWeak) {
10256 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
10264 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
10272 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
10273 const GlobalValue *GV =
N->getGlobal();
10282 return getAddr(
N, DAG);
10289 return getAddr(
N, DAG);
10296 return getAddr(
N, DAG);
10301 bool UseGOT)
const {
10304 const GlobalValue *GV =
N->getGlobal();
10305 MVT XLenVT = Subtarget.getXLenVT();
10324 SDValue TPReg = DAG.
getRegister(RISCV::X4, XLenVT);
10339 SDValue MNHi = DAG.
getNode(RISCVISD::HI,
DL, Ty, AddrHi);
10340 SDValue TPReg = DAG.
getRegister(RISCV::X4, XLenVT);
10342 DAG.
getNode(RISCVISD::ADD_TPREL,
DL, Ty, MNHi, TPReg, AddrAdd);
10343 return DAG.
getNode(RISCVISD::ADD_LO,
DL, Ty, MNAdd, AddrLo);
10351 const GlobalValue *GV =
N->getGlobal();
10365 TargetLowering::CallLoweringInfo CLI(DAG);
10366 CLI.setDebugLoc(
DL)
10379 const GlobalValue *GV =
N->getGlobal();
10389 return SDValue(DAG.
getMachineNode(RISCV::PseudoLA_TLSDESC,
DL, Ty, Addr), 0);
10395 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
10409 Addr = getStaticTLSAddr(
N, DAG,
false);
10412 Addr = getStaticTLSAddr(
N, DAG,
true);
10417 : getDynamicTLSAddr(
N, DAG);
10434 if (
LHS == LHS2 &&
RHS == RHS2) {
10439 }
else if (
LHS == RHS2 &&
RHS == LHS2) {
10447 return std::nullopt;
10458 SDValue FalseV =
N->getOperand(2);
10459 MVT VT =
N->getSimpleValueType(0);
10475 const bool HasZicond = VT.
isScalarInteger() && Subtarget.hasStdExtZicond();
10486 int64_t MulImm = TrueC->getSExtValue();
10488 Subtarget.hasVendorXqciac())
10489 return DAG.
getNode(RISCVISD::QC_MULIADD,
DL, VT, CondV, CondV,
10493 uint64_t TrueVal = TrueC->getZExtValue();
10502 unsigned ShAmount =
Log2_64(TrueM1);
10504 return DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT, CondV,
10520 if (~TrueVal == FalseVal) {
10560 if (Subtarget.hasShortForwardBranchIALU())
10563 unsigned SelOpNo = 0;
10573 unsigned ConstSelOpNo = 1;
10574 unsigned OtherSelOpNo = 2;
10581 if (!ConstSelOpNode || ConstSelOpNode->
isOpaque())
10586 if (!ConstBinOpNode || ConstBinOpNode->
isOpaque())
10592 SDValue NewConstOps[2] = {ConstSelOp, ConstBinOp};
10594 std::swap(NewConstOps[0], NewConstOps[1]);
10606 SDValue NewNonConstOps[2] = {OtherSelOp, ConstBinOp};
10608 std::swap(NewNonConstOps[0], NewNonConstOps[1]);
10611 SDValue NewT = (ConstSelOpNo == 1) ? NewConstOp : NewNonConstOp;
10612 SDValue NewF = (ConstSelOpNo == 1) ? NewNonConstOp : NewConstOp;
10617 SDValue CondV =
Op.getOperand(0);
10618 SDValue TrueV =
Op.getOperand(1);
10619 SDValue FalseV =
Op.getOperand(2);
10621 MVT VT =
Op.getSimpleValueType();
10622 MVT XLenVT = Subtarget.getXLenVT();
10630 if (Subtarget.isPExtPackedType(VT)) {
10632 SDValue TrueVInt = DAG.
getBitcast(IntVT, TrueV);
10633 SDValue FalseVInt = DAG.
getBitcast(IntVT, FalseV);
10634 SDValue ResultInt =
10642 SDValue CondSplat = DAG.
getSplat(SplatCondVT,
DL, CondV);
10652 bool FPinGPR = Subtarget.hasStdExtZfinx();
10656 Subtarget.getXLenVT().getSizeInBits());
10658 bool UseZicondForFPSel = Subtarget.hasStdExtZicond() && FPinGPR &&
10661 if (UseZicondForFPSel) {
10663 auto CastToInt = [&](SDValue
V) -> SDValue {
10668 if (VT == MVT::f16)
10669 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, V);
10671 if (VT == MVT::f32 && Subtarget.is64Bit())
10672 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, XLenVT, V);
10677 SDValue TrueVInt = CastToInt(TrueV);
10678 SDValue FalseVInt = CastToInt(FalseV);
10681 SDValue ResultInt =
10685 if (VT == MVT::f32 && Subtarget.is64Bit())
10686 return DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, VT, ResultInt);
10688 if (VT == MVT::f16)
10689 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, ResultInt);
10702 return DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV);
10705 return DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV);
10709 auto getNotOperand = [](
const SDValue &
Op) -> std::optional<const SDValue> {
10710 using namespace llvm::SDPatternMatch;
10715 return std::nullopt;
10721 auto NotOperand = (TrueV.
getOperand(0) == FalseV)
10723 : getNotOperand(TrueV.getOperand(0));
10726 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, *NotOperand, CondV);
10727 SDValue NOT = DAG.
getNOT(
DL, CMOV, VT);
10732 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV));
10739 auto NotOperand = (FalseV.
getOperand(0) == TrueV)
10741 : getNotOperand(FalseV.getOperand(0));
10744 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, *NotOperand, CondV);
10745 SDValue NOT = DAG.
getNOT(
DL, CMOV, VT);
10750 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV));
10767 int64_t TrueImm =
TrueVal.getSExtValue();
10768 int64_t FalseImm =
FalseVal.getSExtValue();
10787 if ((TrueVal - FalseVal).isPowerOf2() &&
FalseVal.isSignedIntN(12)) {
10792 if ((FalseVal - TrueVal).isPowerOf2() &&
TrueVal.isSignedIntN(12)) {
10804 if ((TrueVal - FalseVal).isPowerOf2() &&
10812 if ((FalseVal - TrueVal).isPowerOf2() && !
FalseVal.isSignedIntN(12) &&
10821 auto getCost = [&](
const APInt &Delta,
const APInt &Addend) {
10823 Delta, Subtarget.getXLen(), Subtarget,
true);
10825 if (Addend.isSignedIntN(12))
10828 Addend, Subtarget.getXLen(), Subtarget,
true);
10829 return AddendCost + DeltaCost;
10831 bool IsCZERO_NEZ =
getCost(FalseVal - TrueVal, TrueVal) <=
10832 getCost(TrueVal - FalseVal, FalseVal);
10834 IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal,
DL, VT);
10836 DAG.
getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
10837 DL, VT, LHSVal, CondV);
10845 SDValue ConstVal = IsCZERO_NEZ ? TrueV : FalseV;
10846 SDValue RegV = IsCZERO_NEZ ? FalseV : TrueV;
10852 unsigned SubOpc = (RawConstVal == -0x800) ?
ISD::XOR : ISD::
SUB;
10853 unsigned AddOpc = (RawConstVal == -0x800) ?
ISD::XOR : ISD::
ADD;
10854 SDValue SubOp = DAG.
getNode(SubOpc,
DL, VT, RegV, ConstVal);
10856 DAG.
getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
10857 DL, VT, SubOp, CondV);
10858 return DAG.
getNode(AddOpc,
DL, VT, CZERO, ConstVal);
10865 using namespace llvm::SDPatternMatch;
10872 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV),
10873 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, TrueV, CondV));
10880 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV),
10881 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, FalseV, CondV));
10887 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV),
10888 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV),
10893 if (
Op.hasOneUse()) {
10894 unsigned UseOpc =
Op->user_begin()->getOpcode();
10896 SDNode *BinOp = *
Op->user_begin();
10903 return lowerSELECT(NewSel, DAG);
10913 if (FPTV && FPFV) {
10932 SDValue
Ops[] = {CondV,
Zero, SetNE, TrueV, FalseV};
10957 if (TrueVal - 1 == FalseVal)
10959 if (TrueVal + 1 == FalseVal)
10966 RHS == TrueV &&
LHS == FalseV) {
10990 SDValue
Ops[] = {
LHS,
RHS, TargetCC, TrueV, FalseV};
10995 SDValue CondV =
Op.getOperand(1);
10997 MVT XLenVT = Subtarget.getXLenVT();
11008 return DAG.
getNode(RISCVISD::BR_CC,
DL,
Op.getValueType(),
Op.getOperand(0),
11009 LHS,
RHS, TargetCC,
Op.getOperand(2));
11012 return DAG.
getNode(RISCVISD::BR_CC,
DL,
Op.getValueType(),
Op.getOperand(0),
11019 RISCVMachineFunctionInfo *FuncInfo = MF.
getInfo<RISCVMachineFunctionInfo>();
11029 MachinePointerInfo(SV));
11034 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
11039 int XLenInBytes = Subtarget.getXLen() / 8;
11041 EVT VT =
Op.getValueType();
11044 unsigned Depth =
Op.getConstantOperandVal(0);
11046 int Offset = -(XLenInBytes * 2);
11058 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
11062 MVT XLenVT = Subtarget.getXLenVT();
11063 int XLenInBytes = Subtarget.getXLen() / 8;
11065 EVT VT =
Op.getValueType();
11067 unsigned Depth =
Op.getConstantOperandVal(0);
11069 int Off = -XLenInBytes;
11070 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
11074 MachinePointerInfo());
11086 SDValue
Lo =
Op.getOperand(0);
11087 SDValue
Hi =
Op.getOperand(1);
11088 SDValue Shamt =
Op.getOperand(2);
11089 EVT VT =
Lo.getValueType();
11090 unsigned XLen = Subtarget.getXLen();
11093 if (Subtarget.hasStdExtP()) {
11098 SDValue ShamtMasked =
11141 SDValue ShiftRightLo =
11152 SDValue Parts[2] = {
Lo,
Hi};
11157 bool IsSRA)
const {
11159 SDValue
Lo =
Op.getOperand(0);
11160 SDValue
Hi =
Op.getOperand(1);
11161 SDValue Shamt =
Op.getOperand(2);
11162 EVT VT =
Lo.getValueType();
11165 if (Subtarget.hasStdExtP()) {
11166 unsigned XLen = Subtarget.getXLen();
11169 if (Subtarget.is64Bit()) {
11177 LoRes = DAG.
getNode(IsSRA ? RISCVISD::NSRA : RISCVISD::NSRL,
DL, VT,
Lo,
11182 SDValue ShamtMasked =
11196 if (Subtarget.is64Bit()) {
11242 SDValue XLenMinus1 = DAG.
getConstant(Subtarget.getXLen() - 1,
DL, VT);
11248 SDValue ShiftLeftHi =
11251 SDValue HiTrue = DAG.
getNode(ShiftRightOp,
DL, VT,
Hi, Shamt);
11252 SDValue LoFalse = DAG.
getNode(ShiftRightOp,
DL, VT,
Hi, ShamtMinusXLen);
11261 SDValue Parts[2] = {
Lo,
Hi};
11270 MVT VT =
Op.getSimpleValueType();
11271 SDValue SplatVal =
Op.getOperand(0);
11275 return DAG.
getNode(RISCVISD::VMSET_VL,
DL, VT, VL);
11279 return DAG.
getNode(RISCVISD::VMCLR_VL,
DL, VT, VL);
11296 MVT VecVT =
Op.getSimpleValueType();
11298 "Unexpected SPLAT_VECTOR_PARTS lowering");
11301 SDValue
Lo =
Op.getOperand(0);
11302 SDValue
Hi =
Op.getOperand(1);
11304 MVT ContainerVT = VecVT;
11324 int64_t ExtTrueVal)
const {
11326 MVT VecVT =
Op.getSimpleValueType();
11327 SDValue Src =
Op.getOperand(0);
11329 assert(Src.getValueType().isVector() &&
11330 Src.getValueType().getVectorElementType() == MVT::i1);
11335 if (Src.getOpcode() ==
ISD::XOR &&
11343 MVT I1ContainerVT =
11350 MVT XLenVT = Subtarget.getXLenVT();
11355 SDValue
Xor = Src.getOperand(0);
11356 if (
Xor.getOpcode() == RISCVISD::VMXOR_VL) {
11357 SDValue ScalableOnes =
Xor.getOperand(1);
11368 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
11369 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
11370 SplatTrueVal = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
11371 DAG.
getUNDEF(ContainerVT), SplatTrueVal, VL);
11373 DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, CC, SplatTrueVal,
11374 SplatZero, DAG.
getUNDEF(ContainerVT), VL);
11385 EVT MaskVT =
Op.getValueType();
11388 "Unexpected type for vector mask lowering");
11389 SDValue Src =
Op.getOperand(0);
11390 MVT VecVT = Src.getSimpleValueType();
11392 MVT ContainerVT = VecVT;
11401 SDValue SplatOne = DAG.
getConstant(1,
DL, Subtarget.getXLenVT());
11402 SDValue SplatZero = DAG.
getConstant(0,
DL, Subtarget.getXLenVT());
11404 SplatOne = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
11405 DAG.
getUNDEF(ContainerVT), SplatOne, VL);
11406 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
11407 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
11410 SDValue Trunc = DAG.
getNode(RISCVISD::AND_VL,
DL, ContainerVT, Src, SplatOne,
11411 DAG.
getUNDEF(ContainerVT), Mask, VL);
11412 Trunc = DAG.
getNode(RISCVISD::SETCC_VL,
DL, MaskContainerVT,
11422 unsigned Opc =
Op.getOpcode();
11425 MVT VT =
Op.getSimpleValueType();
11427 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
11431 return lowerVectorMaskTrunc(
Op, DAG);
11438 SDValue Src =
Op.getOperand(0);
11439 MVT SrcVT = Src.getSimpleValueType();
11444 "Unexpected vector truncate lowering");
11446 MVT ContainerVT = SrcVT;
11457 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL_SSAT;
11459 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL_USAT;
11461 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL;
11467 }
while (SrcEltVT != DstEltVT);
11476RISCVTargetLowering::lowerStrictFPExtendOrRoundLike(
SDValue Op,
11479 SDValue Chain =
Op.getOperand(0);
11480 SDValue Src =
Op.getOperand(1);
11481 MVT VT =
Op.getSimpleValueType();
11482 MVT SrcVT = Src.getSimpleValueType();
11483 MVT ContainerVT = VT;
11502 ? RISCVISD::STRICT_FP_EXTEND_VL
11503 : RISCVISD::STRICT_VFNCVT_ROD_VL;
11506 Chain, Src, Mask, VL);
11507 Chain = Src.getValue(1);
11511 ? RISCVISD::STRICT_FP_EXTEND_VL
11512 : RISCVISD::STRICT_FP_ROUND_VL;
11514 Chain, Src, Mask, VL);
11525RISCVTargetLowering::lowerVectorFPExtendOrRound(
SDValue Op,
11532 MVT VT =
Op.getSimpleValueType();
11534 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
11536 SDValue Src =
Op.getOperand(0);
11537 MVT SrcVT = Src.getSimpleValueType();
11539 bool IsDirectExtend =
11547 bool IsDirectConv = IsDirectExtend || IsDirectTrunc;
11554 MVT ContainerVT = VT;
11564 unsigned ConvOpc = IsExtend ? RISCVISD::FP_EXTEND_VL : RISCVISD::FP_ROUND_VL;
11566 if (IsDirectConv) {
11567 Src = DAG.
getNode(ConvOpc,
DL, ContainerVT, Src, Mask, VL);
11573 unsigned InterConvOpc =
11574 IsExtend ? RISCVISD::FP_EXTEND_VL : RISCVISD::VFNCVT_ROD_VL;
11577 SDValue IntermediateConv =
11578 DAG.
getNode(InterConvOpc,
DL, InterVT, Src, Mask, VL);
11580 DAG.
getNode(ConvOpc,
DL, ContainerVT, IntermediateConv, Mask, VL);
11591static std::optional<MVT>
11597 const unsigned MinVLMAX = VectorBitsMin / EltSize;
11599 if (MaxIdx < MinVLMAX)
11601 else if (MaxIdx < MinVLMAX * 2)
11604 else if (MaxIdx < MinVLMAX * 4)
11609 return std::nullopt;
11622 MVT VecVT =
Op.getSimpleValueType();
11623 MVT XLenVT = Subtarget.getXLenVT();
11624 SDValue Vec =
Op.getOperand(0);
11625 SDValue Val =
Op.getOperand(1);
11627 SDValue Idx =
Op.getOperand(2);
11638 if ((ValVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
11639 (ValVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
11642 SDValue IntInsert = DAG.
getNode(
11644 DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Val), Idx);
11653 unsigned IdxVal = IdxC->getZExtValue();
11657 if (!Subtarget.is64Bit() && (VecVT == MVT::v4i16 || VecVT == MVT::v8i8)) {
11658 unsigned HalfNumElts = NumElts / 2;
11660 MVT HalfVT =
Lo.getSimpleValueType();
11661 if (IdxVal < HalfNumElts) {
11677 if (NumElts == 2) {
11679 SDValue Elt0, Elt1;
11694 if (NumElts == 4 || NumElts == 8) {
11696 unsigned ShiftAmt = IdxVal * EltBits;
11697 uint64_t PosMask = ((1ULL << EltBits) - 1) << ShiftAmt;
11703 DAG.
getNode(RISCVISD::MERGE,
DL, XLenVT, Mask, Vec, ShiftedVal);
11710 MVT ContainerVT = VecVT;
11719 SDValue OrigVec = Vec;
11720 std::optional<unsigned> AlignedIdx;
11722 const unsigned OrigIdx = IdxC->getZExtValue();
11725 DL, DAG, Subtarget)) {
11726 ContainerVT = *ShrunkVT;
11734 if (
auto VLEN = Subtarget.getRealVLen(); VLEN && ContainerVT.
bitsGT(M1VT)) {
11737 unsigned RemIdx = OrigIdx % ElemsPerVReg;
11738 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
11741 ContainerVT = M1VT;
11748 bool IsLegalInsert = Subtarget.is64Bit() || Val.
getValueType() != MVT::i64;
11753 if (!IsLegalInsert) {
11757 IsLegalInsert =
true;
11762 IsLegalInsert =
true;
11771 if (IsLegalInsert) {
11773 VecVT.
isFloatingPoint() ? RISCVISD::VFMV_S_F_VL : RISCVISD::VMV_S_X_VL;
11777 Vec = DAG.
getNode(
Opc,
DL, ContainerVT, Vec, Val, VL);
11792 SDValue ValLo, ValHi;
11793 std::tie(ValLo, ValHi) = DAG.
SplitScalar(Val,
DL, MVT::i32, MVT::i32);
11794 MVT I32ContainerVT =
11804 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
11805 Vec, Vec, ValLo, I32Mask, InsertI64VL);
11809 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
11810 Tail, ValInVec, ValHi, I32Mask, InsertI64VL);
11812 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
11823 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
11825 DAG.
getUNDEF(I32ContainerVT), ValLo,
11826 I32Mask, InsertI64VL);
11827 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
11828 DAG.
getUNDEF(I32ContainerVT), ValInVec, ValHi,
11829 I32Mask, InsertI64VL);
11831 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
11843 SDValue Slideup =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, Vec, ValInVec,
11844 Idx, Mask, InsertVL, Policy);
11860 SDValue Idx =
Op.getOperand(1);
11861 SDValue Vec =
Op.getOperand(0);
11862 EVT EltVT =
Op.getValueType();
11864 MVT XLenVT = Subtarget.getXLenVT();
11869 MVT ContainerVT = VecVT;
11876 DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Vec, Mask, VL);
11877 SDValue Res = DAG.
getSetCC(
DL, XLenVT, Vfirst,
11883 if (NumElts >= 8) {
11885 unsigned WidenVecLen;
11886 SDValue ExtractElementIdx;
11887 SDValue ExtractBitIdx;
11888 unsigned MaxEEW = Subtarget.getELen();
11893 "the number of elements should be power of 2");
11897 ExtractBitIdx = Idx;
11899 WideEltVT = LargestEltVT;
11902 ExtractElementIdx = DAG.
getNode(
11913 Vec, ExtractElementIdx);
11915 SDValue ShiftRight =
11928 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
11929 (EltVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
11932 SDValue IntVec = DAG.
getBitcast(IntVT, Vec);
11933 SDValue IntExtract =
11935 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, EltVT, IntExtract);
11939 if (VecVT != MVT::v4i16 && VecVT != MVT::v2i16 && VecVT != MVT::v8i8 &&
11940 VecVT != MVT::v4i8 && VecVT != MVT::v2i32)
11943 if (!Subtarget.is64Bit() && (VecVT == MVT::v4i16 || VecVT == MVT::v8i8)) {
11947 unsigned IdxVal = IdxC->getZExtValue();
11950 if (IdxVal < HalfNumElts)
11956 SDValue Extracted = DAG.
getBitcast(XLenVT, Vec);
11964 MVT ContainerVT = VecVT;
11974 const auto VLen = Subtarget.getRealVLen();
11976 IdxC && VLen && VecVT.
getSizeInBits().getKnownMinValue() > *VLen) {
11978 unsigned OrigIdx = IdxC->getZExtValue();
11981 unsigned RemIdx = OrigIdx % ElemsPerVReg;
11982 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
11983 unsigned ExtractIdx =
11987 ContainerVT = M1VT;
11992 std::optional<uint64_t> MaxIdx;
11996 MaxIdx = IdxC->getZExtValue();
11998 if (
auto SmallerVT =
12000 ContainerVT = *SmallerVT;
12027 DAG.
getUNDEF(ContainerVT), Vec, Idx, Mask, VL);
12035 SDValue Elt0 = DAG.
getNode(RISCVISD::VMV_X_S,
DL, XLenVT, Vec);
12046 "Unexpected opcode");
12053 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
12058 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
12059 if (!
II || !
II->hasScalarOperand())
12062 unsigned SplatOp =
II->ScalarOperand + 1 + HasChain;
12063 assert(SplatOp <
Op.getNumOperands());
12075 if (OpVT.
bitsLT(XLenVT)) {
12082 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
12092 assert(
II->ScalarOperand > 0 &&
"Unexpected splat operand!");
12093 MVT VT =
Op.getOperand(SplatOp - 1).getSimpleValueType();
12096 assert(XLenVT == MVT::i32 && OpVT == MVT::i64 &&
12107 case Intrinsic::riscv_vslide1up:
12108 case Intrinsic::riscv_vslide1down:
12109 case Intrinsic::riscv_vslide1up_mask:
12110 case Intrinsic::riscv_vslide1down_mask: {
12112 unsigned NumOps =
Op.getNumOperands();
12113 bool IsMasked =
NumOps == 7;
12119 std::tie(ScalarLo, ScalarHi) =
12128 const auto [MinVLMAX, MaxVLMAX] =
12132 if (AVLInt <= MinVLMAX) {
12134 }
else if (AVLInt >= 2 * MaxVLMAX) {
12168 if (IntNo == Intrinsic::riscv_vslide1up ||
12169 IntNo == Intrinsic::riscv_vslide1up_mask) {
12170 Vec = DAG.
getNode(RISCVISD::VSLIDE1UP_VL,
DL, I32VT, Passthru, Vec,
12171 ScalarHi, I32Mask, I32VL);
12172 Vec = DAG.
getNode(RISCVISD::VSLIDE1UP_VL,
DL, I32VT, Passthru, Vec,
12173 ScalarLo, I32Mask, I32VL);
12175 Vec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32VT, Passthru, Vec,
12176 ScalarLo, I32Mask, I32VL);
12177 Vec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32VT, Passthru, Vec,
12178 ScalarHi, I32Mask, I32VL);
12196 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, Mask, Vec, MaskedOff,
12200 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, Mask, Vec, MaskedOff,
12227 const unsigned ElementWidth = 8;
12232 [[maybe_unused]]
unsigned MinVF =
12235 [[maybe_unused]]
unsigned VF =
N->getConstantOperandVal(2);
12239 bool Fractional = VF < LMul1VF;
12240 unsigned LMulVal = Fractional ? LMul1VF / VF : VF / LMul1VF;
12261 MVT ContainerVT = OpVT;
12269 SDValue Res = DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Op0, Mask, VL);
12277 return DAG.
getSelect(
DL, XLenVT, Setcc, VL, Res);
12283 const uint64_t SemEnum =
Op->getConstantOperandVal(1);
12290 EVT SrcEVT = Src.getValueType();
12294 MVT DstVT =
Op.getSimpleValueType();
12298 MVT SrcContainerVT = SrcVT;
12299 MVT DstContainerVT = DstVT;
12327 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
12331 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
12332 if (!
II || !
II->hasScalarOperand())
12335 unsigned SplatOp =
II->ScalarOperand + 1;
12336 assert(SplatOp <
Op.getNumOperands());
12348 if (OpVT.
bitsLT(XLenVT)) {
12351 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
12362 EVT ValType = V.getValueType();
12363 if (ValType.isVector() && ValType.isFloatingPoint()) {
12366 ValType.getVectorElementCount());
12369 if (ValType.isFixedLengthVector()) {
12370 MVT OpContainerVT =
12389 "Unexpected RISC-V packed saturating and rounding shift intrinsic");
12390 case Intrinsic::riscv_psll:
12391 return RISCVISD::PSLL;
12392 case Intrinsic::riscv_psrl:
12393 return RISCVISD::PSRL;
12394 case Intrinsic::riscv_psra:
12395 return RISCVISD::PSRA;
12396 case Intrinsic::riscv_pssha:
12397 return RISCVISD::PSSHA;
12398 case Intrinsic::riscv_psshar:
12399 return RISCVISD::PSSHAR;
12400 case Intrinsic::riscv_psshl:
12401 return RISCVISD::PSSHL;
12402 case Intrinsic::riscv_psshlr:
12403 return RISCVISD::PSSHLR;
12411 case Intrinsic::riscv_pnsrl:
12412 return RISCVISD::PNSRL;
12413 case Intrinsic::riscv_pnsra:
12414 return RISCVISD::PNSRA;
12415 case Intrinsic::riscv_pnsrar:
12416 return RISCVISD::PNSRAR;
12422 MVT VT = Src.getSimpleValueType();
12437 case Intrinsic::riscv_pmulhr:
12438 return RISCVISD::MULHR;
12439 case Intrinsic::riscv_pmulhru:
12440 return RISCVISD::MULHRU;
12441 case Intrinsic::riscv_pmulhsu:
12442 return RISCVISD::MULHSU;
12443 case Intrinsic::riscv_pmulhrsu:
12444 return RISCVISD::MULHRSU;
12452 case Intrinsic::riscv_mulhr_i32:
12453 return RISCVISD::MULHR;
12454 case Intrinsic::riscv_mulhru_u32:
12455 return RISCVISD::MULHRU;
12456 case Intrinsic::riscv_mulhsu_i32:
12457 return RISCVISD::MULHSU;
12458 case Intrinsic::riscv_mulhrsu_i32:
12459 return RISCVISD::MULHRSU;
12467 "Unexpected RISC-V packed multiply high accumulate intrinsic");
12468 case Intrinsic::riscv_pmhacc:
12469 return RISCVISD::MHACC;
12470 case Intrinsic::riscv_pmhracc:
12471 return RISCVISD::MHRACC;
12472 case Intrinsic::riscv_pmhaccu:
12473 return RISCVISD::MHACCU;
12474 case Intrinsic::riscv_pmhraccu:
12475 return RISCVISD::MHRACCU;
12476 case Intrinsic::riscv_pmhaccsu:
12477 return RISCVISD::MHACCSU;
12478 case Intrinsic::riscv_pmhraccsu:
12479 return RISCVISD::MHRACCSU;
12488 "halves intrinsic");
12489 case Intrinsic::riscv_pmhacc_b0:
12490 return RISCVISD::MHACC_H_B0;
12491 case Intrinsic::riscv_pmhacc_b1:
12492 return RISCVISD::MHACC_H_B1;
12493 case Intrinsic::riscv_pmhaccsu_b0:
12494 return RISCVISD::MHACCSU_H_B0;
12495 case Intrinsic::riscv_pmhaccsu_b1:
12496 return RISCVISD::MHACCSU_H_B1;
12497 case Intrinsic::riscv_pmhacc_h0:
12498 return RISCVISD::MHACC_W_H0;
12499 case Intrinsic::riscv_pmhacc_h1:
12500 return RISCVISD::MHACC_W_H1;
12501 case Intrinsic::riscv_pmhaccsu_h0:
12502 return RISCVISD::MHACCSU_W_H0;
12503 case Intrinsic::riscv_pmhaccsu_h1:
12504 return RISCVISD::MHACCSU_W_H1;
12515 case Intrinsic::riscv_pmulh_b0:
12516 return RISCVISD::PMULH_H_B0;
12517 case Intrinsic::riscv_pmulh_b1:
12518 return RISCVISD::PMULH_H_B1;
12519 case Intrinsic::riscv_pmulhsu_b0:
12520 return RISCVISD::PMULHSU_H_B0;
12521 case Intrinsic::riscv_pmulhsu_b1:
12522 return RISCVISD::PMULHSU_H_B1;
12533 case Intrinsic::riscv_pmulh_h0:
12534 case Intrinsic::riscv_mulh_h0:
12535 return RISCVISD::PMULH_W_H0;
12536 case Intrinsic::riscv_pmulh_h1:
12537 case Intrinsic::riscv_mulh_h1:
12538 return RISCVISD::PMULH_W_H1;
12539 case Intrinsic::riscv_pmulhsu_h0:
12540 case Intrinsic::riscv_mulhsu_h0:
12541 return RISCVISD::PMULHSU_W_H0;
12542 case Intrinsic::riscv_pmulhsu_h1:
12543 case Intrinsic::riscv_mulhsu_h1:
12544 return RISCVISD::PMULHSU_W_H1;
12554 llvm_unreachable(
"Unexpected RISC-V scalar multiply-high-parts intrinsic");
12555 case Intrinsic::riscv_pmulh_h0:
12556 case Intrinsic::riscv_mulh_h0:
12557 return RISCVISD::MULH_H0;
12558 case Intrinsic::riscv_pmulh_h1:
12559 case Intrinsic::riscv_mulh_h1:
12560 return RISCVISD::MULH_H1;
12561 case Intrinsic::riscv_pmulhsu_h0:
12562 case Intrinsic::riscv_mulhsu_h0:
12563 return RISCVISD::MULHSU_H0;
12564 case Intrinsic::riscv_pmulhsu_h1:
12565 case Intrinsic::riscv_mulhsu_h1:
12566 return RISCVISD::MULHSU_H1;
12573 llvm_unreachable(
"Unexpected RISC-V packed Q-format accumulate intrinsic");
12574 case Intrinsic::riscv_mqacc_00:
12575 case Intrinsic::riscv_pmqacc_h00:
12576 return RISCVISD::MQACC_00;
12577 case Intrinsic::riscv_mqacc_01:
12578 case Intrinsic::riscv_pmqacc_h01:
12579 return RISCVISD::MQACC_01;
12580 case Intrinsic::riscv_mqacc_11:
12581 case Intrinsic::riscv_pmqacc_h11:
12582 return RISCVISD::MQACC_11;
12583 case Intrinsic::riscv_mqracc_00:
12584 case Intrinsic::riscv_pmqracc_h00:
12585 return RISCVISD::MQRACC_00;
12586 case Intrinsic::riscv_mqracc_01:
12587 case Intrinsic::riscv_pmqracc_h01:
12588 return RISCVISD::MQRACC_01;
12589 case Intrinsic::riscv_mqracc_11:
12590 case Intrinsic::riscv_pmqracc_h11:
12591 return RISCVISD::MQRACC_11;
12598 llvm_unreachable(
"Unexpected RISC-V packed Q-format accumulate intrinsic");
12599 case Intrinsic::riscv_mqacc_00:
12600 case Intrinsic::riscv_pmqacc_h00:
12601 return RISCVISD::PMQACC_W_H00;
12602 case Intrinsic::riscv_mqacc_01:
12603 case Intrinsic::riscv_pmqacc_h01:
12604 return RISCVISD::PMQACC_W_H01;
12605 case Intrinsic::riscv_mqacc_11:
12606 case Intrinsic::riscv_pmqacc_h11:
12607 return RISCVISD::PMQACC_W_H11;
12608 case Intrinsic::riscv_mqracc_00:
12609 case Intrinsic::riscv_pmqracc_h00:
12610 return RISCVISD::PMQRACC_W_H00;
12611 case Intrinsic::riscv_mqracc_01:
12612 case Intrinsic::riscv_pmqracc_h01:
12613 return RISCVISD::PMQRACC_W_H01;
12614 case Intrinsic::riscv_mqracc_11:
12615 case Intrinsic::riscv_pmqracc_h11:
12616 return RISCVISD::PMQRACC_W_H11;
12623 llvm_unreachable(
"Unexpected RISC-V packed horizontal multiply intrinsic");
12624 case Intrinsic::riscv_pm4add:
12625 return RISCVISD::PM4ADD;
12626 case Intrinsic::riscv_pm2add:
12627 return RISCVISD::PM2ADD;
12628 case Intrinsic::riscv_pm2add_x:
12629 return RISCVISD::PM2ADD_X;
12630 case Intrinsic::riscv_pm4addu:
12631 return RISCVISD::PM4ADDU;
12632 case Intrinsic::riscv_pm2addu:
12633 return RISCVISD::PM2ADDU;
12634 case Intrinsic::riscv_pmq2add:
12635 return RISCVISD::PMQ2ADD;
12636 case Intrinsic::riscv_pmqr2add:
12637 return RISCVISD::PMQR2ADD;
12638 case Intrinsic::riscv_pm2sadd:
12639 return RISCVISD::PM2SADD;
12640 case Intrinsic::riscv_pm2sadd_x:
12641 return RISCVISD::PM2SADD_X;
12642 case Intrinsic::riscv_pm2sub:
12643 return RISCVISD::PM2SUB;
12644 case Intrinsic::riscv_pm2sub_x:
12645 return RISCVISD::PM2SUB_X;
12646 case Intrinsic::riscv_pm4addsu:
12647 return RISCVISD::PM4ADDSU;
12648 case Intrinsic::riscv_pm2addsu:
12649 return RISCVISD::PM2ADDSU;
12656 auto Extract = [&](
SDValue V,
unsigned Idx) {
12663 unsigned MulOpc, AccOpc;
12667 case Intrinsic::riscv_pm4add:
12668 MulOpc = RISCVISD::PM2WADD;
12669 AccOpc = RISCVISD::PM2WADDA;
12671 case Intrinsic::riscv_pm4addu:
12672 MulOpc = RISCVISD::PM2WADDU;
12673 AccOpc = RISCVISD::PM2WADDAU;
12675 case Intrinsic::riscv_pm4addsu:
12676 MulOpc = RISCVISD::PM2WADDSU;
12677 AccOpc = RISCVISD::PM2WADDASU;
12681 Acc = DAG.
getNode(AccOpc,
DL, MVT::v2i32, Acc, Rs1Hi, Rs2Hi);
12686 "Unexpected RV32 horizontal multiply source type");
12687 SDValue Rs1Lo = Extract(Rs1, 0);
12688 SDValue Rs1Hi = Extract(Rs1, 1);
12689 SDValue Rs2Lo = Extract(Rs2, 0);
12690 SDValue Rs2Hi = Extract(Rs2, 1);
12692 if (IntNo == Intrinsic::riscv_pmq2add || IntNo == Intrinsic::riscv_pmqr2add) {
12693 unsigned AccOpc = IntNo == Intrinsic::riscv_pmq2add ? RISCVISD::MQWACC
12694 : RISCVISD::MQRWACC;
12703 if (IntNo == Intrinsic::riscv_pm2addu)
12705 else if (IntNo == Intrinsic::riscv_pm2addsu)
12706 MulOpc = RISCVISD::WMULSU;
12708 IntNo == Intrinsic::riscv_pm2sub || IntNo == Intrinsic::riscv_pm2sub_x;
12709 if (IntNo == Intrinsic::riscv_pm2add_x || IntNo == Intrinsic::riscv_pm2sub_x)
12715 unsigned Opc = IsSub ? RISCVISD::SUBD : RISCVISD::ADDD;
12727 case Intrinsic::riscv_pmul_00:
12728 case Intrinsic::riscv_mul_00:
12729 return RISCVISD::PMUL_HALVES_00;
12730 case Intrinsic::riscv_pmul_01:
12731 case Intrinsic::riscv_mul_01:
12732 return RISCVISD::PMUL_HALVES_01;
12733 case Intrinsic::riscv_pmul_11:
12734 case Intrinsic::riscv_mul_11:
12735 return RISCVISD::PMUL_HALVES_11;
12736 case Intrinsic::riscv_pmulu_00:
12737 case Intrinsic::riscv_mulu_00:
12738 return RISCVISD::PMULU_HALVES_00;
12739 case Intrinsic::riscv_pmulu_01:
12740 case Intrinsic::riscv_mulu_01:
12741 return RISCVISD::PMULU_HALVES_01;
12742 case Intrinsic::riscv_pmulu_11:
12743 case Intrinsic::riscv_mulu_11:
12744 return RISCVISD::PMULU_HALVES_11;
12745 case Intrinsic::riscv_pmulsu_00:
12746 case Intrinsic::riscv_mulsu_00:
12747 return RISCVISD::PMULSU_HALVES_00;
12748 case Intrinsic::riscv_pmulsu_11:
12749 case Intrinsic::riscv_mulsu_11:
12750 return RISCVISD::PMULSU_HALVES_11;
12760 case Intrinsic::riscv_pmul_00:
12761 return Intrinsic::riscv_mul_00;
12762 case Intrinsic::riscv_pmul_01:
12763 return Intrinsic::riscv_mul_01;
12764 case Intrinsic::riscv_pmul_11:
12765 return Intrinsic::riscv_mul_11;
12766 case Intrinsic::riscv_pmulu_00:
12767 return Intrinsic::riscv_mulu_00;
12768 case Intrinsic::riscv_pmulu_01:
12769 return Intrinsic::riscv_mulu_01;
12770 case Intrinsic::riscv_pmulu_11:
12771 return Intrinsic::riscv_mulu_11;
12772 case Intrinsic::riscv_pmulsu_00:
12773 return Intrinsic::riscv_mulsu_00;
12774 case Intrinsic::riscv_pmulsu_11:
12775 return Intrinsic::riscv_mulsu_11;
12785 case Intrinsic::riscv_mul_00:
12786 return Intrinsic::riscv_macc_00;
12787 case Intrinsic::riscv_pmul_00:
12788 return Intrinsic::riscv_pmacc_00;
12789 case Intrinsic::riscv_mul_01:
12790 return Intrinsic::riscv_macc_01;
12791 case Intrinsic::riscv_pmul_01:
12792 return Intrinsic::riscv_pmacc_01;
12793 case Intrinsic::riscv_mul_11:
12794 return Intrinsic::riscv_macc_11;
12795 case Intrinsic::riscv_pmul_11:
12796 return Intrinsic::riscv_pmacc_11;
12797 case Intrinsic::riscv_mulu_00:
12798 return Intrinsic::riscv_maccu_00;
12799 case Intrinsic::riscv_pmulu_00:
12800 return Intrinsic::riscv_pmaccu_00;
12801 case Intrinsic::riscv_mulu_01:
12802 return Intrinsic::riscv_maccu_01;
12803 case Intrinsic::riscv_pmulu_01:
12804 return Intrinsic::riscv_pmaccu_01;
12805 case Intrinsic::riscv_mulu_11:
12806 return Intrinsic::riscv_maccu_11;
12807 case Intrinsic::riscv_pmulu_11:
12808 return Intrinsic::riscv_pmaccu_11;
12809 case Intrinsic::riscv_mulsu_00:
12810 return Intrinsic::riscv_maccsu_00;
12811 case Intrinsic::riscv_pmulsu_00:
12812 return Intrinsic::riscv_pmaccsu_00;
12813 case Intrinsic::riscv_mulsu_11:
12814 return Intrinsic::riscv_maccsu_11;
12815 case Intrinsic::riscv_pmulsu_11:
12816 return Intrinsic::riscv_pmaccsu_11;
12824 llvm_unreachable(
"Unexpected RISC-V multiply-parts accumulate intrinsic");
12825 case Intrinsic::riscv_pmacc_00:
12826 case Intrinsic::riscv_macc_00:
12827 return RISCVISD::PMACC_HALVES_00;
12828 case Intrinsic::riscv_pmacc_01:
12829 case Intrinsic::riscv_macc_01:
12830 return RISCVISD::PMACC_HALVES_01;
12831 case Intrinsic::riscv_pmacc_11:
12832 case Intrinsic::riscv_macc_11:
12833 return RISCVISD::PMACC_HALVES_11;
12834 case Intrinsic::riscv_pmaccu_00:
12835 case Intrinsic::riscv_maccu_00:
12836 return RISCVISD::PMACCU_HALVES_00;
12837 case Intrinsic::riscv_pmaccu_01:
12838 case Intrinsic::riscv_maccu_01:
12839 return RISCVISD::PMACCU_HALVES_01;
12840 case Intrinsic::riscv_pmaccu_11:
12841 case Intrinsic::riscv_maccu_11:
12842 return RISCVISD::PMACCU_HALVES_11;
12843 case Intrinsic::riscv_pmaccsu_00:
12844 case Intrinsic::riscv_maccsu_00:
12845 return RISCVISD::PMACCSU_HALVES_00;
12846 case Intrinsic::riscv_pmaccsu_11:
12847 case Intrinsic::riscv_maccsu_11:
12848 return RISCVISD::PMACCSU_HALVES_11;
12853static std::tuple<unsigned, unsigned, unsigned>
12858 case Intrinsic::riscv_mul_00:
12860 case Intrinsic::riscv_mul_01:
12862 case Intrinsic::riscv_mul_11:
12864 case Intrinsic::riscv_mulu_00:
12866 case Intrinsic::riscv_mulu_01:
12868 case Intrinsic::riscv_mulu_11:
12870 case Intrinsic::riscv_mulsu_00:
12871 return {RISCVISD::WMULSU, 0, 0};
12872 case Intrinsic::riscv_mulsu_11:
12873 return {RISCVISD::WMULSU, 1, 1};
12879static std::tuple<unsigned, unsigned, unsigned>
12883 llvm_unreachable(
"Unexpected RISC-V multiply-parts accumulate intrinsic");
12884 case Intrinsic::riscv_macc_00:
12885 return {RISCVISD::WMACC, 0, 0};
12886 case Intrinsic::riscv_macc_01:
12887 return {RISCVISD::WMACC, 0, 1};
12888 case Intrinsic::riscv_macc_11:
12889 return {RISCVISD::WMACC, 1, 1};
12890 case Intrinsic::riscv_maccu_00:
12891 return {RISCVISD::WMACCU, 0, 0};
12892 case Intrinsic::riscv_maccu_01:
12893 return {RISCVISD::WMACCU, 0, 1};
12894 case Intrinsic::riscv_maccu_11:
12895 return {RISCVISD::WMACCU, 1, 1};
12896 case Intrinsic::riscv_maccsu_00:
12897 return {RISCVISD::WMACCSU, 0, 0};
12898 case Intrinsic::riscv_maccsu_11:
12899 return {RISCVISD::WMACCSU, 1, 1};
12905 unsigned IntNo =
Op.getConstantOperandVal(0);
12907 MVT XLenVT = Subtarget.getXLenVT();
12912 case Intrinsic::riscv_tuple_insert: {
12913 SDValue Vec =
Op.getOperand(1);
12914 SDValue SubVec =
Op.getOperand(2);
12915 SDValue
Index =
Op.getOperand(3);
12917 return DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL,
Op.getValueType(), Vec,
12920 case Intrinsic::riscv_tuple_extract: {
12921 SDValue Vec =
Op.getOperand(1);
12922 SDValue
Index =
Op.getOperand(2);
12924 return DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL,
Op.getValueType(), Vec,
12927 case Intrinsic::thread_pointer: {
12931 case Intrinsic::riscv_pmul_00:
12932 case Intrinsic::riscv_pmul_01:
12933 case Intrinsic::riscv_pmul_11:
12934 case Intrinsic::riscv_pmulu_00:
12935 case Intrinsic::riscv_pmulu_01:
12936 case Intrinsic::riscv_pmulu_11:
12937 case Intrinsic::riscv_pmulsu_00:
12938 case Intrinsic::riscv_pmulsu_11: {
12939 MVT VT =
Op.getSimpleValueType();
12940 SDValue Rs1 =
Op.getOperand(1);
12941 SDValue Rs2 =
Op.getOperand(2);
12943 if (!Subtarget.isPExtPackedDoubleType(VT))
12950 if (VT == MVT::v2i32) {
12965 case Intrinsic::riscv_pmacc_00:
12966 case Intrinsic::riscv_pmacc_01:
12967 case Intrinsic::riscv_pmacc_11:
12968 case Intrinsic::riscv_pmaccu_00:
12969 case Intrinsic::riscv_pmaccu_01:
12970 case Intrinsic::riscv_pmaccu_11:
12971 case Intrinsic::riscv_pmaccsu_00:
12972 case Intrinsic::riscv_pmaccsu_11:
12973 case Intrinsic::riscv_macc_00:
12974 case Intrinsic::riscv_macc_01:
12975 case Intrinsic::riscv_macc_11:
12976 case Intrinsic::riscv_maccu_00:
12977 case Intrinsic::riscv_maccu_01:
12978 case Intrinsic::riscv_maccu_11:
12979 case Intrinsic::riscv_maccsu_00:
12980 case Intrinsic::riscv_maccsu_11: {
12981 MVT VT =
Op.getSimpleValueType();
12982 SDValue Rd =
Op.getOperand(1);
12983 SDValue Rs1 =
Op.getOperand(2);
12984 SDValue Rs2 =
Op.getOperand(3);
12986 if (VT != MVT::v2i32 || !Subtarget.isPExtPackedDoubleType(VT))
13001 case Intrinsic::riscv_pas:
13002 case Intrinsic::riscv_psa:
13003 case Intrinsic::riscv_psas:
13004 case Intrinsic::riscv_pssa:
13005 case Intrinsic::riscv_paas:
13006 case Intrinsic::riscv_pasa: {
13010 if (Subtarget.is64Bit() ||
Op.getSimpleValueType() != MVT::v2i32)
13013 unsigned EvenOpc, OddOpc;
13015 case Intrinsic::riscv_pas:
13019 case Intrinsic::riscv_psa:
13023 case Intrinsic::riscv_psas:
13027 case Intrinsic::riscv_pssa:
13031 case Intrinsic::riscv_paas:
13032 EvenOpc = RISCVISD::ASUB;
13035 case Intrinsic::riscv_pasa:
13037 OddOpc = RISCVISD::ASUB;
13043 SDValue
S1 =
Op.getOperand(1);
13044 SDValue S2 =
Op.getOperand(2);
13050 SDValue REven = DAG.
getNode(EvenOpc,
DL, MVT::i32, S1Even, S2Odd);
13051 SDValue ROdd = DAG.
getNode(OddOpc,
DL, MVT::i32, S1Odd, S2Even);
13054 case Intrinsic::riscv_orc_b:
13055 case Intrinsic::riscv_brev8:
13056 case Intrinsic::riscv_sha256sig0:
13057 case Intrinsic::riscv_sha256sig1:
13058 case Intrinsic::riscv_sha256sum0:
13059 case Intrinsic::riscv_sha256sum1:
13060 case Intrinsic::riscv_sm3p0:
13061 case Intrinsic::riscv_sm3p1: {
13064 case Intrinsic::riscv_orc_b:
Opc = RISCVISD::ORC_B;
break;
13065 case Intrinsic::riscv_brev8:
Opc = RISCVISD::BREV8;
break;
13066 case Intrinsic::riscv_sha256sig0:
Opc = RISCVISD::SHA256SIG0;
break;
13067 case Intrinsic::riscv_sha256sig1:
Opc = RISCVISD::SHA256SIG1;
break;
13068 case Intrinsic::riscv_sha256sum0:
Opc = RISCVISD::SHA256SUM0;
break;
13069 case Intrinsic::riscv_sha256sum1:
Opc = RISCVISD::SHA256SUM1;
break;
13070 case Intrinsic::riscv_sm3p0:
Opc = RISCVISD::SM3P0;
break;
13071 case Intrinsic::riscv_sm3p1:
Opc = RISCVISD::SM3P1;
break;
13076 case Intrinsic::riscv_sm4ks:
13077 case Intrinsic::riscv_sm4ed: {
13079 IntNo == Intrinsic::riscv_sm4ks ? RISCVISD::SM4KS : RISCVISD::SM4ED;
13084 case Intrinsic::riscv_zip:
13085 case Intrinsic::riscv_unzip: {
13087 IntNo == Intrinsic::riscv_zip ? RISCVISD::ZIP : RISCVISD::UNZIP;
13090 case Intrinsic::riscv_mopr:
13091 return DAG.
getNode(RISCVISD::MOP_R,
DL, XLenVT,
Op.getOperand(1),
13094 case Intrinsic::riscv_moprr: {
13095 return DAG.
getNode(RISCVISD::MOP_RR,
DL, XLenVT,
Op.getOperand(1),
13096 Op.getOperand(2),
Op.getOperand(3));
13098 case Intrinsic::riscv_clmulh:
13099 case Intrinsic::riscv_clmulr: {
13103 case Intrinsic::riscv_paadd:
13104 case Intrinsic::riscv_paaddu:
13105 case Intrinsic::riscv_pasub:
13106 case Intrinsic::riscv_pasubu:
13107 case Intrinsic::riscv_pabd:
13108 case Intrinsic::riscv_pabdu:
13109 case Intrinsic::riscv_psabs: {
13112 case Intrinsic::riscv_paadd:
13115 case Intrinsic::riscv_paaddu:
13118 case Intrinsic::riscv_pasub:
13119 Opc = RISCVISD::ASUB;
13121 case Intrinsic::riscv_pasubu:
13122 Opc = RISCVISD::ASUBU;
13124 case Intrinsic::riscv_pabd:
13127 case Intrinsic::riscv_pabdu:
13130 case Intrinsic::riscv_psabs:
13131 Opc = RISCVISD::PSABS;
13135 if (IntNo == Intrinsic::riscv_psabs)
13141 case Intrinsic::riscv_pnclipp:
13142 case Intrinsic::riscv_pnclipup: {
13143 bool IsSigned = IntNo == Intrinsic::riscv_pnclipp;
13144 EVT VT =
Op.getValueType();
13145 SDValue Rs1 =
Op.getOperand(1);
13146 SDValue Rs2 =
Op.getOperand(2);
13147 if (Subtarget.is64Bit()) {
13149 unsigned WOpc = IsSigned ? RISCVISD::PNCLIPP_W : RISCVISD::PNCLIPUP_W;
13150 return DAG.
getNode(WOpc,
DL, VT, Rs1, Rs2);
13152 unsigned Opc = IsSigned ? RISCVISD::PNCLIPP : RISCVISD::PNCLIPUP;
13156 MVT XLenVT = Subtarget.getXLenVT();
13158 if (VT == MVT::v4i8) {
13159 unsigned ClipOpc = IsSigned ? RISCVISD::PNCLIP : RISCVISD::PNCLIPU;
13161 return DAG.
getNode(ClipOpc,
DL, VT, Pair, Shift);
13163 if (VT == MVT::v2i16) {
13164 unsigned ClipOpc = IsSigned ? RISCVISD::PNCLIP : RISCVISD::PNCLIPU;
13166 return DAG.
getNode(ClipOpc,
DL, VT, Pair, Shift);
13168 if (VT == MVT::v2i32) {
13169 unsigned ClipOpc = IsSigned ? RISCVISD::NCLIP : RISCVISD::NCLIPU;
13170 auto [Rs1Lo, Rs1Hi] = DAG.
SplitScalar(Rs1,
DL, XLenVT, XLenVT);
13171 auto [Rs2Lo, Rs2Hi] = DAG.
SplitScalar(Rs2,
DL, XLenVT, XLenVT);
13172 SDValue
Lo = DAG.
getNode(ClipOpc,
DL, XLenVT, Rs1Lo, Rs1Hi, Shift);
13173 SDValue
Hi = DAG.
getNode(ClipOpc,
DL, XLenVT, Rs2Lo, Rs2Hi, Shift);
13176 if (VT == MVT::v8i8 || VT == MVT::v4i16) {
13177 unsigned ClipOpc = IsSigned ? RISCVISD::PNCLIP : RISCVISD::PNCLIPU;
13178 MVT HalfVT = VT == MVT::v8i8 ? MVT::v4i8 : MVT::v2i16;
13179 SDValue
Lo = DAG.
getNode(ClipOpc,
DL, HalfVT, Rs1, Shift);
13180 SDValue
Hi = DAG.
getNode(ClipOpc,
DL, HalfVT, Rs2, Shift);
13186 case Intrinsic::riscv_mqacc_00:
13187 case Intrinsic::riscv_mqacc_01:
13188 case Intrinsic::riscv_mqacc_11:
13189 case Intrinsic::riscv_mqracc_00:
13190 case Intrinsic::riscv_mqracc_01:
13191 case Intrinsic::riscv_mqracc_11:
13192 case Intrinsic::riscv_pmqacc_h00:
13193 case Intrinsic::riscv_pmqacc_h01:
13194 case Intrinsic::riscv_pmqacc_h11:
13195 case Intrinsic::riscv_pmqracc_h00:
13196 case Intrinsic::riscv_pmqracc_h01:
13197 case Intrinsic::riscv_pmqracc_h11: {
13198 EVT VT =
Op.getValueType();
13199 SDValue Rd =
Op.getOperand(1);
13200 SDValue Rs1 =
Op.getOperand(2);
13201 SDValue Rs2 =
Op.getOperand(3);
13202 MVT XLenVT = Subtarget.getXLenVT();
13205 if (Subtarget.is64Bit()) {
13215 SDValue
Lo = DAG.
getNode(ScalarOpc,
DL, XLenVT, RdLo, Rs1Lo, Rs2Lo);
13216 SDValue
Hi = DAG.
getNode(ScalarOpc,
DL, XLenVT, RdHi, Rs1Hi, Rs2Hi);
13220 if (VT == XLenVT) {
13227 case Intrinsic::riscv_pmulq:
13228 case Intrinsic::riscv_pmulqr: {
13231 case Intrinsic::riscv_pmulq:
13232 Opc = RISCVISD::MULQ;
13234 case Intrinsic::riscv_pmulqr:
13235 Opc = RISCVISD::MULQR;
13239 EVT VT =
Op.getValueType();
13240 SDValue Rs1 =
Op.getOperand(1);
13241 SDValue Rs2 =
Op.getOperand(2);
13247 if (!Subtarget.is64Bit()) {
13248 if (VT == MVT::v2i32) {
13249 MVT XLenVT = Subtarget.getXLenVT();
13254 SDValue LoRes = DAG.
getNode(
Opc,
DL, XLenVT, Lo1, Lo2);
13255 SDValue HiRes = DAG.
getNode(
Opc,
DL, XLenVT, Hi1, Hi2);
13258 if (VT == MVT::v4i16) {
13261 SDValue LoRes = DAG.
getNode(
Opc,
DL, MVT::v2i16, Rs1Lo, Rs2Lo);
13262 SDValue HiRes = DAG.
getNode(
Opc,
DL, MVT::v2i16, Rs1Hi, Rs2Hi);
13269 case Intrinsic::riscv_psll:
13270 case Intrinsic::riscv_psrl:
13271 case Intrinsic::riscv_psra:
13272 case Intrinsic::riscv_pssha:
13273 case Intrinsic::riscv_psshar:
13274 case Intrinsic::riscv_psshl:
13275 case Intrinsic::riscv_psshlr: {
13276 SDValue ShAmt =
Op.getOperand(2);
13279 Op.getOperand(1), ShAmt);
13281 case Intrinsic::riscv_pwsll:
13282 case Intrinsic::riscv_pwsla: {
13283 MVT VT =
Op.getSimpleValueType();
13284 SDValue Src =
Op.getOperand(1);
13285 MVT SrcVT = Src.getSimpleValueType();
13286 if (!((VT == MVT::v4i16 && SrcVT == MVT::v4i8) ||
13287 (VT == MVT::v2i32 && SrcVT == MVT::v2i16)))
13291 bool IsSigned = IntNo == Intrinsic::riscv_pwsla;
13292 if (!Subtarget.is64Bit()) {
13293 unsigned Opc = IsSigned ? RISCVISD::PWSLA : RISCVISD::PWSLL;
13298 SDValue Wide = DAG.
getNode(ExtOpc,
DL, VT, Src);
13299 return DAG.
getNode(RISCVISD::PSLL,
DL, VT, Wide, ShAmt);
13301 case Intrinsic::riscv_pnsrl:
13302 case Intrinsic::riscv_pnsra:
13303 case Intrinsic::riscv_pnsrar: {
13304 MVT VT =
Op.getSimpleValueType();
13305 MVT SrcVT =
Op.getOperand(1).getSimpleValueType();
13306 if (!((VT == MVT::v4i8 && SrcVT == MVT::v4i16) ||
13307 (VT == MVT::v2i16 && SrcVT == MVT::v2i32)))
13312 Op.getOperand(1), ShAmt);
13314 case Intrinsic::riscv_psati:
13315 case Intrinsic::riscv_pusati: {
13316 bool IsSigned = IntNo == Intrinsic::riscv_psati;
13317 unsigned Opc = IsSigned ? RISCVISD::SATI : RISCVISD::USATI;
13319 unsigned Width =
Op.getConstantOperandVal(2) - (IsSigned ? 1 : 0);
13323 case Intrinsic::riscv_psext_b:
13324 case Intrinsic::riscv_psext_h: {
13325 EVT VT =
Op.getValueType();
13330 unsigned SrcEltBits = IntNo == Intrinsic::riscv_psext_b ? 8 : 16;
13339 case Intrinsic::riscv_pzext_b:
13340 case Intrinsic::riscv_pzext_h: {
13341 EVT VT =
Op.getValueType();
13346 unsigned SrcEltBits = IntNo == Intrinsic::riscv_pzext_b ? 8 : 16;
13352 case Intrinsic::riscv_pabdsumu:
13353 case Intrinsic::riscv_pabdsumau: {
13362 bool IsAcc = IntNo == Intrinsic::riscv_pabdsumau;
13365 SDValue AbdsumuId =
13367 SDValue AbdsumauId =
13370 AbdsumauId,
Op.getOperand(1), Rs1Lo, Rs2Lo)
13372 AbdsumuId, Rs1Lo, Rs2Lo);
13376 case Intrinsic::riscv_pmulhr:
13377 case Intrinsic::riscv_pmulhru:
13378 case Intrinsic::riscv_pmulhsu:
13379 case Intrinsic::riscv_pmulhrsu: {
13380 EVT VT =
Op.getValueType();
13386 if (!Subtarget.is64Bit() && VT == MVT::v4i16) {
13394 if (!Subtarget.is64Bit() && VT == MVT::v2i32) {
13395 auto Extract = [&](SDValue
V,
unsigned Idx) {
13398 SDValue Rs1 =
Op.getOperand(1);
13399 SDValue Rs2 =
Op.getOperand(2);
13401 DAG.
getNode(
Opc,
DL, MVT::i32, Extract(Rs1, 0), Extract(Rs2, 0));
13403 DAG.
getNode(
Opc,
DL, MVT::i32, Extract(Rs1, 1), Extract(Rs2, 1));
13409 case Intrinsic::riscv_mulhr_i32:
13410 case Intrinsic::riscv_mulhru_u32:
13411 case Intrinsic::riscv_mulhsu_i32:
13412 case Intrinsic::riscv_mulhrsu_i32: {
13416 return DAG.
getNode(
Opc,
DL, MVT::i32,
Op.getOperand(1),
Op.getOperand(2));
13418 case Intrinsic::riscv_pmhacc:
13419 case Intrinsic::riscv_pmhracc:
13420 case Intrinsic::riscv_pmhaccu:
13421 case Intrinsic::riscv_pmhraccu:
13422 case Intrinsic::riscv_pmhaccsu:
13423 case Intrinsic::riscv_pmhraccsu: {
13424 EVT VT =
Op.getValueType();
13426 SDValue Rd =
Op.getOperand(1);
13427 SDValue Rs1 =
Op.getOperand(2);
13428 SDValue Rs2 =
Op.getOperand(3);
13433 if (!Subtarget.is64Bit() && VT == MVT::v4i16) {
13437 SDValue
Lo = DAG.
getNode(MulOpc,
DL, MVT::v2i16, RdLo, Rs1Lo, Rs2Lo);
13438 SDValue
Hi = DAG.
getNode(MulOpc,
DL, MVT::v2i16, RdHi, Rs1Hi, Rs2Hi);
13442 if (!Subtarget.is64Bit() && VT == MVT::v2i32) {
13443 auto Extract = [&](SDValue
V,
unsigned Idx) {
13446 SDValue
Lo = DAG.
getNode(MulOpc,
DL, MVT::i32, Extract(Rd, 0),
13447 Extract(Rs1, 0), Extract(Rs2, 0));
13448 SDValue
Hi = DAG.
getNode(MulOpc,
DL, MVT::i32, Extract(Rd, 1),
13449 Extract(Rs1, 1), Extract(Rs2, 1));
13453 return DAG.
getNode(MulOpc,
DL, VT, Rd, Rs1, Rs2);
13455 case Intrinsic::riscv_pmhacc_b0:
13456 case Intrinsic::riscv_pmhacc_b1:
13457 case Intrinsic::riscv_pmhaccsu_b0:
13458 case Intrinsic::riscv_pmhaccsu_b1: {
13459 EVT VT =
Op.getValueType();
13461 SDValue Rd =
Op.getOperand(1);
13462 SDValue Rs1 =
Op.getOperand(2);
13463 SDValue Rs2 =
Op.getOperand(3);
13466 if (!Subtarget.is64Bit() && VT == MVT::v4i16) {
13470 SDValue
Lo = DAG.
getNode(
Opc,
DL, MVT::v2i16, RdLo, Rs1Lo, Rs2Lo);
13471 SDValue
Hi = DAG.
getNode(
Opc,
DL, MVT::v2i16, RdHi, Rs1Hi, Rs2Hi);
13477 case Intrinsic::riscv_pmhacc_h0:
13478 case Intrinsic::riscv_pmhacc_h1:
13479 case Intrinsic::riscv_pmhaccsu_h0:
13480 case Intrinsic::riscv_pmhaccsu_h1: {
13481 EVT VT =
Op.getValueType();
13483 SDValue Rd =
Op.getOperand(1);
13484 SDValue Rs1 =
Op.getOperand(2);
13485 SDValue Rs2 =
Op.getOperand(3);
13489 if (!Subtarget.is64Bit() && VT == MVT::v2i32) {
13490 auto Extract = [&](SDValue
V,
unsigned Idx) {
13495 Extract(Rs1, 0), Rs2Lo);
13497 Extract(Rs1, 1), Rs2Hi);
13503 case Intrinsic::riscv_pmulh_b0:
13504 case Intrinsic::riscv_pmulh_b1:
13505 case Intrinsic::riscv_pmulhsu_b0:
13506 case Intrinsic::riscv_pmulhsu_b1: {
13507 EVT VT =
Op.getValueType();
13508 SDValue Rs1 =
Op.getOperand(1);
13509 SDValue Rs2 =
Op.getOperand(2);
13514 if (!Subtarget.is64Bit() && VT == MVT::v4i16) {
13524 case Intrinsic::riscv_pmulh_h0:
13525 case Intrinsic::riscv_pmulh_h1:
13526 case Intrinsic::riscv_pmulhsu_h0:
13527 case Intrinsic::riscv_pmulhsu_h1: {
13528 EVT VT =
Op.getValueType();
13529 SDValue Rs1 =
Op.getOperand(1);
13530 SDValue Rs2 =
Op.getOperand(2);
13535 if (!Subtarget.is64Bit() && VT == MVT::v2i32) {
13536 auto Extract = [&](SDValue
V,
unsigned Idx) {
13541 SDValue
Lo = DAG.
getNode(SOpc,
DL, MVT::i32, Extract(Rs1, 0), Rs2Lo);
13542 SDValue
Hi = DAG.
getNode(SOpc,
DL, MVT::i32, Extract(Rs1, 1), Rs2Hi);
13546 if (Subtarget.is64Bit())
13551 case Intrinsic::riscv_pmqwacc_i32x2:
13552 case Intrinsic::riscv_pmqrwacc_i32x2: {
13553 EVT VT =
Op.getValueType();
13554 SDValue Acc =
Op.getOperand(1);
13555 SDValue Rs1 =
Op.getOperand(2);
13556 SDValue Rs2 =
Op.getOperand(3);
13558 if (!Subtarget.is64Bit()) {
13559 unsigned Opc = IntNo == Intrinsic::riscv_pmqwacc_i32x2
13560 ? RISCVISD::PMQWACC_H
13561 : RISCVISD::PMQRWACC_H;
13569 SDValue Zip = DAG.
getNode(RISCVISD::PZIP,
DL, MVT::v4i16, Rs1, Rs2);
13570 unsigned Opc = IntNo == Intrinsic::riscv_pmqwacc_i32x2
13571 ? RISCVISD::PMQACC_W_H01
13572 : RISCVISD::PMQRACC_W_H01;
13575 case Intrinsic::riscv_mulh_h0:
13576 case Intrinsic::riscv_mulh_h1:
13577 case Intrinsic::riscv_mulhsu_h0:
13578 case Intrinsic::riscv_mulhsu_h1: {
13582 EVT VT =
Op.getValueType();
13583 if (VT != MVT::i32 || Subtarget.is64Bit())
13586 SDValue Rs1 =
Op.getOperand(1);
13587 SDValue Rs2 =
Op.getOperand(2);
13591 case Intrinsic::riscv_pm4add:
13592 case Intrinsic::riscv_pm2add:
13593 case Intrinsic::riscv_pm2add_x:
13594 case Intrinsic::riscv_pm4addu:
13595 case Intrinsic::riscv_pm2addu:
13596 case Intrinsic::riscv_pmq2add:
13597 case Intrinsic::riscv_pmqr2add:
13598 case Intrinsic::riscv_pm2sadd:
13599 case Intrinsic::riscv_pm2sadd_x:
13600 case Intrinsic::riscv_pm2sub:
13601 case Intrinsic::riscv_pm2sub_x:
13602 case Intrinsic::riscv_pm4addsu:
13603 case Intrinsic::riscv_pm2addsu: {
13604 EVT VT =
Op.getValueType();
13606 SDValue Rs1 =
Op.getOperand(1);
13607 SDValue Rs2 =
Op.getOperand(2);
13611 if (!Subtarget.is64Bit() && VT == MVT::v2i32) {
13621 case Intrinsic::riscv_pmerge: {
13622 EVT VT =
Op.getValueType();
13623 auto buildMerge = [&](SDValue Rs1, SDValue Rs2, SDValue
Mask,
13635 if (!Subtarget.is64Bit() &&
13636 (VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32)) {
13637 EVT WorkVT = VT == MVT::v2i32 ? EVT(MVT::v4i16) : VT;
13638 SDValue Rs1 = DAG.
getBitcast(WorkVT,
Op.getOperand(1));
13639 SDValue Rs2 = DAG.
getBitcast(WorkVT,
Op.getOperand(2));
13641 MVT HalfVT = WorkVT == MVT::v8i8 ? MVT::v4i8 : MVT::v2i16;
13642 auto [Rs1Lo, Rs1Hi] = DAG.
SplitVector(Rs1,
DL, HalfVT, HalfVT);
13643 auto [Rs2Lo, Rs2Hi] = DAG.
SplitVector(Rs2,
DL, HalfVT, HalfVT);
13644 auto [MaskLo, MaskHi] = DAG.
SplitVector(Mask,
DL, HalfVT, HalfVT);
13645 SDValue ResLo = buildMerge(Rs1Lo, Rs2Lo, MaskLo, HalfVT);
13646 SDValue ResHi = buildMerge(Rs1Hi, Rs2Hi, MaskHi, HalfVT);
13651 return buildMerge(
Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3), VT);
13653 case Intrinsic::experimental_get_vector_length:
13655 case Intrinsic::riscv_vmv_x_s: {
13656 SDValue Res = DAG.
getNode(RISCVISD::VMV_X_S,
DL, XLenVT,
Op.getOperand(1));
13659 case Intrinsic::riscv_vfmv_f_s:
13661 case Intrinsic::riscv_vmv_v_x:
13663 Op.getOperand(3),
Op.getSimpleValueType(),
DL, DAG,
13665 case Intrinsic::riscv_vfmv_v_f:
13666 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL,
Op.getValueType(),
13667 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
13668 case Intrinsic::riscv_vmv_s_x: {
13669 SDValue
Scalar =
Op.getOperand(2);
13671 if (
Scalar.getValueType().bitsLE(XLenVT)) {
13673 return DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL,
Op.getValueType(),
13674 Op.getOperand(1), Scalar,
Op.getOperand(3));
13677 assert(
Scalar.getValueType() == MVT::i64 &&
"Unexpected scalar VT!");
13694 MVT VT =
Op.getSimpleValueType();
13695 SDValue Vec =
Op.getOperand(1);
13699 if (
Op.getOperand(1).isUndef())
13700 return SplattedVal;
13701 SDValue SplattedIdx =
13707 SDValue VID = DAG.
getNode(RISCVISD::VID_VL,
DL, VT, Mask, VL);
13708 SDValue SelectCond =
13709 DAG.
getNode(RISCVISD::SETCC_VL,
DL, MaskVT,
13712 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, SelectCond, SplattedVal,
13715 case Intrinsic::riscv_vfmv_s_f:
13716 return DAG.
getNode(RISCVISD::VFMV_S_F_VL,
DL,
Op.getValueType(),
13717 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
13719 case Intrinsic::riscv_vaesdf_vv:
13720 case Intrinsic::riscv_vaesdf_vs:
13721 case Intrinsic::riscv_vaesdm_vv:
13722 case Intrinsic::riscv_vaesdm_vs:
13723 case Intrinsic::riscv_vaesef_vv:
13724 case Intrinsic::riscv_vaesef_vs:
13725 case Intrinsic::riscv_vaesem_vv:
13726 case Intrinsic::riscv_vaesem_vs:
13727 case Intrinsic::riscv_vaeskf1:
13728 case Intrinsic::riscv_vaeskf2:
13729 case Intrinsic::riscv_vaesz_vs:
13730 case Intrinsic::riscv_vsm4k:
13731 case Intrinsic::riscv_vsm4r_vv:
13732 case Intrinsic::riscv_vsm4r_vs: {
13733 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
13734 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
13735 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
13740 case Intrinsic::riscv_vsm3c:
13741 case Intrinsic::riscv_vsm3me: {
13742 if (!
isValidEGW(8,
Op.getSimpleValueType(), Subtarget) ||
13743 !
isValidEGW(8,
Op->getOperand(1).getSimpleValueType(), Subtarget))
13748 case Intrinsic::riscv_vsha2ch:
13749 case Intrinsic::riscv_vsha2cl:
13750 case Intrinsic::riscv_vsha2ms: {
13751 if (
Op->getSimpleValueType(0).getScalarSizeInBits() == 64 &&
13752 !Subtarget.hasStdExtZvknhb())
13754 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
13755 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
13756 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
13760 case Intrinsic::riscv_sf_vc_v_x:
13761 case Intrinsic::riscv_sf_vc_v_i:
13762 case Intrinsic::riscv_sf_vc_v_xv:
13763 case Intrinsic::riscv_sf_vc_v_iv:
13764 case Intrinsic::riscv_sf_vc_v_vv:
13765 case Intrinsic::riscv_sf_vc_v_fv:
13766 case Intrinsic::riscv_sf_vc_v_xvv:
13767 case Intrinsic::riscv_sf_vc_v_ivv:
13768 case Intrinsic::riscv_sf_vc_v_vvv:
13769 case Intrinsic::riscv_sf_vc_v_fvv:
13770 case Intrinsic::riscv_sf_vc_v_xvw:
13771 case Intrinsic::riscv_sf_vc_v_ivw:
13772 case Intrinsic::riscv_sf_vc_v_vvw:
13773 case Intrinsic::riscv_sf_vc_v_fvw: {
13774 MVT VT =
Op.getSimpleValueType();
13811 MVT VT =
Op.getSimpleValueType();
13815 if (VT.isFloatingPoint()) {
13817 VT.getVectorElementCount());
13820 if (VT.isFixedLengthVector())
13829 if (VT.isFixedLengthVector())
13831 if (VT.isFloatingPoint())
13854 case Intrinsic::riscv_seg2_load_mask:
13855 case Intrinsic::riscv_seg3_load_mask:
13856 case Intrinsic::riscv_seg4_load_mask:
13857 case Intrinsic::riscv_seg5_load_mask:
13858 case Intrinsic::riscv_seg6_load_mask:
13859 case Intrinsic::riscv_seg7_load_mask:
13860 case Intrinsic::riscv_seg8_load_mask:
13863 case Intrinsic::riscv_sseg2_load_mask:
13864 case Intrinsic::riscv_sseg3_load_mask:
13865 case Intrinsic::riscv_sseg4_load_mask:
13866 case Intrinsic::riscv_sseg5_load_mask:
13867 case Intrinsic::riscv_sseg6_load_mask:
13868 case Intrinsic::riscv_sseg7_load_mask:
13869 case Intrinsic::riscv_sseg8_load_mask:
13877 Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
13878 Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
13879 Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
13880 Intrinsic::riscv_vlseg8_mask};
13882 Intrinsic::riscv_vlsseg2_mask, Intrinsic::riscv_vlsseg3_mask,
13883 Intrinsic::riscv_vlsseg4_mask, Intrinsic::riscv_vlsseg5_mask,
13884 Intrinsic::riscv_vlsseg6_mask, Intrinsic::riscv_vlsseg7_mask,
13885 Intrinsic::riscv_vlsseg8_mask};
13888 unsigned NF =
Op->getNumValues() - 1;
13889 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
13891 MVT VT =
Op->getSimpleValueType(0);
13899 SDValue VL =
Op.getOperand(
Op.getNumOperands() - 1);
13900 SDValue Mask =
Op.getOperand(
Op.getNumOperands() - 2);
13901 MVT MaskVT = Mask.getSimpleValueType();
13906 IsStrided ? VlssegInts[NF - 2] : VlsegInts[NF - 2],
DL, XLenVT);
13922 Ops.insert(std::next(
Ops.begin(), 4),
Op.getOperand(3));
13926 Load->getMemoryVT(),
Load->getMemOperand());
13928 for (
unsigned int RetIdx = 0; RetIdx < NF; RetIdx++) {
13930 Result.getValue(0),
13934 Results.push_back(Result.getValue(1));
13940 unsigned IntNo =
Op.getConstantOperandVal(1);
13944 case Intrinsic::riscv_seg2_load_mask:
13945 case Intrinsic::riscv_seg3_load_mask:
13946 case Intrinsic::riscv_seg4_load_mask:
13947 case Intrinsic::riscv_seg5_load_mask:
13948 case Intrinsic::riscv_seg6_load_mask:
13949 case Intrinsic::riscv_seg7_load_mask:
13950 case Intrinsic::riscv_seg8_load_mask:
13951 case Intrinsic::riscv_sseg2_load_mask:
13952 case Intrinsic::riscv_sseg3_load_mask:
13953 case Intrinsic::riscv_sseg4_load_mask:
13954 case Intrinsic::riscv_sseg5_load_mask:
13955 case Intrinsic::riscv_sseg6_load_mask:
13956 case Intrinsic::riscv_sseg7_load_mask:
13957 case Intrinsic::riscv_sseg8_load_mask:
13960 case Intrinsic::riscv_sf_vc_v_x_se:
13962 case Intrinsic::riscv_sf_vc_v_i_se:
13964 case Intrinsic::riscv_sf_vc_v_xv_se:
13966 case Intrinsic::riscv_sf_vc_v_iv_se:
13968 case Intrinsic::riscv_sf_vc_v_vv_se:
13970 case Intrinsic::riscv_sf_vc_v_fv_se:
13972 case Intrinsic::riscv_sf_vc_v_xvv_se:
13974 case Intrinsic::riscv_sf_vc_v_ivv_se:
13976 case Intrinsic::riscv_sf_vc_v_vvv_se:
13978 case Intrinsic::riscv_sf_vc_v_fvv_se:
13980 case Intrinsic::riscv_sf_vc_v_xvw_se:
13982 case Intrinsic::riscv_sf_vc_v_ivw_se:
13984 case Intrinsic::riscv_sf_vc_v_vvw_se:
13986 case Intrinsic::riscv_sf_vc_v_fvw_se:
13999 case Intrinsic::riscv_seg2_store_mask:
14000 case Intrinsic::riscv_seg3_store_mask:
14001 case Intrinsic::riscv_seg4_store_mask:
14002 case Intrinsic::riscv_seg5_store_mask:
14003 case Intrinsic::riscv_seg6_store_mask:
14004 case Intrinsic::riscv_seg7_store_mask:
14005 case Intrinsic::riscv_seg8_store_mask:
14008 case Intrinsic::riscv_sseg2_store_mask:
14009 case Intrinsic::riscv_sseg3_store_mask:
14010 case Intrinsic::riscv_sseg4_store_mask:
14011 case Intrinsic::riscv_sseg5_store_mask:
14012 case Intrinsic::riscv_sseg6_store_mask:
14013 case Intrinsic::riscv_sseg7_store_mask:
14014 case Intrinsic::riscv_sseg8_store_mask:
14023 Intrinsic::riscv_vsseg2_mask, Intrinsic::riscv_vsseg3_mask,
14024 Intrinsic::riscv_vsseg4_mask, Intrinsic::riscv_vsseg5_mask,
14025 Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
14026 Intrinsic::riscv_vsseg8_mask};
14028 Intrinsic::riscv_vssseg2_mask, Intrinsic::riscv_vssseg3_mask,
14029 Intrinsic::riscv_vssseg4_mask, Intrinsic::riscv_vssseg5_mask,
14030 Intrinsic::riscv_vssseg6_mask, Intrinsic::riscv_vssseg7_mask,
14031 Intrinsic::riscv_vssseg8_mask};
14035 unsigned NF =
Op->getNumOperands() - (IsStrided ? 6 : 5);
14036 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
14038 MVT VT =
Op->getOperand(2).getSimpleValueType();
14044 SDValue VL =
Op.getOperand(
Op.getNumOperands() - 1);
14045 SDValue Mask =
Op.getOperand(
Op.getNumOperands() - 2);
14046 MVT MaskVT = Mask.getSimpleValueType();
14051 IsStrided ? VsssegInts[NF - 2] : VssegInts[NF - 2],
DL, XLenVT);
14057 for (
unsigned i = 0; i < NF; i++)
14059 RISCVISD::TUPLE_INSERT,
DL, VecTupTy, StoredVal,
14065 FixedIntrinsic->getChain(),
14074 Ops.insert(std::next(
Ops.begin(), 4),
14075 Op.getOperand(
Op.getNumOperands() - 3));
14079 FixedIntrinsic->getMemoryVT(), FixedIntrinsic->getMemOperand());
14084 unsigned IntNo =
Op.getConstantOperandVal(1);
14088 case Intrinsic::riscv_seg2_store_mask:
14089 case Intrinsic::riscv_seg3_store_mask:
14090 case Intrinsic::riscv_seg4_store_mask:
14091 case Intrinsic::riscv_seg5_store_mask:
14092 case Intrinsic::riscv_seg6_store_mask:
14093 case Intrinsic::riscv_seg7_store_mask:
14094 case Intrinsic::riscv_seg8_store_mask:
14095 case Intrinsic::riscv_sseg2_store_mask:
14096 case Intrinsic::riscv_sseg3_store_mask:
14097 case Intrinsic::riscv_sseg4_store_mask:
14098 case Intrinsic::riscv_sseg5_store_mask:
14099 case Intrinsic::riscv_sseg6_store_mask:
14100 case Intrinsic::riscv_sseg7_store_mask:
14101 case Intrinsic::riscv_sseg8_store_mask:
14104 case Intrinsic::riscv_sf_vc_xv_se:
14106 case Intrinsic::riscv_sf_vc_iv_se:
14108 case Intrinsic::riscv_sf_vc_vv_se:
14110 case Intrinsic::riscv_sf_vc_fv_se:
14112 case Intrinsic::riscv_sf_vc_xvv_se:
14114 case Intrinsic::riscv_sf_vc_ivv_se:
14116 case Intrinsic::riscv_sf_vc_vvv_se:
14118 case Intrinsic::riscv_sf_vc_fvv_se:
14120 case Intrinsic::riscv_sf_vc_xvw_se:
14122 case Intrinsic::riscv_sf_vc_ivw_se:
14124 case Intrinsic::riscv_sf_vc_vvw_se:
14126 case Intrinsic::riscv_sf_vc_fvw_se:
14134 switch (ISDOpcode) {
14137 case ISD::VP_REDUCE_ADD:
14139 return RISCVISD::VECREDUCE_ADD_VL;
14140 case ISD::VP_REDUCE_UMAX:
14142 return RISCVISD::VECREDUCE_UMAX_VL;
14143 case ISD::VP_REDUCE_SMAX:
14145 return RISCVISD::VECREDUCE_SMAX_VL;
14146 case ISD::VP_REDUCE_UMIN:
14148 return RISCVISD::VECREDUCE_UMIN_VL;
14149 case ISD::VP_REDUCE_SMIN:
14151 return RISCVISD::VECREDUCE_SMIN_VL;
14152 case ISD::VP_REDUCE_AND:
14154 return RISCVISD::VECREDUCE_AND_VL;
14155 case ISD::VP_REDUCE_OR:
14157 return RISCVISD::VECREDUCE_OR_VL;
14158 case ISD::VP_REDUCE_XOR:
14160 return RISCVISD::VECREDUCE_XOR_VL;
14161 case ISD::VP_REDUCE_FADD:
14162 return RISCVISD::VECREDUCE_FADD_VL;
14163 case ISD::VP_REDUCE_SEQ_FADD:
14164 return RISCVISD::VECREDUCE_SEQ_FADD_VL;
14165 case ISD::VP_REDUCE_FMAX:
14166 case ISD::VP_REDUCE_FMAXIMUM:
14167 return RISCVISD::VECREDUCE_FMAX_VL;
14168 case ISD::VP_REDUCE_FMIN:
14169 case ISD::VP_REDUCE_FMINIMUM:
14170 return RISCVISD::VECREDUCE_FMIN_VL;
14179 SDValue Vec =
Op.getOperand(IsVP ? 1 : 0);
14184 Op.getOpcode() == ISD::VP_REDUCE_AND ||
14185 Op.getOpcode() == ISD::VP_REDUCE_OR ||
14186 Op.getOpcode() == ISD::VP_REDUCE_XOR) &&
14187 "Unexpected reduction lowering");
14189 MVT XLenVT = Subtarget.getXLenVT();
14191 MVT ContainerVT = VecVT;
14199 Mask =
Op.getOperand(2);
14200 VL =
Op.getOperand(3);
14202 std::tie(Mask, VL) =
14207 switch (
Op.getOpcode()) {
14211 case ISD::VP_REDUCE_AND: {
14214 Vec = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Vec,
14217 Vec = DAG.
getNOT(
DL, Vec, ContainerVT);
14218 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
14223 case ISD::VP_REDUCE_OR:
14225 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
14229 case ISD::VP_REDUCE_XOR: {
14232 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
14240 SDValue SetCC = DAG.
getSetCC(
DL, XLenVT, Vec, Zero, CC);
14253 return DAG.
getNode(BaseOpc,
DL,
Op.getValueType(), SetCC,
Op.getOperand(0));
14259 return (RegisterAVL && RegisterAVL->getReg() == RISCV::X0) ||
14260 (ImmAVL && ImmAVL->getZExtValue() >= 1);
14276 auto InnerVT = VecVT.
bitsLE(M1VT) ? VecVT : M1VT;
14280 auto InnerVL = NonZeroAVL ? VL : DAG.
getConstant(1,
DL, XLenVT);
14283 if (M1VT != InnerVT)
14288 SDValue Ops[] = {PassThru, Vec, InitialValue, Mask, VL, Policy};
14296 SDValue Vec =
Op.getOperand(0);
14306 VecEVT =
Lo.getValueType();
14319 MVT ContainerVT = VecVT;
14342 Mask, VL,
DL, DAG, Subtarget);
14348static std::tuple<unsigned, SDValue, SDValue>
14352 auto Flags =
Op->getFlags();
14353 unsigned Opcode =
Op.getOpcode();
14361 return std::make_tuple(RISCVISD::VECREDUCE_FADD_VL,
Op.getOperand(0), Zero);
14364 return std::make_tuple(RISCVISD::VECREDUCE_SEQ_FADD_VL,
Op.getOperand(1),
14373 ? RISCVISD::VECREDUCE_FMIN_VL
14374 : RISCVISD::VECREDUCE_FMAX_VL;
14375 return std::make_tuple(RVVOpc,
Op.getOperand(0), Front);
14383 MVT VecEltVT =
Op.getSimpleValueType();
14385 unsigned RVVOpcode;
14386 SDValue VectorVal, ScalarVal;
14387 std::tie(RVVOpcode, VectorVal, ScalarVal) =
14391 MVT ContainerVT = VecVT;
14397 MVT ResVT =
Op.getSimpleValueType();
14400 VL,
DL, DAG, Subtarget);
14405 if (
Op->getFlags().hasNoNaNs())
14411 {VectorVal, VectorVal, DAG.getCondCode(ISD::SETNE),
14412 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
14413 MVT XLenVT = Subtarget.getXLenVT();
14414 SDValue CPop = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, IsNan, Mask, VL);
14418 DL, ResVT, NoNaNs, Res,
14425 unsigned Opc =
Op.getOpcode();
14426 SDValue
Start =
Op.getOperand(0);
14427 SDValue Vec =
Op.getOperand(1);
14429 MVT XLenVT = Subtarget.getXLenVT();
14439 SDValue VL =
Op.getOperand(3);
14440 SDValue
Mask =
Op.getOperand(2);
14449 Vec, Mask, VL,
DL, DAG, Subtarget);
14450 if ((
Opc != ISD::VP_REDUCE_FMINIMUM &&
Opc != ISD::VP_REDUCE_FMAXIMUM) ||
14451 Op->getFlags().hasNoNaNs())
14458 RISCVISD::SETCC_VL,
DL, PredVT,
14460 SDValue VCPop = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, IsNaN, Mask, VL);
14468 DL, ResVT, NoNaNs, Res,
14477 SDValue Vec =
Op.getOperand(0);
14478 SDValue SubVec =
Op.getOperand(1);
14483 MVT XLenVT = Subtarget.getXLenVT();
14484 unsigned OrigIdx =
Op.getConstantOperandVal(2);
14485 const RISCVRegisterInfo *
TRI = Subtarget.getRegisterInfo();
14487 bool IsPExtInsert =
14488 Subtarget.hasStdExtP() &&
14489 ((Subtarget.is64Bit() &&
14490 (SubVecVT == MVT::v2i16 || SubVecVT == MVT::v4i8)) ||
14491 (!Subtarget.is64Bit() && (VecVT == MVT::v4i16 || VecVT == MVT::v8i8)));
14495 if (IsPExtInsert) {
14496 if ((VecVT != MVT::v4i16 && VecVT != MVT::v8i8) ||
14501 if (!Subtarget.is64Bit()) {
14508 if (OrigIdx == 0 && Vec.
isUndef())
14519 assert(OrigIdx % 8 == 0 &&
"Invalid index");
14522 "Unexpected mask vector lowering");
14552 const auto VLen = Subtarget.getRealVLen();
14554 MVT ContainerVT = VecVT;
14576 if (OrigIdx == 0) {
14578 DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, ContainerVT, Vec, SubVec, VL);
14581 SubVec =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, Vec, SubVec,
14582 SlideupAmt, Mask, VL, Policy);
14590 MVT ContainerVecVT = VecVT;
14596 MVT ContainerSubVecVT = SubVecVT;
14602 unsigned SubRegIdx;
14603 ElementCount RemIdx;
14612 ContainerVecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
14613 SubRegIdx = Decompose.first;
14615 (OrigIdx % Vscale));
14619 ContainerVecVT, ContainerSubVecVT, OrigIdx,
TRI);
14620 SubRegIdx = Decompose.first;
14626 Subtarget.expandVScale(SubVecVT.
getSizeInBits()).getKnownMinValue()));
14627 bool ExactlyVecRegSized =
14629 .isKnownMultipleOf(Subtarget.expandVScale(VecRegSize));
14644 if (RemIdx.
isZero() && (ExactlyVecRegSized || Vec.
isUndef())) {
14648 if (SubRegIdx == RISCV::NoSubRegister) {
14670 MVT InterSubVT = ContainerVecVT;
14671 SDValue AlignedExtract = Vec;
14693 if (Subtarget.expandVScale(EndIndex) ==
14700 SubVec = DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, InterSubVT, AlignedExtract,
14708 SubVec =
getVSlideup(DAG, Subtarget,
DL, InterSubVT, AlignedExtract, SubVec,
14709 SlideupAmt, Mask, VL, Policy);
14714 if (ContainerVecVT.
bitsGT(InterSubVT))
14722 return DAG.
getBitcast(
Op.getSimpleValueType(), SubVec);
14727 SDValue Vec =
Op.getOperand(0);
14728 MVT SubVecVT =
Op.getSimpleValueType();
14732 MVT XLenVT = Subtarget.getXLenVT();
14733 unsigned OrigIdx =
Op.getConstantOperandVal(1);
14734 const RISCVRegisterInfo *
TRI = Subtarget.getRegisterInfo();
14749 assert(OrigIdx % 8 == 0 &&
"Invalid index");
14752 "Unexpected mask vector lowering");
14778 const auto VLen = Subtarget.getRealVLen();
14786 MVT ContainerVT = VecVT;
14794 if (
auto ShrunkVT =
14796 ContainerVT = *ShrunkVT;
14805 SDValue SlidedownAmt = DAG.
getConstant(OrigIdx,
DL, XLenVT);
14806 SDValue Slidedown =
14808 DAG.
getUNDEF(ContainerVT), Vec, SlidedownAmt, Mask, VL);
14819 MVT ContainerSubVecVT = SubVecVT;
14823 unsigned SubRegIdx;
14824 ElementCount RemIdx;
14833 VecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
14834 SubRegIdx = Decompose.first;
14836 (OrigIdx % Vscale));
14840 VecVT, ContainerSubVecVT, OrigIdx,
TRI);
14841 SubRegIdx = Decompose.first;
14868 MVT InterSubVT = VecVT;
14873 assert(SubRegIdx != RISCV::NoSubRegister);
14890 SDValue Slidedown =
14892 Vec, SlidedownAmt, Mask, VL);
14900 return DAG.
getBitcast(
Op.getSimpleValueType(), Slidedown);
14907 MVT VT =
N.getSimpleValueType();
14911 assert(
Op.getSimpleValueType() == VT &&
14912 "Operands and result must be same type");
14916 unsigned NumVals =
N->getNumValues();
14920 N.getValueType().changeVectorElementType(*DAG.
getContext(), MVT::i8)));
14923 for (
unsigned I = 0;
I < NumVals;
I++) {
14929 if (TruncVals.
size() > 1)
14931 return TruncVals.
front();
14937 MVT VecVT =
Op.getSimpleValueType();
14939 const unsigned Factor =
Op->getNumValues();
14948 MVT ContainerVecVT = VecVT;
14956 for (
unsigned i = 0; i != Factor; ++i) {
14959 Ops[i * 2 + 1] = OpHi;
14970 for (
unsigned i = 0; i != Factor; ++i)
14977 if (Subtarget.hasStdExtZvzip() && Factor == 2 && !IsFixedVector) {
14978 MVT VT =
Op->getSimpleValueType(0);
14982 SDValue
V1 =
Op->getOperand(0);
14983 SDValue V2 =
Op->getOperand(1);
15003 if (Factor == 2 && !IsFixedVector) {
15020 SDValue EvenSplat = DAG.
getConstant(0b01010101,
DL, MVT::nxv8i8);
15021 EvenSplat = DAG.
getBitcast(MVT::nxv64i1, EvenSplat);
15024 SDValue OddSplat = DAG.
getConstant(0b10101010,
DL, MVT::nxv8i8);
15025 OddSplat = DAG.
getBitcast(MVT::nxv64i1, OddSplat);
15030 EvenMask, DAG.
getUNDEF(ConcatVT));
15043 MVT XLenVT = Subtarget.getXLenVT();
15048 MachinePointerInfo PtrInfo;
15049 if (IsFixedVector) {
15064 MachinePointerInfo PI = PtrInfo;
15066 for (
auto [Idx, FieldOp] :
enumerate(
Op->op_values())) {
15072 Tokens[Idx] = DAG.
getStore(Chain,
DL, FieldOp, BasePtr, PI, Alignment);
15077 std::tie(Mask, VL) =
15086 SDValue StoreOps[] = {
15097 SDValue Passthru = DAG.
getUNDEF(ConcatVT);
15099 Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
15100 Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
15101 Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
15102 Intrinsic::riscv_vlseg8_mask};
15104 SDValue LoadOps[] = {
15126 for (
unsigned i = 0U; i < Factor; ++i) {
15128 DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL, ContainerVecVT,
Load,
15141 MVT VecVT =
Op.getSimpleValueType();
15150 MVT ContainerVecVT = VecVT;
15159 (Subtarget.hasStdExtZvzip() && Factor == 2 &&
15163 for (
unsigned i = 0; i != Factor; ++i) {
15166 Ops[i + Factor] = OpHi;
15177 for (
unsigned i = 0; i != Factor; ++i) {
15178 unsigned IdxLo = 2 * i;
15179 unsigned IdxHi = 2 * i + 1;
15181 Res[IdxLo / Factor].
getValue(IdxLo % Factor),
15182 Res[IdxHi / Factor].
getValue(IdxHi % Factor));
15188 MVT XLenVT = Subtarget.getXLenVT();
15191 SDValue Interleaved;
15207 EVT PtrVT =
StackPtr.getValueType();
15213 Intrinsic::riscv_vsseg2_mask, Intrinsic::riscv_vsseg3_mask,
15214 Intrinsic::riscv_vsseg4_mask, Intrinsic::riscv_vsseg5_mask,
15215 Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
15216 Intrinsic::riscv_vsseg8_mask,
15223 SDValue StoredVal = DAG.
getUNDEF(VecTupTy);
15224 for (
unsigned i = 0; i < Factor; i++) {
15225 SDValue OpVal =
Op.getOperand(i);
15228 StoredVal = DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL, VecTupTy, StoredVal,
15249 for (
unsigned i = 0; i != Factor; ++i) {
15253 Loads[i] = DAG.
getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
15259 if (Subtarget.hasStdExtZvzip() && !
Op.getOperand(0).isUndef() &&
15260 !
Op.getOperand(1).isUndef()) {
15261 MVT VT =
Op->getSimpleValueType(0);
15285 Op.getOperand(0),
Op.getOperand(1));
15309 DAG.
getNode(RISCVISD::ADD_VL,
DL, IdxVT, Idx, VLMax, Idx, OddMask, VL);
15314 Interleaved = DAG.
getNode(RISCVISD::VRGATHEREI16_VV_VL,
DL, ConcatVT,
15331 MVT VT =
Op.getSimpleValueType();
15333 MVT XLenVT = Subtarget.getXLenVT();
15335 SDValue StepVec = DAG.
getNode(RISCVISD::VID_VL,
DL, VT, Mask, VL);
15336 uint64_t StepValImm =
Op.getConstantOperandVal(0);
15337 if (StepValImm != 1) {
15346 VL, VT,
DL, DAG, Subtarget);
15361 MVT VecVT =
Op.getSimpleValueType();
15365 if (Subtarget.hasStdExtP() && !Subtarget.hasVInstructions()) {
15367 "Unexpected packed VECTOR_REVERSE type");
15368 SDValue
V =
Op.getOperand(0);
15369 if (VecVT == MVT::v2i32) {
15389 MVT ContainerVT = VecVT;
15390 SDValue Vec =
Op.getOperand(0);
15396 MVT XLenVT = Subtarget.getXLenVT();
15442 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
15443 unsigned MaxVLMAX =
15448 unsigned GatherOpc = RISCVISD::VRGATHER_VV_VL;
15453 if (MaxVLMAX > 256 && EltSize == 8) {
15469 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
15477 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
15482 SDValue VLMinus1 = DAG.
getNode(
15497 SDValue VID = DAG.
getNode(RISCVISD::VID_VL,
DL, IntVT, Mask, VL);
15498 SDValue Indices = DAG.
getNode(RISCVISD::SUB_VL,
DL, IntVT, SplatVL, VID,
15501 SDValue Gather = DAG.
getNode(GatherOpc,
DL, ContainerVT, Vec, Indices,
15502 DAG.
getUNDEF(ContainerVT), Mask, VL);
15511 SDValue
V1 =
Op.getOperand(0);
15512 SDValue V2 =
Op.getOperand(1);
15513 SDValue
Offset =
Op.getOperand(2);
15514 MVT XLenVT = Subtarget.getXLenVT();
15515 MVT VecVT =
Op.getSimpleValueType();
15519 SDValue DownOffset, UpOffset;
15535 DAG, Subtarget,
DL, VecVT, DAG.
getUNDEF(VecVT),
V1, DownOffset, TrueMask,
15536 Subtarget.hasVLDependentLatency() ? UpOffset
15538 return getVSlideup(DAG, Subtarget,
DL, VecVT, SlideDown, V2, UpOffset,
15544RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(
SDValue Op,
15550 Load->getMemoryVT(),
15551 *
Load->getMemOperand()) &&
15552 "Expecting a correctly-aligned load");
15554 MVT VT =
Op.getSimpleValueType();
15555 MVT XLenVT = Subtarget.getXLenVT();
15560 const auto [MinVLMAX, MaxVLMAX] =
15564 MachineMemOperand *MMO =
Load->getMemOperand();
15577 IsMaskOp ? Intrinsic::riscv_vlm : Intrinsic::riscv_vle,
DL, XLenVT);
15581 Ops.push_back(
Load->getBasePtr());
15583 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
15586 Load->getMemoryVT(),
Load->getMemOperand());
15593RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(
SDValue Op,
15599 Store->getMemoryVT(),
15600 *
Store->getMemOperand()) &&
15601 "Expecting a correctly-aligned store");
15603 SDValue StoreVal =
Store->getValue();
15605 MVT XLenVT = Subtarget.getXLenVT();
15621 const auto [MinVLMAX, MaxVLMAX] =
15625 MachineMemOperand *MMO =
Store->getMemOperand();
15635 IsMaskOp ? Intrinsic::riscv_vsm : Intrinsic::riscv_vse,
DL, XLenVT);
15638 {Store->getChain(), IntID, NewValue, Store->getBasePtr(), VL},
15639 Store->getMemoryVT(),
Store->getMemOperand());
15645 MVT VT =
Op.getSimpleValueType();
15648 EVT MemVT = MemSD->getMemoryVT();
15649 MachineMemOperand *MMO = MemSD->getMemOperand();
15650 SDValue Chain = MemSD->getChain();
15651 SDValue
BasePtr = MemSD->getBasePtr();
15653 SDValue
Mask, PassThru, VL;
15654 bool IsExpandingLoad =
false;
15656 Mask = VPLoad->getMask();
15658 VL = VPLoad->getVectorLength();
15662 PassThru =
MLoad->getPassThru();
15663 IsExpandingLoad =
MLoad->isExpandingLoad();
15668 MVT XLenVT = Subtarget.getXLenVT();
15670 MVT ContainerVT = VT;
15683 SDValue ExpandingVL;
15684 if (!IsUnmasked && IsExpandingLoad) {
15687 DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Mask,
15691 unsigned IntID = IsUnmasked || IsExpandingLoad ? Intrinsic::riscv_vle
15692 : Intrinsic::riscv_vle_mask;
15694 if (IntID == Intrinsic::riscv_vle)
15697 Ops.push_back(PassThru);
15698 Ops.push_back(BasePtr);
15699 if (IntID == Intrinsic::riscv_vle_mask)
15700 Ops.push_back(Mask);
15702 if (IntID == Intrinsic::riscv_vle_mask)
15705 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
15709 Chain =
Result.getValue(1);
15711 MVT IndexVT = ContainerVT;
15716 bool UseVRGATHEREI16 =
false;
15723 if (IndexEltVT == MVT::i8 && MaxEltCount > 256) {
15727 UseVRGATHEREI16 =
true;
15733 DAG.
getUNDEF(IndexVT), Mask, ExpandingVL);
15735 DAG.
getNode(UseVRGATHEREI16 ? RISCVISD::VRGATHEREI16_VV_VL
15736 : RISCVISD::VRGATHER_VV_VL,
15737 DL, ContainerVT, Result, Iota, PassThru, Mask, ExpandingVL);
15748 MVT VT =
Op->getSimpleValueType(0);
15751 EVT MemVT = VPLoadFF->getMemoryVT();
15752 MachineMemOperand *MMO = VPLoadFF->getMemOperand();
15753 SDValue Chain = VPLoadFF->getChain();
15754 SDValue
BasePtr = VPLoadFF->getBasePtr();
15756 SDValue
Mask = VPLoadFF->getMask();
15757 SDValue VL = VPLoadFF->getVectorLength();
15759 MVT XLenVT = Subtarget.getXLenVT();
15761 MVT ContainerVT = VT;
15768 unsigned IntID = Intrinsic::riscv_vleff_mask;
15778 SDVTList VTs = DAG.
getVTList({ContainerVT,
Op->getValueType(1), MVT::Other});
15782 SDValue OutVL =
Result.getValue(1);
15783 Chain =
Result.getValue(2);
15796 EVT MemVT = MemSD->getMemoryVT();
15797 MachineMemOperand *MMO = MemSD->getMemOperand();
15798 SDValue Chain = MemSD->getChain();
15799 SDValue
BasePtr = MemSD->getBasePtr();
15800 SDValue Val,
Mask, VL;
15802 bool IsCompressingStore =
false;
15804 Val = VPStore->getValue();
15805 Mask = VPStore->getMask();
15806 VL = VPStore->getVectorLength();
15809 Val = MStore->getValue();
15810 Mask = MStore->getMask();
15811 IsCompressingStore = MStore->isCompressingStore();
15818 MVT XLenVT = Subtarget.getXLenVT();
15820 MVT ContainerVT = VT;
15825 if (!IsUnmasked || IsCompressingStore) {
15834 if (IsCompressingStore) {
15838 DAG.
getUNDEF(ContainerVT), Val, Mask, VL);
15840 DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Mask,
15845 IsUnmasked ? Intrinsic::riscv_vse : Intrinsic::riscv_vse_mask;
15847 Ops.push_back(Val);
15848 Ops.push_back(BasePtr);
15850 Ops.push_back(Mask);
15860 SDValue Val =
Op.getOperand(0);
15861 SDValue
Mask =
Op.getOperand(1);
15862 SDValue Passthru =
Op.getOperand(2);
15865 MVT XLenVT = Subtarget.getXLenVT();
15866 MVT ContainerVT = VT;
15879 Passthru, Val, Mask, VL);
15889 unsigned Opc =
Op.getOpcode();
15891 SDValue Chain =
Op.getOperand(0);
15892 SDValue Op1 =
Op.getOperand(1);
15893 SDValue Op2 =
Op.getOperand(2);
15894 SDValue CC =
Op.getOperand(3);
15896 MVT VT =
Op.getSimpleValueType();
15904 SDVTList VTList =
Op->getVTList();
15924 SDValue Res = DAG.
getNOT(
DL, OEQ, VT);
15929 MVT ContainerInVT = InVT;
15946 SDValue OrderMask1 = DAG.
getNode(
15947 RISCVISD::STRICT_FSETCC_VL,
DL, DAG.
getVTList(MaskVT, MVT::Other),
15948 {Chain, Op1, Op1, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
15950 SDValue OrderMask2 = DAG.
getNode(
15951 RISCVISD::STRICT_FSETCC_VL,
DL, DAG.
getVTList(MaskVT, MVT::Other),
15952 {Chain, Op2, Op2, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
15955 DAG.
getNode(RISCVISD::VMAND_VL,
DL, MaskVT, OrderMask1, OrderMask2, VL);
15958 Res = DAG.
getNode(RISCVISD::STRICT_FSETCCS_VL,
DL,
15960 {Chain, Op1, Op2, CC, Mask, Mask, VL});
15963 : RISCVISD::STRICT_FSETCCS_VL;
15965 {Chain, Op1, Op2, CC, DAG.getUNDEF(MaskVT), Mask, VL});
15978 MVT VT =
Op.getSimpleValueType();
15979 SDValue
X =
Op.getOperand(0);
15988 SDValue SplatZero = DAG.
getNode(
15989 RISCVISD::VMV_V_X_VL,
DL, ContainerVT, DAG.
getUNDEF(ContainerVT),
15992 if (Subtarget.hasStdExtZvabd()) {
15994 DAG.
getUNDEF(ContainerVT), Mask, VL);
15996 SDValue NegX = DAG.
getNode(RISCVISD::SUB_VL,
DL, ContainerVT, SplatZero,
X,
15997 DAG.
getUNDEF(ContainerVT), Mask, VL);
15999 DAG.
getUNDEF(ContainerVT), Mask, VL);
16006 const auto &TSInfo =
16010 bool HasPassthruOp = TSInfo.hasPassthruOp(NewOpc);
16011 bool HasMask = TSInfo.hasMaskOp(NewOpc);
16013 MVT VT =
Op.getSimpleValueType();
16018 for (
const SDValue &V :
Op->op_values()) {
16022 if (!
V.getValueType().isVector()) {
16028 assert(useRVVForFixedLengthVectorVT(
V.getSimpleValueType()) &&
16029 "Only fixed length vectors are supported!");
16031 V.getSimpleValueType().getVectorElementType());
16040 Ops.push_back(Mask);
16045 if (
Op->isStrictFPOpcode()) {
16046 SDValue ScalableRes =
16053 SDValue ScalableRes =
16064 const auto &TSInfo =
16068 bool HasPassthruOp = TSInfo.hasPassthruOp(RISCVISDOpc);
16071 MVT VT =
Op.getSimpleValueType();
16074 MVT ContainerVT = VT;
16079 SDValue
V = OpIdx.value();
16083 if (HasPassthruOp) {
16086 if (*MaskIdx == OpIdx.index())
16090 assert(
Op.getOpcode() == ISD::VP_MERGE);
16092 Ops.push_back(
Ops.back());
16096 if (RISCVISDOpc == RISCVISD::VFCVT_RM_X_F_VL &&
16099 Subtarget.getXLenVT()));
16101 if (!
V.getValueType().isFixedLengthVector()) {
16106 MVT OpVT =
V.getSimpleValueType();
16108 assert(useRVVForFixedLengthVectorVT(OpVT) &&
16109 "Only fixed length vectors are supported!");
16116 SDValue VPOp = DAG.
getNode(RISCVISDOpc,
DL, ContainerVT,
Ops,
Op->getFlags());
16124 MVT VT =
Op.getSimpleValueType();
16125 MVT XLenVT = Subtarget.getXLenVT();
16127 SDValue
Mask =
Op.getOperand(0);
16130 SDValue VL =
Op.getOperand(3);
16138 MVT ContainerVT = VT;
16151 SDValue VLMax = DAG.
getRegister(RISCV::X0, XLenVT);
16152 SDValue SplatOne = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, PromotedVT,
16155 SDValue SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, PromotedVT,
16158 TrueVal = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, PromotedVT, TrueVal, SplatOne,
16159 SplatZero, DAG.
getUNDEF(PromotedVT), VL);
16162 SplatOne, SplatZero, DAG.
getUNDEF(PromotedVT), VLMax);
16165 SDValue VPMerge = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, PromotedVT, Mask,
16166 TrueVal, FalseVal, FalseVal, VL);
16169 SDValue TrueMask = DAG.
getNode(RISCVISD::VMSET_VL,
DL, ContainerVT, VL);
16171 RISCVISD::SETCC_VL,
DL, ContainerVT,
16181RISCVTargetLowering::lowerVPSpliceExperimental(
SDValue Op,
16183 using namespace SDPatternMatch;
16187 SDValue Op1 =
Op.getOperand(0);
16188 SDValue Op2 =
Op.getOperand(1);
16189 SDValue
Offset =
Op.getOperand(2);
16190 SDValue
Mask =
Op.getOperand(3);
16191 SDValue EVL1 =
Op.getOperand(4);
16192 SDValue EVL2 =
Op.getOperand(5);
16194 const MVT XLenVT = Subtarget.getXLenVT();
16195 MVT VT =
Op.getSimpleValueType();
16196 MVT ContainerVT = VT;
16206 if (IsMaskVector) {
16210 SDValue SplatOneOp1 = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
16213 SDValue SplatZeroOp1 = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
16216 Op1 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, Op1, SplatOneOp1,
16217 SplatZeroOp1, DAG.
getUNDEF(ContainerVT), EVL1);
16219 SDValue SplatOneOp2 = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
16222 SDValue SplatZeroOp2 = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
16225 Op2 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, Op2, SplatOneOp2,
16226 SplatZeroOp2, DAG.
getUNDEF(ContainerVT), EVL2);
16229 auto getVectorFirstEle = [](SDValue Vec) {
16242 if (
auto FirstEle = getVectorFirstEle(
Op->getOperand(0))) {
16245 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
16246 (EltVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
16254 : RISCVISD::VSLIDE1UP_VL,
16255 DL, ContainerVT, DAG.
getUNDEF(ContainerVT), Op2,
16256 FirstEle, Mask, EVL2);
16266 SDValue DownOffset, UpOffset;
16267 if (ImmValue >= 0) {
16281 DAG.
getUNDEF(ContainerVT), Op1, DownOffset, Mask,
16282 Subtarget.hasVLDependentLatency() ? UpOffset : EVL2);
16286 if (IsMaskVector) {
16290 {Result, DAG.getConstant(0, DL, ContainerVT),
16291 DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(getMaskTypeFor(ContainerVT)),
16301RISCVTargetLowering::lowerVPReverseExperimental(
SDValue Op,
16304 MVT VT =
Op.getSimpleValueType();
16305 MVT XLenVT = Subtarget.getXLenVT();
16307 SDValue Op1 =
Op.getOperand(0);
16308 SDValue
Mask =
Op.getOperand(1);
16309 SDValue EVL =
Op.getOperand(2);
16311 MVT ContainerVT = VT;
16319 MVT GatherVT = ContainerVT;
16323 if (IsMaskVector) {
16327 SDValue SplatOne = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, IndicesVT,
16330 SDValue SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, IndicesVT,
16333 Op1 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, IndicesVT, Op1, SplatOne,
16334 SplatZero, DAG.
getUNDEF(IndicesVT), EVL);
16339 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
16340 unsigned MaxVLMAX =
16343 unsigned GatherOpc = RISCVISD::VRGATHER_VV_VL;
16349 if (MaxVLMAX > 256 && EltSize == 8) {
16376 DAG.
getUNDEF(GatherVT), Result, Diff, Mask, EVL);
16378 if (IsMaskVector) {
16381 DAG.
getNode(RISCVISD::SETCC_VL,
DL, ContainerVT,
16394 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
16397 SDValue VID = DAG.
getNode(RISCVISD::VID_VL,
DL, IndicesVT, Mask, EVL);
16400 SDValue VecLenSplat = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, IndicesVT,
16401 DAG.
getUNDEF(IndicesVT), VecLen, EVL);
16402 SDValue VRSUB = DAG.
getNode(RISCVISD::SUB_VL,
DL, IndicesVT, VecLenSplat, VID,
16403 DAG.
getUNDEF(IndicesVT), Mask, EVL);
16405 DAG.
getUNDEF(GatherVT), Mask, EVL);
16407 if (IsMaskVector) {
16410 RISCVISD::SETCC_VL,
DL, ContainerVT,
16423 MVT XLenVT = Subtarget.getXLenVT();
16424 MVT VT =
Op.getSimpleValueType();
16425 MVT ContainerVT = VT;
16429 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
16433 SDValue
Mask = VPNode->getMask();
16437 : Intrinsic::riscv_vlse_mask,
16440 DAG.
getUNDEF(ContainerVT), VPNode->getBasePtr(),
16441 VPNode->getStride()};
16447 Ops.push_back(Mask);
16449 Ops.push_back(VPNode->getVectorLength());
16453 Ops.push_back(Policy);
16458 VPNode->getMemoryVT(), VPNode->getMemOperand());
16459 SDValue Chain =
Result.getValue(1);
16470 MVT XLenVT = Subtarget.getXLenVT();
16473 SDValue StoreVal = VPNode->getValue();
16475 MVT ContainerVT = VT;
16482 SDValue
Mask = VPNode->getMask();
16486 : Intrinsic::riscv_vsse_mask,
16489 VPNode->getBasePtr(), VPNode->getStride()};
16495 Ops.push_back(Mask);
16497 Ops.push_back(VPNode->getVectorLength());
16500 Ops, VPNode->getMemoryVT(),
16501 VPNode->getMemOperand());
16513 MVT VT =
Op.getSimpleValueType();
16516 EVT MemVT = MemSD->getMemoryVT();
16517 MachineMemOperand *MMO = MemSD->getMemOperand();
16518 SDValue Chain = MemSD->getChain();
16519 SDValue
BasePtr = MemSD->getBasePtr();
16525 Index = VPGN->getIndex();
16526 Mask = VPGN->getMask();
16528 VL = VPGN->getVectorLength();
16534 Index = MGN->getIndex();
16535 Mask = MGN->getMask();
16536 PassThru = MGN->getPassThru();
16540 MVT IndexVT =
Index.getSimpleValueType();
16541 MVT XLenVT = Subtarget.getXLenVT();
16544 "Unexpected VTs!");
16545 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
16548 "Unexpected extending MGATHER/VP_GATHER");
16554 MVT ContainerVT = VT;
16578 IsUnmasked ? Intrinsic::riscv_vluxei : Intrinsic::riscv_vluxei_mask;
16583 Ops.push_back(PassThru);
16584 Ops.push_back(BasePtr);
16585 Ops.push_back(Index);
16587 Ops.push_back(Mask);
16592 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
16595 Chain =
Result.getValue(1);
16613 EVT MemVT = MemSD->getMemoryVT();
16614 MachineMemOperand *MMO = MemSD->getMemOperand();
16615 SDValue Chain = MemSD->getChain();
16616 SDValue
BasePtr = MemSD->getBasePtr();
16618 [[maybe_unused]]
bool IsTruncatingStore =
false;
16622 Index = VPSN->getIndex();
16623 Mask = VPSN->getMask();
16624 Val = VPSN->getValue();
16625 VL = VPSN->getVectorLength();
16627 IsTruncatingStore =
false;
16631 Index = MSN->getIndex();
16632 Mask = MSN->getMask();
16633 Val = MSN->getValue();
16634 IsTruncatingStore = MSN->isTruncatingStore();
16638 MVT IndexVT =
Index.getSimpleValueType();
16639 MVT XLenVT = Subtarget.getXLenVT();
16642 "Unexpected VTs!");
16643 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
16646 assert(!IsTruncatingStore &&
"Unexpected truncating MSCATTER/VP_SCATTER");
16652 MVT ContainerVT = VT;
16676 IsUnmasked ? Intrinsic::riscv_vsoxei : Intrinsic::riscv_vsoxei_mask;
16678 Ops.push_back(Val);
16679 Ops.push_back(BasePtr);
16680 Ops.push_back(Index);
16682 Ops.push_back(Mask);
16691 const MVT XLenVT = Subtarget.getXLenVT();
16693 SDValue Chain =
Op->getOperand(0);
16695 SDVTList VTs = DAG.
getVTList(XLenVT, MVT::Other);
16696 SDValue
RM = DAG.
getNode(RISCVISD::READ_CSR,
DL, VTs, Chain, SysRegNo);
16702 static const int Table =
16721 const MVT XLenVT = Subtarget.getXLenVT();
16723 SDValue Chain =
Op->getOperand(0);
16724 SDValue RMValue =
Op->getOperand(1);
16731 static const unsigned Table =
16746 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
16752 const MVT XLenVT = Subtarget.getXLenVT();
16754 SDValue Chain =
Op->getOperand(0);
16756 SDVTList VTs = DAG.
getVTList(XLenVT, MVT::Other);
16757 return DAG.
getNode(RISCVISD::READ_CSR,
DL, VTs, Chain, SysRegNo);
16762 const MVT XLenVT = Subtarget.getXLenVT();
16764 SDValue Chain =
Op->getOperand(0);
16765 SDValue EnvValue =
Op->getOperand(1);
16769 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
16775 const MVT XLenVT = Subtarget.getXLenVT();
16777 SDValue Chain =
Op->getOperand(0);
16778 SDValue EnvValue = DAG.
getRegister(RISCV::X0, XLenVT);
16781 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
16795 SDValue Result = DAG.
getNode(RISCVISD::READ_CSR,
DL, VTs, Chain, SysRegNo);
16796 Chain = Result.getValue(1);
16802 const MVT XLenVT = Subtarget.getXLenVT();
16805 SDValue Chain =
Op->getOperand(0);
16806 SDValue EnvValue =
Op->getOperand(1);
16808 SDValue ModeMask = DAG.
getConstant(ModeMaskValue,
DL, XLenVT);
16812 Chain = DAG.
getNode(RISCVISD::CLEAR_CSR,
DL, MVT::Other, Chain, SysRegNo,
16814 return DAG.
getNode(RISCVISD::SET_CSR,
DL, MVT::Other, Chain, SysRegNo,
16820 const MVT XLenVT = Subtarget.getXLenVT();
16823 SDValue Chain =
Op->getOperand(0);
16825 SDValue ModeMask = DAG.
getConstant(ModeMaskValue,
DL, XLenVT);
16827 return DAG.
getNode(RISCVISD::CLEAR_CSR,
DL, MVT::Other, Chain, SysRegNo,
16835 bool isRISCV64 = Subtarget.is64Bit();
16849 return RISCVISD::SLLW;
16851 return RISCVISD::SRAW;
16853 return RISCVISD::SRLW;
16855 return RISCVISD::DIVW;
16857 return RISCVISD::DIVUW;
16859 return RISCVISD::REMUW;
16861 return RISCVISD::ROLW;
16863 return RISCVISD::RORW;
16908 switch (
N->getOpcode()) {
16910 llvm_unreachable(
"Don't know how to custom type legalize this operation!");
16915 bool IsStrict =
N->isStrictFPOpcode();
16918 SDValue Op0 = IsStrict ?
N->getOperand(1) :
N->getOperand(0);
16925 if (!Subtarget.is64Bit()) {
16926 assert(
N->getValueType(0) == MVT::i64 &&
16927 "Unexpected custom legalisation");
16934 DL, {MVT::i32, MVT::Other}, {
N->getOperand(0), Op0});
16946 assert(
N->getValueType(0) == MVT::i32 &&
"Unexpected custom legalisation");
16955 !Subtarget.hasStdExtZfhOrZhinx()) {
16960 unsigned Opc = IsSigned ? RISCVISD::STRICT_FCVT_W_RV64
16961 : RISCVISD::STRICT_FCVT_WU_RV64;
16964 Opc,
DL, VTs, Chain, Op0,
16973 !Subtarget.hasStdExtZfhOrZhinx()) ||
16977 unsigned Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
16998 std::tie(Result, Chain) =
16999 makeLibCall(DAG, LC,
N->getValueType(0), Op0, CallOptions,
DL, Chain);
17014 if (Op0.
getValueType() == MVT::f16 && !Subtarget.hasStdExtZfhOrZhinx())
17018 DAG.
getNode(RISCVISD::FCVT_W_RV64,
DL, MVT::i64, Op0,
17026 RTLIB::Libcall LC = RTLIB::getLROUND(Op0.
getValueType());
17027 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected FP type for LROUND!");
17038 assert(!Subtarget.is64Bit() &&
"READCYCLECOUNTER/READSTEADYCOUNTER only "
17039 "has custom type legalization on riscv32");
17041 SDValue LoCounter, HiCounter;
17042 MVT XLenVT = Subtarget.getXLenVT();
17052 N->getOperand(0), LoCounter, HiCounter);
17067 if (
N->getValueType(0) == MVT::i64) {
17068 assert(Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit() &&
17069 "Unexpected custom legalisation");
17071 if (Ld->getAlign() < Subtarget.getZilsdAlign())
17076 RISCVISD::LD_RV32,
DL,
17077 DAG.
getVTList({MVT::i32, MVT::i32, MVT::Other}),
17078 {Ld->getChain(), Ld->getBasePtr()}, MVT::i64, Ld->getMemOperand());
17082 Results.append({Pair, Result.getValue(2)});
17086 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
17087 "Unexpected custom legalisation");
17091 Ld->getBasePtr(), Ld->getMemoryVT(),
17092 Ld->getMemOperand());
17098 unsigned Size =
N->getSimpleValueType(0).getSizeInBits();
17099 unsigned XLen = Subtarget.getXLen();
17107 assert(
Size == (XLen * 2) &&
"Unexpected custom legalisation");
17110 unsigned LoHiOpc) {
17111 MVT XLenVT = Subtarget.getXLenVT();
17115 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit()) {
17118 Hi =
Lo.getValue(1);
17132 if (LHSIsU && RHSIsU) {
17139 if (LHSIsS && RHSIsS)
17141 else if (RHSIsU && LHSIsS)
17143 MakeMULPair(LHS, RHS, RISCVISD::MULHSU, RISCVISD::WMULSU));
17144 else if (LHSIsU && RHSIsS)
17146 MakeMULPair(RHS, LHS, RISCVISD::MULHSU, RISCVISD::WMULSU));
17154 if (
N->getValueType(0) == MVT::i64) {
17155 assert(!Subtarget.is64Bit() && Subtarget.hasStdExtP() &&
17156 "Unexpected custom legalisation");
17159 auto [LHSLo, LHSHi] =
17161 auto [RHSLo, RHSHi] =
17164 N->getOpcode() ==
ISD::ADD ? RISCVISD::ADDD : RISCVISD::SUBD;
17166 LHSLo, LHSHi, RHSLo, RHSHi);
17172 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
17173 "Unexpected custom legalisation");
17177 MVT VT =
N->getSimpleValueType(0);
17179 Subtarget.is64Bit() && (VT == MVT::v2i16 || VT == MVT::v4i8) &&
17180 "Unexpected custom legalisation");
17198 for (
unsigned i = 0; i != NumElts; ++i)
17199 ShuffleMask[i] = i * 2;
17203 DAG.
getUNDEF(WidenVT), ShuffleMask));
17209 EVT VT =
N->getValueType(0);
17211 assert(Subtarget.is64Bit() && (VT == MVT::v2i16 || VT == MVT::v4i8) &&
17212 "Unexpected vector type for P-extension shift");
17216 SDValue ShiftAmt =
N->getOperand(1);
17228 if (VT == MVT::i64) {
17229 assert(!Subtarget.is64Bit() && Subtarget.hasStdExtP() &&
17230 "Unexpected custom legalisation");
17235 unsigned WideOpc = 0;
17238 WideOpc = RISCVISD::WSLL;
17240 WideOpc = RISCVISD::WSLA;
17256 if (!ShAmtC || ShAmtC->getZExtValue() >= 32)
17270 uint64_t ShAmtVal = ShAmtC->getZExtValue();
17275 bool IsSRA =
N->getOpcode() ==
ISD::SRA;
17276 LoRes = DAG.
getNode(IsSRA ? RISCVISD::NSRA : RISCVISD::NSRL,
DL,
17277 MVT::i32,
Lo,
Hi, ShAmt);
17286 assert(VT == MVT::i32 && Subtarget.is64Bit() &&
17287 "Unexpected custom legalisation");
17290 if (
N->getOpcode() ==
ISD::SHL && Subtarget.hasStdExtZbs() &&
17316 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
17317 "Unexpected custom legalisation");
17318 assert((Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb() ||
17319 Subtarget.hasVendorXTHeadBb()) &&
17320 "Unexpected custom legalization");
17322 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()))
17331 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
17332 "Unexpected custom legalisation");
17337 switch (
N->getOpcode()) {
17341 Opc = RISCVISD::CTZW;
17345 Opc = RISCVISD::CLZW;
17348 Opc = RISCVISD::CLSW;
17359 MVT VT =
N->getSimpleValueType(0);
17360 assert((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) &&
17361 Subtarget.is64Bit() && Subtarget.hasStdExtM() &&
17362 "Unexpected custom legalisation");
17374 if (VT != MVT::i32)
17383 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
17384 "Unexpected custom legalisation");
17406 EVT OType =
N->getValueType(1);
17423 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
17424 "Unexpected custom legalisation");
17441 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res,
17445 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1),
N->getOperand(0),
17452 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res, LHS,
17464 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
17465 "Unexpected custom legalisation");
17467 if (Subtarget.hasStdExtP()) {
17483 assert(!Subtarget.hasStdExtZbb() &&
"Unexpected custom legalisation");
17489 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
17490 "Unexpected custom legalisation");
17492 if (Subtarget.hasStdExtP()) {
17500 if (Subtarget.hasStdExtZbb()) {
17534 EVT VT =
N->getValueType(0);
17538 MVT XLenVT = Subtarget.getXLenVT();
17539 if (VT == MVT::i16 &&
17540 ((Op0VT == MVT::f16 && Subtarget.hasStdExtZfhminOrZhinxmin()) ||
17541 (Op0VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
17544 }
else if (VT == MVT::i32 && Op0VT == MVT::f32 && Subtarget.is64Bit() &&
17545 Subtarget.hasStdExtFOrZfinx()) {
17547 DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Op0);
17549 }
else if (VT == MVT::i64 && Op0VT == MVT::f64 && !Subtarget.is64Bit() &&
17550 Subtarget.hasStdExtDOrZdinx()) {
17552 DAG.
getVTList(MVT::i32, MVT::i32), Op0);
17556 if (!Subtarget.isLittleEndian())
17575 assert(
N->getValueType(0) == MVT::i8 && Subtarget.hasStdExtZbkb() &&
17576 "Unexpected custom legalisation");
17577 MVT XLenVT = Subtarget.getXLenVT();
17585 case RISCVISD::BREV8:
17586 case RISCVISD::ORC_B: {
17587 MVT VT =
N->getSimpleValueType(0);
17588 MVT XLenVT = Subtarget.getXLenVT();
17589 assert((VT == MVT::i16 || (VT == MVT::i32 && Subtarget.is64Bit())) &&
17590 "Unexpected custom legalisation");
17591 assert(((
N->getOpcode() == RISCVISD::BREV8 && Subtarget.hasStdExtZbkb()) ||
17592 (
N->getOpcode() == RISCVISD::ORC_B && Subtarget.hasStdExtZbb())) &&
17593 "Unexpected extension");
17601 case RISCVISD::ASUB:
17602 case RISCVISD::ASUBU:
17603 case RISCVISD::MULHSU:
17604 case RISCVISD::MULHR:
17605 case RISCVISD::MULHRU:
17606 case RISCVISD::MULHRSU: {
17607 MVT VT =
N->getSimpleValueType(0);
17610 unsigned Opcode =
N->getOpcode();
17612 [[maybe_unused]]
bool IsMulH =
17613 Opcode == RISCVISD::MULHSU || Opcode == RISCVISD::MULHR ||
17614 Opcode == RISCVISD::MULHRU || Opcode == RISCVISD::MULHRSU;
17615 assert(VT == MVT::v2i16 || (!IsMulH && VT == MVT::v4i8));
17616 MVT NewVT = MVT::v4i16;
17617 if (VT == MVT::v4i8)
17643 assert(!Subtarget.is64Bit() &&
N->getValueType(0) == MVT::i64 &&
17645 "Unexpected EXTRACT_VECTOR_ELT legalization");
17648 MVT ContainerVT = VecVT;
17654 MVT XLenVT = Subtarget.getXLenVT();
17663 DAG.
getUNDEF(ContainerVT), Vec, Idx, Mask, VL);
17675 DAG.
getNode(RISCVISD::SRL_VL,
DL, ContainerVT, Vec, ThirtyTwoV,
17676 DAG.
getUNDEF(ContainerVT), Mask, VL);
17684 unsigned IntNo =
N->getConstantOperandVal(0);
17688 "Don't know how to custom type legalize this intrinsic!");
17689 case Intrinsic::experimental_get_vector_length: {
17694 case Intrinsic::riscv_psext_h:
17696 case Intrinsic::riscv_pzext_h:
17698 case Intrinsic::riscv_psext_b:
17699 case Intrinsic::riscv_pzext_b: {
17700 bool IsSExt = IntNo == Intrinsic::riscv_psext_b;
17701 const char *UnsupportedMsg =
17702 IsSExt ?
"unsupported llvm.riscv.psext intrinsic"
17703 :
"unsupported llvm.riscv.pzext intrinsic";
17704 EVT VT =
N->getValueType(0);
17705 if (!Subtarget.is64Bit() || VT != MVT::v2i16)
17719 case Intrinsic::riscv_pmhacc:
17720 case Intrinsic::riscv_pmhracc:
17721 case Intrinsic::riscv_pmhaccu:
17722 case Intrinsic::riscv_pmhraccu:
17723 case Intrinsic::riscv_pmhaccsu:
17724 case Intrinsic::riscv_pmhraccsu: {
17725 EVT VT =
N->getValueType(0);
17726 if (!Subtarget.is64Bit() || VT != MVT::v2i16)
17729 EVT WideVT = MVT::v4i16;
17738 WideVT, Rd, Rs1, Rs2);
17742 case Intrinsic::riscv_pmhacc_b0:
17743 case Intrinsic::riscv_pmhacc_b1:
17744 case Intrinsic::riscv_pmhaccsu_b0:
17745 case Intrinsic::riscv_pmhaccsu_b1: {
17749 EVT VT =
N->getValueType(0);
17750 if (!Subtarget.is64Bit() || VT != MVT::v2i16)
17753 EVT WideVT = MVT::v4i16;
17761 N->getOperand(3), DAG.
getUNDEF(MVT::v4i8));
17763 DL, WideVT, Rd, Rs1, Rs2);
17767 case Intrinsic::riscv_pm4add:
17768 case Intrinsic::riscv_pm2add:
17769 case Intrinsic::riscv_pm2add_x:
17770 case Intrinsic::riscv_pm4addu:
17771 case Intrinsic::riscv_pm2addu:
17772 case Intrinsic::riscv_pmq2add:
17773 case Intrinsic::riscv_pmqr2add:
17774 case Intrinsic::riscv_pm2sadd:
17775 case Intrinsic::riscv_pm2sadd_x:
17776 case Intrinsic::riscv_pm2sub:
17777 case Intrinsic::riscv_pm2sub_x:
17778 case Intrinsic::riscv_pm4addsu:
17779 case Intrinsic::riscv_pm2addsu: {
17780 MVT VT =
N->getSimpleValueType(0);
17785 if (!Subtarget.is64Bit() && VT == MVT::i64) {
17791 assert(Subtarget.is64Bit() && VT == MVT::i32 &&
17792 "Unexpected horizontal multiply legalization");
17794 MVT WideSrcVT = SrcVT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16;
17804 case Intrinsic::riscv_pmul_00:
17805 case Intrinsic::riscv_pmul_01:
17806 case Intrinsic::riscv_pmul_11:
17807 case Intrinsic::riscv_pmulu_00:
17808 case Intrinsic::riscv_pmulu_01:
17809 case Intrinsic::riscv_pmulu_11:
17810 case Intrinsic::riscv_pmulsu_00:
17811 case Intrinsic::riscv_pmulsu_11: {
17812 MVT VT =
N->getSimpleValueType(0);
17813 if (!Subtarget.is64Bit() || VT != MVT::v2i16)
17818 N->getOperand(1),
Undef);
17820 N->getOperand(2),
Undef);
17826 case Intrinsic::riscv_mul_00:
17827 case Intrinsic::riscv_mul_01:
17828 case Intrinsic::riscv_mul_11:
17829 case Intrinsic::riscv_mulu_00:
17830 case Intrinsic::riscv_mulu_01:
17831 case Intrinsic::riscv_mulu_11:
17832 case Intrinsic::riscv_mulsu_00:
17833 case Intrinsic::riscv_mulsu_11: {
17836 MVT VT =
N->getSimpleValueType(0);
17837 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
17838 if (Subtarget.hasStdExtP() && Subtarget.is64Bit() && VT == MVT::i32 &&
17839 SrcVT == MVT::v2i16) {
17843 N->getOperand(1),
Undef);
17845 N->getOperand(2),
Undef);
17851 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() && VT == MVT::i64 &&
17852 SrcVT == MVT::v2i32) {
17866 case Intrinsic::riscv_pmulh_b0:
17867 case Intrinsic::riscv_pmulh_b1:
17868 case Intrinsic::riscv_pmulhsu_b0:
17869 case Intrinsic::riscv_pmulhsu_b1: {
17872 EVT VT =
N->getValueType(0);
17873 if (!Subtarget.is64Bit() || VT != MVT::v2i16)
17878 N->getOperand(1),
Undef);
17887 case Intrinsic::riscv_mulh_h0:
17888 case Intrinsic::riscv_mulh_h1:
17889 case Intrinsic::riscv_mulhsu_h0:
17890 case Intrinsic::riscv_mulhsu_h1: {
17893 MVT VT =
N->getSimpleValueType(0);
17894 MVT SrcVT =
N->getOperand(2).getSimpleValueType();
17895 if (Subtarget.hasStdExtP() && Subtarget.is64Bit() && VT == MVT::i32 &&
17896 SrcVT == MVT::v2i16) {
17902 N->getOperand(2),
Undef);
17904 MVT::v2i32, Rd, Rs1);
17909 "unsupported llvm.riscv multiply-high-parts intrinsic");
17911 case Intrinsic::riscv_macc_00:
17912 case Intrinsic::riscv_macc_01:
17913 case Intrinsic::riscv_macc_11:
17914 case Intrinsic::riscv_maccu_00:
17915 case Intrinsic::riscv_maccu_01:
17916 case Intrinsic::riscv_maccu_11:
17917 case Intrinsic::riscv_maccsu_00:
17918 case Intrinsic::riscv_maccsu_11: {
17921 MVT VT =
N->getSimpleValueType(0);
17922 MVT SrcVT =
N->getOperand(2).getSimpleValueType();
17923 if (Subtarget.hasStdExtP() && Subtarget.is64Bit() && VT == MVT::i32 &&
17924 SrcVT == MVT::v2i16) {
17930 N->getOperand(2),
Undef);
17932 N->getOperand(3),
Undef);
17934 MVT::v2i32, Rd, Rs1, Rs2);
17938 if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() && VT == MVT::i64 &&
17939 SrcVT == MVT::v2i32) {
17940 auto [
Opc, Rs1Lane, Rs2Lane] =
17942 auto [RdLo, RdHi] =
17949 RdLo, RdHi, Rs1, Rs2);
17956 case Intrinsic::riscv_paadd:
17957 case Intrinsic::riscv_paaddu:
17958 case Intrinsic::riscv_pasub:
17959 case Intrinsic::riscv_pasubu:
17960 case Intrinsic::riscv_pabd:
17961 case Intrinsic::riscv_pabdu:
17962 case Intrinsic::riscv_pas:
17963 case Intrinsic::riscv_psa:
17964 case Intrinsic::riscv_psas:
17965 case Intrinsic::riscv_pssa:
17966 case Intrinsic::riscv_paas:
17967 case Intrinsic::riscv_pasa:
17968 case Intrinsic::riscv_pmerge:
17969 case Intrinsic::riscv_pmulq:
17970 case Intrinsic::riscv_pmulqr:
17971 case Intrinsic::riscv_pmulhr:
17972 case Intrinsic::riscv_pmulhru:
17973 case Intrinsic::riscv_pmulhsu:
17974 case Intrinsic::riscv_pmulhrsu:
17975 case Intrinsic::riscv_psabs:
17976 case Intrinsic::riscv_psati:
17977 case Intrinsic::riscv_pusati: {
17978 EVT VT =
N->getValueType(0);
17979 if (!Subtarget.is64Bit() || (VT != MVT::v4i8 && VT != MVT::v2i16))
17984 case Intrinsic::riscv_paadd:
17987 case Intrinsic::riscv_paaddu:
17990 case Intrinsic::riscv_pasub:
17991 Opc = RISCVISD::ASUB;
17993 case Intrinsic::riscv_pasubu:
17994 Opc = RISCVISD::ASUBU;
17996 case Intrinsic::riscv_pabd:
17999 case Intrinsic::riscv_pabdu:
18002 case Intrinsic::riscv_psabs:
18003 Opc = RISCVISD::PSABS;
18005 case Intrinsic::riscv_pmulq:
18006 Opc = RISCVISD::MULQ;
18008 case Intrinsic::riscv_pmulqr:
18009 Opc = RISCVISD::MULQR;
18011 case Intrinsic::riscv_pmulhr:
18012 case Intrinsic::riscv_pmulhru:
18013 case Intrinsic::riscv_pmulhsu:
18014 case Intrinsic::riscv_pmulhrsu:
18024 EVT WideVT = VT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16;
18028 if (
Op.getValueType() == VT)
18039 case Intrinsic::riscv_mulhr_i32:
18040 case Intrinsic::riscv_mulhru_u32:
18041 case Intrinsic::riscv_mulhsu_i32:
18042 case Intrinsic::riscv_mulhrsu_i32: {
18045 MVT VT =
N->getSimpleValueType(0);
18046 if (!Subtarget.is64Bit() || VT != MVT::i32)
18057 case Intrinsic::riscv_pnclipp:
18058 case Intrinsic::riscv_pnclipup: {
18059 bool IsSigned = IntNo == Intrinsic::riscv_pnclipp;
18060 EVT VT =
N->getValueType(0);
18061 if (!Subtarget.is64Bit() || (VT != MVT::v4i8 && VT != MVT::v2i16))
18063 unsigned Opc = IsSigned ? RISCVISD::PNCLIPP : RISCVISD::PNCLIPUP;
18066 if (VT == MVT::v4i8) {
18067 MVT WideSrcVT = MVT::v4i16;
18073 MVT WideSrcVT = MVT::v2i32;
18081 case Intrinsic::riscv_psll:
18082 case Intrinsic::riscv_psrl:
18083 case Intrinsic::riscv_psra:
18084 case Intrinsic::riscv_pssha:
18085 case Intrinsic::riscv_psshar:
18086 case Intrinsic::riscv_psshl:
18087 case Intrinsic::riscv_psshlr: {
18088 MVT VT =
N->getSimpleValueType(0);
18089 if (!Subtarget.is64Bit() || (VT != MVT::v4i8 && VT != MVT::v2i16))
18092 EVT WideVT = VT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16;
18102 case Intrinsic::riscv_pnsrl:
18103 case Intrinsic::riscv_pnsra:
18104 case Intrinsic::riscv_pnsrar: {
18105 MVT VT =
N->getSimpleValueType(0);
18106 if (!Subtarget.is64Bit() || (VT != MVT::v4i8 && VT != MVT::v2i16))
18110 MVT SrcVT = Src.getSimpleValueType();
18111 if (!((VT == MVT::v4i8 && SrcVT == MVT::v4i16) ||
18112 (VT == MVT::v2i16 && SrcVT == MVT::v2i32)))
18115 MVT XLenVT = Subtarget.getXLenVT();
18122 case Intrinsic::riscv_pnsrl:
18123 Opc = RISCVISD::PSRL;
18125 case Intrinsic::riscv_pnsra:
18126 Opc = RISCVISD::PSRA;
18128 case Intrinsic::riscv_pnsrar:
18129 Opc = RISCVISD::PSSHAR;
18137 MVT UnzipVT = VT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16;
18144 case Intrinsic::riscv_predsum:
18145 case Intrinsic::riscv_predsumu: {
18146 bool IsSigned = IntNo == Intrinsic::riscv_predsum;
18160 if (!Subtarget.is64Bit() &&
N->getValueType(0) == MVT::i64) {
18163 if (VecVT == MVT::v2i32) {
18179 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
18183 if (VecVT == MVT::v4i8 || VecVT == MVT::v2i16)
18185 DAG,
DL, Vec, VecVT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16);
18191 SDValue Res = RedSum(MVT::i64, Vec, Acc);
18195 case Intrinsic::riscv_pabdsumu:
18196 case Intrinsic::riscv_pabdsumau: {
18197 bool IsAcc = IntNo == Intrinsic::riscv_pabdsumau;
18199 SDValue Rs1 =
N->getOperand(
N->getNumOperands() - 2);
18200 SDValue Rs2 =
N->getOperand(
N->getNumOperands() - 1);
18205 if (!Subtarget.is64Bit() &&
N->getValueType(0) == MVT::i64) {
18230 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
18232 if (VecVT == MVT::v4i8) {
18240 Ops.push_back(Rs1);
18241 Ops.push_back(Rs2);
18246 case Intrinsic::riscv_mqacc_00:
18247 case Intrinsic::riscv_mqacc_01:
18248 case Intrinsic::riscv_mqacc_11:
18249 case Intrinsic::riscv_mqracc_00:
18250 case Intrinsic::riscv_mqracc_01:
18251 case Intrinsic::riscv_mqracc_11: {
18252 EVT VT =
N->getValueType(0);
18253 if (Subtarget.is64Bit() && VT == MVT::i32) {
18256 auto WidenSrc = [&](
SDValue V) {
18260 SDValue Rs1 = WidenSrc(
N->getOperand(2));
18261 SDValue Rs2 = WidenSrc(
N->getOperand(3));
18268 if (!Subtarget.is64Bit() && VT == MVT::i64) {
18269 bool IsRound = IntNo == Intrinsic::riscv_mqracc_00 ||
18270 IntNo == Intrinsic::riscv_mqracc_01 ||
18271 IntNo == Intrinsic::riscv_mqracc_11;
18272 bool Hi1 = IntNo == Intrinsic::riscv_mqacc_11 ||
18273 IntNo == Intrinsic::riscv_mqracc_11;
18274 bool Hi2 = IntNo == Intrinsic::riscv_mqacc_01 ||
18275 IntNo == Intrinsic::riscv_mqacc_11 ||
18276 IntNo == Intrinsic::riscv_mqracc_01 ||
18277 IntNo == Intrinsic::riscv_mqracc_11;
18278 MVT XLenVT = Subtarget.getXLenVT();
18283 auto [RdLo, RdHi] =
18285 unsigned Opc = IsRound ? RISCVISD::MQRWACC : RISCVISD::MQWACC;
18294 case Intrinsic::riscv_orc_b:
18295 case Intrinsic::riscv_brev8:
18296 case Intrinsic::riscv_sha256sig0:
18297 case Intrinsic::riscv_sha256sig1:
18298 case Intrinsic::riscv_sha256sum0:
18299 case Intrinsic::riscv_sha256sum1:
18300 case Intrinsic::riscv_sm3p0:
18301 case Intrinsic::riscv_sm3p1: {
18302 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
18306 case Intrinsic::riscv_orc_b:
Opc = RISCVISD::ORC_B;
break;
18307 case Intrinsic::riscv_brev8:
Opc = RISCVISD::BREV8;
break;
18308 case Intrinsic::riscv_sha256sig0:
Opc = RISCVISD::SHA256SIG0;
break;
18309 case Intrinsic::riscv_sha256sig1:
Opc = RISCVISD::SHA256SIG1;
break;
18310 case Intrinsic::riscv_sha256sum0:
Opc = RISCVISD::SHA256SUM0;
break;
18311 case Intrinsic::riscv_sha256sum1:
Opc = RISCVISD::SHA256SUM1;
break;
18312 case Intrinsic::riscv_sm3p0:
Opc = RISCVISD::SM3P0;
break;
18313 case Intrinsic::riscv_sm3p1:
Opc = RISCVISD::SM3P1;
break;
18322 case Intrinsic::riscv_sm4ks:
18323 case Intrinsic::riscv_sm4ed: {
18325 IntNo == Intrinsic::riscv_sm4ks ? RISCVISD::SM4KS : RISCVISD::SM4ED;
18331 DAG.
getNode(
Opc,
DL, MVT::i64, NewOp0, NewOp1,
N->getOperand(3));
18335 case Intrinsic::riscv_mopr: {
18336 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
18341 RISCVISD::MOP_R,
DL, MVT::i64, NewOp,
18346 case Intrinsic::riscv_moprr: {
18347 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
18354 RISCVISD::MOP_RR,
DL, MVT::i64, NewOp0, NewOp1,
18359 case Intrinsic::riscv_clmulh:
18360 case Intrinsic::riscv_clmulr: {
18361 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
18389 case Intrinsic::riscv_vmv_x_s: {
18390 EVT VT =
N->getValueType(0);
18391 MVT XLenVT = Subtarget.getXLenVT();
18392 if (VT.
bitsLT(XLenVT)) {
18395 Subtarget.getXLenVT(),
N->getOperand(1));
18400 assert(VT == MVT::i64 && !Subtarget.is64Bit() &&
18401 "Unexpected custom legalization");
18417 SDValue LShr32 = DAG.
getNode(RISCVISD::SRL_VL,
DL, VecVT, Vec, ThirtyTwoV,
18439 case ISD::VP_REDUCE_ADD:
18440 case ISD::VP_REDUCE_AND:
18441 case ISD::VP_REDUCE_OR:
18442 case ISD::VP_REDUCE_XOR:
18443 case ISD::VP_REDUCE_SMAX:
18444 case ISD::VP_REDUCE_UMAX:
18445 case ISD::VP_REDUCE_SMIN:
18446 case ISD::VP_REDUCE_UMIN:
18514 const EVT VT =
N->getValueType(0);
18515 const unsigned Opc =
N->getOpcode();
18525 if (!
N->getFlags().hasAllowReassociation())
18536 "Inconsistent mappings");
18540 if (!
LHS.hasOneUse() || !
RHS.hasOneUse())
18569 if (0 == std::min(LHSIdx, RHSIdx) && 1 == std::max(LHSIdx, RHSIdx)) {
18572 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
N->getFlags());
18579 if (
LHS.getOpcode() != ReduceOpc)
18593 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
18594 ReduceVec->
getFlags() &
N->getFlags());
18604 auto BinOpToRVVReduce = [](
unsigned Opc) {
18609 return RISCVISD::VECREDUCE_ADD_VL;
18611 return RISCVISD::VECREDUCE_UMAX_VL;
18613 return RISCVISD::VECREDUCE_SMAX_VL;
18615 return RISCVISD::VECREDUCE_UMIN_VL;
18617 return RISCVISD::VECREDUCE_SMIN_VL;
18619 return RISCVISD::VECREDUCE_AND_VL;
18621 return RISCVISD::VECREDUCE_OR_VL;
18623 return RISCVISD::VECREDUCE_XOR_VL;
18625 return RISCVISD::VECREDUCE_FADD_VL;
18627 return RISCVISD::VECREDUCE_FMAX_VL;
18629 return RISCVISD::VECREDUCE_FMIN_VL;
18633 auto IsReduction = [&BinOpToRVVReduce](
SDValue V,
unsigned Opc) {
18636 V.getOperand(0).getOpcode() == BinOpToRVVReduce(
Opc);
18639 unsigned Opc =
N->getOpcode();
18640 unsigned ReduceIdx;
18641 if (IsReduction(
N->getOperand(0),
Opc))
18643 else if (IsReduction(
N->getOperand(1),
Opc))
18649 if (
Opc ==
ISD::FADD && !
N->getFlags().hasAllowReassociation())
18652 SDValue Extract =
N->getOperand(ReduceIdx);
18665 if (ScalarV.
getOpcode() != RISCVISD::VFMV_S_F_VL &&
18666 ScalarV.
getOpcode() != RISCVISD::VMV_S_X_VL &&
18667 ScalarV.
getOpcode() != RISCVISD::VMV_V_X_VL)
18684 SDValue NewStart =
N->getOperand(1 - ReduceIdx);
18717 EVT VT =
N->getValueType(0);
18733 int64_t C0 = N0C->getSExtValue();
18734 int64_t C1 = N1C->getSExtValue();
18735 if (C0 <= 0 || C1 <= 0)
18738 int64_t Diff = std::abs(C0 - C1);
18744 int64_t Bits = std::min(C0, C1);
18776 if (VShift.
slt(1) || VShift.
sgt(3))
18780 EVT VT =
N->getValueType(0);
18800 EVT VT =
N->getValueType(0);
18828 EVT VT =
N->getValueType(0);
18836 if (!Subtarget.hasStdExtZicond() ||
N->getOpcode() !=
ISD::AND)
18849 Slct.
getOpcode() != RISCVISD::SELECT_CC) ||
18857 bool SwapSelectOps;
18858 unsigned OpOffset = Slct.
getOpcode() == RISCVISD::SELECT_CC ? 2 : 0;
18863 SwapSelectOps =
false;
18864 NonConstantVal = FalseVal;
18866 SwapSelectOps =
true;
18867 NonConstantVal = TrueVal;
18873 FalseVal = DAG.
getNode(
N->getOpcode(),
SDLoc(
N), VT, OtherOp, NonConstantVal);
18878 if (Slct.
getOpcode() == RISCVISD::SELECT_CC)
18921 EVT VT =
N->getValueType(0);
18936 if (!N0C->hasOneUse())
18938 int64_t C0 = N0C->getSExtValue();
18939 int64_t C1 = N1C->getSExtValue();
18946 if (C0 == -1 || C0 == 0 || C0 == 1 ||
18954 }
else if ((C1 / C0 + 1) != 0 &&
isInt<12>(C1 / C0 + 1) &&
18958 }
else if ((C1 / C0 - 1) != 0 &&
isInt<12>(C1 / C0 - 1) &&
18986 EVT VT =
N->getValueType(0);
19017 unsigned OuterExtend =
19021 OuterExtend,
SDLoc(
N), VT,
19029 EVT VT =
N->getValueType(0);
19063 EVT VT =
N->getValueType(0);
19065 bool IsPExtPackedDoubleType =
19068 !(Subtarget.hasStdExtP() && !Subtarget.
is64Bit() && VT == MVT::v4i8) &&
19069 !(Subtarget.hasStdExtP() && Subtarget.
is64Bit() && VT == MVT::v8i8))
19094 if (IsPExtPackedDoubleType) {
19099 if (HalfVT == MVT::v4i8) {
19100 ResLo = MakePWMulSU(XLo, CLo);
19101 ResHi = MakePWMulSU(XHi, CHi);
19103 ResLo = DAG.
getNode(RISCVISD::MULHSU,
DL, HalfVT, XLo, CLo);
19104 ResHi = DAG.
getNode(RISCVISD::MULHSU,
DL, HalfVT, XHi, CHi);
19109 if (Subtarget.hasStdExtP() && !Subtarget.
is64Bit() && VT == MVT::v4i8)
19114 if (Subtarget.hasStdExtP() && Subtarget.
is64Bit() && VT == MVT::v8i8) {
19128 if (!Subtarget.hasStdExtP())
19131 for (
unsigned I = 0;
I != 2; ++
I) {
19143 N->getOperand(1 -
I),
Mul.getOperand(1),
19144 Mul.getOperand(2));
19153 if (!Subtarget.hasStdExtP() || !Subtarget.
is64Bit())
19156 unsigned Opcode =
N->getOpcode();
19160 EVT VT =
N->getValueType(0);
19161 if (VT != MVT::v4i16 && VT != MVT::v2i32)
19166 unsigned ExtendOpcode = N0.
getOpcode();
19174 MVT SrcVT = VT == MVT::v4i16 ? MVT::v4i8 : MVT::v2i16;
19175 MVT LegalSrcVT = VT == MVT::v4i16 ? MVT::v8i8 : MVT::v4i16;
19176 if (
A.getValueType() != SrcVT ||
B.getValueType() != SrcVT)
19179 if (VT == MVT::v4i16 && !IsSExt)
19182 bool IsPM2Halfword = VT == MVT::v2i32 && (IsSExt || Opcode ==
ISD::ADD);
19183 if (VT == MVT::v2i32 && !IsPM2Halfword)
19191 if (VT == MVT::v4i16) {
19202 unsigned Opc = Opcode ==
ISD::ADD ? RISCVISD::PM2ADD_H : RISCVISD::PM2SUB_H;
19207 return DAG.
getNode(RISCVISD::PM2ADDU_H,
DL, VT, Zip, Ones);
19216 if (!Subtarget.hasStdExtP() || !Subtarget.
is64Bit())
19222 MVT VT =
N->getSimpleValueType(0);
19223 if (VT != MVT::v4i16 && VT != MVT::v2i32)
19226 auto MatchExtend = [](
SDValue V,
unsigned ExtendOpcode,
MVT SrcVT,
19234 MVT SrcVT = VT == MVT::v4i16 ? MVT::v4i8 : MVT::v2i16;
19235 unsigned ExtendOpcode = Ext.
getOpcode();
19239 if (!MatchExtend(Ext, ExtendOpcode, SrcVT,
B))
19245 if (MatchExtend(
Add.getOperand(0), ExtendOpcode, SrcVT,
A))
19246 Acc =
Add.getOperand(1);
19247 else if (MatchExtend(
Add.getOperand(1), ExtendOpcode, SrcVT,
A))
19248 Acc =
Add.getOperand(0);
19252 if (Acc.getValueType() != VT)
19261 if (!Match(
N->getOperand(0),
N->getOperand(1), Acc,
A,
B, IsSExt) &&
19262 !Match(
N->getOperand(1),
N->getOperand(0), Acc,
A,
B, IsSExt))
19265 if (VT == MVT::v4i16 && !IsSExt)
19269 MVT LegalSrcVT = VT == MVT::v4i16 ? MVT::v8i8 : MVT::v4i16;
19270 MVT SrcVT = VT == MVT::v4i16 ? MVT::v4i8 : MVT::v2i16;
19275 if (VT == MVT::v4i16) {
19286 unsigned Opc = IsSExt ? RISCVISD::PM2ADDA_H : RISCVISD::PM2ADDAU_H;
19295 if (!Subtarget.hasStdExtP() || !Subtarget.
is64Bit())
19301 MVT VT =
N->getSimpleValueType(0);
19302 if (VT != MVT::v4i16 && VT != MVT::v2i32)
19305 MVT SrcVT = VT == MVT::v4i16 ? MVT::v4i8 : MVT::v2i16;
19314 Extend(ExtB,
B))) ||
19326 MVT LegalSrcVT = VT == MVT::v4i16 ? MVT::v8i8 : MVT::v4i16;
19331 if (VT == MVT::v4i16) {
19342 return DAG.
getNode(RISCVISD::PM2SUBA_H,
DL, VT, Acc, Zip, Ones);
19383 EVT VT =
N->getValueType(0);
19393 APInt ImmValMinus1 = N0C->getAPIntValue() - 1;
19403 if (!isIntEqualitySetCC(CCVal) || !SetCCOpVT.
isInteger())
19426 if (!Subtarget.hasStdExtZbb())
19429 EVT VT =
N->getValueType(0);
19431 if (VT != Subtarget.
getXLenVT() && VT != MVT::i32 && VT != MVT::i16)
19443 unsigned ShiftedAmount = 8 - ShAmtCLeft->getZExtValue();
19445 if (ShiftedAmount >= 8)
19449 SDValue RightShiftOperand = N1;
19451 if (ShiftedAmount != 0) {
19455 if (!ShAmtCRight || ShAmtCRight->getZExtValue() != ShiftedAmount)
19464 if (LeftShiftOperand != RightShiftOperand)
19468 Mask <<= ShiftedAmount;
19474 return DAG.
getNode(RISCVISD::ORC_B,
SDLoc(
N), VT, LeftShiftOperand);
19482 EVT VT =
N->getValueType(0);
19513 unsigned ShAmt2 = Bits - 1 - ShAmt;
19541 bool IsAnd =
N->getOpcode() ==
ISD::AND;
19565 EVT VT =
N->getValueType(0);
19590 EVT VT =
N->getValueType(0);
19594 if (VT != MVT::v4i16 && VT != MVT::v2i16 && VT != MVT::v8i8 &&
19595 VT != MVT::v4i8 && VT != MVT::v2i32 && VT != MVT::i32)
19603 unsigned ShAmtVal =
C->getZExtValue();
19607 bool IsRounding =
false;
19608 if (
Op.getOpcode() ==
ISD::ADD && (EltBits == 16 || EltBits == 32)) {
19610 if (RndC && RndC->
getZExtValue() == (1ULL << (EltBits - 1)) &&
19612 Op =
Op.getOperand(0);
19618 if (
Op.getNumOperands() != 2)
19629 if (!(LHSIsSExt || LHSIsZExt) || !(RHSIsSExt || RHSIsZExt))
19635 if (
A.getValueType() != VT ||
B.getValueType() != VT)
19639 switch (
Op.getOpcode()) {
19646 if (LHSIsSExt && RHSIsSExt)
19647 Opc = RISCVISD::ASUB;
19648 else if (LHSIsZExt && RHSIsZExt)
19649 Opc = RISCVISD::ASUBU;
19655 if (ShAmtVal != EltBits || (EltBits != 16 && EltBits != 32))
19657 if (!Subtarget.
is64Bit() && VT == MVT::v4i16)
19660 if (LHSIsSExt && RHSIsSExt) {
19661 Opc = RISCVISD::MULHR;
19662 }
else if (LHSIsZExt && RHSIsZExt) {
19663 Opc = RISCVISD::MULHRU;
19664 }
else if ((LHSIsSExt && RHSIsZExt) || (LHSIsZExt && RHSIsSExt)) {
19665 Opc = RISCVISD::MULHRSU;
19667 if (LHSIsZExt && RHSIsSExt)
19676 if ((LHSIsSExt && RHSIsZExt) || (LHSIsZExt && RHSIsSExt)) {
19677 Opc = RISCVISD::MULHSU;
19679 if (LHSIsZExt && RHSIsSExt)
19687 if (!Subtarget.
is64Bit() && VT == MVT::v2i32) {
19702 if (Subtarget.
is64Bit() && VT == MVT::v8i8 &&
Opc == RISCVISD::MULHSU) {
19705 DAG.
getNode(RISCVISD::PMULSU_HALVES_00,
DL, MVT::v4i16,
A,
B);
19707 DAG.
getNode(RISCVISD::PMULSU_HALVES_11,
DL, MVT::v4i16,
A,
B);
19720 EVT VT =
N->getValueType(0);
19723 if (Subtarget.hasStdExtP() &&
19732 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() && VT == MVT::i1 &&
19775 EVT VT =
N->getValueType(0);
19794 EVT WideVT =
X.getValueType();
19831 if (Mask != ExpectedMask)
19848 EVT VT =
N->getValueType(0);
19854 APInt MaskVal, ShiftVal;
19869 APInt InnerMask = MaskVal.
lshr(ShiftAmt);
19870 bool IsNarrowable =
19871 InnerMask == 0xff || InnerMask == 0xffff || InnerMask == 0xffffffff;
19899 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
19938 if (N0.
getOpcode() != RISCVISD::CZERO_EQZ ||
19939 N1.
getOpcode() != RISCVISD::CZERO_NEZ ||
19957 EVT VT =
N->getValueType(0);
19975 if (!Subtarget.hasVendorXqcibm())
19987 if (
N->getValueType(0) != MVT::i32)
19989 unsigned Width, ShAmt;
20006 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
20011 if (!Subtarget.hasVendorXqcibm())
20021 unsigned ShAmt, Width;
20025 if (
N->getValueType(0) != MVT::i32)
20030 if (Width == 1 && Subtarget.hasStdExtZbs())
20042 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
20050 if (!Subtarget.hasVendorXqcibm())
20056 APInt MaskImm, OrImm;
20075 unsigned ShAmt, Width;
20077 if (!
Known.Zero.isShiftedMask(ShAmt, Width))
20088 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
20129 if (Cmp.getOpcode() != RISCVISD::VMSET_VL &&
20130 N->getOperand(1).getOpcode() != RISCVISD::VMSET_VL)
20133 if (Cmp.getOpcode() == RISCVISD::VMSET_VL)
20134 Cmp =
N->getOperand(1);
20136 if (Cmp.getOpcode() != RISCVISD::SETCC_VL || !Cmp.hasOneUse() ||
20137 !Cmp.getOperand(0).getValueType().isInteger() ||
20138 !Cmp.getOperand(3).isUndef())
20143 return DAG.
getNode(RISCVISD::SETCC_VL,
SDLoc(
N), Cmp.getValueType(),
20144 {Cmp.getOperand(0), Cmp.getOperand(1), DAG.getCondCode(CC),
20145 Cmp.getOperand(3), Cmp.getOperand(4), Cmp.getOperand(5)});
20156 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
20171 if (N0.
getOpcode() == RISCVISD::SLLW &&
20175 return DAG.
getNode(RISCVISD::ROLW,
DL, MVT::i64,
20186 const APInt &
Imm = ConstN00->getAPIntValue();
20187 if ((
Imm + 1).isSignedIntN(12))
20211 EVT VT =
N->getValueType(0);
20220 bool IsAdd = (
E & 3) == 1;
20221 E -= IsAdd ? 1 : -1;
20225 Result = DAG.
getNode(AddSubOp,
DL, VT, Result, ShiftVal);
20235 uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
20240 auto PreferSub = [
X, MulAmtLowBit]() {
20249 if (
isPowerOf2_64(MulAmt - MulAmtLowBit) && !(CanSub && PreferSub())) {
20251 ShiftAmt1 = MulAmt - MulAmtLowBit;
20252 }
else if (CanSub) {
20254 ShiftAmt1 = MulAmt + MulAmtLowBit;
20258 EVT VT =
N->getValueType(0);
20268 unsigned ShY,
bool AddX,
unsigned Shift) {
20270 EVT VT =
N->getValueType(0);
20285 ShlAdd = DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT, ShlAdd,
20295 uint64_t MulAmt,
unsigned Shift) {
20321 assert(ShX != 0 &&
"MulAmt=4,6,10 handled before");
20328 EVT VT =
N->getValueType(0);
20345 EVT VT =
N->getValueType(0);
20354 bool ShouldExpandMul =
20356 !Subtarget.hasStdExtZmmul();
20357 if (!ShouldExpandMul)
20387 if (Shift >= 1 && Shift <= 3 &&
isPowerOf2_64(MulAmt & (MulAmt - 1))) {
20392 return DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT,
X,
20399 if (MulAmt > 2 &&
isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
20401 if (ScaleShift >= 1 && ScaleShift < 4) {
20433 if (!Subtarget.hasStdExtZmmul())
20443 EVT VT =
N->getValueType(0);
20450 if (
N->getOperand(0).getOpcode() !=
ISD::AND ||
20451 N->getOperand(0).getOperand(0).getOpcode() !=
ISD::SRL)
20464 if (!
V1.isMask(HalfSize) || V2 != (1ULL | 1ULL << HalfSize) ||
20465 V3 != (HalfSize - 1))
20480 if (!Subtarget.hasStdExtP())
20483 EVT VT =
N->getValueType(0);
20484 if (VT != MVT::v4i16 && VT != MVT::v2i32)
20494 if (!(N0IsSExt || N0IsZExt) || !(N1IsSExt || N1IsZExt) || !N0.
hasOneUse() ||
20500 EVT SrcVT = VT == MVT::v4i16 ? MVT::v4i8 : MVT::v2i16;
20501 if (
A.getValueType() != SrcVT ||
B.getValueType() != SrcVT)
20504 unsigned RV32Opc, RV64Opc;
20505 bool IsSignedUnsigned =
false;
20506 if (N0IsSExt && N1IsSExt) {
20507 RV32Opc = RISCVISD::PWMUL;
20508 RV64Opc = RISCVISD::PMUL_HALVES_01;
20509 }
else if (N0IsZExt && N1IsZExt) {
20510 RV32Opc = RISCVISD::PWMULU;
20511 RV64Opc = RISCVISD::PMULU_HALVES_01;
20513 IsSignedUnsigned =
true;
20514 RV32Opc = RISCVISD::PWMULSU;
20515 RV64Opc = RISCVISD::PMULSU_HALVES_00;
20516 if (N0IsZExt && N1IsSExt)
20524 MVT LegalSrcVT = VT == MVT::v4i16 ? MVT::v8i8 : MVT::v4i16;
20528 if (IsSignedUnsigned) {
20530 A = DAG.
getNode(RISCVISD::PZIP,
DL, LegalSrcVT,
A, Zero);
20531 B = DAG.
getNode(RISCVISD::PZIP,
DL, LegalSrcVT,
B, Zero);
20536 return DAG.
getNode(RV64Opc,
DL, VT, Zip, Zip);
20542 EVT VT =
N->getValueType(0);
20550 unsigned AddSubOpc;
20556 auto IsAddSubWith1 = [&](
SDValue V) ->
bool {
20557 AddSubOpc = V->getOpcode();
20569 if (IsAddSubWith1(N0)) {
20571 return DAG.
getNode(AddSubOpc,
DL, VT, N1, MulVal);
20574 if (IsAddSubWith1(N1)) {
20576 return DAG.
getNode(AddSubOpc,
DL, VT, N0, MulVal);
20594 if (isIndexTypeSigned(IndexType))
20597 if (!
N->hasOneUse())
20600 EVT VT =
N.getValueType();
20612 unsigned ActiveBits = std::max(8u,
Known.countMaxActiveBits());
20639 EVT SrcVT = Src.getValueType();
20647 NewElen = std::max(NewElen, 8U);
20699 !
LHS.getValueType().isInteger())
20709 EVT ElementVT =
LHS.getValueType().getScalarType();
20710 uint64_t ElementSize =
LHS.getScalarValueSizeInBits();
20735 if (!StepVector || !StepVector->second.isOne())
20737 const APInt &Start = StepVector->first;
20742 : Start.zextOrTrunc(ElementSize),
20765 BaseIndex = DAG.
getNode(MinOpc,
DL, ElementVT, Boundary, BaseIndex);
20769 return DAG.
getSetCC(
DL, MaskVT, NewStepVector, Boundary, CC);
20784 EVT OpVT =
X.getValueType();
20796 auto IsVectorBitCastCheap = [](
SDValue X) {
20801 if (!IsVectorBitCastCheap(
X) || !IsVectorBitCastCheap(
Y))
20805 Attribute::NoImplicitFloat))
20813 auto GetPreferredEltVT = [](
SDValue V) ->
MVT {
20828 if (
Use.getResNo() != V.getResNo())
20833 EVT CastVT =
User->getValueType(0);
20844 auto IsValidEltVT = [&](
MVT VT) {
20851 if (OpSize % EltSize != 0)
20855 unsigned NumElts = OpSize / EltSize;
20861 MVT EltVT = GetPreferredEltVT(
X);
20862 if (!IsValidEltVT(EltVT))
20863 EltVT = GetPreferredEltVT(
Y);
20866 if (!IsValidEltVT(EltVT))
20870 unsigned NumElts = OpSize / EltSize;
20895 EVT VT =
N->getValueType(0);
20904 if (!isIntEqualitySetCC(
Cond))
20929 if (OpVT == MVT::i64 &&
isUInt<32>(AndRHSInt) &&
20933 if (ShiftBits != 0 && NewC >= -2048 && NewC <= 2048) {
20939 return DAG.
getSetCC(dl, VT, Shift,
20950 if (N1Width <= TrailingOnes &&
isInt<12>(N1SExt) &&
20961 if (OpVT != MVT::i64 || !Subtarget.
is64Bit())
20981 const APInt &C1 = N1C->getAPIntValue();
20999 EVT VT =
N->getValueType(0);
21001 unsigned Opc = Src.getOpcode();
21006 if (
Opc == RISCVISD::FMV_X_ANYEXTH && SrcVT.
bitsGE(MVT::i16) &&
21007 Subtarget.hasStdExtZfhmin())
21008 return DAG.
getNode(RISCVISD::FMV_X_SIGNEXTH,
DL, VT, Src.getOperand(0));
21014 return DAG.
getNode(RISCVISD::SLLW,
DL, VT, Src.getOperand(0),
21015 Src.getOperand(1));
21034struct CombineResult;
21036enum ExtKind : uint8_t {