38#include "llvm/IR/IntrinsicsRISCV.h"
53#define DEBUG_TYPE "riscv-lower"
59 cl::desc(
"Give the maximum size (in number of nodes) of the web of "
60 "instructions that we will consider for VW expansion"),
65 cl::desc(
"Allow the formation of VW_W operations (e.g., "
66 "VWADD_W) with splat constants"),
71 cl::desc(
"Set the minimum number of repetitions of a divisor to allow "
72 "transformation to multiplications by the reciprocal"),
77 cl::desc(
"Give the maximum number of instructions that we will "
78 "use for creating a floating-point immediate value"),
89 !Subtarget.hasStdExtF()) {
90 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
91 "doesn't support the F instruction set extension (ignoring "
95 !Subtarget.hasStdExtD()) {
96 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
97 "doesn't support the D instruction set extension (ignoring "
121 if (Subtarget.hasStdExtZfhmin())
123 if (Subtarget.hasStdExtZfbfmin())
125 if (Subtarget.hasStdExtF())
127 if (Subtarget.hasStdExtD())
129 if (Subtarget.hasStdExtZhinxmin())
131 if (Subtarget.hasStdExtZfinx())
133 if (Subtarget.hasStdExtZdinx()) {
141 MVT::nxv1i1, MVT::nxv2i1, MVT::nxv4i1, MVT::nxv8i1,
142 MVT::nxv16i1, MVT::nxv32i1, MVT::nxv64i1};
144 MVT::nxv1i8, MVT::nxv2i8, MVT::nxv4i8, MVT::nxv8i8, MVT::nxv16i8,
145 MVT::nxv32i8, MVT::nxv64i8, MVT::nxv1i16, MVT::nxv2i16, MVT::nxv4i16,
146 MVT::nxv8i16, MVT::nxv16i16, MVT::nxv32i16, MVT::nxv1i32, MVT::nxv2i32,
147 MVT::nxv4i32, MVT::nxv8i32, MVT::nxv16i32, MVT::nxv1i64, MVT::nxv2i64,
148 MVT::nxv4i64, MVT::nxv8i64};
150 MVT::nxv1f16, MVT::nxv2f16, MVT::nxv4f16,
151 MVT::nxv8f16, MVT::nxv16f16, MVT::nxv32f16};
153 MVT::nxv1bf16, MVT::nxv2bf16, MVT::nxv4bf16,
154 MVT::nxv8bf16, MVT::nxv16bf16, MVT::nxv32bf16};
156 MVT::nxv1f32, MVT::nxv2f32, MVT::nxv4f32, MVT::nxv8f32, MVT::nxv16f32};
158 MVT::nxv1f64, MVT::nxv2f64, MVT::nxv4f64, MVT::nxv8f64};
160 MVT::riscv_nxv1i8x2, MVT::riscv_nxv1i8x3, MVT::riscv_nxv1i8x4,
161 MVT::riscv_nxv1i8x5, MVT::riscv_nxv1i8x6, MVT::riscv_nxv1i8x7,
162 MVT::riscv_nxv1i8x8, MVT::riscv_nxv2i8x2, MVT::riscv_nxv2i8x3,
163 MVT::riscv_nxv2i8x4, MVT::riscv_nxv2i8x5, MVT::riscv_nxv2i8x6,
164 MVT::riscv_nxv2i8x7, MVT::riscv_nxv2i8x8, MVT::riscv_nxv4i8x2,
165 MVT::riscv_nxv4i8x3, MVT::riscv_nxv4i8x4, MVT::riscv_nxv4i8x5,
166 MVT::riscv_nxv4i8x6, MVT::riscv_nxv4i8x7, MVT::riscv_nxv4i8x8,
167 MVT::riscv_nxv8i8x2, MVT::riscv_nxv8i8x3, MVT::riscv_nxv8i8x4,
168 MVT::riscv_nxv8i8x5, MVT::riscv_nxv8i8x6, MVT::riscv_nxv8i8x7,
169 MVT::riscv_nxv8i8x8, MVT::riscv_nxv16i8x2, MVT::riscv_nxv16i8x3,
170 MVT::riscv_nxv16i8x4, MVT::riscv_nxv32i8x2};
173 auto addRegClassForRVV = [
this](
MVT VT) {
177 if (VT.getVectorMinNumElements() < MinElts)
180 unsigned Size = VT.getSizeInBits().getKnownMinValue();
183 RC = &RISCV::VRRegClass;
185 RC = &RISCV::VRM2RegClass;
187 RC = &RISCV::VRM4RegClass;
189 RC = &RISCV::VRM8RegClass;
196 for (
MVT VT : BoolVecVTs)
197 addRegClassForRVV(VT);
198 for (
MVT VT : IntVecVTs) {
199 if (VT.getVectorElementType() == MVT::i64 &&
202 addRegClassForRVV(VT);
206 for (
MVT VT : F16VecVTs)
207 addRegClassForRVV(VT);
210 for (
MVT VT : BF16VecVTs)
211 addRegClassForRVV(VT);
214 for (
MVT VT : F32VecVTs)
215 addRegClassForRVV(VT);
218 for (
MVT VT : F64VecVTs)
219 addRegClassForRVV(VT);
222 auto addRegClassForFixedVectors = [
this](
MVT VT) {
229 if (useRVVForFixedLengthVectorVT(VT))
230 addRegClassForFixedVectors(VT);
233 if (useRVVForFixedLengthVectorVT(VT))
234 addRegClassForFixedVectors(VT);
294 if (!(Subtarget.hasVendorXCValu() && !Subtarget.
is64Bit())) {
304 if (!Subtarget.hasVendorXTHeadBb())
309 if (!Subtarget.hasStdExtZbb() && !Subtarget.hasVendorXTHeadBb() &&
310 !(Subtarget.hasVendorXCValu() && !Subtarget.
is64Bit()))
320 if (!Subtarget.hasStdExtZbb())
326 if (!Subtarget.hasStdExtZmmul()) {
328 }
else if (Subtarget.
is64Bit()) {
335 if (!Subtarget.hasStdExtM()) {
338 }
else if (Subtarget.
is64Bit()) {
340 {MVT::i8, MVT::i16, MVT::i32},
Custom);
350 if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) {
353 }
else if (Subtarget.hasVendorXTHeadBb()) {
357 }
else if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.
is64Bit()) {
366 (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb() ||
367 Subtarget.hasVendorXTHeadBb())
371 if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.
is64Bit()) {
379 if (Subtarget.hasStdExtZbb() ||
380 (Subtarget.hasVendorXCValu() && !Subtarget.
is64Bit())) {
385 if (Subtarget.hasStdExtZbb() ||
386 (Subtarget.hasVendorXCVbitmanip() && !Subtarget.
is64Bit())) {
393 if (Subtarget.hasStdExtZbb() || Subtarget.hasVendorXTHeadBb() ||
394 (Subtarget.hasVendorXCVbitmanip() && !Subtarget.
is64Bit())) {
403 if (Subtarget.hasVendorXCValu() && !Subtarget.
is64Bit()) {
405 }
else if (Subtarget.hasShortForwardBranchOpt()) {
408 }
else if (Subtarget.
is64Bit()) {
414 else if (!Subtarget.hasVendorXTHeadCondMov())
417 static const unsigned FPLegalNodeTypes[] = {
431 static const unsigned FPOpToExpand[] = {
435 static const unsigned FPRndMode[] = {
439 static const unsigned ZfhminZfbfminPromoteOps[] = {
450 if (Subtarget.hasStdExtZfbfmin()) {
473 if (Subtarget.hasStdExtZfa())
500 Subtarget.hasStdExtZfh() && Subtarget.hasStdExtZfa() ?
Legal :
Promote);
542 if (Subtarget.hasStdExtZfa()) {
560 if (Subtarget.hasStdExtZfa()) {
642 if (Subtarget.hasStdExtZicbop()) {
646 if (Subtarget.hasStdExtA()) {
648 if (Subtarget.hasStdExtZabha() && Subtarget.hasStdExtZacas())
652 }
else if (Subtarget.hasForcedAtomics()) {
676 {MVT::i8, MVT::i16},
Custom);
687 static const unsigned IntegerVPOps[] = {
688 ISD::VP_ADD, ISD::VP_SUB, ISD::VP_MUL,
689 ISD::VP_SDIV, ISD::VP_UDIV, ISD::VP_SREM,
690 ISD::VP_UREM, ISD::VP_AND, ISD::VP_OR,
691 ISD::VP_XOR, ISD::VP_SRA, ISD::VP_SRL,
692 ISD::VP_SHL, ISD::VP_REDUCE_ADD, ISD::VP_REDUCE_AND,
693 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR, ISD::VP_REDUCE_SMAX,
694 ISD::VP_REDUCE_SMIN, ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN,
695 ISD::VP_MERGE, ISD::VP_SELECT, ISD::VP_FP_TO_SINT,
696 ISD::VP_FP_TO_UINT, ISD::VP_SETCC, ISD::VP_SIGN_EXTEND,
697 ISD::VP_ZERO_EXTEND, ISD::VP_TRUNCATE, ISD::VP_SMIN,
698 ISD::VP_SMAX, ISD::VP_UMIN, ISD::VP_UMAX,
699 ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE,
700 ISD::VP_SADDSAT, ISD::VP_UADDSAT, ISD::VP_SSUBSAT,
701 ISD::VP_USUBSAT, ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_UNDEF,
702 ISD::EXPERIMENTAL_VP_SPLAT};
704 static const unsigned FloatingPointVPOps[] = {
705 ISD::VP_FADD, ISD::VP_FSUB, ISD::VP_FMUL,
706 ISD::VP_FDIV, ISD::VP_FNEG, ISD::VP_FABS,
707 ISD::VP_FMA, ISD::VP_REDUCE_FADD, ISD::VP_REDUCE_SEQ_FADD,
708 ISD::VP_REDUCE_FMIN, ISD::VP_REDUCE_FMAX, ISD::VP_MERGE,
709 ISD::VP_SELECT, ISD::VP_SINT_TO_FP, ISD::VP_UINT_TO_FP,
710 ISD::VP_SETCC, ISD::VP_FP_ROUND, ISD::VP_FP_EXTEND,
711 ISD::VP_SQRT, ISD::VP_FMINNUM, ISD::VP_FMAXNUM,
712 ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND,
713 ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO,
714 ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS,
715 ISD::VP_FMINIMUM, ISD::VP_FMAXIMUM, ISD::VP_LRINT,
716 ISD::VP_LLRINT, ISD::EXPERIMENTAL_VP_REVERSE,
717 ISD::EXPERIMENTAL_VP_SPLICE, ISD::VP_REDUCE_FMINIMUM,
718 ISD::VP_REDUCE_FMAXIMUM, ISD::EXPERIMENTAL_VP_SPLAT};
720 static const unsigned IntegerVecReduceOps[] = {
725 static const unsigned FloatingPointVecReduceOps[] = {
729 static const unsigned FloatingPointLibCallOps[] = {
742 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR,
743 ISD::VP_REDUCE_SMAX, ISD::VP_REDUCE_SMIN,
744 ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN},
748 for (
MVT VT : BoolVecVTs) {
778 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
802 ISD::VP_TRUNCATE, ISD::VP_SETCC},
818 for (
MVT VT : IntVecVTs) {
829 if (VT.getVectorElementType() == MVT::i64 && !Subtarget.hasStdExtV())
879 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
880 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
904 if (Subtarget.hasStdExtZvkb()) {
912 if (Subtarget.hasStdExtZvbb()) {
916 ISD::VP_CTTZ_ZERO_UNDEF, ISD::VP_CTPOP},
922 ISD::VP_CTTZ_ZERO_UNDEF, ISD::VP_CTPOP},
931 ISD::VP_CTLZ_ZERO_UNDEF, ISD::VP_CTTZ_ZERO_UNDEF},
939 for (
MVT VT : VecTupleVTs) {
960 static const unsigned ZvfhminZvfbfminPromoteOps[] = {
970 static const unsigned ZvfhminZvfbfminPromoteVPOps[] = {
985 ISD::VP_FROUNDTOZERO,
991 ISD::VP_REDUCE_FMINIMUM,
992 ISD::VP_REDUCE_FMAXIMUM};
995 const auto SetCommonVFPActions = [&](
MVT VT) {
1030 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1031 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1064 const auto SetCommonVFPExtLoadTruncStoreActions =
1066 for (
auto SmallVT : SmallerVTs) {
1074 const auto SetCommonPromoteToF32Actions = [&](
MVT VT) {
1099 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1100 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1123 for (
MVT VT : F16VecVTs) {
1126 SetCommonVFPActions(VT);
1129 for (
MVT VT : F16VecVTs) {
1132 SetCommonPromoteToF32Actions(VT);
1137 for (
MVT VT : BF16VecVTs) {
1140 SetCommonPromoteToF32Actions(VT);
1145 for (
MVT VT : F32VecVTs) {
1148 SetCommonVFPActions(VT);
1149 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1150 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1155 for (
MVT VT : F64VecVTs) {
1158 SetCommonVFPActions(VT);
1159 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1160 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1161 SetCommonVFPExtLoadTruncStoreActions(VT, F32VecVTs);
1167 if (!useRVVForFixedLengthVectorVT(VT))
1213 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1240 ISD::VP_SETCC, ISD::VP_TRUNCATE},
1264 ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1265 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1302 if (Subtarget.hasStdExtZvkb())
1305 if (Subtarget.hasStdExtZvbb()) {
1329 if (!useRVVForFixedLengthVectorVT(VT))
1350 ISD::VP_SCATTER, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1351 ISD::EXPERIMENTAL_VP_STRIDED_STORE},
1367 if (Subtarget.hasStdExtZfhmin()) {
1391 if (Subtarget.hasStdExtZfbfmin()) {
1451 if (Subtarget.hasStdExtZfbfmin())
1460 if (Subtarget.hasStdExtA())
1463 if (Subtarget.hasForcedAtomics()) {
1473 if (Subtarget.hasVendorXTHeadMemIdx()) {
1489 if (Subtarget.hasVendorXCVmem() && !Subtarget.
is64Bit()) {
1515 if (Subtarget.hasStdExtZbb())
1518 if ((Subtarget.hasStdExtZbs() && Subtarget.
is64Bit()) ||
1522 if (Subtarget.hasStdExtZbkb())
1535 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_REVERSE,
1542 if (Subtarget.hasVendorXTHeadMemPair())
1585MVT RISCVTargetLowering::getVPExplicitVectorLengthTy()
const {
1590bool RISCVTargetLowering::shouldExpandGetVectorLength(
EVT TripCountVT,
1592 bool IsScalable)
const {
1599 if (TripCountVT != MVT::i32 && TripCountVT != Subtarget.
getXLenVT())
1624 unsigned Intrinsic)
const {
1625 auto &
DL =
I.getDataLayout();
1627 auto SetRVVLoadStoreInfo = [&](
unsigned PtrOp,
bool IsStore,
1628 bool IsUnitStrided,
bool UsePtrVal =
false) {
1633 Info.ptrVal =
I.getArgOperand(PtrOp);
1635 Info.fallbackAddressSpace =
1636 I.getArgOperand(PtrOp)->getType()->getPointerAddressSpace();
1640 MemTy =
I.getArgOperand(0)->getType();
1643 MemTy =
I.getType();
1653 if (cast<TargetExtType>(MemTy)->
getName() ==
"riscv.vector.tuple")
1656 1 << cast<ConstantInt>(
I.getArgOperand(
I.arg_size() - 1))
1658 Info.align =
DL.getABITypeAlign(MemTy);
1668 if (
I.hasMetadata(LLVMContext::MD_nontemporal))
1672 switch (Intrinsic) {
1675 case Intrinsic::riscv_masked_atomicrmw_xchg_i32:
1676 case Intrinsic::riscv_masked_atomicrmw_add_i32:
1677 case Intrinsic::riscv_masked_atomicrmw_sub_i32:
1678 case Intrinsic::riscv_masked_atomicrmw_nand_i32:
1679 case Intrinsic::riscv_masked_atomicrmw_max_i32:
1680 case Intrinsic::riscv_masked_atomicrmw_min_i32:
1681 case Intrinsic::riscv_masked_atomicrmw_umax_i32:
1682 case Intrinsic::riscv_masked_atomicrmw_umin_i32:
1683 case Intrinsic::riscv_masked_cmpxchg_i32:
1685 Info.memVT = MVT::i32;
1686 Info.ptrVal =
I.getArgOperand(0);
1692 case Intrinsic::riscv_seg2_load:
1693 case Intrinsic::riscv_seg3_load:
1694 case Intrinsic::riscv_seg4_load:
1695 case Intrinsic::riscv_seg5_load:
1696 case Intrinsic::riscv_seg6_load:
1697 case Intrinsic::riscv_seg7_load:
1698 case Intrinsic::riscv_seg8_load:
1699 return SetRVVLoadStoreInfo( 0,
false,
1701 case Intrinsic::riscv_seg2_store:
1702 case Intrinsic::riscv_seg3_store:
1703 case Intrinsic::riscv_seg4_store:
1704 case Intrinsic::riscv_seg5_store:
1705 case Intrinsic::riscv_seg6_store:
1706 case Intrinsic::riscv_seg7_store:
1707 case Intrinsic::riscv_seg8_store:
1709 return SetRVVLoadStoreInfo(
I.arg_size() - 2,
1712 case Intrinsic::riscv_vle:
1713 case Intrinsic::riscv_vle_mask:
1714 case Intrinsic::riscv_vleff:
1715 case Intrinsic::riscv_vleff_mask:
1716 return SetRVVLoadStoreInfo( 1,
1720 case Intrinsic::riscv_vse:
1721 case Intrinsic::riscv_vse_mask:
1722 return SetRVVLoadStoreInfo( 1,
1726 case Intrinsic::riscv_vlse:
1727 case Intrinsic::riscv_vlse_mask:
1728 case Intrinsic::riscv_vloxei:
1729 case Intrinsic::riscv_vloxei_mask:
1730 case Intrinsic::riscv_vluxei:
1731 case Intrinsic::riscv_vluxei_mask:
1732 return SetRVVLoadStoreInfo( 1,
1735 case Intrinsic::riscv_vsse:
1736 case Intrinsic::riscv_vsse_mask:
1737 case Intrinsic::riscv_vsoxei:
1738 case Intrinsic::riscv_vsoxei_mask:
1739 case Intrinsic::riscv_vsuxei:
1740 case Intrinsic::riscv_vsuxei_mask:
1741 return SetRVVLoadStoreInfo( 1,
1744 case Intrinsic::riscv_vlseg2:
1745 case Intrinsic::riscv_vlseg3:
1746 case Intrinsic::riscv_vlseg4:
1747 case Intrinsic::riscv_vlseg5:
1748 case Intrinsic::riscv_vlseg6:
1749 case Intrinsic::riscv_vlseg7:
1750 case Intrinsic::riscv_vlseg8:
1751 case Intrinsic::riscv_vlseg2ff:
1752 case Intrinsic::riscv_vlseg3ff:
1753 case Intrinsic::riscv_vlseg4ff:
1754 case Intrinsic::riscv_vlseg5ff:
1755 case Intrinsic::riscv_vlseg6ff:
1756 case Intrinsic::riscv_vlseg7ff:
1757 case Intrinsic::riscv_vlseg8ff:
1758 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
1761 case Intrinsic::riscv_vlseg2_mask:
1762 case Intrinsic::riscv_vlseg3_mask:
1763 case Intrinsic::riscv_vlseg4_mask:
1764 case Intrinsic::riscv_vlseg5_mask:
1765 case Intrinsic::riscv_vlseg6_mask:
1766 case Intrinsic::riscv_vlseg7_mask:
1767 case Intrinsic::riscv_vlseg8_mask:
1768 case Intrinsic::riscv_vlseg2ff_mask:
1769 case Intrinsic::riscv_vlseg3ff_mask:
1770 case Intrinsic::riscv_vlseg4ff_mask:
1771 case Intrinsic::riscv_vlseg5ff_mask:
1772 case Intrinsic::riscv_vlseg6ff_mask:
1773 case Intrinsic::riscv_vlseg7ff_mask:
1774 case Intrinsic::riscv_vlseg8ff_mask:
1775 return SetRVVLoadStoreInfo(
I.arg_size() - 5,
1778 case Intrinsic::riscv_vlsseg2:
1779 case Intrinsic::riscv_vlsseg3:
1780 case Intrinsic::riscv_vlsseg4:
1781 case Intrinsic::riscv_vlsseg5:
1782 case Intrinsic::riscv_vlsseg6:
1783 case Intrinsic::riscv_vlsseg7:
1784 case Intrinsic::riscv_vlsseg8:
1785 case Intrinsic::riscv_vloxseg2:
1786 case Intrinsic::riscv_vloxseg3:
1787 case Intrinsic::riscv_vloxseg4:
1788 case Intrinsic::riscv_vloxseg5:
1789 case Intrinsic::riscv_vloxseg6:
1790 case Intrinsic::riscv_vloxseg7:
1791 case Intrinsic::riscv_vloxseg8:
1792 case Intrinsic::riscv_vluxseg2:
1793 case Intrinsic::riscv_vluxseg3:
1794 case Intrinsic::riscv_vluxseg4:
1795 case Intrinsic::riscv_vluxseg5:
1796 case Intrinsic::riscv_vluxseg6:
1797 case Intrinsic::riscv_vluxseg7:
1798 case Intrinsic::riscv_vluxseg8:
1799 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
1802 case Intrinsic::riscv_vlsseg2_mask:
1803 case Intrinsic::riscv_vlsseg3_mask:
1804 case Intrinsic::riscv_vlsseg4_mask:
1805 case Intrinsic::riscv_vlsseg5_mask:
1806 case Intrinsic::riscv_vlsseg6_mask:
1807 case Intrinsic::riscv_vlsseg7_mask:
1808 case Intrinsic::riscv_vlsseg8_mask:
1809 case Intrinsic::riscv_vloxseg2_mask:
1810 case Intrinsic::riscv_vloxseg3_mask:
1811 case Intrinsic::riscv_vloxseg4_mask:
1812 case Intrinsic::riscv_vloxseg5_mask:
1813 case Intrinsic::riscv_vloxseg6_mask:
1814 case Intrinsic::riscv_vloxseg7_mask:
1815 case Intrinsic::riscv_vloxseg8_mask:
1816 case Intrinsic::riscv_vluxseg2_mask:
1817 case Intrinsic::riscv_vluxseg3_mask:
1818 case Intrinsic::riscv_vluxseg4_mask:
1819 case Intrinsic::riscv_vluxseg5_mask:
1820 case Intrinsic::riscv_vluxseg6_mask:
1821 case Intrinsic::riscv_vluxseg7_mask:
1822 case Intrinsic::riscv_vluxseg8_mask:
1823 return SetRVVLoadStoreInfo(
I.arg_size() - 6,
1826 case Intrinsic::riscv_vsseg2:
1827 case Intrinsic::riscv_vsseg3:
1828 case Intrinsic::riscv_vsseg4:
1829 case Intrinsic::riscv_vsseg5:
1830 case Intrinsic::riscv_vsseg6:
1831 case Intrinsic::riscv_vsseg7:
1832 case Intrinsic::riscv_vsseg8:
1833 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
1836 case Intrinsic::riscv_vsseg2_mask:
1837 case Intrinsic::riscv_vsseg3_mask:
1838 case Intrinsic::riscv_vsseg4_mask:
1839 case Intrinsic::riscv_vsseg5_mask:
1840 case Intrinsic::riscv_vsseg6_mask:
1841 case Intrinsic::riscv_vsseg7_mask:
1842 case Intrinsic::riscv_vsseg8_mask:
1843 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
1846 case Intrinsic::riscv_vssseg2:
1847 case Intrinsic::riscv_vssseg3:
1848 case Intrinsic::riscv_vssseg4:
1849 case Intrinsic::riscv_vssseg5:
1850 case Intrinsic::riscv_vssseg6:
1851 case Intrinsic::riscv_vssseg7:
1852 case Intrinsic::riscv_vssseg8:
1853 case Intrinsic::riscv_vsoxseg2:
1854 case Intrinsic::riscv_vsoxseg3:
1855 case Intrinsic::riscv_vsoxseg4:
1856 case Intrinsic::riscv_vsoxseg5:
1857 case Intrinsic::riscv_vsoxseg6:
1858 case Intrinsic::riscv_vsoxseg7:
1859 case Intrinsic::riscv_vsoxseg8:
1860 case Intrinsic::riscv_vsuxseg2:
1861 case Intrinsic::riscv_vsuxseg3:
1862 case Intrinsic::riscv_vsuxseg4:
1863 case Intrinsic::riscv_vsuxseg5:
1864 case Intrinsic::riscv_vsuxseg6:
1865 case Intrinsic::riscv_vsuxseg7:
1866 case Intrinsic::riscv_vsuxseg8:
1867 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
1870 case Intrinsic::riscv_vssseg2_mask:
1871 case Intrinsic::riscv_vssseg3_mask:
1872 case Intrinsic::riscv_vssseg4_mask:
1873 case Intrinsic::riscv_vssseg5_mask:
1874 case Intrinsic::riscv_vssseg6_mask:
1875 case Intrinsic::riscv_vssseg7_mask:
1876 case Intrinsic::riscv_vssseg8_mask:
1877 case Intrinsic::riscv_vsoxseg2_mask:
1878 case Intrinsic::riscv_vsoxseg3_mask:
1879 case Intrinsic::riscv_vsoxseg4_mask:
1880 case Intrinsic::riscv_vsoxseg5_mask:
1881 case Intrinsic::riscv_vsoxseg6_mask:
1882 case Intrinsic::riscv_vsoxseg7_mask:
1883 case Intrinsic::riscv_vsoxseg8_mask:
1884 case Intrinsic::riscv_vsuxseg2_mask:
1885 case Intrinsic::riscv_vsuxseg3_mask:
1886 case Intrinsic::riscv_vsuxseg4_mask:
1887 case Intrinsic::riscv_vsuxseg5_mask:
1888 case Intrinsic::riscv_vsuxseg6_mask:
1889 case Intrinsic::riscv_vsuxseg7_mask:
1890 case Intrinsic::riscv_vsuxseg8_mask:
1891 return SetRVVLoadStoreInfo(
I.arg_size() - 5,
1932 return isInt<12>(Imm);
1936 return isInt<12>(Imm);
1949 return (SrcBits == 64 && DestBits == 32);
1960 return (SrcBits == 64 && DestBits == 32);
1971 if (SrcBits == DestBits * 2) {
1982 if (
auto *LD = dyn_cast<LoadSDNode>(Val)) {
1983 EVT MemVT = LD->getMemoryVT();
1984 if ((MemVT == MVT::i8 || MemVT == MVT::i16) &&
1994 return Subtarget.
is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
2002 return Subtarget.hasStdExtZbb() ||
2003 (Subtarget.hasVendorXCVbitmanip() && !Subtarget.
is64Bit());
2007 return Subtarget.hasStdExtZbb() || Subtarget.hasVendorXTHeadBb() ||
2008 (Subtarget.hasVendorXCVbitmanip() && !Subtarget.
is64Bit());
2019 if (!Subtarget.hasStdExtZbs() && !Subtarget.hasVendorXTHeadBs())
2024 return !Mask->getValue().isSignedIntN(12) && Mask->getValue().isPowerOf2();
2028 EVT VT =
Y.getValueType();
2034 return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
2035 (!isa<ConstantSDNode>(
Y) || cast<ConstantSDNode>(
Y)->isOpaque());
2040 if (Subtarget.hasStdExtZbs())
2041 return X.getValueType().isScalarInteger();
2042 auto *
C = dyn_cast<ConstantSDNode>(
Y);
2044 if (Subtarget.hasVendorXTHeadBs())
2045 return C !=
nullptr;
2047 return C &&
C->getAPIntValue().ule(10);
2067 if (BitSize > Subtarget.
getXLen())
2071 int64_t Val = Imm.getSExtValue();
2079 if (!Subtarget.enableUnalignedScalarMem())
2095 unsigned OldShiftOpcode,
unsigned NewShiftOpcode,
2102 if (XC && OldShiftOpcode ==
ISD::SRL && XC->isOne())
2106 if (NewShiftOpcode ==
ISD::SRL &&
CC->isOne())
2150 if (!Subtarget.hasStdExtZfa())
2153 bool IsSupportedVT =
false;
2154 if (VT == MVT::f16) {
2155 IsSupportedVT = Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZvfh();
2156 }
else if (VT == MVT::f32) {
2157 IsSupportedVT =
true;
2158 }
else if (VT == MVT::f64) {
2159 assert(Subtarget.hasStdExtD() &&
"Expect D extension");
2160 IsSupportedVT =
true;
2170 bool ForCodeSize)
const {
2171 bool IsLegalVT =
false;
2174 else if (VT == MVT::f32)
2176 else if (VT == MVT::f64)
2178 else if (VT == MVT::bf16)
2179 IsLegalVT = Subtarget.hasStdExtZfbfmin();
2191 return Imm.isZero();
2195 if (Imm.isNegZero())
2200 const int FmvCost = Subtarget.hasStdExtZfinx() ? 0 : 1;
2203 Subtarget.
getXLen(), Subtarget);
2209 unsigned Index)
const {
2222 if (EltVT == MVT::i1)
2235 if (Index + ResElts <= MinVLMAX && Index < 31)
2244 return (ResElts * 2) == SrcElts && (Index == 0 || Index == ResElts);
2263 std::optional<MVT> RegisterVT)
const {
2265 if (VT == (Subtarget.
is64Bit() ? MVT::i128 : MVT::i64) && RegisterVT &&
2266 *RegisterVT == MVT::Untyped)
2286 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
2288 Context,
CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
2303 isa<ConstantSDNode>(
LHS.getOperand(1))) {
2309 ShAmt =
LHS.getValueSizeInBits() - 1 -
Log2_64(Mask);
2322 if (
auto *RHSC = dyn_cast<ConstantSDNode>(
RHS)) {
2323 int64_t
C = RHSC->getSExtValue();
2361 if (VT.
SimpleTy >= MVT::riscv_nxv1i8x2 &&
2362 VT.
SimpleTy <= MVT::riscv_nxv1i8x8)
2364 if (VT.
SimpleTy >= MVT::riscv_nxv2i8x2 &&
2365 VT.
SimpleTy <= MVT::riscv_nxv2i8x8)
2367 if (VT.
SimpleTy >= MVT::riscv_nxv4i8x2 &&
2368 VT.
SimpleTy <= MVT::riscv_nxv4i8x8)
2370 if (VT.
SimpleTy >= MVT::riscv_nxv8i8x2 &&
2371 VT.
SimpleTy <= MVT::riscv_nxv8i8x8)
2373 if (VT.
SimpleTy >= MVT::riscv_nxv16i8x2 &&
2374 VT.
SimpleTy <= MVT::riscv_nxv16i8x4)
2376 if (VT.
SimpleTy == MVT::riscv_nxv32i8x2)
2386 switch (KnownSize) {
2414 return RISCV::VRRegClassID;
2416 return RISCV::VRM2RegClassID;
2418 return RISCV::VRM4RegClassID;
2420 return RISCV::VRM8RegClassID;
2430 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
2431 "Unexpected subreg numbering");
2432 return RISCV::sub_vrm1_0 + Index;
2435 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
2436 "Unexpected subreg numbering");
2437 return RISCV::sub_vrm2_0 + Index;
2440 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
2441 "Unexpected subreg numbering");
2442 return RISCV::sub_vrm4_0 + Index;
2450 unsigned RegsPerField =
2453 switch (RegsPerField) {
2456 return RISCV::VRN2M1RegClassID;
2458 return RISCV::VRN3M1RegClassID;
2460 return RISCV::VRN4M1RegClassID;
2462 return RISCV::VRN5M1RegClassID;
2464 return RISCV::VRN6M1RegClassID;
2466 return RISCV::VRN7M1RegClassID;
2468 return RISCV::VRN8M1RegClassID;
2472 return RISCV::VRN2M2RegClassID;
2474 return RISCV::VRN3M2RegClassID;
2476 return RISCV::VRN4M2RegClassID;
2480 return RISCV::VRN2M4RegClassID;
2488 return RISCV::VRRegClassID;
2497std::pair<unsigned, unsigned>
2499 MVT VecVT,
MVT SubVecVT,
unsigned InsertExtractIdx,
2501 static_assert((RISCV::VRM8RegClassID > RISCV::VRM4RegClassID &&
2502 RISCV::VRM4RegClassID > RISCV::VRM2RegClassID &&
2503 RISCV::VRM2RegClassID > RISCV::VRRegClassID),
2504 "Register classes not ordered");
2511 if (VecRegClassID == SubRegClassID)
2512 return {RISCV::NoSubRegister, 0};
2515 "Only allow scalable vector subvector.");
2517 "Invalid vector tuple insert/extract for vector and subvector with "
2528 unsigned SubRegIdx = RISCV::NoSubRegister;
2529 for (
const unsigned RCID :
2530 {RISCV::VRM4RegClassID, RISCV::VRM2RegClassID, RISCV::VRRegClassID})
2531 if (VecRegClassID > RCID && SubRegClassID <= RCID) {
2535 SubRegIdx =
TRI->composeSubRegIndices(SubRegIdx,
2540 return {SubRegIdx, InsertExtractIdx};
2545bool RISCVTargetLowering::mergeStoresAfterLegalization(
EVT VT)
const {
2576unsigned RISCVTargetLowering::combineRepeatedFPDivisors()
const {
2583 "Unexpected opcode");
2585 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
2587 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
2590 return Op.getOperand(
II->VLOperand + 1 + HasChain);
2664bool RISCVTargetLowering::useRVVForFixedLengthVectorVT(
MVT VT)
const {
2665 return ::useRVVForFixedLengthVectorVT(VT, Subtarget);
2674 "Expected legal fixed length vector!");
2677 unsigned MaxELen = Subtarget.
getELen();
2711 return ::getContainerForFixedLengthVector(*
this, VT,
getSubtarget());
2718 "Expected to convert into a scalable vector!");
2719 assert(V.getValueType().isFixedLengthVector() &&
2720 "Expected a fixed length vector operand!");
2730 "Expected to convert into a fixed length vector!");
2731 assert(V.getValueType().isScalableVector() &&
2732 "Expected a scalable vector operand!");
2755static std::pair<SDValue, SDValue>
2764static std::pair<SDValue, SDValue>
2777static std::pair<SDValue, SDValue>
2794std::pair<unsigned, unsigned>
2810 return std::make_pair(MinVLMAX, MaxVLMAX);
2822 EVT VT,
unsigned DefinedValues)
const {
2836 std::tie(LMul, Fractional) =
2839 Cost = LMul <= DLenFactor ? (DLenFactor / LMul) : 1;
2841 Cost = (LMul * DLenFactor);
2884 Op.getValueType() == MVT::bf16) {
2885 bool IsStrict =
Op->isStrictFPOpcode();
2890 {Op.getOperand(0), Op.getOperand(1)});
2892 {
Op.getValueType(), MVT::Other},
2898 DAG.
getNode(
Op.getOpcode(),
DL, MVT::f32,
Op.getOperand(0)),
2913 MVT DstVT =
Op.getSimpleValueType();
2914 EVT SatVT = cast<VTSDNode>(
Op.getOperand(1))->getVT();
2922 Src.getValueType() == MVT::bf16) {
2929 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
2937 Opc,
DL, DstVT, Src,
2951 MVT SrcVT = Src.getSimpleValueType();
2957 if (SatVT != DstEltVT)
2960 MVT DstContainerVT = DstVT;
2961 MVT SrcContainerVT = SrcVT;
2967 "Expected same element count");
2976 {Src, Src, DAG.getCondCode(ISD::SETNE),
2977 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
2981 if (DstEltSize > (2 * SrcEltSize)) {
2987 MVT CvtContainerVT = DstContainerVT;
2988 MVT CvtEltVT = DstEltVT;
2989 if (SrcEltSize > (2 * DstEltSize)) {
2998 while (CvtContainerVT != DstContainerVT) {
3004 Res = DAG.
getNode(ClipOpc,
DL, CvtContainerVT, Res, Mask, VL);
3011 Res, DAG.
getUNDEF(DstContainerVT), VL);
3021 bool IsStrict =
Op->isStrictFPOpcode();
3022 SDValue SrcVal =
Op.getOperand(IsStrict ? 1 : 0);
3032 {
Op.getOperand(0), SrcVal});
3033 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
3034 {Ext.getValue(1), Ext.getValue(0)});
3048 case ISD::VP_FROUNDEVEN:
3052 case ISD::VP_FROUNDTOZERO:
3056 case ISD::VP_FFLOOR:
3064 case ISD::VP_FROUND:
3081 MVT VT =
Op.getSimpleValueType();
3088 MVT ContainerVT = VT;
3095 if (
Op->isVPOpcode()) {
3096 Mask =
Op.getOperand(1);
3100 VL =
Op.getOperand(2);
3122 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3136 switch (
Op.getOpcode()) {
3144 case ISD::VP_FFLOOR:
3147 case ISD::VP_FROUND:
3148 case ISD::VP_FROUNDEVEN:
3149 case ISD::VP_FROUNDTOZERO: {
3161 case ISD::VP_FNEARBYINT:
3174 Src, Src, Mask, VL);
3189 MVT VT =
Op.getSimpleValueType();
3193 MVT ContainerVT = VT;
3205 MVT MaskVT = Mask.getSimpleValueType();
3208 {Chain, Src, Src, DAG.getCondCode(ISD::SETUNE),
3209 DAG.getUNDEF(MaskVT), Mask, VL});
3213 {Chain, Src, Src, Src, Unorder, VL});
3214 Chain = Src.getValue(1);
3230 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3242 switch (
Op.getOpcode()) {
3253 {Chain, Src, Mask, DAG.getTargetConstant(FRM, DL, XLenVT), VL});
3259 DAG.
getVTList(IntVT, MVT::Other), Chain, Src, Mask, VL);
3263 DAG.
getVTList(ContainerVT, MVT::Other), Chain, Src,
3272 DAG.
getVTList(ContainerVT, MVT::Other), Chain,
3273 Truncated, Mask, VL);
3279 Src, Src, Mask, VL);
3289 MVT VT =
Op.getSimpleValueType();
3317 MVT VT =
Op.getSimpleValueType();
3322 MVT ContainerVT = VT;
3367 "Unexpected vector MVT");
3395 return std::nullopt;
3413 unsigned EltSizeInBits) {
3416 return std::nullopt;
3417 bool IsInteger =
Op.getValueType().isInteger();
3419 std::optional<unsigned> SeqStepDenom;
3420 std::optional<APInt> SeqStepNum;
3421 std::optional<APInt> SeqAddend;
3422 std::optional<std::pair<APInt, unsigned>> PrevElt;
3423 assert(EltSizeInBits >=
Op.getValueType().getScalarSizeInBits());
3428 const unsigned OpSize =
Op.getScalarValueSizeInBits();
3430 if (Elt.isUndef()) {
3431 Elts[
Idx] = std::nullopt;
3435 Elts[
Idx] = Elt->getAsAPIntVal().trunc(OpSize).zext(EltSizeInBits);
3440 return std::nullopt;
3441 Elts[
Idx] = *ExactInteger;
3454 unsigned IdxDiff =
Idx - PrevElt->second;
3455 APInt ValDiff = *Elt - PrevElt->first;
3463 int64_t Remainder = ValDiff.
srem(IdxDiff);
3468 return std::nullopt;
3469 ValDiff = ValDiff.
sdiv(IdxDiff);
3474 SeqStepNum = ValDiff;
3475 else if (ValDiff != SeqStepNum)
3476 return std::nullopt;
3479 SeqStepDenom = IdxDiff;
3480 else if (IdxDiff != *SeqStepDenom)
3481 return std::nullopt;
3485 if (!PrevElt || PrevElt->first != *Elt)
3486 PrevElt = std::make_pair(*Elt,
Idx);
3490 if (!SeqStepNum || !SeqStepDenom)
3491 return std::nullopt;
3499 (
APInt(EltSizeInBits,
Idx,
false,
true) *
3501 .sdiv(*SeqStepDenom);
3503 APInt Addend = *Elt - ExpectedVal;
3506 else if (Addend != SeqAddend)
3507 return std::nullopt;
3510 assert(SeqAddend &&
"Must have an addend if we have a step");
3512 return VIDSequence{SeqStepNum->getSExtValue(), *SeqStepDenom,
3513 SeqAddend->getSExtValue()};
3528 MVT SrcVT = Src.getSimpleValueType();
3538 auto *CIdx = dyn_cast<ConstantSDNode>(
Idx);
3544 MVT ContainerVT = VT;
3548 MVT SrcContainerVT = SrcVT;
3583 MVT VT =
Op.getSimpleValueType();
3595 unsigned MostCommonCount = 0;
3597 unsigned NumUndefElts =
3605 unsigned NumScalarLoads = 0;
3611 unsigned &Count = ValueCounts[V];
3613 if (
auto *CFP = dyn_cast<ConstantFPSDNode>(V))
3614 NumScalarLoads += !CFP->isExactlyValue(+0.0);
3619 if (++Count >= MostCommonCount) {
3621 MostCommonCount = Count;
3625 assert(DominantValue &&
"Not expecting an all-undef BUILD_VECTOR");
3626 unsigned NumDefElts = NumElts - NumUndefElts;
3627 unsigned DominantValueCountThreshold = NumDefElts <= 2 ? 0 : NumDefElts - 2;
3633 ((MostCommonCount > DominantValueCountThreshold) ||
3646 !LastOp.isUndef() && ValueCounts[LastOp] == 1 &&
3647 LastOp != DominantValue) {
3656 Processed.insert(LastOp);
3661 const SDValue &V = OpIdx.value();
3662 if (V.isUndef() || !Processed.insert(V).second)
3664 if (ValueCounts[V] == 1) {
3673 return DAG.getConstant(V == V1, DL, XLenVT);
3689 MVT VT =
Op.getSimpleValueType();
3719 unsigned NumViaIntegerBits = std::clamp(NumElts, 8u, Subtarget.
getXLen());
3720 NumViaIntegerBits = std::min(NumViaIntegerBits, Subtarget.
getELen());
3728 unsigned IntegerViaVecElts =
divideCeil(NumElts, NumViaIntegerBits);
3729 MVT IntegerViaVecVT =
3734 unsigned BitPos = 0, IntegerEltIdx = 0;
3737 for (
unsigned I = 0;
I < NumElts;) {
3739 bool BitValue = !V.isUndef() && V->getAsZExtVal();
3740 Bits |= ((
uint64_t)BitValue << BitPos);
3746 if (
I % NumViaIntegerBits == 0 ||
I == NumElts) {
3747 if (NumViaIntegerBits <= 32)
3748 Bits = SignExtend64<32>(Bits);
3750 Elts[IntegerEltIdx] = Elt;
3759 if (NumElts < NumViaIntegerBits) {
3763 assert(IntegerViaVecVT == MVT::v1i8 &&
"Unexpected mask vector type");
3791 int64_t StepNumerator = SimpleVID->StepNumerator;
3792 unsigned StepDenominator = SimpleVID->StepDenominator;
3793 int64_t Addend = SimpleVID->Addend;
3795 assert(StepNumerator != 0 &&
"Invalid step");
3796 bool Negate =
false;
3797 int64_t SplatStepVal = StepNumerator;
3801 if (StepNumerator != 1 && StepNumerator !=
INT64_MIN &&
3803 Negate = StepNumerator < 0;
3805 SplatStepVal =
Log2_64(std::abs(StepNumerator));
3812 if (((StepOpcode ==
ISD::MUL && isInt<12>(SplatStepVal)) ||
3813 (StepOpcode ==
ISD::SHL && isUInt<5>(SplatStepVal))) &&
3815 (SplatStepVal >= 0 || StepDenominator == 1) && isInt<5>(Addend)) {
3818 MVT VIDContainerVT =
3826 if ((StepOpcode ==
ISD::MUL && SplatStepVal != 1) ||
3827 (StepOpcode ==
ISD::SHL && SplatStepVal != 0)) {
3829 VID = DAG.
getNode(StepOpcode,
DL, VIDVT, VID, SplatStep);
3831 if (StepDenominator != 1) {
3836 if (Addend != 0 || Negate) {
3855 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32) &&
3856 "Unexpected sequence type");
3860 unsigned ViaVecLen =
3864 uint64_t EltMask = maskTrailingOnes<uint64_t>(EltBitSize);
3867 for (
const auto &OpIdx :
enumerate(
Op->op_values())) {
3868 const auto &SeqV = OpIdx.value();
3869 if (!SeqV.isUndef())
3871 ((SeqV->getAsZExtVal() & EltMask) << (OpIdx.index() * EltBitSize));
3877 if (ViaIntVT == MVT::i32)
3878 SplatValue = SignExtend64<32>(SplatValue);
3900 const auto *BV = cast<BuildVectorSDNode>(
Op);
3903 BV->getRepeatedSequence(Sequence) &&
3904 (Sequence.size() * EltBitSize) <= Subtarget.
getELen()) {
3905 unsigned SeqLen = Sequence.size();
3907 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32 ||
3908 ViaIntVT == MVT::i64) &&
3909 "Unexpected sequence type");
3914 const unsigned RequiredVL = NumElts / SeqLen;
3915 const unsigned ViaVecLen =
3917 NumElts : RequiredVL;
3920 unsigned EltIdx = 0;
3921 uint64_t EltMask = maskTrailingOnes<uint64_t>(EltBitSize);
3925 for (
const auto &SeqV : Sequence) {
3926 if (!SeqV.isUndef())
3928 ((SeqV->getAsZExtVal() & EltMask) << (EltIdx * EltBitSize));
3935 if (ViaIntVT == MVT::i32)
3936 SplatValue = SignExtend64<32>(SplatValue);
3942 (!Subtarget.
is64Bit() && ViaIntVT == MVT::i64)) &&
3943 "Unexpected bitcast sequence");
3944 if (ViaIntVT.
bitsLE(XLenVT) || isInt<32>(SplatValue)) {
3947 MVT ViaContainerVT =
3954 if (ViaVecLen != RequiredVL)
3974 Source, DAG, Subtarget);
3994 return RISCV::PACKH;
3996 return Subtarget.
is64Bit() ? RISCV::PACKW : RISCV::PACK;
4011 MVT VT =
Op.getSimpleValueType();
4019 if (!Subtarget.hasStdExtZbb() || !Subtarget.hasStdExtZba())
4024 if (ElemSizeInBits >= std::min(Subtarget.
getELen(), Subtarget.
getXLen()) ||
4038 if (Subtarget.hasStdExtZbkb())
4043 ElemDL, XLenVT,
A,
B),
4055 NewOperands.
reserve(NumElts / 2);
4057 NewOperands.
push_back(pack(
Op.getOperand(i),
Op.getOperand(i + 1)));
4067 MVT VT =
Op.getSimpleValueType();
4078 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) || EltVT == MVT::bf16) {
4083 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4084 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin())) {
4087 if (
auto *
C = dyn_cast<ConstantFPSDNode>(Elem)) {
4171 auto OneVRegOfOps =
ArrayRef(BuildVectorOps).
slice(i, ElemsPerVReg);
4175 unsigned InsertIdx = (i / ElemsPerVReg) * NumOpElts;
4198 unsigned NumUndefElts =
4200 unsigned NumDefElts = NumElts - NumUndefElts;
4201 if (NumDefElts >= 8 && NumDefElts > NumElts / 2 &&
4208 for (
unsigned i = 0; i < NumElts; i++) {
4210 if (i < NumElts / 2) {
4217 bool SelectMaskVal = (i < NumElts / 2);
4220 assert(SubVecAOps.
size() == NumElts && SubVecBOps.
size() == NumElts &&
4221 MaskVals.
size() == NumElts);
4256 unsigned UndefCount = 0;
4263 LinearBudget -= PerSlideCost;
4266 LinearBudget -= PerSlideCost;
4269 LinearBudget -= PerSlideCost;
4272 if (LinearBudget < 0)
4277 "Illegal type which will result in reserved encoding");
4302 Vec,
Offset, Mask, VL, Policy);
4315 Vec,
Offset, Mask, VL, Policy);
4325 if (isa<ConstantSDNode>(
Lo) && isa<ConstantSDNode>(
Hi)) {
4326 int32_t LoC = cast<ConstantSDNode>(
Lo)->getSExtValue();
4327 int32_t HiC = cast<ConstantSDNode>(
Hi)->getSExtValue();
4330 if ((LoC >> 31) == HiC)
4341 (isa<RegisterSDNode>(VL) &&
4342 cast<RegisterSDNode>(VL)->
getReg() == RISCV::X0))
4344 else if (isa<ConstantSDNode>(VL) && isUInt<4>(VL->
getAsZExtVal()))
4359 isa<ConstantSDNode>(
Hi.getOperand(1)) &&
4360 Hi.getConstantOperandVal(1) == 31)
4379 assert(Scalar.getValueType() == MVT::i64 &&
"Unexpected VT!");
4391 bool HasPassthru = Passthru && !Passthru.
isUndef();
4392 if (!HasPassthru && !Passthru)
4399 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) ||
4400 EltVT == MVT::bf16) {
4401 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4402 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
4416 if (Scalar.getValueType().bitsLE(XLenVT)) {
4423 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
4427 assert(XLenVT == MVT::i32 && Scalar.getValueType() == MVT::i64 &&
4428 "Unexpected scalar for splat lowering!");
4452 SDValue ExtractedVal = Scalar.getOperand(0);
4457 MVT ExtractedContainerVT = ExtractedVT;
4460 DAG, ExtractedContainerVT, Subtarget);
4462 ExtractedVal, DAG, Subtarget);
4464 if (ExtractedContainerVT.
bitsLE(VT))
4479 if (!Scalar.getValueType().bitsLE(XLenVT))
4482 VT,
DL, DAG, Subtarget);
4490 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
4510 if (Src != V2.getOperand(0))
4515 if (Src.getValueType().getVectorNumElements() != (NumElts * 2))
4520 V2.getConstantOperandVal(1) != NumElts)
4538 int Size = Mask.size();
4540 assert(
Size == (
int)NumElts &&
"Unexpected mask size");
4546 EvenSrc = StartIndexes[0];
4547 OddSrc = StartIndexes[1];
4550 if (EvenSrc != 0 && OddSrc != 0)
4560 int HalfNumElts = NumElts / 2;
4561 return ((EvenSrc % HalfNumElts) == 0) && ((OddSrc % HalfNumElts) == 0);
4577 int Size = Mask.size();
4589 for (
int i = 0; i !=
Size; ++i) {
4595 int StartIdx = i - (M %
Size);
4603 int CandidateRotation = StartIdx < 0 ? -StartIdx :
Size - StartIdx;
4606 Rotation = CandidateRotation;
4607 else if (Rotation != CandidateRotation)
4612 int MaskSrc = M <
Size ? 0 : 1;
4617 int &TargetSrc = StartIdx < 0 ? HiSrc : LoSrc;
4622 TargetSrc = MaskSrc;
4623 else if (TargetSrc != MaskSrc)
4630 assert(Rotation != 0 &&
"Failed to locate a viable rotation!");
4631 assert((LoSrc >= 0 || HiSrc >= 0) &&
4632 "Failed to find a rotated input vector!");
4646 ElementCount SrcEC = Src.getValueType().getVectorElementCount();
4653 unsigned Shift = Index * EltBits;
4680 auto findNonEXTRACT_SUBVECTORParent =
4681 [](
SDValue Parent) -> std::pair<SDValue, uint64_t> {
4686 Parent.getOperand(0).getSimpleValueType().isFixedLengthVector()) {
4687 Offset += Parent.getConstantOperandVal(1);
4688 Parent = Parent.getOperand(0);
4690 return std::make_pair(Parent,
Offset);
4693 auto [V1Src, V1IndexOffset] = findNonEXTRACT_SUBVECTORParent(V1);
4694 auto [V2Src, V2IndexOffset] = findNonEXTRACT_SUBVECTORParent(V2);
4703 for (
size_t i = 0; i != NewMask.
size(); ++i) {
4704 if (NewMask[i] == -1)
4707 if (
static_cast<size_t>(NewMask[i]) < NewMask.
size()) {
4708 NewMask[i] = NewMask[i] + V1IndexOffset;
4712 NewMask[i] = NewMask[i] - NewMask.
size() + V2IndexOffset;
4718 if (NewMask[0] <= 0)
4722 for (
unsigned i = 1; i != NewMask.
size(); ++i)
4723 if (NewMask[i - 1] + 1 != NewMask[i])
4727 MVT SrcVT = Src.getSimpleValueType();
4758 int NumSubElts, Index;
4763 bool OpsSwapped = Mask[Index] < (int)NumElts;
4764 SDValue InPlace = OpsSwapped ? V2 : V1;
4765 SDValue ToInsert = OpsSwapped ? V1 : V2;
4775 if (NumSubElts + Index >= (
int)NumElts)
4789 Res =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, InPlace, ToInsert,
4801 bool OpsSwapped =
false;
4802 if (!isa<BuildVectorSDNode>(V1)) {
4803 if (!isa<BuildVectorSDNode>(V2))
4808 SDValue Splat = cast<BuildVectorSDNode>(V1)->getSplatValue();
4816 const unsigned E = Mask.size() - ((
Offset > 0) ?
Offset : 0);
4817 for (
unsigned i = S; i != E; ++i)
4818 if (Mask[i] >= 0 && (
unsigned)Mask[i] !=
Base + i +
Offset)
4824 bool IsVSlidedown = isSlideMask(Mask, OpsSwapped ? 0 : NumElts, 1);
4825 if (!IsVSlidedown && !isSlideMask(Mask, OpsSwapped ? 0 : NumElts, -1))
4828 const int InsertIdx = Mask[IsVSlidedown ? (NumElts - 1) : 0];
4830 if (InsertIdx < 0 || InsertIdx / NumElts != (
unsigned)OpsSwapped)
4853 auto OpCode = IsVSlidedown ?
4858 auto Vec = DAG.
getNode(OpCode,
DL, ContainerVT,
4861 Splat, TrueMask, VL);
4872 for (
unsigned i = 0; i < Mask.size(); i++)
4873 LaneIsUndef[i % Factor] &= (Mask[i] == -1);
4876 for (
unsigned i = 0; i < Factor; i++) {
4887 for (
unsigned i = 0; i < Mask.size() / Factor; i++) {
4888 unsigned j = i * Factor + Index;
4889 if (Mask[j] != -1 && (
unsigned)Mask[j] != i)
4902 MVT VT = V.getSimpleValueType();
4917 EC.multiplyCoefficientBy(Factor));
4936 MVT VecContainerVT = VecVT;
4953 MVT WideContainerVT = WideVT;
4959 EvenV = DAG.
getBitcast(VecContainerVT, EvenV);
4966 if (Subtarget.hasStdExtZvbb()) {
4971 OffsetVec, Passthru, Mask, VL);
4973 Interleaved, EvenV, Passthru, Mask, VL);
4981 OddV, Passthru, Mask, VL);
4987 OddV, AllOnesVec, Passthru, Mask, VL);
4995 Interleaved, OddsMul, Passthru, Mask, VL);
5002 Interleaved = DAG.
getBitcast(ResultContainerVT, Interleaved);
5048 if (ViaEltSize > NumElts)
5057 if (ViaEltSize > NumElts)
5063 if (ViaEltSize > NumElts)
5072 MVT &RotateVT,
unsigned &RotateAmt) {
5078 unsigned NumSubElts;
5080 NumElts, NumSubElts, RotateAmt))
5083 NumElts / NumSubElts);
5151 unsigned NumOfSrcRegs = NumElts / NumOpElts;
5152 unsigned NumOfDestRegs = NumElts / NumOpElts;
5161 Mask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs,
5162 [&]() {
Operands.emplace_back(); },
5163 [&](
ArrayRef<int> SrcSubMask,
unsigned SrcVecIdx,
unsigned DstVecIdx) {
5164 Operands.emplace_back().emplace_back(
5165 SrcVecIdx, UINT_MAX,
5168 [&](
ArrayRef<int> SrcSubMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
5174 assert(
Operands.size() == NumOfDestRegs &&
"Whole vector must be processed");
5179 unsigned NumShuffles = std::accumulate(
5186 for (const auto &P : Data) {
5187 unsigned Idx2 = std::get<1>(P);
5188 ArrayRef<int> Mask = std::get<2>(P);
5189 if (Idx2 != UINT_MAX)
5191 else if (ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
5196 if ((NumOfDestRegs > 2 && NumShuffles > NumOfDestRegs) ||
5197 (NumOfDestRegs <= 2 && NumShuffles >= 4))
5199 auto ExtractValue = [&, &DAG = DAG](
SDValue SrcVec,
unsigned ExtractIdx) {
5201 DAG.getVectorIdxConstant(ExtractIdx,
DL));
5205 auto PerformShuffle = [&, &DAG = DAG](
SDValue SubVec1,
SDValue SubVec2,
5207 SDValue SubVec = DAG.getVectorShuffle(OneRegVT,
DL, SubVec1, SubVec2, Mask);
5210 SDValue Vec = DAG.getUNDEF(ContainerVT);
5215 for (
unsigned I : seq<unsigned>(
Data.size())) {
5216 const auto &[Idx1, Idx2,
_] =
Data[
I];
5219 "Expected both indices to be extracted already.");
5222 SDValue V = ExtractValue(Idx1 >= NumOfSrcRegs ? V2 : V1,
5223 (Idx1 % NumOfSrcRegs) * NumOpElts);
5225 if (Idx2 != UINT_MAX)
5226 Values[Idx2] = ExtractValue(Idx2 >= NumOfSrcRegs ? V2 : V1,
5227 (Idx2 % NumOfSrcRegs) * NumOpElts);
5230 for (
const auto &[Idx1, Idx2, Mask] :
Data) {
5232 SDValue V2 = Idx2 == UINT_MAX ? V1 : Values.
at(Idx2);
5233 V = PerformShuffle(V1, V2, Mask);
5237 unsigned InsertIdx =
I * NumOpElts;
5240 DAG.getVectorIdxConstant(InsertIdx,
DL));
5250 bool SawUndef =
false;
5251 for (
unsigned i = 0; i < Mask.size(); i++) {
5252 if (Mask[i] == -1) {
5258 if (i > (
unsigned)Mask[i])
5260 if (Mask[i] <=
Last)
5291 for (
int Idx : Mask) {
5294 unsigned SrcIdx =
Idx % Mask.size();
5296 if (Srcs[SrcIdx] == -1)
5299 else if (Srcs[SrcIdx] != Src)
5305 for (
int Lane : Srcs) {
5318 for (
unsigned I = 0;
I < Mask.size();
I++) {
5322 NewMask[
I] = Mask[
I] % Mask.size();
5336 MVT VT =
Op.getSimpleValueType();
5344 if (ElementSize > 32)
5367 MVT VT =
Op.getSimpleValueType();
5382 V2 = V2.isUndef() ? DAG.
getUNDEF(WidenVT)
5406 V.getOperand(0).getSimpleValueType().getVectorNumElements();
5407 V = V.getOperand(
Offset / OpElements);
5413 auto *Ld = cast<LoadSDNode>(V);
5423 SDValue Ops[] = {Ld->getChain(),
5437 MVT SplatVT = ContainerVT;
5440 if (SVT == MVT::bf16 ||
5441 (SVT == MVT::f16 && !Subtarget.hasStdExtZfh())) {
5450 V = DAG.
getLoad(SVT,
DL, Ld->getChain(), NewAddr,
5451 Ld->getPointerInfo().getWithOffset(
Offset),
5452 Ld->getOriginalAlign(),
5456 Ld->getPointerInfo().getWithOffset(
Offset), SVT,
5457 Ld->getOriginalAlign(),
5458 Ld->getMemOperand()->getFlags());
5470 assert(Lane < (
int)NumElts &&
"Unexpected lane!");
5473 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
5495 if (Subtarget.hasStdExtZvkb())
5506 LoV = LoSrc == 0 ? V1 : V2;
5510 HiV = HiSrc == 0 ? V1 : V2;
5516 unsigned InvRotate = NumElts - Rotation;
5526 Res =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, Res, LoV,
5544 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
5545 for (
unsigned Factor = 2; Factor <= MaxFactor; Factor <<= 1) {
5561 int EvenSrc, OddSrc;
5569 bool LaneIsUndef[2] = {
true,
true};
5570 for (
unsigned i = 0; i < Mask.size(); i++)
5571 LaneIsUndef[i % 2] &= (Mask[i] == -1);
5573 int Size = Mask.size();
5575 if (LaneIsUndef[0]) {
5578 assert(EvenSrc >= 0 &&
"Undef source?");
5579 EvenV = (EvenSrc /
Size) == 0 ? V1 : V2;
5584 if (LaneIsUndef[1]) {
5587 assert(OddSrc >= 0 &&
"Undef source?");
5588 OddV = (OddSrc /
Size) == 0 ? V1 : V2;
5598 assert(!V1.
isUndef() &&
"Unexpected shuffle canonicalization");
5618 for (
auto Idx : Mask) {
5634 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
5635 for (
unsigned Factor = 4; Factor <= MaxFactor; Factor <<= 1) {
5648 any_of(Mask, [&](
const auto &
Idx) {
return Idx > 255; })) {
5677 MVT IndexContainerVT =
5682 for (
int MaskIndex : Mask) {
5683 bool IsLHSIndex = MaskIndex < (int)NumElts && MaskIndex >= 0;
5692 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
5702 for (
int MaskIndex : Mask) {
5703 bool IsLHSOrUndefIndex = MaskIndex < (int)NumElts;
5704 ShuffleMaskLHS.
push_back(IsLHSOrUndefIndex && MaskIndex >= 0
5706 ShuffleMaskRHS.
push_back(IsLHSOrUndefIndex ? -1 : (MaskIndex - NumElts));
5737 for (
int MaskIndex : Mask) {
5738 bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ !SwapOps;
5742 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
5774RISCVTargetLowering::lowerCTLZ_CTTZ_ZERO_UNDEF(
SDValue Op,
5776 MVT VT =
Op.getSimpleValueType();
5780 MVT ContainerVT = VT;
5783 if (
Op->isVPOpcode()) {
5784 Mask =
Op.getOperand(1);
5788 VL =
Op.getOperand(2);
5794 MVT FloatEltVT = (EltSize >= 32) ? MVT::f64 : MVT::f32;
5796 FloatEltVT = MVT::f32;
5803 "Expected legal float type!");
5810 }
else if (
Op.getOpcode() == ISD::VP_CTTZ_ZERO_UNDEF) {
5813 Src = DAG.
getNode(ISD::VP_AND,
DL, VT, Src, Neg, Mask, VL);
5818 if (FloatVT.
bitsGT(VT)) {
5819 if (
Op->isVPOpcode())
5820 FloatVal = DAG.
getNode(ISD::VP_UINT_TO_FP,
DL, FloatVT, Src, Mask, VL);
5829 if (!
Op->isVPOpcode())
5833 MVT ContainerFloatVT =
5836 Src, Mask, RTZRM, VL);
5843 unsigned ShiftAmt = FloatEltVT == MVT::f64 ? 52 : 23;
5847 if (
Op->isVPOpcode()) {
5856 else if (IntVT.
bitsGT(VT))
5861 unsigned ExponentBias = FloatEltVT == MVT::f64 ? 1023 : 127;
5866 if (
Op.getOpcode() == ISD::VP_CTTZ_ZERO_UNDEF)
5867 return DAG.
getNode(ISD::VP_SUB,
DL, VT, Exp,
5872 unsigned Adjust = ExponentBias + (EltSize - 1);
5874 if (
Op->isVPOpcode())
5884 else if (
Op.getOpcode() == ISD::VP_CTLZ)
5885 Res = DAG.
getNode(ISD::VP_UMIN,
DL, VT, Res,
5895 MVT SrcVT =
Source.getSimpleValueType();
5904 SrcVT = ContainerVT;
5917 if (
Op->getOpcode() == ISD::VP_CTTZ_ELTS_ZERO_UNDEF)
5934 auto *
Load = cast<LoadSDNode>(
Op);
5935 assert(Load &&
Load->getMemoryVT().isVector() &&
"Expected vector load");
5938 Load->getMemoryVT(),
5939 *
Load->getMemOperand()))
5943 MVT VT =
Op.getSimpleValueType();
5945 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
5946 "Unexpected unaligned RVV load type");
5950 "Expecting equally-sized RVV vector types to be legal");
5952 Load->getPointerInfo(),
Load->getOriginalAlign(),
5953 Load->getMemOperand()->getFlags());
5963 auto *
Store = cast<StoreSDNode>(
Op);
5964 assert(Store &&
Store->getValue().getValueType().isVector() &&
5965 "Expected vector store");
5968 Store->getMemoryVT(),
5969 *
Store->getMemOperand()))
5976 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
5977 "Unexpected unaligned RVV store type");
5981 "Expecting equally-sized RVV vector types to be legal");
5982 StoredVal = DAG.
getBitcast(NewVT, StoredVal);
5984 Store->getPointerInfo(),
Store->getOriginalAlign(),
5985 Store->getMemOperand()->getFlags());
5990 assert(
Op.getValueType() == MVT::i64 &&
"Unexpected VT");
5992 int64_t Imm = cast<ConstantSDNode>(
Op)->getSExtValue();
6019 unsigned ShiftAmt, AddOpc;
6030 MVT VT =
Op.getSimpleValueType();
6031 const APFloat &
Imm = cast<ConstantFPSDNode>(
Op)->getValueAPF();
6034 bool Negate =
false;
6038 if (Index < 0 &&
Imm.isNegative()) {
6066 if (Subtarget.hasStdExtZtso()) {
6090 MVT VT =
Op.getSimpleValueType();
6092 unsigned Check =
Op.getConstantOperandVal(1);
6093 unsigned TDCMask = 0;
6121 MVT VT0 =
Op.getOperand(0).getSimpleValueType();
6126 if (
Op.getOpcode() == ISD::VP_IS_FPCLASS) {
6128 VL =
Op.getOperand(3);
6131 VL,
Op->getFlags());
6146 if (
Op.getOpcode() == ISD::VP_IS_FPCLASS) {
6148 MVT MaskContainerVT =
6151 VL =
Op.getOperand(3);
6156 Mask, VL,
Op->getFlags());
6159 DAG.
getUNDEF(ContainerDstVT), TDCMaskV, VL);
6164 DAG.
getUNDEF(ContainerVT), Mask, VL});
6168 TDCMaskV, DAG.
getUNDEF(ContainerDstVT), Mask, VL);
6172 DAG.
getUNDEF(ContainerDstVT), SplatZero, VL);
6176 DAG.
getUNDEF(ContainerVT), Mask, VL});
6192 MVT VT =
Op.getSimpleValueType();
6219 return DAG.
getNode(Opc,
DL, VT, NewX, NewY);
6226 MVT ContainerVT = VT;
6234 if (
Op->isVPOpcode()) {
6235 Mask =
Op.getOperand(2);
6239 VL =
Op.getOperand(3);
6247 {X, X, DAG.getCondCode(ISD::SETOEQ),
6248 DAG.getUNDEF(ContainerVT), Mask, VL});
6256 {Y, Y, DAG.getCondCode(ISD::SETOEQ),
6257 DAG.getUNDEF(ContainerVT), Mask, VL});
6267 DAG.
getUNDEF(ContainerVT), Mask, VL);
6277 "Wrong opcode for lowering FABS or FNEG.");
6280 MVT VT =
Op.getSimpleValueType();
6281 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
6288 Mask = Mask.sext(Subtarget.
getXLen());
6301 MVT VT =
Op.getSimpleValueType();
6302 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
6312 if (SignSize == Subtarget.
getXLen()) {
6314 }
else if (SignSize == 16) {
6316 }
else if (SignSize == 32) {
6318 }
else if (SignSize == 64) {
6319 assert(XLenVT == MVT::i32 &&
"Unexpected type");
6329 if (ShiftAmount > 0) {
6332 }
else if (ShiftAmount < 0) {
6358#define OP_CASE(NODE) \
6360 return RISCVISD::NODE##_VL;
6361#define VP_CASE(NODE) \
6362 case ISD::VP_##NODE: \
6363 return RISCVISD::NODE##_VL;
6365 switch (
Op.getOpcode()) {
6443 case ISD::VP_CTLZ_ZERO_UNDEF:
6446 case ISD::VP_CTTZ_ZERO_UNDEF:
6455 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
6460 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
6465 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
6468 case ISD::VP_SELECT:
6477 case ISD::VP_SIGN_EXTEND:
6479 case ISD::VP_ZERO_EXTEND:
6481 case ISD::VP_FP_TO_SINT:
6483 case ISD::VP_FP_TO_UINT:
6486 case ISD::VP_FMINNUM:
6489 case ISD::VP_FMAXNUM:
6494 case ISD::VP_LLRINT:
6506 "not a RISC-V target specific op");
6510 "adding target specific op should update this function");
6530 "not a RISC-V target specific op");
6534 "adding target specific op should update this function");
6547 if (
Op.getValueType() == MVT::nxv32f16 &&
6551 if (
Op.getValueType() == MVT::nxv32bf16)
6564 if (!
Op.getOperand(j).getValueType().isVector()) {
6565 LoOperands[j] =
Op.getOperand(j);
6566 HiOperands[j] =
Op.getOperand(j);
6569 std::tie(LoOperands[j], HiOperands[j]) =
6574 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
6576 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
6591 std::tie(LoOperands[j], HiOperands[j]) =
6595 if (!
Op.getOperand(j).getValueType().isVector()) {
6596 LoOperands[j] =
Op.getOperand(j);
6597 HiOperands[j] =
Op.getOperand(j);
6600 std::tie(LoOperands[j], HiOperands[j]) =
6605 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
6607 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
6617 auto [EVLLo, EVLHi] =
6618 DAG.
SplitEVL(
Op.getOperand(3),
Op.getOperand(1).getValueType(),
DL);
6622 {Op.getOperand(0), Lo, MaskLo, EVLLo},
Op->getFlags());
6624 {ResLo, Hi, MaskHi, EVLHi},
Op->getFlags());
6642 if (!
Op.getOperand(j).getValueType().isVector()) {
6643 LoOperands[j] =
Op.getOperand(j);
6644 HiOperands[j] =
Op.getOperand(j);
6647 std::tie(LoOperands[j], HiOperands[j]) =
6652 DAG.
getNode(
Op.getOpcode(),
DL, LoVTs, LoOperands,
Op->getFlags());
6655 DAG.
getNode(
Op.getOpcode(),
DL, HiVTs, HiOperands,
Op->getFlags());
6664 switch (
Op.getOpcode()) {
6670 return lowerGlobalAddress(
Op, DAG);
6672 return lowerBlockAddress(
Op, DAG);
6674 return lowerConstantPool(
Op, DAG);
6676 return lowerJumpTable(
Op, DAG);
6678 return lowerGlobalTLSAddress(
Op, DAG);
6682 return lowerConstantFP(
Op, DAG);
6684 return lowerSELECT(
Op, DAG);
6686 return lowerBRCOND(
Op, DAG);
6688 return lowerVASTART(
Op, DAG);
6690 return lowerFRAMEADDR(
Op, DAG);
6692 return lowerRETURNADDR(
Op, DAG);
6694 return lowerShiftLeftParts(
Op, DAG);
6696 return lowerShiftRightParts(
Op, DAG,
true);
6698 return lowerShiftRightParts(
Op, DAG,
false);
6701 if (
Op.getValueType().isFixedLengthVector()) {
6702 assert(Subtarget.hasStdExtZvkb());
6703 return lowerToScalableOp(
Op, DAG);
6705 assert(Subtarget.hasVendorXTHeadBb() &&
6706 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
6707 "Unexpected custom legalization");
6709 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6714 EVT VT =
Op.getValueType();
6718 if (Op0VT == MVT::i16 &&
6720 (VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
6724 if (VT == MVT::f32 && Op0VT == MVT::i32 && Subtarget.
is64Bit() &&
6729 if (VT == MVT::f64 && Op0VT == MVT::i64 && !Subtarget.
is64Bit() &&
6745 "Unexpected types");
6779 return LowerINTRINSIC_WO_CHAIN(
Op, DAG);
6781 return LowerINTRINSIC_W_CHAIN(
Op, DAG);
6783 return LowerINTRINSIC_VOID(
Op, DAG);
6785 return LowerIS_FPCLASS(
Op, DAG);
6787 MVT VT =
Op.getSimpleValueType();
6789 assert(Subtarget.hasStdExtZvbb());
6790 return lowerToScalableOp(
Op, DAG);
6793 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected custom legalization");
6803 if (!
Op.getSimpleValueType().isVector())
6805 return lowerVectorTruncLike(
Op, DAG);
6808 if (
Op.getOperand(0).getValueType().isVector() &&
6809 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
6810 return lowerVectorMaskExt(
Op, DAG, 1);
6813 if (
Op.getOperand(0).getValueType().isVector() &&
6814 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
6815 return lowerVectorMaskExt(
Op, DAG, -1);
6818 return lowerSPLAT_VECTOR_PARTS(
Op, DAG);
6820 return lowerINSERT_VECTOR_ELT(
Op, DAG);
6822 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
6824 MVT VT =
Op.getSimpleValueType();
6832 MVT ContainerVT = VT;
6840 DAG.
getUNDEF(ContainerVT), Scalar, VL);
6844 DAG.
getUNDEF(ContainerVT), Scalar, VL);
6852 MVT VT =
Op.getSimpleValueType();
6872 }
else if ((Val % 8) == 0) {
6888 if (
Op.getValueType() == MVT::f16 && Subtarget.
is64Bit() &&
6889 Op.getOperand(1).getValueType() == MVT::i32) {
6906 return lowerVectorFPExtendOrRoundLike(
Op, DAG);
6909 return lowerStrictFPExtendOrRoundLike(
Op, DAG);
6912 if (
Op.getValueType().isVector() &&
6913 ((
Op.getValueType().getScalarType() == MVT::f16 &&
6916 Op.getValueType().getScalarType() == MVT::bf16)) {
6932 Op1.getValueType().isVector() &&
6933 ((Op1.getValueType().getScalarType() == MVT::f16 &&
6936 Op1.getValueType().getScalarType() == MVT::bf16)) {
6942 Op1.getValueType().getVectorElementCount());
6945 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), WidenVec);
6955 MVT VT =
Op.getSimpleValueType();
6958 bool IsStrict =
Op->isStrictFPOpcode();
6959 SDValue Src =
Op.getOperand(0 + IsStrict);
6960 MVT SrcVT = Src.getSimpleValueType();
6971 "Unexpected vector element types");
6975 if (EltSize > (2 * SrcEltSize)) {
6987 Op.getOperand(0), Ext);
6991 assert(SrcEltVT == MVT::f16 &&
"Unexpected FP_TO_[US]INT lowering");
6996 auto [FExt, Chain] =
6998 return DAG.
getNode(
Op.getOpcode(),
DL,
Op->getVTList(), Chain, FExt);
7005 if (SrcEltSize > (2 * EltSize)) {
7008 assert(EltVT == MVT::f16 &&
"Unexpected [US]_TO_FP lowering");
7013 Op.getOperand(0), Src);
7028 Op.getOperand(0), Src);
7042 unsigned RVVOpc = 0;
7043 switch (
Op.getOpcode()) {
7075 "Expected same element count");
7082 Op.getOperand(0), Src, Mask, VL);
7086 Src = DAG.
getNode(RVVOpc,
DL, ContainerVT, Src, Mask, VL);
7101 makeLibCall(DAG, LC, MVT::f32,
Op.getOperand(0), CallOptions,
DL).first;
7108 MVT VT =
Op.getSimpleValueType();
7128 bool IsStrict =
Op->isStrictFPOpcode();
7129 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
7133 std::tie(Res, Chain) =
7134 makeLibCall(DAG, LC, MVT::f32, Op0, CallOptions,
DL, Chain);
7149 bool IsStrict =
Op->isStrictFPOpcode();
7150 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
7156 std::tie(Res, Chain) =
makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MVT::f32, Arg,
7157 CallOptions,
DL, Chain);
7174 if (
Op.getValueType().isVector())
7179 assert(
Op.getOperand(0).getValueType() == MVT::f16 &&
7180 "Unexpected custom legalisation");
7183 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), Ext);
7189 assert(
Op.getOperand(1).getValueType() == MVT::f16 &&
7190 "Unexpected custom legalisation");
7193 {
Op.getOperand(0),
Op.getOperand(1)});
7194 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
7195 {Ext.getValue(1), Ext.getValue(0)});
7202 return lowerVECREDUCE(
Op, DAG);
7206 if (
Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
7207 return lowerVectorMaskVecReduction(
Op, DAG,
false);
7208 return lowerVECREDUCE(
Op, DAG);
7215 return lowerFPVECREDUCE(
Op, DAG);
7216 case ISD::VP_REDUCE_ADD:
7217 case ISD::VP_REDUCE_UMAX:
7218 case ISD::VP_REDUCE_SMAX:
7219 case ISD::VP_REDUCE_UMIN:
7220 case ISD::VP_REDUCE_SMIN:
7221 case ISD::VP_REDUCE_FADD:
7222 case ISD::VP_REDUCE_SEQ_FADD:
7223 case ISD::VP_REDUCE_FMIN:
7224 case ISD::VP_REDUCE_FMAX:
7225 case ISD::VP_REDUCE_FMINIMUM:
7226 case ISD::VP_REDUCE_FMAXIMUM:
7229 return lowerVPREDUCE(
Op, DAG);
7230 case ISD::VP_REDUCE_AND:
7231 case ISD::VP_REDUCE_OR:
7232 case ISD::VP_REDUCE_XOR:
7233 if (
Op.getOperand(1).getValueType().getVectorElementType() == MVT::i1)
7234 return lowerVectorMaskVecReduction(
Op, DAG,
true);
7235 return lowerVPREDUCE(
Op, DAG);
7236 case ISD::VP_CTTZ_ELTS:
7237 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7238 return lowerVPCttzElements(
Op, DAG);
7242 DAG.
getUNDEF(ContainerVT), DAG, Subtarget);
7245 return lowerINSERT_SUBVECTOR(
Op, DAG);
7247 return lowerEXTRACT_SUBVECTOR(
Op, DAG);
7249 return lowerVECTOR_DEINTERLEAVE(
Op, DAG);
7251 return lowerVECTOR_INTERLEAVE(
Op, DAG);
7253 return lowerSTEP_VECTOR(
Op, DAG);
7255 return lowerVECTOR_REVERSE(
Op, DAG);
7257 return lowerVECTOR_SPLICE(
Op, DAG);
7261 MVT VT =
Op.getSimpleValueType();
7263 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) ||
7264 EltVT == MVT::bf16) {
7267 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
7268 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
7278 if (EltVT == MVT::i1)
7279 return lowerVectorMaskSplat(
Op, DAG);
7288 MVT VT =
Op.getSimpleValueType();
7289 MVT ContainerVT = VT;
7307 Op->ops().take_front(HalfNumOps));
7309 Op->ops().drop_front(HalfNumOps));
7313 unsigned NumOpElts =
7314 Op.getOperand(0).getSimpleValueType().getVectorMinNumElements();
7317 SDValue SubVec = OpIdx.value();
7328 auto *Load = cast<LoadSDNode>(
Op);
7329 EVT VecTy = Load->getMemoryVT();
7336 unsigned NumElts = Sz / (NF * 8);
7337 int Log2LMUL =
Log2_64(NumElts) - 3;
7340 Flag.setNoUnsignedWrap(
true);
7342 SDValue BasePtr = Load->getBasePtr();
7350 for (
unsigned i = 0; i < NF; ++i) {
7363 if (
auto V = expandUnalignedRVVLoad(
Op, DAG))
7365 if (
Op.getValueType().isFixedLengthVector())
7366 return lowerFixedLengthVectorLoadToRVV(
Op, DAG);
7370 auto *Store = cast<StoreSDNode>(
Op);
7371 SDValue StoredVal = Store->getValue();
7379 unsigned NumElts = Sz / (NF * 8);
7380 int Log2LMUL =
Log2_64(NumElts) - 3;
7383 Flag.setNoUnsignedWrap(
true);
7385 SDValue Chain = Store->getChain();
7386 SDValue BasePtr = Store->getBasePtr();
7393 for (
unsigned i = 0; i < NF; ++i) {
7397 Ret = DAG.
getStore(Chain,
DL, Extract, BasePtr,
7399 Store->getOriginalAlign(),
7400 Store->getMemOperand()->getFlags());
7401 Chain = Ret.getValue(0);
7407 if (
auto V = expandUnalignedRVVStore(
Op, DAG))
7409 if (
Op.getOperand(1).getValueType().isFixedLengthVector())
7410 return lowerFixedLengthVectorStoreToRVV(
Op, DAG);
7415 return lowerMaskedLoad(
Op, DAG);
7418 return lowerMaskedStore(
Op, DAG);
7420 return lowerVectorCompress(
Op, DAG);
7429 EVT VT =
Op.getValueType();
7440 MVT OpVT =
Op.getOperand(0).getSimpleValueType();
7442 MVT VT =
Op.getSimpleValueType();
7447 "Unexpected CondCode");
7455 if (isa<ConstantSDNode>(
RHS)) {
7456 int64_t Imm = cast<ConstantSDNode>(
RHS)->getSExtValue();
7457 if (Imm != 0 && isInt<12>((
uint64_t)Imm + 1)) {
7479 return lowerFixedLengthVectorSetccToRVV(
Op, DAG);
7495 return lowerToScalableOp(
Op, DAG);
7499 if (
Op.getSimpleValueType().isFixedLengthVector())
7500 return lowerToScalableOp(
Op, DAG);
7502 assert(
Op.getOperand(1).getValueType() == MVT::i32 && Subtarget.
is64Bit() &&
7503 "Unexpected custom legalisation");
7507 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
7533 return lowerToScalableOp(
Op, DAG);
7537 EVT VT =
Op->getValueType(0);
7552 return lowerABS(
Op, DAG);
7557 if (Subtarget.hasStdExtZvbb())
7558 return lowerToScalableOp(
Op, DAG);
7560 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
7562 return lowerFixedLengthVectorSelectToRVV(
Op, DAG);
7564 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
7568 return lowerFixedLengthVectorFCOPYSIGNToRVV(
Op, DAG);
7577 return lowerToScalableOp(
Op, DAG);
7580 return lowerVectorStrictFSetcc(
Op, DAG);
7590 case ISD::VP_GATHER:
7591 return lowerMaskedGather(
Op, DAG);
7593 case ISD::VP_SCATTER:
7594 return lowerMaskedScatter(
Op, DAG);
7596 return lowerGET_ROUNDING(
Op, DAG);
7598 return lowerSET_ROUNDING(
Op, DAG);
7600 return lowerEH_DWARF_CFA(
Op, DAG);
7602 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7603 return lowerVPMergeMask(
Op, DAG);
7605 case ISD::VP_SELECT:
7613 case ISD::VP_UADDSAT:
7614 case ISD::VP_USUBSAT:
7615 case ISD::VP_SADDSAT:
7616 case ISD::VP_SSUBSAT:
7618 case ISD::VP_LLRINT:
7619 return lowerVPOp(
Op, DAG);
7623 return lowerLogicVPOp(
Op, DAG);
7632 case ISD::VP_FMINNUM:
7633 case ISD::VP_FMAXNUM:
7634 case ISD::VP_FCOPYSIGN:
7641 return lowerVPOp(
Op, DAG);
7642 case ISD::VP_IS_FPCLASS:
7643 return LowerIS_FPCLASS(
Op, DAG);
7644 case ISD::VP_SIGN_EXTEND:
7645 case ISD::VP_ZERO_EXTEND:
7646 if (
Op.getOperand(0).getSimpleValueType().getVectorElementType() == MVT::i1)
7647 return lowerVPExtMaskOp(
Op, DAG);
7648 return lowerVPOp(
Op, DAG);
7649 case ISD::VP_TRUNCATE:
7650 return lowerVectorTruncLike(
Op, DAG);
7651 case ISD::VP_FP_EXTEND:
7652 case ISD::VP_FP_ROUND:
7653 return lowerVectorFPExtendOrRoundLike(
Op, DAG);
7654 case ISD::VP_SINT_TO_FP:
7655 case ISD::VP_UINT_TO_FP:
7656 if (
Op.getValueType().isVector() &&
7657 ((
Op.getValueType().getScalarType() == MVT::f16 &&
7660 Op.getValueType().getScalarType() == MVT::bf16)) {
7673 case ISD::VP_FP_TO_SINT:
7674 case ISD::VP_FP_TO_UINT:
7676 Op1.getValueType().isVector() &&
7677 ((Op1.getValueType().getScalarType() == MVT::f16 &&
7680 Op1.getValueType().getScalarType() == MVT::bf16)) {
7686 Op1.getValueType().getVectorElementCount());
7690 {WidenVec, Op.getOperand(1), Op.getOperand(2)});
7692 return lowerVPFPIntConvOp(
Op, DAG);
7696 if (
Op.getOperand(0).getSimpleValueType().getVectorElementType() == MVT::i1)
7697 return lowerVPSetCCMaskOp(
Op, DAG);
7703 case ISD::VP_BITREVERSE:
7705 return lowerVPOp(
Op, DAG);
7707 case ISD::VP_CTLZ_ZERO_UNDEF:
7708 if (Subtarget.hasStdExtZvbb())
7709 return lowerVPOp(
Op, DAG);
7710 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
7712 case ISD::VP_CTTZ_ZERO_UNDEF:
7713 if (Subtarget.hasStdExtZvbb())
7714 return lowerVPOp(
Op, DAG);
7715 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
7717 return lowerVPOp(
Op, DAG);
7718 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
7719 return lowerVPStridedLoad(
Op, DAG);
7720 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7721 return lowerVPStridedStore(
Op, DAG);
7723 case ISD::VP_FFLOOR:
7725 case ISD::VP_FNEARBYINT:
7726 case ISD::VP_FROUND:
7727 case ISD::VP_FROUNDEVEN:
7728 case ISD::VP_FROUNDTOZERO:
7732 case ISD::VP_FMAXIMUM:
7733 case ISD::VP_FMINIMUM:
7737 case ISD::EXPERIMENTAL_VP_SPLICE:
7738 return lowerVPSpliceExperimental(
Op, DAG);
7739 case ISD::EXPERIMENTAL_VP_REVERSE:
7740 return lowerVPReverseExperimental(
Op, DAG);
7741 case ISD::EXPERIMENTAL_VP_SPLAT:
7742 return lowerVPSplatExperimental(
Op, DAG);
7745 "llvm.clear_cache only needs custom lower on Linux targets");
7748 return emitFlushICache(DAG,
Op.getOperand(0),
Op.getOperand(1),
7749 Op.getOperand(2), Flags,
DL);
7752 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7754 return lowerINIT_TRAMPOLINE(
Op, DAG);
7756 return lowerADJUST_TRAMPOLINE(
Op, DAG);
7763 MakeLibCallOptions CallOptions;
7764 std::pair<SDValue, SDValue> CallResult =
7765 makeLibCall(DAG, RTLIB::RISCV_FLUSH_ICACHE, MVT::isVoid,
7766 {Start,
End, Flags}, CallOptions,
DL, InChain);
7769 return CallResult.second;
7782 std::unique_ptr<MCCodeEmitter> CodeEmitter(
7789 const Value *TrmpAddr = cast<SrcValueSDNode>(
Op.getOperand(4))->getValue();
7801 constexpr unsigned StaticChainOffset = 16;
7802 constexpr unsigned FunctionAddressOffset = 24;
7806 auto GetEncoding = [&](
const MCInst &MC) {
7809 CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI);
7819 GetEncoding(
MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)),
7824 MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(
7825 FunctionAddressOffset)),
7829 MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(
7830 StaticChainOffset)),
7849 SDValue FunctionAddress =
Op.getOperand(2);
7853 struct OffsetValuePair {
7857 } OffsetValues[] = {
7858 {StaticChainOffset, StaticChain},
7859 {FunctionAddressOffset, FunctionAddress},
7864 DAG.
getConstant(OffsetValue.Offset, dl, MVT::i64));
7865 OffsetValue.Addr =
Addr;
7866 OutChains[
Idx + 4] =
7875 SDValue EndOfTrmp = OffsetValues[0].Addr;
7889 return Op.getOperand(0);
7906 N->getOffset(), Flags);
7935template <
class NodeTy>
7937 bool IsLocal,
bool IsExternWeak)
const {
7947 if (IsLocal && !Subtarget.allowTaggedGlobals())
8017 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
8026 return getAddr(
N, DAG);
8033 return getAddr(
N, DAG);
8040 return getAddr(
N, DAG);
8045 bool UseGOT)
const {
8109 Args.push_back(Entry);
8142 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
8156 Addr = getStaticTLSAddr(
N, DAG,
false);
8159 Addr = getStaticTLSAddr(
N, DAG,
true);
8164 : getDynamicTLSAddr(
N, DAG);
8181 if (
LHS == LHS2 &&
RHS == RHS2) {
8186 }
else if (
LHS == RHS2 &&
RHS == LHS2) {
8194 return std::nullopt;
8202 MVT VT =
N->getSimpleValueType(0);
8232 if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
8235 if (~TrueVal == FalseVal) {
8275 if (Subtarget.hasShortForwardBranchOpt())
8278 unsigned SelOpNo = 0;
8288 unsigned ConstSelOpNo = 1;
8289 unsigned OtherSelOpNo = 2;
8290 if (!dyn_cast<ConstantSDNode>(Sel->
getOperand(ConstSelOpNo))) {
8295 ConstantSDNode *ConstSelOpNode = dyn_cast<ConstantSDNode>(ConstSelOp);
8296 if (!ConstSelOpNode || ConstSelOpNode->
isOpaque())
8300 ConstantSDNode *ConstBinOpNode = dyn_cast<ConstantSDNode>(ConstBinOp);
8301 if (!ConstBinOpNode || ConstBinOpNode->
isOpaque())
8307 SDValue NewConstOps[2] = {ConstSelOp, ConstBinOp};
8309 std::swap(NewConstOps[0], NewConstOps[1]);
8321 SDValue NewNonConstOps[2] = {OtherSelOp, ConstBinOp};
8323 std::swap(NewNonConstOps[0], NewNonConstOps[1]);
8326 SDValue NewT = (ConstSelOpNo == 1) ? NewConstOp : NewNonConstOp;
8327 SDValue NewF = (ConstSelOpNo == 1) ? NewNonConstOp : NewConstOp;
8336 MVT VT =
Op.getSimpleValueType();
8350 if ((Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps()) &&
8378 if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
8382 TrueVal, Subtarget.
getXLen(), Subtarget,
true);
8384 FalseVal, Subtarget.
getXLen(), Subtarget,
true);
8385 bool IsCZERO_NEZ = TrueValCost <= FalseValCost;
8387 IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal,
DL, VT);
8392 DL, VT, LHSVal, CondV);
8408 if (
Op.hasOneUse()) {
8409 unsigned UseOpc =
Op->user_begin()->getOpcode();
8418 return lowerSELECT(NewSel, DAG);
8447 SDValue Ops[] = {CondV,
Zero, SetNE, TrueV, FalseV};
8468 if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV) &&
8472 if (TrueVal - 1 == FalseVal)
8474 if (TrueVal + 1 == FalseVal)
8481 RHS == TrueV && LHS == FalseV) {
8498 if (isa<ConstantSDNode>(TrueV) && !isa<ConstantSDNode>(FalseV)) {
8524 LHS, RHS, TargetCC,
Op.getOperand(2));
8542 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
8554 int XLenInBytes = Subtarget.
getXLen() / 8;
8556 EVT VT =
Op.getValueType();
8559 unsigned Depth =
Op.getConstantOperandVal(0);
8561 int Offset = -(XLenInBytes * 2);
8578 int XLenInBytes = Subtarget.
getXLen() / 8;
8583 EVT VT =
Op.getValueType();
8585 unsigned Depth =
Op.getConstantOperandVal(0);
8587 int Off = -XLenInBytes;
8588 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
8607 EVT VT =
Lo.getValueType();
8646 EVT VT =
Lo.getValueType();
8697 MVT VT =
Op.getSimpleValueType();
8723 MVT VecVT =
Op.getSimpleValueType();
8725 "Unexpected SPLAT_VECTOR_PARTS lowering");
8731 MVT ContainerVT = VecVT;
8751 int64_t ExtTrueVal)
const {
8753 MVT VecVT =
Op.getSimpleValueType();
8756 assert(Src.getValueType().isVector() &&
8757 Src.getValueType().getVectorElementType() == MVT::i1);
8778 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
8780 DAG.
getUNDEF(ContainerVT), SplatTrueVal, VL);
8783 SplatZero, DAG.
getUNDEF(ContainerVT), VL);
8788SDValue RISCVTargetLowering::lowerFixedLengthVectorExtendToRVV(
8790 MVT ExtVT =
Op.getSimpleValueType();
8794 MVT VT =
Op.getOperand(0).getSimpleValueType();
8820 bool IsVPTrunc =
Op.getOpcode() == ISD::VP_TRUNCATE;
8822 EVT MaskVT =
Op.getValueType();
8825 "Unexpected type for vector mask lowering");
8827 MVT VecVT = Src.getSimpleValueType();
8831 VL =
Op.getOperand(2);
8834 MVT ContainerVT = VecVT;
8840 MVT MaskContainerVT =
8847 std::tie(Mask, VL) =
8855 DAG.
getUNDEF(ContainerVT), SplatOne, VL);
8857 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
8861 DAG.
getUNDEF(ContainerVT), Mask, VL);
8864 DAG.
getUNDEF(MaskContainerVT), Mask, VL});
8872 unsigned Opc =
Op.getOpcode();
8873 bool IsVPTrunc = Opc == ISD::VP_TRUNCATE;
8876 MVT VT =
Op.getSimpleValueType();
8878 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
8882 return lowerVectorMaskTruncLike(
Op, DAG);
8890 MVT SrcVT = Src.getSimpleValueType();
8895 "Unexpected vector truncate lowering");
8897 MVT ContainerVT = SrcVT;
8901 VL =
Op.getOperand(2);
8914 std::tie(Mask, VL) =
8930 }
while (SrcEltVT != DstEltVT);
8939RISCVTargetLowering::lowerStrictFPExtendOrRoundLike(
SDValue Op,
8944 MVT VT =
Op.getSimpleValueType();
8945 MVT SrcVT = Src.getSimpleValueType();
8946 MVT ContainerVT = VT;
8969 Chain, Src, Mask, VL);
8970 Chain = Src.getValue(1);
8977 Chain, Src, Mask, VL);
8988RISCVTargetLowering::lowerVectorFPExtendOrRoundLike(
SDValue Op,
8991 Op.getOpcode() == ISD::VP_FP_ROUND ||
Op.getOpcode() == ISD::VP_FP_EXTEND;
8998 MVT VT =
Op.getSimpleValueType();
9000 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
9003 MVT SrcVT = Src.getSimpleValueType();
9005 bool IsDirectExtend =
9013 bool IsDirectConv = IsDirectExtend || IsDirectTrunc;
9016 MVT ContainerVT = VT;
9020 VL =
Op.getOperand(2);
9034 std::tie(Mask, VL) =
9040 Src = DAG.
getNode(ConvOpc,
DL, ContainerVT, Src, Mask, VL);
9046 unsigned InterConvOpc =
9051 DAG.
getNode(InterConvOpc,
DL, InterVT, Src, Mask, VL);
9053 DAG.
getNode(ConvOpc,
DL, ContainerVT, IntermediateConv, Mask, VL);
9064static std::optional<MVT>
9070 const unsigned MinVLMAX = VectorBitsMin / EltSize;
9072 if (MaxIdx < MinVLMAX)
9074 else if (MaxIdx < MinVLMAX * 2)
9076 else if (MaxIdx < MinVLMAX * 4)
9081 return std::nullopt;
9094 MVT VecVT =
Op.getSimpleValueType();
9111 ValVT == MVT::bf16) {
9120 MVT ContainerVT = VecVT;
9129 MVT OrigContainerVT = ContainerVT;
9132 if (
auto *IdxC = dyn_cast<ConstantSDNode>(
Idx)) {
9133 const unsigned OrigIdx = IdxC->getZExtValue();
9136 DL, DAG, Subtarget)) {
9137 ContainerVT = *ShrunkVT;
9146 VLEN && ContainerVT.
bitsGT(M1VT)) {
9149 unsigned RemIdx = OrigIdx % ElemsPerVReg;
9150 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
9151 unsigned ExtractIdx =
9168 if (!IsLegalInsert && isa<ConstantSDNode>(Val)) {
9169 const auto *CVal = cast<ConstantSDNode>(Val);
9170 if (isInt<32>(CVal->getSExtValue())) {
9171 IsLegalInsert =
true;
9180 if (IsLegalInsert) {
9186 Vec = DAG.
getNode(Opc,
DL, ContainerVT, Vec, Val, VL);
9202 std::tie(ValLo, ValHi) = DAG.
SplitScalar(Val,
DL, MVT::i32, MVT::i32);
9203 MVT I32ContainerVT =
9214 Vec, Vec, ValLo, I32Mask, InsertI64VL);
9219 Tail, ValInVec, ValHi, I32Mask, InsertI64VL);
9221 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
9226 ValInVec, AlignedIdx);
9236 DAG.
getUNDEF(I32ContainerVT), ValLo,
9237 I32Mask, InsertI64VL);
9239 DAG.
getUNDEF(I32ContainerVT), ValInVec, ValHi,
9240 I32Mask, InsertI64VL);
9242 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
9255 Idx, Mask, InsertVL, Policy);
9259 Slideup, AlignedIdx);
9274 EVT EltVT =
Op.getValueType();
9281 MVT ContainerVT = VecVT;
9297 unsigned WidenVecLen;
9300 unsigned MaxEEW = Subtarget.
getELen();
9305 "the number of elements should be power of 2");
9309 ExtractBitIdx =
Idx;
9311 WideEltVT = LargestEltVT;
9314 ExtractElementIdx = DAG.
getNode(
9325 Vec, ExtractElementIdx);
9341 EltVT == MVT::bf16) {
9351 MVT ContainerVT = VecVT;
9362 if (
auto *IdxC = dyn_cast<ConstantSDNode>(
Idx);
9363 IdxC && VLen && VecVT.
getSizeInBits().getKnownMinValue() > *VLen) {
9365 unsigned OrigIdx = IdxC->getZExtValue();
9368 unsigned RemIdx = OrigIdx % ElemsPerVReg;
9369 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
9370 unsigned ExtractIdx =
9380 std::optional<uint64_t> MaxIdx;
9383 if (
auto *IdxC = dyn_cast<ConstantSDNode>(
Idx))
9384 MaxIdx = IdxC->getZExtValue();
9386 if (
auto SmallerVT =
9388 ContainerVT = *SmallerVT;
9435 "Unexpected opcode");
9442 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
9447 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
9448 if (!
II || !
II->hasScalarOperand())
9451 unsigned SplatOp =
II->ScalarOperand + 1 + HasChain;
9464 if (OpVT.
bitsLT(XLenVT)) {
9471 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
9481 assert(
II->ScalarOperand > 0 &&
"Unexpected splat operand!");
9482 MVT VT =
Op.getOperand(SplatOp - 1).getSimpleValueType();
9485 assert(XLenVT == MVT::i32 && OpVT == MVT::i64 &&
9496 case Intrinsic::riscv_vslide1up:
9497 case Intrinsic::riscv_vslide1down:
9498 case Intrinsic::riscv_vslide1up_mask:
9499 case Intrinsic::riscv_vslide1down_mask: {
9502 bool IsMasked = NumOps == 7;
9508 std::tie(ScalarLo, ScalarHi) =
9516 if (isa<ConstantSDNode>(AVL)) {
9517 const auto [MinVLMAX, MaxVLMAX] =
9521 if (AVLInt <= MinVLMAX) {
9523 }
else if (AVLInt >= 2 * MaxVLMAX) {
9557 if (IntNo == Intrinsic::riscv_vslide1up ||
9558 IntNo == Intrinsic::riscv_vslide1up_mask) {
9560 ScalarHi, I32Mask, I32VL);
9562 ScalarLo, I32Mask, I32VL);
9565 ScalarLo, I32Mask, I32VL);
9567 ScalarHi, I32Mask, I32VL);
9616 const unsigned ElementWidth = 8;
9621 [[maybe_unused]]
unsigned MinVF =
9624 [[maybe_unused]]
unsigned VF =
N->getConstantOperandVal(2);
9628 bool Fractional = VF < LMul1VF;
9629 unsigned LMulVal = Fractional ? LMul1VF / VF : VF / LMul1VF;
9650 MVT ContainerVT = OpVT;
9677 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
9681 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
9682 if (!
II || !
II->hasScalarOperand())
9685 unsigned SplatOp =
II->ScalarOperand + 1;
9698 if (OpVT.
bitsLT(XLenVT)) {
9701 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
9712 EVT ValType = V.getValueType();
9713 if (ValType.isVector() && ValType.isFloatingPoint()) {
9716 ValType.getVectorElementCount());
9719 if (ValType.isFixedLengthVector()) {
9721 DAG, V.getSimpleValueType(), Subtarget);
9737 unsigned IntNo =
Op.getConstantOperandVal(0);
9744 case Intrinsic::riscv_tuple_insert: {
9752 case Intrinsic::riscv_tuple_extract: {
9759 case Intrinsic::thread_pointer: {
9763 case Intrinsic::riscv_orc_b:
9764 case Intrinsic::riscv_brev8:
9765 case Intrinsic::riscv_sha256sig0:
9766 case Intrinsic::riscv_sha256sig1:
9767 case Intrinsic::riscv_sha256sum0:
9768 case Intrinsic::riscv_sha256sum1:
9769 case Intrinsic::riscv_sm3p0:
9770 case Intrinsic::riscv_sm3p1: {
9783 return DAG.
getNode(Opc,
DL, XLenVT,
Op.getOperand(1));
9785 case Intrinsic::riscv_sm4ks:
9786 case Intrinsic::riscv_sm4ed: {
9790 return DAG.
getNode(Opc,
DL, XLenVT,
Op.getOperand(1),
Op.getOperand(2),
9793 case Intrinsic::riscv_zip:
9794 case Intrinsic::riscv_unzip: {
9797 return DAG.
getNode(Opc,
DL, XLenVT,
Op.getOperand(1));
9799 case Intrinsic::riscv_mopr:
9803 case Intrinsic::riscv_moprr: {
9805 Op.getOperand(2),
Op.getOperand(3));
9807 case Intrinsic::riscv_clmul:
9810 case Intrinsic::riscv_clmulh:
9811 case Intrinsic::riscv_clmulr: {
9814 return DAG.
getNode(Opc,
DL, XLenVT,
Op.getOperand(1),
Op.getOperand(2));
9816 case Intrinsic::experimental_get_vector_length:
9818 case Intrinsic::experimental_cttz_elts:
9820 case Intrinsic::riscv_vmv_x_s: {
9824 case Intrinsic::riscv_vfmv_f_s:
9827 case Intrinsic::riscv_vmv_v_x:
9829 Op.getOperand(3),
Op.getSimpleValueType(),
DL, DAG,
9831 case Intrinsic::riscv_vfmv_v_f:
9833 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
9834 case Intrinsic::riscv_vmv_s_x: {
9837 if (
Scalar.getValueType().bitsLE(XLenVT)) {
9840 Op.getOperand(1), Scalar,
Op.getOperand(3));
9843 assert(
Scalar.getValueType() == MVT::i64 &&
"Unexpected scalar VT!");
9860 MVT VT =
Op.getSimpleValueType();
9865 if (
Op.getOperand(1).isUndef())
9881 case Intrinsic::riscv_vfmv_s_f:
9883 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
9885 case Intrinsic::riscv_vaesdf_vv:
9886 case Intrinsic::riscv_vaesdf_vs:
9887 case Intrinsic::riscv_vaesdm_vv:
9888 case Intrinsic::riscv_vaesdm_vs:
9889 case Intrinsic::riscv_vaesef_vv:
9890 case Intrinsic::riscv_vaesef_vs:
9891 case Intrinsic::riscv_vaesem_vv:
9892 case Intrinsic::riscv_vaesem_vs:
9893 case Intrinsic::riscv_vaeskf1:
9894 case Intrinsic::riscv_vaeskf2:
9895 case Intrinsic::riscv_vaesz_vs:
9896 case Intrinsic::riscv_vsm4k:
9897 case Intrinsic::riscv_vsm4r_vv:
9898 case Intrinsic::riscv_vsm4r_vs: {
9899 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
9900 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
9901 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
9906 case Intrinsic::riscv_vsm3c:
9907 case Intrinsic::riscv_vsm3me: {
9908 if (!
isValidEGW(8,
Op.getSimpleValueType(), Subtarget) ||
9909 !
isValidEGW(8,
Op->getOperand(1).getSimpleValueType(), Subtarget))
9914 case Intrinsic::riscv_vsha2ch:
9915 case Intrinsic::riscv_vsha2cl:
9916 case Intrinsic::riscv_vsha2ms: {
9917 if (
Op->getSimpleValueType(0).getScalarSizeInBits() == 64 &&
9918 !Subtarget.hasStdExtZvknhb())
9920 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
9921 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
9922 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
9926 case Intrinsic::riscv_sf_vc_v_x:
9927 case Intrinsic::riscv_sf_vc_v_i:
9928 case Intrinsic::riscv_sf_vc_v_xv:
9929 case Intrinsic::riscv_sf_vc_v_iv:
9930 case Intrinsic::riscv_sf_vc_v_vv:
9931 case Intrinsic::riscv_sf_vc_v_fv:
9932 case Intrinsic::riscv_sf_vc_v_xvv:
9933 case Intrinsic::riscv_sf_vc_v_ivv:
9934 case Intrinsic::riscv_sf_vc_v_vvv:
9935 case Intrinsic::riscv_sf_vc_v_fvv:
9936 case Intrinsic::riscv_sf_vc_v_xvw:
9937 case Intrinsic::riscv_sf_vc_v_ivw:
9938 case Intrinsic::riscv_sf_vc_v_vvw:
9939 case Intrinsic::riscv_sf_vc_v_fvw: {
9940 MVT VT =
Op.getSimpleValueType();
9977 MVT VT =
Op.getSimpleValueType();
9981 if (VT.isFloatingPoint()) {
9986 if (VT.isFixedLengthVector())
9996 if (VT.isFixedLengthVector())
9998 if (VT.isFloatingPoint())
10017 unsigned IntNo =
Op.getConstantOperandVal(1);
10021 case Intrinsic::riscv_seg2_load:
10022 case Intrinsic::riscv_seg3_load:
10023 case Intrinsic::riscv_seg4_load:
10024 case Intrinsic::riscv_seg5_load:
10025 case Intrinsic::riscv_seg6_load:
10026 case Intrinsic::riscv_seg7_load:
10027 case Intrinsic::riscv_seg8_load: {
10030 Intrinsic::riscv_vlseg2, Intrinsic::riscv_vlseg3,
10031 Intrinsic::riscv_vlseg4, Intrinsic::riscv_vlseg5,
10032 Intrinsic::riscv_vlseg6, Intrinsic::riscv_vlseg7,
10033 Intrinsic::riscv_vlseg8};
10034 unsigned NF =
Op->getNumValues() - 1;
10035 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
10037 MVT VT =
Op->getSimpleValueType(0);
10045 auto *
Load = cast<MemIntrinsicSDNode>(
Op);
10057 Load->getMemoryVT(),
Load->getMemOperand());
10059 for (
unsigned int RetIdx = 0; RetIdx < NF; RetIdx++) {
10068 case Intrinsic::riscv_sf_vc_v_x_se:
10070 case Intrinsic::riscv_sf_vc_v_i_se:
10072 case Intrinsic::riscv_sf_vc_v_xv_se:
10074 case Intrinsic::riscv_sf_vc_v_iv_se:
10076 case Intrinsic::riscv_sf_vc_v_vv_se:
10078 case Intrinsic::riscv_sf_vc_v_fv_se:
10080 case Intrinsic::riscv_sf_vc_v_xvv_se:
10082 case Intrinsic::riscv_sf_vc_v_ivv_se:
10084 case Intrinsic::riscv_sf_vc_v_vvv_se:
10086 case Intrinsic::riscv_sf_vc_v_fvv_se:
10088 case Intrinsic::riscv_sf_vc_v_xvw_se:
10090 case Intrinsic::riscv_sf_vc_v_ivw_se:
10092 case Intrinsic::riscv_sf_vc_v_vvw_se:
10094 case Intrinsic::riscv_sf_vc_v_fvw_se:
10103 unsigned IntNo =
Op.getConstantOperandVal(1);
10107 case Intrinsic::riscv_seg2_store:
10108 case Intrinsic::riscv_seg3_store:
10109 case Intrinsic::riscv_seg4_store:
10110 case Intrinsic::riscv_seg5_store:
10111 case Intrinsic::riscv_seg6_store:
10112 case Intrinsic::riscv_seg7_store:
10113 case Intrinsic::riscv_seg8_store: {
10116 Intrinsic::riscv_vsseg2, Intrinsic::riscv_vsseg3,
10117 Intrinsic::riscv_vsseg4, Intrinsic::riscv_vsseg5,
10118 Intrinsic::riscv_vsseg6, Intrinsic::riscv_vsseg7,
10119 Intrinsic::riscv_vsseg8};
10122 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
10124 MVT VT =
Op->getOperand(2).getSimpleValueType();
10134 auto *FixedIntrinsic = cast<MemIntrinsicSDNode>(
Op);
10137 for (
unsigned i = 0; i < NF; i++)
10141 ContainerVT, FixedIntrinsic->getOperand(2 + i), DAG, Subtarget),
10145 FixedIntrinsic->getChain(),
10154 FixedIntrinsic->getMemoryVT(), FixedIntrinsic->getMemOperand());
10156 case Intrinsic::riscv_sf_vc_xv_se:
10158 case Intrinsic::riscv_sf_vc_iv_se:
10160 case Intrinsic::riscv_sf_vc_vv_se:
10162 case Intrinsic::riscv_sf_vc_fv_se:
10164 case Intrinsic::riscv_sf_vc_xvv_se:
10166 case Intrinsic::riscv_sf_vc_ivv_se:
10168 case Intrinsic::riscv_sf_vc_vvv_se:
10170 case Intrinsic::riscv_sf_vc_fvv_se:
10172 case Intrinsic::riscv_sf_vc_xvw_se:
10174 case Intrinsic::riscv_sf_vc_ivw_se:
10176 case Intrinsic::riscv_sf_vc_vvw_se:
10178 case Intrinsic::riscv_sf_vc_fvw_se:
10186 switch (ISDOpcode) {
10189 case ISD::VP_REDUCE_ADD:
10192 case ISD::VP_REDUCE_UMAX:
10195 case ISD::VP_REDUCE_SMAX:
10198 case ISD::VP_REDUCE_UMIN:
10201 case ISD::VP_REDUCE_SMIN:
10204 case ISD::VP_REDUCE_AND:
10207 case ISD::VP_REDUCE_OR:
10210 case ISD::VP_REDUCE_XOR:
10213 case ISD::VP_REDUCE_FADD:
10215 case ISD::VP_REDUCE_SEQ_FADD:
10217 case ISD::VP_REDUCE_FMAX:
10218 case ISD::VP_REDUCE_FMAXIMUM:
10220 case ISD::VP_REDUCE_FMIN:
10221 case ISD::VP_REDUCE_FMINIMUM:
10231 SDValue Vec =
Op.getOperand(IsVP ? 1 : 0);
10236 Op.getOpcode() == ISD::VP_REDUCE_AND ||
10237 Op.getOpcode() == ISD::VP_REDUCE_OR ||
10238 Op.getOpcode() == ISD::VP_REDUCE_XOR) &&
10239 "Unexpected reduction lowering");
10243 MVT ContainerVT = VecVT;
10251 Mask =
Op.getOperand(2);
10252 VL =
Op.getOperand(3);
10254 std::tie(Mask, VL) =
10259 switch (
Op.getOpcode()) {
10263 case ISD::VP_REDUCE_AND: {
10275 case ISD::VP_REDUCE_OR:
10281 case ISD::VP_REDUCE_XOR: {
10305 return DAG.
getNode(BaseOpc,
DL,
Op.getValueType(), SetCC,
Op.getOperand(0));
10309 auto *RegisterAVL = dyn_cast<RegisterSDNode>(AVL);
10310 auto *ImmAVL = dyn_cast<ConstantSDNode>(AVL);
10311 return (RegisterAVL && RegisterAVL->getReg() == RISCV::X0) ||
10312 (ImmAVL && ImmAVL->getZExtValue() >= 1);
10328 auto InnerVT = VecVT.
bitsLE(M1VT) ? VecVT : M1VT;
10332 auto InnerVL = NonZeroAVL ? VL : DAG.
getConstant(1,
DL, XLenVT);
10335 if (M1VT != InnerVT)
10341 SDValue Ops[] = {PassThru, Vec, InitialValue, Mask, VL, Policy};
10360 VecEVT =
Lo.getValueType();
10373 MVT ContainerVT = VecVT;
10393 Mask, VL,
DL, DAG, Subtarget);
10399static std::tuple<unsigned, SDValue, SDValue>
10403 auto Flags =
Op->getFlags();
10404 unsigned Opcode =
Op.getOpcode();
10428 return std::make_tuple(RVVOpc,
Op.getOperand(0), Front);
10436 MVT VecEltVT =
Op.getSimpleValueType();
10438 unsigned RVVOpcode;
10439 SDValue VectorVal, ScalarVal;
10440 std::tie(RVVOpcode, VectorVal, ScalarVal) =
10444 MVT ContainerVT = VecVT;
10450 MVT ResVT =
Op.getSimpleValueType();
10453 VL,
DL, DAG, Subtarget);
10458 if (
Op->getFlags().hasNoNaNs())
10464 {VectorVal, VectorVal, DAG.getCondCode(ISD::SETNE),
10465 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
10471 DL, ResVT, NoNaNs, Res,
10478 unsigned Opc =
Op.getOpcode();
10501 Vec, Mask, VL,
DL, DAG, Subtarget);
10502 if ((Opc != ISD::VP_REDUCE_FMINIMUM && Opc != ISD::VP_REDUCE_FMAXIMUM) ||
10503 Op->getFlags().hasNoNaNs())
10520 DL, ResVT, NoNaNs, Res,
10533 unsigned OrigIdx =
Op.getConstantOperandVal(2);
10536 if (OrigIdx == 0 && Vec.
isUndef())
10547 assert(OrigIdx % 8 == 0 &&
"Invalid index");
10550 "Unexpected mask vector lowering");
10582 MVT ContainerVT = VecVT;
10589 DAG.
getUNDEF(ContainerVT), SubVec,
10606 if (OrigIdx == 0) {
10611 SubVec =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, Vec, SubVec,
10612 SlideupAmt, Mask, VL, Policy);
10620 MVT ContainerVecVT = VecVT;
10626 MVT ContainerSubVecVT = SubVecVT;
10632 unsigned SubRegIdx;
10642 ContainerVecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
10643 SubRegIdx = Decompose.first;
10645 (OrigIdx % Vscale));
10649 ContainerVecVT, ContainerSubVecVT, OrigIdx,
TRI);
10650 SubRegIdx = Decompose.first;
10657 bool ExactlyVecRegSized =
10659 .isKnownMultipleOf(Subtarget.
expandVScale(VecRegSize));
10674 if (RemIdx.
isZero() && (ExactlyVecRegSized || Vec.
isUndef())) {
10678 if (SubRegIdx == RISCV::NoSubRegister) {
10701 MVT InterSubVT = ContainerVecVT;
10702 SDValue AlignedExtract = Vec;
10742 SubVec =
getVSlideup(DAG, Subtarget,
DL, InterSubVT, AlignedExtract, SubVec,
10743 SlideupAmt, Mask, VL, Policy);
10748 if (ContainerVecVT.
bitsGT(InterSubVT))
10757 return DAG.
getBitcast(
Op.getSimpleValueType(), SubVec);
10763 MVT SubVecVT =
Op.getSimpleValueType();
10768 unsigned OrigIdx =
Op.getConstantOperandVal(1);
10784 assert(OrigIdx % 8 == 0 &&
"Invalid index");
10787 "Unexpected mask vector lowering");
10821 MVT ContainerVT = VecVT;
10829 if (
auto ShrunkVT =
10831 ContainerVT = *ShrunkVT;
10844 DAG.
getUNDEF(ContainerVT), Vec, SlidedownAmt, Mask, VL);
10856 MVT ContainerSubVecVT = SubVecVT;
10860 unsigned SubRegIdx;
10870 VecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
10871 SubRegIdx = Decompose.first;
10873 (OrigIdx % Vscale));
10877 VecVT, ContainerSubVecVT, OrigIdx,
TRI);
10878 SubRegIdx = Decompose.first;
10905 MVT InterSubVT = VecVT;
10910 assert(SubRegIdx != RISCV::NoSubRegister);
10930 Vec, SlidedownAmt, Mask, VL);
10939 return DAG.
getBitcast(
Op.getSimpleValueType(), Slidedown);
10946 MVT VT =
N.getSimpleValueType();
10950 assert(
Op.getSimpleValueType() == VT &&
10951 "Operands and result must be same type");
10955 unsigned NumVals =
N->getNumValues();
10958 NumVals,
N.getValueType().changeVectorElementType(MVT::i8)));
10961 for (
unsigned I = 0;
I < NumVals;
I++) {
10967 if (TruncVals.
size() > 1)
10969 return TruncVals.
front();
10975 MVT VecVT =
Op.getSimpleValueType();
10978 "vector_interleave on non-scalable vector!");
10989 EVT SplitVT = Op0Lo.getValueType();
10992 DAG.
getVTList(SplitVT, SplitVT), Op0Lo, Op0Hi);
10994 DAG.
getVTList(SplitVT, SplitVT), Op1Lo, Op1Hi);
11008 Op.getOperand(0),
Op.getOperand(1));
11027 EvenSplat = DAG.
getBitcast(MVT::nxv64i1, EvenSplat);
11032 OddSplat = DAG.
getBitcast(MVT::nxv64i1, OddSplat);
11038 EvenMask, DAG.
getUNDEF(ConcatVT));
11054 MVT VecVT =
Op.getSimpleValueType();
11057 "vector_interleave on non-scalable vector!");
11070 EVT SplitVT = Op0Lo.getValueType();
11073 DAG.
getVTList(SplitVT, SplitVT), Op0Lo, Op1Lo);
11075 DAG.
getVTList(SplitVT, SplitVT), Op0Hi, Op1Hi);
11097 Op.getOperand(0),
Op.getOperand(1));
11145 MVT VT =
Op.getSimpleValueType();
11150 uint64_t StepValImm =
Op.getConstantOperandVal(0);
11151 if (StepValImm != 1) {
11160 VL, VT,
DL, DAG, Subtarget);
11175 MVT VecVT =
Op.getSimpleValueType();
11184 MVT ContainerVT = VecVT;
11238 unsigned MaxVLMAX =
11248 if (MaxVLMAX > 256 && EltSize == 8) {
11277 assert(isUInt<16>(MaxVLMAX - 1));
11303 DAG.
getUNDEF(ContainerVT), Mask, VL);
11315 MVT VecVT =
Op.getSimpleValueType();
11319 int64_t ImmValue = cast<ConstantSDNode>(
Op.getOperand(2))->getSExtValue();
11320 SDValue DownOffset, UpOffset;
11321 if (ImmValue >= 0) {
11337 DownOffset, TrueMask, UpOffset);
11338 return getVSlideup(DAG, Subtarget,
DL, VecVT, SlideDown, V2, UpOffset,
11344RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(
SDValue Op,
11347 auto *
Load = cast<LoadSDNode>(
Op);
11350 Load->getMemoryVT(),
11351 *
Load->getMemOperand()) &&
11352 "Expecting a correctly-aligned load");
11354 MVT VT =
Op.getSimpleValueType();
11360 const auto [MinVLMAX, MaxVLMAX] =
11363 getLMUL1VT(ContainerVT).bitsLE(ContainerVT)) {
11377 IsMaskOp ? Intrinsic::riscv_vlm : Intrinsic::riscv_vle,
DL, XLenVT);
11380 Ops.push_back(DAG.
getUNDEF(ContainerVT));
11381 Ops.push_back(
Load->getBasePtr());
11386 Load->getMemoryVT(),
Load->getMemOperand());
11393RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(
SDValue Op,
11396 auto *
Store = cast<StoreSDNode>(
Op);
11399 Store->getMemoryVT(),
11400 *
Store->getMemOperand()) &&
11401 "Expecting a correctly-aligned store");
11422 const auto [MinVLMAX, MaxVLMAX] =
11425 getLMUL1VT(ContainerVT).bitsLE(ContainerVT)) {
11436 IsMaskOp ? Intrinsic::riscv_vsm : Intrinsic::riscv_vse,
DL, XLenVT);
11439 {Store->getChain(), IntID, NewValue, Store->getBasePtr(), VL},
11440 Store->getMemoryVT(),
Store->getMemOperand());
11446 MVT VT =
Op.getSimpleValueType();
11448 const auto *MemSD = cast<MemSDNode>(
Op);
11449 EVT MemVT = MemSD->getMemoryVT();
11451 SDValue Chain = MemSD->getChain();
11455 bool IsExpandingLoad =
false;
11456 if (
const auto *VPLoad = dyn_cast<VPLoadSDNode>(
Op)) {
11457 Mask = VPLoad->getMask();
11459 VL = VPLoad->getVectorLength();
11461 const auto *MLoad = cast<MaskedLoadSDNode>(
Op);
11462 Mask = MLoad->getMask();
11463 PassThru = MLoad->getPassThru();
11464 IsExpandingLoad = MLoad->isExpandingLoad();
11471 MVT ContainerVT = VT;
11485 if (!IsUnmasked && IsExpandingLoad) {
11492 unsigned IntID = IsUnmasked || IsExpandingLoad ? Intrinsic::riscv_vle
11493 : Intrinsic::riscv_vle_mask;
11495 if (IntID == Intrinsic::riscv_vle)
11496 Ops.push_back(DAG.
getUNDEF(ContainerVT));
11498 Ops.push_back(PassThru);
11499 Ops.push_back(BasePtr);
11500 if (IntID == Intrinsic::riscv_vle_mask)
11501 Ops.push_back(Mask);
11503 if (IntID == Intrinsic::riscv_vle_mask)
11510 Chain =
Result.getValue(1);
11512 MVT IndexVT = ContainerVT;
11517 bool UseVRGATHEREI16 =
false;
11525 UseVRGATHEREI16 =
true;
11531 DAG.
getUNDEF(IndexVT), Mask, ExpandingVL);
11535 DL, ContainerVT, Result, Iota, PassThru, Mask, ExpandingVL);
11548 const auto *MemSD = cast<MemSDNode>(
Op);
11549 EVT MemVT = MemSD->getMemoryVT();
11551 SDValue Chain = MemSD->getChain();
11555 bool IsCompressingStore =
false;
11556 if (
const auto *VPStore = dyn_cast<VPStoreSDNode>(
Op)) {
11557 Val = VPStore->getValue();
11558 Mask = VPStore->getMask();
11559 VL = VPStore->getVectorLength();
11561 const auto *MStore = cast<MaskedStoreSDNode>(
Op);
11562 Val = MStore->getValue();
11563 Mask = MStore->getMask();
11564 IsCompressingStore = MStore->isCompressingStore();
11573 MVT ContainerVT = VT;
11578 if (!IsUnmasked || IsCompressingStore) {
11587 if (IsCompressingStore) {
11590 DAG.
getUNDEF(ContainerVT), Val, Mask, VL);
11597 IsUnmasked ? Intrinsic::riscv_vse : Intrinsic::riscv_vse_mask;
11599 Ops.push_back(Val);
11600 Ops.push_back(BasePtr);
11602 Ops.push_back(Mask);
11606 DAG.
getVTList(MVT::Other), Ops, MemVT, MMO);
11618 MVT ContainerVT = VT;
11631 Passthru, Val, Mask, VL);
11640RISCVTargetLowering::lowerFixedLengthVectorSetccToRVV(
SDValue Op,
11642 MVT InVT =
Op.getOperand(0).getSimpleValueType();
11645 MVT VT =
Op.getSimpleValueType();
11659 {Op1, Op2,
Op.getOperand(2), DAG.
getUNDEF(MaskVT), Mask, VL});
11666 unsigned Opc =
Op.getOpcode();
11673 MVT VT =
Op.getSimpleValueType();
11706 MVT ContainerInVT = InVT;
11725 {Chain, Op1, Op1, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
11729 {Chain, Op2, Op2, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
11737 {Chain, Op1, Op2, CC, Mask, Mask, VL});
11742 {Chain, Op1, Op2, CC, DAG.getUNDEF(MaskVT), Mask, VL});
11755 MVT VT =
Op.getSimpleValueType();
11759 "Unexpected type for ISD::ABS");
11761 MVT ContainerVT = VT;
11768 if (
Op->getOpcode() == ISD::VP_ABS) {
11769 Mask =
Op->getOperand(1);
11773 VL =
Op->getOperand(2);
11781 DAG.
getUNDEF(ContainerVT), Mask, VL);
11783 DAG.
getUNDEF(ContainerVT), Mask, VL);
11790SDValue RISCVTargetLowering::lowerFixedLengthVectorFCOPYSIGNToRVV(
11793 MVT VT =
Op.getSimpleValueType();
11797 "Can only handle COPYSIGN with matching types.");
11806 Sign, DAG.
getUNDEF(ContainerVT), Mask, VL);
11811SDValue RISCVTargetLowering::lowerFixedLengthVectorSelectToRVV(
11813 MVT VT =
Op.getSimpleValueType();
11816 MVT I1ContainerVT =
11830 Op2, DAG.
getUNDEF(ContainerVT), VL);
11841 MVT VT =
Op.getSimpleValueType();
11846 for (
const SDValue &V :
Op->op_values()) {
11847 assert(!isa<VTSDNode>(V) &&
"Unexpected VTSDNode node!");
11850 if (!
V.getValueType().isVector()) {
11856 assert(useRVVForFixedLengthVectorVT(
V.getSimpleValueType()) &&
11857 "Only fixed length vectors are supported!");
11871 if (
Op->isStrictFPOpcode()) {
11880 DAG.
getNode(NewOpc,
DL, ContainerVT, Ops,
Op->getFlags());
11894 MVT VT =
Op.getSimpleValueType();
11897 MVT ContainerVT = VT;
11903 assert(!isa<VTSDNode>(V) &&
"Unexpected VTSDNode node!");
11906 if (HasPassthruOp) {
11909 if (*MaskIdx == OpIdx.index())
11913 if (
Op.getOpcode() == ISD::VP_MERGE) {
11917 assert(
Op.getOpcode() == ISD::VP_SELECT);
11929 if (!
V.getValueType().isFixedLengthVector()) {
11934 MVT OpVT =
V.getSimpleValueType();
11936 assert(useRVVForFixedLengthVectorVT(OpVT) &&
11937 "Only fixed length vectors are supported!");
11942 return DAG.
getNode(RISCVISDOpc,
DL, VT, Ops,
Op->getFlags());
11952 MVT VT =
Op.getSimpleValueType();
11958 MVT ContainerVT = VT;
11968 DAG.
getUNDEF(ContainerVT), Zero, VL);
11971 Op.getOpcode() == ISD::VP_ZERO_EXTEND ? 1 : -1,
DL, XLenVT);
11973 DAG.
getUNDEF(ContainerVT), SplatValue, VL);
11976 ZeroSplat, DAG.
getUNDEF(ContainerVT), VL);
11985 MVT VT =
Op.getSimpleValueType();
11989 ISD::CondCode Condition = cast<CondCodeSDNode>(
Op.getOperand(2))->get();
11993 MVT ContainerVT = VT;
12003 switch (Condition) {
12071 MVT DstVT =
Op.getSimpleValueType();
12072 MVT SrcVT = Src.getSimpleValueType();
12085 if (DstEltSize >= SrcEltSize) {
12094 if (SrcEltSize == 1) {
12105 ZeroSplat, DAG.
getUNDEF(IntVT), VL);
12106 }
else if (DstEltSize > (2 * SrcEltSize)) {
12110 Src = DAG.
getNode(RISCVISDExtOpc,
DL, IntVT, Src, Mask, VL);
12116 "Wrong input/output vector types");
12119 if (DstEltSize > (2 * SrcEltSize)) {
12135 MVT InterimFVT = DstVT;
12136 if (SrcEltSize > (2 * DstEltSize)) {
12137 assert(SrcEltSize == (4 * DstEltSize) &&
"Unexpected types!");
12144 if (InterimFVT != DstVT) {
12150 "Wrong input/output vector types");
12154 if (DstEltSize == 1) {
12157 assert(SrcEltSize >= 16 &&
"Unexpected FP type!");
12167 DAG.
getUNDEF(InterimIVT), SplatZero, VL);
12177 while (InterimIVT != DstVT) {
12189 MVT VT =
Op.getSimpleValueType();
12198 MVT VT =
Op.getSimpleValueType();
12212 MVT ContainerVT = VT;
12233 SplatZero, DAG.
getUNDEF(PromotedVT), VL);
12236 SplatOne, SplatZero, DAG.
getUNDEF(PromotedVT), VLMax);
12240 TrueVal, FalseVal, FalseVal, VL);
12255RISCVTargetLowering::lowerVPSpliceExperimental(
SDValue Op,
12267 MVT VT =
Op.getSimpleValueType();
12268 MVT ContainerVT = VT;
12278 if (IsMaskVector) {
12289 SplatZeroOp1, DAG.
getUNDEF(ContainerVT), EVL1);
12298 SplatZeroOp2, DAG.
getUNDEF(ContainerVT), EVL2);
12301 int64_t ImmValue = cast<ConstantSDNode>(
Offset)->getSExtValue();
12302 SDValue DownOffset, UpOffset;
12303 if (ImmValue >= 0) {
12317 Op1, DownOffset, Mask, UpOffset);
12321 if (IsMaskVector) {
12325 {Result, DAG.getConstant(0, DL, ContainerVT),
12326 DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(getMaskTypeFor(ContainerVT)),
12341 MVT VT =
Op.getSimpleValueType();
12343 MVT ContainerVT = VT;
12359RISCVTargetLowering::lowerVPReverseExperimental(
SDValue Op,
12362 MVT VT =
Op.getSimpleValueType();
12369 MVT ContainerVT = VT;
12377 MVT GatherVT = ContainerVT;
12381 if (IsMaskVector) {
12392 SplatZero, DAG.
getUNDEF(IndicesVT), EVL);
12398 unsigned MaxVLMAX =
12407 if (MaxVLMAX > 256 && EltSize == 8) {
12435 DAG.
getUNDEF(GatherVT), Result, Diff, Mask, EVL);
12437 if (IsMaskVector) {
12460 DAG.
getUNDEF(IndicesVT), VecLen, EVL);
12462 DAG.
getUNDEF(IndicesVT), Mask, EVL);
12464 DAG.
getUNDEF(GatherVT), Mask, EVL);
12466 if (IsMaskVector) {
12481 MVT VT =
Op.getSimpleValueType();
12483 return lowerVPOp(
Op, DAG);
12490 MVT ContainerVT = VT;
12509 MVT VT =
Op.getSimpleValueType();
12510 MVT ContainerVT = VT;
12516 auto *VPNode = cast<VPStridedLoadSDNode>(
Op);
12522 : Intrinsic::riscv_vlse_mask,
12525 DAG.
getUNDEF(ContainerVT), VPNode->getBasePtr(),
12526 VPNode->getStride()};
12534 Ops.
push_back(VPNode->getVectorLength());
12542 VPNode->getMemoryVT(), VPNode->getMemOperand());
12556 auto *VPNode = cast<VPStridedStoreSDNode>(
Op);
12557 SDValue StoreVal = VPNode->getValue();
12559 MVT ContainerVT = VT;
12570 : Intrinsic::riscv_vsse_mask,
12573 VPNode->getBasePtr(), VPNode->getStride()};
12581 Ops.
push_back(VPNode->getVectorLength());
12584 Ops, VPNode->getMemoryVT(),
12585 VPNode->getMemOperand());
12597 MVT VT =
Op.getSimpleValueType();
12599 const auto *MemSD = cast<MemSDNode>(
Op.getNode());
12600 EVT MemVT = MemSD->getMemoryVT();
12602 SDValue Chain = MemSD->getChain();
12608 if (
auto *VPGN = dyn_cast<VPGatherSDNode>(
Op.getNode())) {
12609 Index = VPGN->getIndex();
12610 Mask = VPGN->getMask();
12612 VL = VPGN->getVectorLength();
12617 auto *MGN = cast<MaskedGatherSDNode>(
Op.getNode());
12618 Index = MGN->getIndex();
12619 Mask = MGN->getMask();
12620 PassThru = MGN->getPassThru();
12624 MVT IndexVT =
Index.getSimpleValueType();
12628 "Unexpected VTs!");
12629 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
12632 "Unexpected extending MGATHER/VP_GATHER");
12638 MVT ContainerVT = VT;
12662 IsUnmasked ? Intrinsic::riscv_vluxei : Intrinsic::riscv_vluxei_mask;
12679 Chain =
Result.getValue(1);
12696 const auto *MemSD = cast<MemSDNode>(
Op.getNode());
12697 EVT MemVT = MemSD->getMemoryVT();
12699 SDValue Chain = MemSD->getChain();
12702 [[maybe_unused]]
bool IsTruncatingStore =
false;
12705 if (
auto *VPSN = dyn_cast<VPScatterSDNode>(
Op.getNode())) {
12706 Index = VPSN->getIndex();
12707 Mask = VPSN->getMask();
12708 Val = VPSN->getValue();
12709 VL = VPSN->getVectorLength();
12711 IsTruncatingStore =
false;
12714 auto *MSN = cast<MaskedScatterSDNode>(
Op.getNode());
12715 Index = MSN->getIndex();
12716 Mask = MSN->getMask();
12717 Val = MSN->getValue();
12718 IsTruncatingStore = MSN->isTruncatingStore();
12722 MVT IndexVT =
Index.getSimpleValueType();
12726 "Unexpected VTs!");
12727 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
12730 assert(!IsTruncatingStore &&
"Unexpected truncating MSCATTER/VP_SCATTER");
12736 MVT ContainerVT = VT;
12760 IsUnmasked ? Intrinsic::riscv_vsoxei : Intrinsic::riscv_vsoxei_mask;
12770 DAG.
getVTList(MVT::Other), Ops, MemVT, MMO);
12786 static const int Table =
12815 static const unsigned Table =
12838 bool isRISCV64 = Subtarget.
is64Bit();
12902 switch (
N->getOpcode()) {
12904 llvm_unreachable(
"Don't know how to custom type legalize this operation!");
12910 "Unexpected custom legalisation");
12911 bool IsStrict =
N->isStrictFPOpcode();
12914 SDValue Op0 = IsStrict ?
N->getOperand(1) :
N->getOperand(0);
12932 Opc,
DL, VTs, Chain, Op0,
12966 std::tie(Result, Chain) =
12967 makeLibCall(DAG, LC,
N->getValueType(0), Op0, CallOptions,
DL, Chain);
12995 Op0.
getValueType() == MVT::f64 ? RTLIB::LROUND_F64 : RTLIB::LROUND_F32;
13006 assert(!Subtarget.
is64Bit() &&
"READCYCLECOUNTER/READSTEADYCOUNTER only "
13007 "has custom type legalization on riscv32");
13009 SDValue LoCounter, HiCounter;
13020 N->getOperand(0), LoCounter, HiCounter);
13044 unsigned Size =
N->getSimpleValueType(0).getSizeInBits();
13045 unsigned XLen = Subtarget.
getXLen();
13048 assert(
Size == (XLen * 2) &&
"Unexpected custom legalisation");
13056 if (LHSIsU == RHSIsU)
13073 if (RHSIsU && LHSIsS && !RHSIsS)
13075 else if (LHSIsU && RHSIsS && !LHSIsS)
13085 "Unexpected custom legalisation");
13092 "Unexpected custom legalisation");
13095 if (
N->getOpcode() ==
ISD::SHL && Subtarget.hasStdExtZbs() &&
13121 "Unexpected custom legalisation");
13122 assert((Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb() ||
13123 Subtarget.hasVendorXTHeadBb()) &&
13124 "Unexpected custom legalization");
13125 if (!isa<ConstantSDNode>(
N->getOperand(1)) &&
13126 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()))
13135 "Unexpected custom legalisation");
13149 MVT VT =
N->getSimpleValueType(0);
13150 assert((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) &&
13151 Subtarget.
is64Bit() && Subtarget.hasStdExtM() &&
13152 "Unexpected custom legalisation");
13164 if (VT != MVT::i32)
13173 "Unexpected custom legalisation");
13177 if (!isa<ConstantSDNode>(
N->getOperand(1)))
13194 EVT OType =
N->getValueType(1);
13207 "Unexpected custom legalisation");
13224 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res,
13228 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1),
N->getOperand(0),
13246 !Subtarget.hasStdExtZbb() &&
"Unexpected custom legalisation");
13255 "Unexpected custom legalisation");
13261 "Unexpected custom legalisation");
13263 if (Subtarget.hasStdExtZbb()) {
13297 EVT VT =
N->getValueType(0);
13302 if (VT == MVT::i16 &&
13304 (Op0VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
13307 }
else if (VT == MVT::i32 && Op0VT == MVT::f32 && Subtarget.
is64Bit() &&
13312 }
else if (VT == MVT::i64 && Op0VT == MVT::f64 && !Subtarget.
is64Bit() &&
13315 DAG.
getVTList(MVT::i32, MVT::i32), Op0);
13336 MVT VT =
N->getSimpleValueType(0);
13338 assert((VT == MVT::i16 || (VT == MVT::i32 && Subtarget.
is64Bit())) &&
13339 "Unexpected custom legalisation");
13342 "Unexpected extension");
13368 assert(!Subtarget.
is64Bit() &&
N->getValueType(0) == MVT::i64 &&
13370 "Unexpected EXTRACT_VECTOR_ELT legalization");
13373 MVT ContainerVT = VecVT;
13401 DAG.
getUNDEF(ContainerVT), Mask, VL);
13409 unsigned IntNo =
N->getConstantOperandVal(0);
13413 "Don't know how to custom type legalize this intrinsic!");
13414 case Intrinsic::experimental_get_vector_length: {
13419 case Intrinsic::experimental_cttz_elts: {
13425 case Intrinsic::riscv_orc_b:
13426 case Intrinsic::riscv_brev8:
13427 case Intrinsic::riscv_sha256sig0:
13428 case Intrinsic::riscv_sha256sig1:
13429 case Intrinsic::riscv_sha256sum0:
13430 case Intrinsic::riscv_sha256sum1:
13431 case Intrinsic::riscv_sm3p0:
13432 case Intrinsic::riscv_sm3p1: {
13433 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13453 case Intrinsic::riscv_sm4ks:
13454 case Intrinsic::riscv_sm4ed: {
13462 DAG.
getNode(Opc,
DL, MVT::i64, NewOp0, NewOp1,
N->getOperand(3));
13466 case Intrinsic::riscv_mopr: {
13467 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13477 case Intrinsic::riscv_moprr: {
13478 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13490 case Intrinsic::riscv_clmul: {
13491 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13502 case Intrinsic::riscv_clmulh:
13503 case Intrinsic::riscv_clmulr: {
13504 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13532 case Intrinsic::riscv_vmv_x_s: {
13533 EVT VT =
N->getValueType(0);
13535 if (VT.
bitsLT(XLenVT)) {
13544 "Unexpected custom legalization");
13582 case ISD::VP_REDUCE_ADD:
13583 case ISD::VP_REDUCE_AND:
13584 case ISD::VP_REDUCE_OR:
13585 case ISD::VP_REDUCE_XOR:
13586 case ISD::VP_REDUCE_SMAX:
13587 case ISD::VP_REDUCE_UMAX:
13588 case ISD::VP_REDUCE_SMIN:
13589 case ISD::VP_REDUCE_UMIN:
13653 const EVT VT =
N->getValueType(0);
13654 const unsigned Opc =
N->getOpcode();
13661 (Opc !=
ISD::FADD || !
N->getFlags().hasAllowReassociation()))
13666 "Inconsistent mappings");
13677 !isa<ConstantSDNode>(
RHS.getOperand(1)))
13680 uint64_t RHSIdx = cast<ConstantSDNode>(
RHS.getOperand(1))->getLimitedValue();
13695 LHS.getOperand(0) == SrcVec && isa<ConstantSDNode>(
LHS.getOperand(1))) {
13697 cast<ConstantSDNode>(
LHS.getOperand(1))->getLimitedValue();
13698 if (0 == std::min(LHSIdx, RHSIdx) && 1 == std::max(LHSIdx, RHSIdx)) {
13702 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
N->getFlags());
13709 if (
LHS.getOpcode() != ReduceOpc)
13724 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
13725 ReduceVec->
getFlags() &
N->getFlags());
13735 auto BinOpToRVVReduce = [](
unsigned Opc) {
13764 auto IsReduction = [&BinOpToRVVReduce](
SDValue V,
unsigned Opc) {
13767 V.getOperand(0).getOpcode() == BinOpToRVVReduce(Opc);
13770 unsigned Opc =
N->getOpcode();
13771 unsigned ReduceIdx;
13772 if (IsReduction(
N->getOperand(0), Opc))
13774 else if (IsReduction(
N->getOperand(1), Opc))
13780 if (Opc ==
ISD::FADD && !
N->getFlags().hasAllowReassociation())
13783 SDValue Extract =
N->getOperand(ReduceIdx);
13815 SDValue NewStart =
N->getOperand(1 - ReduceIdx);
13842 if (!Subtarget.hasStdExtZba())
13846 EVT VT =
N->getValueType(0);
13858 auto *N0C = dyn_cast<ConstantSDNode>(N0->
getOperand(1));
13859 auto *N1C = dyn_cast<ConstantSDNode>(N1->
getOperand(1));
13862 int64_t C0 = N0C->getSExtValue();
13863 int64_t C1 = N1C->getSExtValue();
13864 if (C0 <= 0 || C1 <= 0)
13868 int64_t Bits = std::min(C0, C1);
13869 int64_t Diff = std::abs(C0 - C1);
13870 if (Diff != 1 && Diff != 2 && Diff != 3)
13897 EVT VT =
N->getValueType(0);
13905 if ((!Subtarget.hasStdExtZicond() &&
13906 !Subtarget.hasVendorXVentanaCondOps()) ||
13928 bool SwapSelectOps;
13934 SwapSelectOps =
false;
13935 NonConstantVal = FalseVal;
13937 SwapSelectOps =
true;
13938 NonConstantVal = TrueVal;
13944 FalseVal = DAG.
getNode(
N->getOpcode(),
SDLoc(
N), VT, OtherOp, NonConstantVal);
13992 EVT VT =
N->getValueType(0);
14000 auto *N0C = dyn_cast<ConstantSDNode>(N0->
getOperand(1));
14001 auto *N1C = dyn_cast<ConstantSDNode>(
N->getOperand(1));
14007 if (!N0C->hasOneUse())
14009 int64_t C0 = N0C->getSExtValue();
14010 int64_t C1 = N1C->getSExtValue();
14012 if (C0 == -1 || C0 == 0 || C0 == 1 || isInt<12>(C1))
14015 if ((C1 / C0) != 0 && isInt<12>(C1 / C0) && isInt<12>(C1 % C0) &&
14016 !isInt<12>(C0 * (C1 / C0))) {
14019 }
else if ((C1 / C0 + 1) != 0 && isInt<12>(C1 / C0 + 1) &&
14020 isInt<12>(C1 % C0 - C0) && !isInt<12>(C0 * (C1 / C0 + 1))) {
14023 }
else if ((C1 / C0 - 1) != 0 && isInt<12>(C1 / C0 - 1) &&
14024 isInt<12>(C1 % C0 + C0) && !isInt<12>(C0 * (C1 / C0 - 1))) {
14051 EVT VT =
N->getValueType(0);
14082 unsigned OuterExtend =
14086 OuterExtend,
SDLoc(
N), VT,
14094 EVT VT =
N->getValueType(0);
14142 EVT VT =
N->getValueType(0);
14146 auto *N0C = dyn_cast<ConstantSDNode>(N0);
14152 APInt ImmValMinus1 = N0C->getAPIntValue() - 1;
14162 if (!isIntEqualitySetCC(CCVal) || !SetCCOpVT.
isInteger())
14185 if (!Subtarget.hasStdExtZbb())
14188 EVT VT =
N->getValueType(0);
14190 if (VT != Subtarget.
getXLenVT() && VT != MVT::i32 && VT != MVT::i16)
14199 auto *ShAmtCLeft = dyn_cast<ConstantSDNode>(N0.
getOperand(1));
14202 unsigned ShiftedAmount = 8 - ShAmtCLeft->getZExtValue();
14204 if (ShiftedAmount >= 8)
14208 SDValue RightShiftOperand = N1;
14210 if (ShiftedAmount != 0) {
14213 auto *ShAmtCRight = dyn_cast<ConstantSDNode>(N1.
getOperand(1));
14214 if (!ShAmtCRight || ShAmtCRight->getZExtValue() != ShiftedAmount)
14223 if (LeftShiftOperand != RightShiftOperand)
14227 Mask <<= ShiftedAmount;
14241 EVT VT =
N->getValueType(0);
14272 bool IsAnd =
N->getOpcode() ==
ISD::AND;
14296 EVT VT =
N->getValueType(0);
14320 EVT VT =
N->getValueType(0);
14347 if (CondLHS != True)
14354 if (!CondRHSC || CondRHSC->
getAPIntValue() != (1ULL << ScalarBits))
14366 if (!FalseRHSC || !FalseRHSC->
isZero())
14386 EVT VT =
N->getValueType(0);
14393 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() && VT == MVT::i1 &&
14420 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
14472 EVT VT =
N->getValueType(0);
14518 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
14543 auto *ConstN00 = dyn_cast<ConstantSDNode>(N0.
getOperand(0));
14548 const APInt &Imm = ConstN00->getAPIntValue();
14549 if ((Imm + 1).isSignedIntN(12))
14570 EVT VT =
N->getValueType(0);
14582 const bool HasShlAdd =
14583 Subtarget.hasStdExtZba() || Subtarget.hasVendorXTHeadBa();
14597 for (
uint64_t Divisor : {3, 5, 9}) {
14598 if (MulAmt % Divisor != 0)
14600 uint64_t MulAmt2 = MulAmt / Divisor;
14607 if (
X.getOpcode() ==
ISD::AND && isa<ConstantSDNode>(
X.getOperand(1)) &&
14608 X.getConstantOperandVal(1) == UINT64_C(0xffffffff)) {
14625 if (MulAmt2 == 3 || MulAmt2 == 5 || MulAmt2 == 9) {
14641 if (ScaleShift >= 1 && ScaleShift < 4) {
14642 unsigned ShiftAmt =
Log2_64((MulAmt & (MulAmt - 1)));
14656 for (
uint64_t Divisor : {3, 5, 9}) {
14661 if ((
C >> TZ) == Divisor && (TZ == 1 || TZ == 2 || TZ == 3)) {
14672 if (MulAmt > 2 &&
isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
14674 if (ScaleShift >= 1 && ScaleShift < 4) {
14675 unsigned ShiftAmt =
Log2_64(((MulAmt - 1) & (MulAmt - 2)));
14701 uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
14703 uint64_t ShiftAmt1 = MulAmt + MulAmtLowBit;
14714 for (
uint64_t Divisor : {3, 5, 9}) {
14715 if (MulAmt % Divisor != 0)
14717 uint64_t MulAmt2 = MulAmt / Divisor;
14720 for (
uint64_t Divisor2 : {3, 5, 9}) {
14721 if (MulAmt2 % Divisor2 != 0)
14723 uint64_t MulAmt3 = MulAmt2 / Divisor2;
14746 EVT VT =
N->getValueType(0);
14753 if (
N->getOperand(0).getOpcode() !=
ISD::AND ||
14754 N->getOperand(0).getOperand(0).getOpcode() !=
ISD::SRL)
14767 if (!V1.
isMask(HalfSize) || V2 != (1ULL | 1ULL << HalfSize) ||
14768 V3 != (HalfSize - 1))
14784 EVT VT =
N->getValueType(0);
14792 unsigned AddSubOpc;
14798 auto IsAddSubWith1 = [&](
SDValue V) ->
bool {
14799 AddSubOpc = V->getOpcode();
14801 SDValue Opnd = V->getOperand(1);
14802 MulOper = V->getOperand(0);
14811 if (IsAddSubWith1(N0)) {
14813 return DAG.
getNode(AddSubOpc,
DL, VT, N1, MulVal);
14816 if (IsAddSubWith1(N1)) {
14818 return DAG.
getNode(AddSubOpc,
DL, VT, N0, MulVal);
14833 if (isIndexTypeSigned(IndexType))
14836 if (!
N->hasOneUse())
14839 EVT VT =
N.getValueType();
14878 EVT SrcVT = Src.getValueType();
14882 NewElen = std::max(NewElen, 8U);
14905 EVT VT =
N->getValueType(0);
14908 if (OpVT != MVT::i64 || !Subtarget.
is64Bit())
14912 auto *N1C = dyn_cast<ConstantSDNode>(N1);
14924 if (!isIntEqualitySetCC(
Cond))
14933 const APInt &C1 = N1C->getAPIntValue();
14951 EVT VT =
N->getValueType(0);
14952 EVT SrcVT = cast<VTSDNode>(
N->getOperand(1))->
getVT();
14953 unsigned Opc = Src.getOpcode();
14958 Subtarget.hasStdExtZfhmin())
14960 Src.getOperand(0));
14964 VT == MVT::i64 && !isa<ConstantSDNode>(Src.getOperand(1)) &&
14967 Src.getOperand(1));
14975struct CombineResult;
14977enum ExtKind :
uint8_t { ZExt = 1 << 0, SExt = 1 << 1, FPExt = 1 << 2 };
15004struct NodeExtensionHelper {
15013 bool SupportsFPExt;
15016 bool EnforceOneUse;
15031 return OrigOperand;
15042 unsigned getExtOpc(ExtKind SupportsExt)
const {
15043 switch (SupportsExt) {
15044 case ExtKind::SExt:
15046 case ExtKind::ZExt:
15048 case ExtKind::FPExt:
15059 std::optional<ExtKind> SupportsExt)
const {
15060 if (!SupportsExt.has_value())
15061 return OrigOperand;
15063 MVT NarrowVT = getNarrowType(Root, *SupportsExt);
15067 if (
Source.getValueType() == NarrowVT)
15071 if (
Source.getValueType().getVectorElementType() == MVT::bf16) {
15077 unsigned ExtOpc = getExtOpc(*SupportsExt);
15081 auto [
Mask, VL] = getMaskAndVL(Root, DAG, Subtarget);
15088 return DAG.
getNode(ExtOpc,
DL, NarrowVT, Source, Mask, VL);
15100 DAG.
getUNDEF(NarrowVT), Source, VL);
15113 static MVT getNarrowType(
const SDNode *Root, ExtKind SupportsExt) {
15119 MVT EltVT = SupportsExt == ExtKind::FPExt
15121 :
MVT::getIntegerVT(NarrowSize);
15123 assert((
int)NarrowSize >= (SupportsExt == ExtKind::FPExt ? 16 : 8) &&
15124 "Trying to extend something we can't represent");
15131 static unsigned getSExtOpcode(
unsigned Opcode) {
15154 static unsigned getZExtOpcode(
unsigned Opcode) {
15180 static unsigned getFPExtOpcode(
unsigned Opcode) {
15205 static unsigned getSUOpcode(
unsigned Opcode) {
15207 "SU is only supported for MUL");
15213 static unsigned getWOpcode(
unsigned Opcode, ExtKind SupportsExt) {
15233 using CombineToTry = std::function<std::optional<CombineResult>(
15234 SDNode * ,
const NodeExtensionHelper & ,
15239 bool needToPromoteOtherUsers()
const {
return EnforceOneUse; }
15243 unsigned Opc = OrigOperand.
getOpcode();
15247 "Unexpected Opcode");
15260 unsigned ScalarBits =
Op.getValueSizeInBits();
15262 if (ScalarBits < EltBits) {
15265 !Subtarget.
is64Bit() &&
"Unexpected splat");
15267 SupportsSExt =
true;
15271 SupportsZExt =
true;
15273 EnforceOneUse =
false;
15277 unsigned NarrowSize = EltBits / 2;
15280 if (NarrowSize < 8)
15284 SupportsSExt =
true;
15288 SupportsZExt =
true;
15290 EnforceOneUse =
false;
15293 bool isSupportedFPExtend(
SDNode *Root,
MVT NarrowEltVT,
15300 if (NarrowEltVT == MVT::bf16 && (!Subtarget.hasStdExtZvfbfwma() ||
15310 SupportsZExt =
false;
15311 SupportsSExt =
false;
15312 SupportsFPExt =
false;
15313 EnforceOneUse =
true;
15314 unsigned Opc = OrigOperand.
getOpcode();
15336 SupportsZExt =
true;
15339 SupportsSExt =
true;
15344 if (!isSupportedFPExtend(Root, NarrowEltVT, Subtarget))
15346 SupportsFPExt =
true;
15351 fillUpExtensionSupportForSplat(Root, DAG, Subtarget);
15363 if (!isSupportedFPExtend(Root,
Op.getOperand(0).getSimpleValueType(),
15368 unsigned ScalarBits =
Op.getOperand(0).getValueSizeInBits();
15369 if (NarrowSize != ScalarBits)
15372 SupportsFPExt =
true;
15381 static bool isSupportedRoot(
const SDNode *Root,
15410 Subtarget.hasStdExtZvbb();
15412 return Subtarget.hasStdExtZvbb();
15426 assert(isSupportedRoot(Root, Subtarget) &&
15427 "Trying to build an helper with an "
15428 "unsupported root");
15429 assert(OperandIdx < 2 &&
"Requesting something else than LHS or RHS");
15445 if (OperandIdx == 1) {
15454 EnforceOneUse =
false;
15459 fillUpExtensionSupport(Root, DAG, Subtarget);
15465 static std::pair<SDValue, SDValue>
15468 assert(isSupportedRoot(Root, Subtarget) &&
"Unexpected root");
15487 switch (
N->getOpcode()) {
15529struct CombineResult {
15531 unsigned TargetOpcode;
15533 std::optional<ExtKind> LHSExt;
15534 std::optional<ExtKind> RHSExt;
15538 NodeExtensionHelper
LHS;
15540 NodeExtensionHelper
RHS;
15542 CombineResult(
unsigned TargetOpcode,
SDNode *Root,
15543 const NodeExtensionHelper &
LHS, std::optional<ExtKind> LHSExt,
15544 const NodeExtensionHelper &
RHS, std::optional<ExtKind> RHSExt)
15545 : TargetOpcode(TargetOpcode), LHSExt(LHSExt), RHSExt(RHSExt), Root(Root),
15554 std::tie(Mask, VL) =
15555 NodeExtensionHelper::getMaskAndVL(Root, DAG, Subtarget);
15569 LHS.getOrCreateExtendedOp(Root, DAG, Subtarget, LHSExt),
15570 RHS.getOrCreateExtendedOp(Root, DAG, Subtarget, RHSExt),
15571 Passthru, Mask, VL);
15585static std::optional<CombineResult>
15586canFoldToVWWithSameExtensionImpl(
SDNode *Root,
const NodeExtensionHelper &LHS,
15587 const NodeExtensionHelper &RHS,
15590 if ((AllowExtMask & ExtKind::ZExt) &&
LHS.SupportsZExt &&
RHS.SupportsZExt)
15591 return CombineResult(NodeExtensionHelper::getZExtOpcode(Root->
getOpcode()),
15592 Root, LHS, {ExtKind::ZExt}, RHS,
15594 if ((AllowExtMask & ExtKind::SExt) &&
LHS.SupportsSExt &&
RHS.SupportsSExt)
15595 return CombineResult(NodeExtensionHelper::getSExtOpcode(Root->
getOpcode()),
15596 Root, LHS, {ExtKind::SExt}, RHS,
15598 if ((AllowExtMask & ExtKind::FPExt) &&
LHS.SupportsFPExt &&
RHS.SupportsFPExt)
15599 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
15600 Root, LHS, {ExtKind::FPExt}, RHS,
15602 return std::nullopt;
15611static std::optional<CombineResult>
15612canFoldToVWWithSameExtension(
SDNode *Root,
const NodeExtensionHelper &LHS,
15615 return canFoldToVWWithSameExtensionImpl(
15616 Root, LHS, RHS, ExtKind::ZExt | ExtKind::SExt | ExtKind::FPExt, DAG,
15624static std::optional<CombineResult>
15625canFoldToVW_W(
SDNode *Root,
const NodeExtensionHelper &LHS,
15628 if (
RHS.SupportsFPExt)
15629 return CombineResult(
15630 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::FPExt),
15631 Root, LHS, std::nullopt, RHS, {ExtKind::FPExt});
15638 return CombineResult(
15639 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::ZExt), Root,
15640 LHS, std::nullopt, RHS, {ExtKind::ZExt});
15642 return CombineResult(
15643 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::SExt), Root,
15644 LHS, std::nullopt, RHS, {ExtKind::SExt});
15645 return std::nullopt;
15652static std::optional<CombineResult>
15653canFoldToVWWithSEXT(
SDNode *Root,
const NodeExtensionHelper &LHS,
15656 return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::SExt, DAG,
15664static std::optional<CombineResult>
15665canFoldToVWWithZEXT(
SDNode *Root,
const NodeExtensionHelper &LHS,
15668 return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::ZExt, DAG,
15676static std::optional<CombineResult>
15677canFoldToVWWithFPEXT(
SDNode *Root,
const NodeExtensionHelper &LHS,
15680 return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::FPExt, DAG,
15688static std::optional<CombineResult>
15689canFoldToVW_SU(
SDNode *Root,
const NodeExtensionHelper &LHS,
15693 if (!
LHS.SupportsSExt || !
RHS.SupportsZExt)
15694 return std::nullopt;
15695 return CombineResult(NodeExtensionHelper::getSUOpcode(Root->
getOpcode()),
15696 Root, LHS, {ExtKind::SExt}, RHS,
15701NodeExtensionHelper::getSupportedFoldings(
const SDNode *Root) {
15712 Strategies.
push_back(canFoldToVWWithSameExtension);
15721 Strategies.
push_back(canFoldToVWWithSameExtension);
15726 Strategies.
push_back(canFoldToVWWithSameExtension);
15733 Strategies.
push_back(canFoldToVWWithZEXT);
15738 Strategies.
push_back(canFoldToVWWithSEXT);
15743 Strategies.
push_back(canFoldToVWWithZEXT);
15748 Strategies.
push_back(canFoldToVWWithFPEXT);
15777 if (!NodeExtensionHelper::isSupportedRoot(
N, Subtarget))
15783 Inserted.insert(
N);
15786 while (!Worklist.
empty()) {
15789 NodeExtensionHelper
LHS(Root, 0, DAG, Subtarget);
15790 NodeExtensionHelper
RHS(Root, 1, DAG, Subtarget);
15791 auto AppendUsersIfNeeded = [&Worklist, &Subtarget,
15792 &Inserted](
const NodeExtensionHelper &
Op) {
15793 if (
Op.needToPromoteOtherUsers()) {
15796 if (!NodeExtensionHelper::isSupportedRoot(TheUser, Subtarget))
15801 if (Inserted.insert(TheUser).second)
15814 NodeExtensionHelper::getSupportedFoldings(Root);
15816 assert(!FoldingStrategies.
empty() &&
"Nothing to be folded");
15817 bool Matched =
false;
15818 for (
int Attempt = 0;
15819 (Attempt != 1 + NodeExtensionHelper::isCommutative(Root)) && !Matched;
15822 for (NodeExtensionHelper::CombineToTry FoldingStrategy :
15823 FoldingStrategies) {
15824 std::optional<CombineResult> Res =
15825 FoldingStrategy(Root,
LHS,
RHS, DAG, Subtarget);
15832 if (Res->LHSExt.has_value())
15833 if (!AppendUsersIfNeeded(
LHS))
15835 if (Res->RHSExt.has_value())
15836 if (!AppendUsersIfNeeded(
RHS))
15848 SDValue InputRootReplacement;
15855 for (CombineResult Res : CombinesToApply) {
15856 SDValue NewValue = Res.materialize(DAG, Subtarget);
15857 if (!InputRootReplacement) {
15859 "First element is expected to be the current node");
15860 InputRootReplacement = NewValue;
15865 for (std::pair<SDValue, SDValue> OldNewValues : ValuesToReplace) {
15869 return InputRootReplacement;
15876 unsigned Opc =
N->getOpcode();
15881 SDValue MergeOp =
N->getOperand(1);
15882 unsigned MergeOpc = MergeOp.
getOpcode();
15893 SDValue Passthru =
N->getOperand(2);
15907 Z = Z.getOperand(1);
15913 {Y, X, Y, MergeOp->getOperand(0), N->getOperand(4)},
15920 [[maybe_unused]]
unsigned Opc =
N->getOpcode();
15949 EVT NewMemVT = (MemVT == MVT::i32) ? MVT::i64 : MVT::i128;
15955 auto Ext = cast<LoadSDNode>(LSNode1)->getExtensionType();
15957 if (MemVT == MVT::i32)
15963 Opcode,
SDLoc(LSNode1), DAG.
getVTList({XLenVT, XLenVT, MVT::Other}),
15998 if (!Subtarget.hasVendorXTHeadMemPair())
16010 auto ExtractBaseAndOffset = [](
SDValue Ptr) -> std::pair<SDValue, uint64_t> {
16012 if (
auto *C1 = dyn_cast<ConstantSDNode>(
Ptr->getOperand(1)))
16013 return {
Ptr->getOperand(0), C1->getZExtValue()};
16017 auto [Base1, Offset1] = ExtractBaseAndOffset(LSNode1->
getOperand(OpNum));
16038 auto [Base2, Offset2] = ExtractBaseAndOffset(LSNode2->
getOperand(OpNum));
16041 if (Base1 != Base2)
16045 bool Valid =
false;
16046 if (MemVT == MVT::i32) {
16048 if ((Offset1 + 4 == Offset2) && isShiftedUInt<2, 3>(Offset1))
16050 }
else if (MemVT == MVT::i64) {
16052 if ((Offset1 + 8 == Offset2) && isShiftedUInt<2, 4>(Offset1))
16086 if (Src->isStrictFPOpcode())
16094 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
16104 EVT VT =
N->getValueType(0);
16107 MVT SrcVT = Src.getSimpleValueType();
16108 MVT SrcContainerVT = SrcVT;
16110 SDValue XVal = Src.getOperand(0);
16137 FpToInt = DAG.
getNode(Opc,
DL, ContainerVT, XVal, Mask, VL);
16141 FpToInt = DAG.
getNode(Opc,
DL, ContainerVT, XVal, Mask,
16154 if (VT != MVT::i32 && VT != XLenVT)
16184 EVT DstVT =
N->getValueType(0);
16185 if (DstVT != XLenVT)
16191 if (Src->isStrictFPOpcode())
16199 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
16202 EVT SatVT = cast<VTSDNode>(
N->getOperand(1))->getVT();
16211 if (SatVT == DstVT)
16213 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
16219 Src = Src.getOperand(0);
16240 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected extension");
16246 EVT VT =
N->getValueType(0);
16261 auto *VPLoad = dyn_cast<VPLoadSDNode>(
N->getOperand(0));
16265 EVT LoadVT = VPLoad->getValueType(0);
16269 N->getOperand(2) != VPLoad->getVectorLength() ||
16270 !
N->getOperand(0).hasOneUse())
16277 SDValue LoadMask = VPLoad->getMask();
16282 if (LoadMask.
getOpcode() != ISD::EXPERIMENTAL_VP_REVERSE ||
16284 LoadMask.
getOperand(2) != VPLoad->getVectorLength())
16292 SDValue NumElem = VPLoad->getVectorLength();
16293 uint64_t ElemWidthByte = VPLoad->getValueType(0).getScalarSizeInBits() / 8;
16305 PtrInfo, VPLoad->getMemOperand()->getFlags(),
16309 LoadVT,
DL, VPLoad->getChain(),
Base, Stride, LoadMask,
16310 VPLoad->getVectorLength(), MMO, VPLoad->isExpandingLoad());
16322 auto *VPStore = cast<VPStoreSDNode>(
N);
16324 if (VPStore->getValue().getOpcode() != ISD::EXPERIMENTAL_VP_REVERSE)
16327 SDValue VPReverse = VPStore->getValue();
16333 VPStore->getVectorLength() != VPReverse.
getOperand(2) ||
16337 SDValue StoreMask = VPStore->getMask();
16342 if (StoreMask.
getOpcode() != ISD::EXPERIMENTAL_VP_REVERSE ||
16344 StoreMask.
getOperand(2) != VPStore->getVectorLength())
16352 SDValue NumElem = VPStore->getVectorLength();
16366 PtrInfo, VPStore->getMemOperand()->getFlags(),
16371 VPStore->getOffset(), Stride, StoreMask, VPStore->getVectorLength(),
16372 VPStore->getMemoryVT(), MMO, VPStore->getAddressingMode(),
16373 VPStore->isTruncatingStore(), VPStore->isCompressingStore());
16422 unsigned Offset = IsStrict ? 1 : 0;
16429 auto invertIfNegative = [&Mask, &VL](
SDValue &V) {
16431 V.getOperand(2) == VL) {
16433 V = V.getOperand(0);
16440 bool NegA = invertIfNegative(
A);
16441 bool NegB = invertIfNegative(
B);
16442 bool NegC = invertIfNegative(
C);
16445 if (!NegA && !NegB && !NegC)
16451 {N->getOperand(0), A, B, C, Mask, VL});
16475 EVT VT =
N->getValueType(0);
16480 if (!isa<ConstantSDNode>(
N->getOperand(1)))
16482 uint64_t ShAmt =
N->getConstantOperandVal(1);
16490 cast<VTSDNode>(N0.
getOperand(1))->getVT().getSizeInBits();
16495 if (LShAmt < ExtSize) {
16508 if (ShAmt > 32 || VT != MVT::i64)
16524 AddC = dyn_cast<ConstantSDNode>(N0.
getOperand(IsAdd ? 1 : 0));
16537 !isa<ConstantSDNode>(U->getOperand(1)) ||
16538 U->getConstantOperandVal(1) > 32)
16593 if (!
Cond.hasOneUse())
16612 EVT VT =
Cond.getValueType();
16657 LHS =
LHS.getOperand(0);
16667 LHS.getOperand(0).getValueType() == Subtarget.
getXLenVT()) {
16671 CCVal = cast<CondCodeSDNode>(
LHS.getOperand(2))->get();
16675 RHS =
LHS.getOperand(1);
16676 LHS =
LHS.getOperand(0);
16685 RHS =
LHS.getOperand(1);
16686 LHS =
LHS.getOperand(0);
16702 ShAmt =
LHS.getValueSizeInBits() - 1 - ShAmt;
16743 bool Commutative =
true;
16744 unsigned Opc = TrueVal.getOpcode();
16752 Commutative =
false;
16760 if (!TrueVal.hasOneUse() || isa<ConstantSDNode>(FalseVal))
16764 if (FalseVal == TrueVal.getOperand(0))
16766 else if (Commutative && FalseVal == TrueVal.getOperand(1))
16771 EVT VT =
N->getValueType(0);
16773 SDValue OtherOp = TrueVal.getOperand(1 - OpToFold);
16779 assert(IdentityOperand &&
"No identity operand!");
16784 DAG.
getSelect(
DL, OtherOpVT,
N->getOperand(0), OtherOp, IdentityOperand);
16785 return DAG.
getNode(TrueVal.getOpcode(),
DL, VT, FalseVal, NewSel);
16806 CountZeroes =
N->getOperand(2);
16807 ValOnZero =
N->getOperand(1);
16809 CountZeroes =
N->getOperand(1);
16810 ValOnZero =
N->getOperand(2);
16829 if (
Cond->getOperand(0) != CountZeroesArgument)
16845 CountZeroes, BitWidthMinusOne);
16855 EVT VT =
N->getValueType(0);
16856 EVT CondVT =
Cond.getValueType();
16864 (Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps())) {
16870 const APInt &MaskVal =
LHS.getConstantOperandAPInt(1);
16881 if (!TrueVal.hasOneUse() || !FalseVal.hasOneUse())
16885 if (TrueVal.getOpcode() ==
ISD::SUB && FalseVal.getOpcode() ==
ISD::ADD) {
16893 SDValue A = FalseVal.getOperand(0);
16894 SDValue B = FalseVal.getOperand(1);
16896 return ((TrueVal.getOperand(0) ==
A && TrueVal.getOperand(1) ==
B) ||
16897 (TrueVal.getOperand(1) ==
A && TrueVal.getOperand(0) ==
B));
16905 EVT VT =
N->getValueType(0);
16907 SDValue TrueVal =
N->getOperand(1);
16908 SDValue FalseVal =
N->getOperand(2);
16914 SDValue Sub = SwapCC ? TrueVal : FalseVal;
16938 SDValue TrueVal =
N->getOperand(1);
16939 SDValue FalseVal =
N->getOperand(2);
16954 EVT VT =
N->getValueType(0);
16961 const unsigned Opcode =
N->op_begin()->getNode()->getOpcode();
16976 if (
Op.isUndef()) {
16989 if (
Op.getOpcode() != Opcode || !
Op.hasOneUse())
16993 if (!isa<ConstantSDNode>(
Op.getOperand(1)) &&
16994 !isa<ConstantFPSDNode>(
Op.getOperand(1)))
16998 if (
Op.getOperand(0).getValueType() !=
Op.getOperand(1).getValueType())
17026 const unsigned InVecOpcode = InVec->
getOpcode();
17036 if (!isa<ConstantSDNode>(InValRHS) && !isa<ConstantFPSDNode>(InValRHS))
17043 InVecLHS, InValLHS, EltNo);
17045 InVecRHS, InValRHS, EltNo);
17054 auto *IndexC = dyn_cast<ConstantSDNode>(EltNo);
17057 unsigned Elt = IndexC->getZExtValue();
17065 unsigned ConcatOpIdx = Elt / ConcatNumElts;
17068 ConcatOp, InVal, NewIdx);
17072 ConcatOps[ConcatOpIdx] = ConcatOp;
17084 EVT VT =
N->getValueType(0);
17094 auto *BaseLd = dyn_cast<LoadSDNode>(
N->getOperand(0));
17096 !
SDValue(BaseLd, 0).hasOneUse())
17099 EVT BaseLdVT = BaseLd->getValueType(0);
17106 auto *Ld = dyn_cast<LoadSDNode>(
Op);
17107 if (!Ld || !Ld->isSimple() || !
Op.hasOneUse() ||
17109 Ld->getValueType(0) != BaseLdVT)
17118 using PtrDiff = std::pair<std::variant<int64_t, SDValue>,
bool>;
17120 LoadSDNode *Ld2) -> std::optional<PtrDiff> {
17125 if (BIO1.equalBaseIndex(BIO2, DAG))
17130 SDValue P2 = Ld2->getBasePtr();
17133 if (P1.getOpcode() ==
ISD::ADD && P1.getOperand(0) == P2)
17134 return {{P1.getOperand(1),
true}};
17136 return std::nullopt;
17140 auto BaseDiff = GetPtrDiff(Lds[0], Lds[1]);
17145 for (
auto *It = Lds.
begin() + 1; It != Lds.
end() - 1; It++)
17146 if (GetPtrDiff(*It, *std::next(It)) != BaseDiff)
17154 unsigned WideScalarBitWidth =
17167 auto [StrideVariant, MustNegateStride] = *BaseDiff;
17169 std::holds_alternative<SDValue>(StrideVariant)
17170 ? std::get<SDValue>(StrideVariant)
17173 if (MustNegateStride)
17181 if (
auto *ConstStride = dyn_cast<ConstantSDNode>(Stride);
17182 ConstStride && ConstStride->getSExtValue() >= 0)
17186 ConstStride->getSExtValue() * (
N->getNumOperands() - 1);
17192 BaseLd->getPointerInfo(), BaseLd->getMemOperand()->getFlags(), MemSize,
17196 WideVecVT,
DL, BaseLd->getChain(), BaseLd->getBasePtr(), Stride,
17210 EVT VT =
N->getValueType(0);
17222 SDValue Sub = SwapCC ? V1 : V2;
17227 for (
int MaskIndex : Mask) {
17228 bool SelectMaskVal = (MaskIndex < (int)NumElts);
17231 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
17269 if (
N->getValueType(0).isFixedLengthVector())
17272 SDValue Addend =
N->getOperand(0);
17276 SDValue AddPassthruOp =
N->getOperand(2);
17277 if (!AddPassthruOp.
isUndef())
17281 auto IsVWMulOpc = [](
unsigned Opc) {
17300 if (!MulPassthruOp.
isUndef())
17310 return std::make_pair(
N->getOperand(3),
N->getOperand(4));
17311 }(
N, DAG, Subtarget);
17316 if (AddMask != MulMask || AddVL != MulVL)
17321 "Unexpected opcode after VWMACC_VL");
17323 "Unexpected opcode after VWMACC_VL!");
17325 "Unexpected opcode after VWMUL_VL!");
17327 "Unexpected opcode after VWMUL_VL!");
17330 EVT VT =
N->getValueType(0);
17346 const EVT IndexVT = Index.getValueType();
17350 if (!isIndexTypeSigned(IndexType))
17382 for (
unsigned i = 0; i < Index->getNumOperands(); i++) {
17385 if (Index->getOperand(i)->isUndef())
17387 uint64_t C = Index->getConstantOperandVal(i);
17388 if (
C % ElementSize != 0)
17390 C =
C / ElementSize;
17394 ActiveLanes.
set(
C);
17396 return ActiveLanes.
all();
17414 if (NumElems % 2 != 0)
17418 const unsigned WiderElementSize = ElementSize * 2;
17419 if (WiderElementSize > ST.getELen()/8)
17422 if (!ST.enableUnalignedVectorMem() && BaseAlign < WiderElementSize)
17425 for (
unsigned i = 0; i < Index->getNumOperands(); i++) {
17428 if (Index->getOperand(i)->isUndef())
17432 uint64_t C = Index->getConstantOperandVal(i);
17434 if (
C % WiderElementSize != 0)
17439 if (
C !=
Last + ElementSize)
17456 (isa<RegisterSDNode>(VL) &&
17457 cast<RegisterSDNode>(VL)->getReg() == RISCV::X0);
17459 Mask.getOperand(0) != VL)
17462 auto IsTruncNode = [&](
SDValue V) {
17464 V.getOperand(1) == Mask && V.getOperand(2) == VL;
17471 while (IsTruncNode(
Op)) {
17472 if (!
Op.hasOneUse())
17474 Op =
Op.getOperand(0);
17509 MVT VT =
N->getSimpleValueType(0);
17514 auto MatchMinMax = [&VL, &Mask](
SDValue V,
unsigned Opc,
unsigned OpcVL,
17516 if (V.getOpcode() != Opc &&
17517 !(V.getOpcode() == OpcVL && V.getOperand(2).isUndef() &&
17518 V.getOperand(3) == Mask && V.getOperand(4) == VL))
17526 Op.getOperand(1).getValueType().isFixedLengthVector() &&
17528 Op.getOperand(1).getOperand(0).getValueType() ==
Op.getValueType() &&
17530 Op =
Op.getOperand(1).getOperand(0);
17533 return V.getOperand(0);
17536 Op.getOperand(2) == VL) {
17537 if (
auto *Op1 = dyn_cast<ConstantSDNode>(
Op.getOperand(1))) {
17539 Op1->getAPIntValue().sextOrTrunc(
Op.getScalarValueSizeInBits());
17540 return V.getOperand(0);
17549 auto DetectUSatPattern = [&](
SDValue V) {
17574 V.getOperand(1), DAG.
getUNDEF(V.getValueType()),
17580 auto DetectSSatPattern = [&](
SDValue V) {
17582 unsigned NumSrcBits = V.getScalarValueSizeInBits();
17590 if (HiC == SignedMax && LoC == SignedMin)
17596 if (HiC == SignedMax && LoC == SignedMin)
17606 Src.getOperand(1) == Mask && Src.getOperand(2) == VL &&
17608 Src = Src.getOperand(0);
17612 if ((Val = DetectUSatPattern(Src)))
17614 else if ((Val = DetectSSatPattern(Src)))
17624 Val = DAG.
getNode(ClipOpc,
DL, ValVT, Val, Mask, VL);
17625 }
while (ValVT != VT);
17639 EVT VT =
N->getValueType(0);
17647 Src = Src.getOperand(0);
17652 Src = Src.getOperand(0);
17653 EVT SrcEVT = Src.getValueType();
17685 auto SimplifyDemandedLowBitsHelper = [&](
unsigned OpNo,
unsigned LowBits) {
17696 switch (
N->getOpcode()) {
17716 APInt V =
C->getValueAPF().bitcastToAPInt();
17751 if (SimplifyDemandedLowBitsHelper(0, 32) ||
17752 SimplifyDemandedLowBitsHelper(1, 5))
17760 if (SimplifyDemandedLowBitsHelper(0, 32))
17777 MVT VT =
N->getSimpleValueType(0);
17780 if (
auto *CFP = dyn_cast<ConstantFPSDNode>(Op0)) {
17793 "Unexpected value type!");
17798 cast<LoadSDNode>(Op0)->isSimple()) {
17800 auto *LN0 = cast<LoadSDNode>(Op0);
17803 LN0->getBasePtr(), IVT, LN0->getMemOperand());
17827 EVT VT =
N->getValueType(0);
17880 if (!
C || !
C->getValueAPF().isExactlyValue(+1.0))
17882 EVT VT =
N->getValueType(0);
17911 if (
N->getValueType(0) == MVT::i64 && Subtarget.
is64Bit()) {
17916 Src.getOperand(0));
17921 Src.getOperand(0), Src.getOperand(1));
17944 unsigned Opc =
N->getOpcode();
17959 return DAG.
getNode(InvOpc,
SDLoc(
N),
N->getValueType(0), Val, NewCond);
17969 N->getValueType(0), Val,
Cond.getOperand(0));
17980 SDValue FalseV =
N->getOperand(4);
17982 EVT VT =
N->getValueType(0);
17985 if (TrueV == FalseV)
17990 if (!Subtarget.hasShortForwardBranchOpt() && isa<ConstantSDNode>(TrueV) &&
17996 int64_t TrueSImm = cast<ConstantSDNode>(TrueV)->getSExtValue();
17997 int64_t FalseSImm = cast<ConstantSDNode>(FalseV)->getSExtValue();
18000 if (isInt<12>(TrueSImm) && isInt<12>(FalseSImm) &&
18001 isInt<12>(TrueSImm - FalseSImm)) {
18017 {LHS, RHS, CC, TrueV, FalseV});
18084 N->getOperand(0),
LHS,
RHS,
CC,
N->getOperand(4));
18097 EVT VT =
N->getValueType(0);
18121 const auto *MGN = cast<MaskedGatherSDNode>(
N);
18122 const EVT VT =
N->getValueType(0);
18123 SDValue Index = MGN->getIndex();
18124 SDValue ScaleOp = MGN->getScale();
18126 assert(!MGN->isIndexScaled() &&
18127 "Scaled gather/scatter should not be formed");
18132 N->getVTList(), MGN->getMemoryVT(),
DL,
18133 {MGN->getChain(), MGN->getPassThru(), MGN->getMask(),
18134 MGN->getBasePtr(), Index, ScaleOp},
18135 MGN->getMemOperand(), IndexType, MGN->getExtensionType());
18139 N->getVTList(), MGN->getMemoryVT(),
DL,
18140 {MGN->getChain(), MGN->getPassThru(), MGN->getMask(),
18141 MGN->getBasePtr(), Index, ScaleOp},
18142 MGN->getMemOperand(), IndexType, MGN->getExtensionType());
18148 if (std::optional<VIDSequence> SimpleVID =
18150 SimpleVID && SimpleVID->StepDenominator == 1) {
18151 const int64_t StepNumerator = SimpleVID->StepNumerator;
18152 const int64_t Addend = SimpleVID->Addend;
18159 assert(MGN->getBasePtr()->getValueType(0) == PtrVT);
18167 VT,
DL, MGN->getChain(), BasePtr,
18169 EVL, MGN->getMemOperand());
18171 StridedLoad, MGN->getPassThru(), EVL);
18181 MGN->getBasePtr(), DAG.
getUNDEF(XLenVT),
18183 MGN->getMemoryVT(), MGN->getMemOperand(),
18192 MGN->getMemOperand()->getBaseAlign(), Subtarget)) {
18194 for (
unsigned i = 0; i < Index->getNumOperands(); i += 2)
18195 NewIndices.
push_back(Index.getOperand(i));
18196 EVT IndexVT = Index.getValueType()
18197 .getHalfNumVectorElementsVT(*DAG.
getContext());
18203 assert(EltCnt.isKnownEven() &&
"Splitting vector, but not in half!");
18205 EltCnt.divideCoefficientBy(2));
18208 EltCnt.divideCoefficientBy(2));
18213 {MGN->getChain(), Passthru, Mask, MGN->getBasePtr(),
18222 const auto *MSN = cast<MaskedScatterSDNode>(
N);
18223 SDValue Index = MSN->getIndex();
18224 SDValue ScaleOp = MSN->getScale();
18226 assert(!MSN->isIndexScaled() &&
18227 "Scaled gather/scatter should not be formed");
18232 N->getVTList(), MSN->getMemoryVT(),
DL,
18233 {MSN->getChain(), MSN->getValue(), MSN->getMask(), MSN->getBasePtr(),
18235 MSN->getMemOperand(), IndexType, MSN->isTruncatingStore());
18239 N->getVTList(), MSN->getMemoryVT(),
DL,
18240 {MSN->getChain(), MSN->getValue(), MSN->getMask(), MSN->getBasePtr(),
18242 MSN->getMemOperand(), IndexType, MSN->isTruncatingStore());
18244 EVT VT = MSN->getValue()->getValueType(0);
18246 if (!MSN->isTruncatingStore() &&
18250 return DAG.
getMaskedStore(MSN->getChain(),
DL, Shuffle, MSN->getBasePtr(),
18251 DAG.
getUNDEF(XLenVT), MSN->getMask(),
18252 MSN->getMemoryVT(), MSN->getMemOperand(),
18257 case ISD::VP_GATHER: {
18258 const auto *VPGN = cast<VPGatherSDNode>(
N);
18259 SDValue Index = VPGN->getIndex();
18260 SDValue ScaleOp = VPGN->getScale();
18262 assert(!VPGN->isIndexScaled() &&
18263 "Scaled gather/scatter should not be formed");
18268 {VPGN->getChain(), VPGN->getBasePtr(), Index,
18269 ScaleOp, VPGN->getMask(),
18270 VPGN->getVectorLength()},
18271 VPGN->getMemOperand(), IndexType);
18275 {VPGN->getChain(), VPGN->getBasePtr(), Index,
18276 ScaleOp, VPGN->getMask(),
18277 VPGN->getVectorLength()},
18278 VPGN->getMemOperand(), IndexType);
18282 case ISD::VP_SCATTER: {
18283 const auto *VPSN = cast<VPScatterSDNode>(
N);
18284 SDValue Index = VPSN->getIndex();
18285 SDValue ScaleOp = VPSN->getScale();
18287 assert(!VPSN->isIndexScaled() &&
18288 "Scaled gather/scatter should not be formed");
18293 {VPSN->getChain(), VPSN->getValue(),
18294 VPSN->getBasePtr(), Index, ScaleOp,
18295 VPSN->getMask(), VPSN->getVectorLength()},
18296 VPSN->getMemOperand(), IndexType);
18300 {VPSN->getChain(), VPSN->getValue(),
18301 VPSN->getBasePtr(), Index, ScaleOp,
18302 VPSN->getMask(), VPSN->getVectorLength()},
18303 VPSN->getMemOperand(), IndexType);
18317 EVT VT =
N->getValueType(0);
18320 return DAG.
getNode(
N->getOpcode(),
DL, VT,
N->getOperand(0), ShAmt,
18321 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
18339 EVT VT =
N->getValueType(0);
18343 return DAG.
getNode(
N->getOpcode(),
DL, VT,
N->getOperand(0), ShAmt);
18383 auto *Store = cast<StoreSDNode>(
N);
18384 SDValue Chain = Store->getChain();
18385 EVT MemVT = Store->getMemoryVT();
18386 SDValue Val = Store->getValue();
18389 bool IsScalarizable =
18391 Store->isSimple() &&
18421 NewVT, *Store->getMemOperand())) {
18423 return DAG.
getStore(Chain,
DL, NewV, Store->getBasePtr(),
18424 Store->getPointerInfo(), Store->getOriginalAlign(),
18425 Store->getMemOperand()->getFlags());
18433 if (
auto *L = dyn_cast<LoadSDNode>(Val);
18435 L->hasNUsesOfValue(1, 0) && L->hasNUsesOfValue(1, 1) &&
18437 L->getMemoryVT() == MemVT) {
18440 NewVT, *Store->getMemOperand()) &&
18442 NewVT, *L->getMemOperand())) {
18444 L->getPointerInfo(), L->getOriginalAlign(),
18445 L->getMemOperand()->getFlags());
18446 return DAG.
getStore(Chain,
DL, NewL, Store->getBasePtr(),
18447 Store->getPointerInfo(), Store->getOriginalAlign(),
18448 Store->getMemOperand()->getFlags());
18460 MVT VecVT = Src.getSimpleValueType();
18467 Store->getChain(),
DL, Src, Store->getBasePtr(), Store->getOffset(),
18470 Store->getMemOperand(), Store->getAddressingMode(),
18471 Store->isTruncatingStore(),
false);
18478 EVT VT =
N->getValueType(0);
18504 const MVT VT =
N->getSimpleValueType(0);
18505 SDValue Passthru =
N->getOperand(0);
18506 SDValue Scalar =
N->getOperand(1);
18515 const MVT VT =
N->getSimpleValueType(0);
18516 SDValue Passthru =
N->getOperand(0);
18517 SDValue Scalar =
N->getOperand(1);
18522 unsigned ScalarSize = Scalar.getValueSizeInBits();
18524 if (ScalarSize > EltWidth && Passthru.
isUndef())
18525 if (SimplifyDemandedLowBitsHelper(1, EltWidth))
18532 (!Const || Const->isZero() ||
18533 !Const->getAPIntValue().sextOrTrunc(EltWidth).isSignedIntN(5)))
18543 if (
N->getOperand(0).isUndef() &&
18546 Src.getOperand(0).getValueType().isScalableVector()) {
18547 EVT VT =
N->getValueType(0);
18548 EVT SrcVT = Src.getOperand(0).getValueType();
18552 return Src.getOperand(0);
18558 const MVT VT =
N->getSimpleValueType(0);
18559 SDValue Passthru =
N->getOperand(0);
18560 SDValue Scalar =
N->getOperand(1);
18564 Scalar.getOperand(0).getValueType() ==
N->getValueType(0))
18565 return Scalar.getOperand(0);
18574 DAG.
getNode(
N->getOpcode(),
DL, M1VT, M1Passthru, Scalar, VL);
18584 Const && !Const->isZero() && isInt<5>(Const->getSExtValue()) &&
18592 MVT VecVT =
N->getOperand(0).getSimpleValueType();
18594 if (M1VT.
bitsLT(VecVT)) {
18605 unsigned IntNo =
N->getConstantOperandVal(IntOpNo);
18610 case Intrinsic::riscv_vcpop:
18611 case Intrinsic::riscv_vcpop_mask:
18612 case Intrinsic::riscv_vfirst:
18613 case Intrinsic::riscv_vfirst_mask: {
18615 if (IntNo == Intrinsic::riscv_vcpop_mask ||
18616 IntNo == Intrinsic::riscv_vfirst_mask)
18617 VL =
N->getOperand(3);
18622 EVT VT =
N->getValueType(0);
18623 if (IntNo == Intrinsic::riscv_vfirst ||
18624 IntNo == Intrinsic::riscv_vfirst_mask)
18630 case ISD::EXPERIMENTAL_VP_REVERSE:
18632 case ISD::VP_STORE:
18637 EVT VT =
N->getValueType(0);
18648 for (
unsigned i = 0; i < NF; ++i)
18655 if ((SrcVT == MVT::v1i1 || SrcVT == MVT::v2i1 || SrcVT == MVT::v4i1) &&
18678 EVT XVT,
unsigned KeptBits)
const {
18683 if (XVT != MVT::i32 && XVT != MVT::i64)
18687 if (KeptBits == 32 || KeptBits == 64)
18691 return Subtarget.hasStdExtZbb() &&
18692 ((KeptBits == 8 && XVT == MVT::i64 && !Subtarget.
is64Bit()) ||
18700 "Expected shift op");
18718 if (!isa<StoreSDNode>(
Use) && !isa<LoadSDNode>(
Use))
18727 return isUsedByLdSt(N0.
getNode(),
N);
18729 auto *C1 = dyn_cast<ConstantSDNode>(N0->
getOperand(1));
18730 auto *C2 = dyn_cast<ConstantSDNode>(
N->getOperand(1));
18733 if (Subtarget.hasStdExtZba() && C2 && C2->getZExtValue() >= 1 &&
18734 C2->getZExtValue() <= 3 &&
N->hasOneUse() &&
18735 N->user_begin()->getOpcode() ==
ISD::ADD &&
18736 !isUsedByLdSt(*
N->user_begin(),
nullptr) &&
18737 !isa<ConstantSDNode>(
N->user_begin()->getOperand(1)))
18741 const APInt &C1Int = C1->getAPIntValue();
18742 APInt ShiftedC1Int = C1Int << C2->getAPIntValue();
18768 if (C1Cost < ShiftedC1Cost)
18791 EVT VT =
Op.getValueType();
18795 unsigned Opcode =
Op.getOpcode();
18803 const APInt &Mask =
C->getAPIntValue();
18812 auto IsLegalMask = [ShrunkMask, ExpandedMask](
const APInt &Mask) ->
bool {
18813 return ShrunkMask.
isSubsetOf(Mask) && Mask.isSubsetOf(ExpandedMask);
18815 auto UseMask = [Mask,
Op, &TLO](
const APInt &NewMask) ->
bool {
18816 if (NewMask == Mask)
18821 Op.getOperand(0), NewC);
18834 APInt NewMask =
APInt(Mask.getBitWidth(), 0xffff);
18835 if (IsLegalMask(NewMask))
18836 return UseMask(NewMask);
18839 if (VT == MVT::i64) {
18841 if (IsLegalMask(NewMask))
18842 return UseMask(NewMask);
18857 APInt NewMask = ShrunkMask;
18858 if (MinSignedBits <= 12)
18860 else if (!
C->isOpaque() && MinSignedBits <= 32 && !ShrunkMask.
isSignedIntN(32))
18866 assert(IsLegalMask(NewMask));
18867 return UseMask(NewMask);
18871 static const uint64_t GREVMasks[] = {
18872 0x5555555555555555ULL, 0x3333333333333333ULL, 0x0F0F0F0F0F0F0F0FULL,
18873 0x00FF00FF00FF00FFULL, 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL};
18875 for (
unsigned Stage = 0; Stage != 6; ++Stage) {
18876 unsigned Shift = 1 << Stage;
18877 if (ShAmt & Shift) {
18879 uint64_t Res = ((x & Mask) << Shift) | ((x >> Shift) & Mask);
18891 const APInt &DemandedElts,
18893 unsigned Depth)
const {
18895 unsigned Opc =
Op.getOpcode();
18900 "Should use MaskedValueIsZero if you don't know whether Op"
18901 " is a target node!");
18984 assert(MinVLenB > 0 &&
"READ_VLENB without vector extension enabled?");
18987 if (MaxVLenB == MinVLenB)
19004 case Intrinsic::riscv_vsetvli:
19005 case Intrinsic::riscv_vsetvlimax: {
19006 bool HasAVL = IntNo == Intrinsic::riscv_vsetvli;
19007 unsigned VSEW =
Op.getConstantOperandVal(HasAVL + 1);
19013 MaxVL = (Fractional) ? MaxVL / LMul : MaxVL * LMul;
19016 if (HasAVL && isa<ConstantSDNode>(
Op.getOperand(1)))
19017 MaxVL = std::min(MaxVL,
Op.getConstantOperandVal(1));
19019 unsigned KnownZeroFirstBit =
Log2_32(MaxVL) + 1;
19032 unsigned Depth)
const {
19033 switch (
Op.getOpcode()) {
19039 if (Tmp == 1)
return 1;
19042 return std::min(Tmp, Tmp2);
19054 if (Tmp < 33)
return 1;
19079 unsigned XLen = Subtarget.
getXLen();
19080 unsigned EltBits =
Op.getOperand(0).getScalarValueSizeInBits();
19081 if (EltBits <= XLen)
19082 return XLen - EltBits + 1;
19086 unsigned IntNo =
Op.getConstantOperandVal(1);
19090 case Intrinsic::riscv_masked_atomicrmw_xchg_i64:
19091 case Intrinsic::riscv_masked_atomicrmw_add_i64:
19092 case Intrinsic::riscv_masked_atomicrmw_sub_i64:
19093 case Intrinsic::riscv_masked_atomicrmw_nand_i64:
19094 case Intrinsic::riscv_masked_atomicrmw_max_i64:
19095 case Intrinsic::riscv_masked_atomicrmw_min_i64:
19096 case Intrinsic::riscv_masked_atomicrmw_umax_i64:
19097 case Intrinsic::riscv_masked_atomicrmw_umin_i64:
19098 case Intrinsic::riscv_masked_cmpxchg_i64:
19106 assert(Subtarget.hasStdExtA());
19121 switch (
Op.getOpcode()) {
19127 return !
Op.getValueType().isInteger();
19135 assert(Ld &&
"Unexpected null LoadSDNode");
19143 auto *CNode = dyn_cast<ConstantPoolSDNode>(
Ptr);
19144 if (!CNode || CNode->isMachineConstantPoolEntry() ||
19145 CNode->getOffset() != 0)
19153 auto *CNode = GetSupportedConstantPool(
Ptr);
19154 if (!CNode || CNode->getTargetFlags() != 0)
19157 return CNode->getConstVal();
19165 auto *CNodeLo = GetSupportedConstantPool(
Ptr.getOperand(1));
19166 auto *CNodeHi = GetSupportedConstantPool(
Ptr.getOperand(0).getOperand(0));
19172 if (CNodeLo->getConstVal() != CNodeHi->getConstVal())
19175 return CNodeLo->getConstVal();
19180 assert(
MI.getOpcode() == RISCV::ReadCounterWide &&
"Unexpected instruction");
19212 Register ReadAgainReg =
RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
19215 int64_t LoCounter =
MI.getOperand(2).getImm();
19216 int64_t HiCounter =
MI.getOperand(3).getImm();
19226 BuildMI(LoopMBB,
DL,
TII->get(RISCV::CSRRS), ReadAgainReg)
19238 MI.eraseFromParent();
19246 assert(
MI.getOpcode() == RISCV::SplitF64Pseudo &&
"Unexpected instruction");
19254 Register SrcReg =
MI.getOperand(2).getReg();
19274 MI.eraseFromParent();
19281 assert(
MI.getOpcode() == RISCV::BuildPairF64Pseudo &&
19282 "Unexpected instruction");
19288 Register DstReg =
MI.getOperand(0).getReg();
19311 MI.eraseFromParent();
19316 switch (
MI.getOpcode()) {
19319 case RISCV::Select_GPR_Using_CC_GPR:
19320 case RISCV::Select_GPR_Using_CC_Imm:
19321 case RISCV::Select_FPR16_Using_CC_GPR:
19322 case RISCV::Select_FPR16INX_Using_CC_GPR:
19323 case RISCV::Select_FPR32_Using_CC_GPR:
19324 case RISCV::Select_FPR32INX_Using_CC_GPR:
19325 case RISCV::Select_FPR64_Using_CC_GPR:
19326 case RISCV::Select_FPR64INX_Using_CC_GPR:
19327 case RISCV::Select_FPR64IN32X_Using_CC_GPR:
19333 unsigned RelOpcode,
unsigned EqOpcode,
19336 Register DstReg =
MI.getOperand(0).getReg();
19337 Register Src1Reg =
MI.getOperand(1).getReg();
19338 Register Src2Reg =
MI.getOperand(2).getReg();
19340 Register SavedFFlags =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
19364 MI.eraseFromParent();
19415 F->insert(It, FirstMBB);
19416 F->insert(It, SecondMBB);
19417 F->insert(It, SinkMBB);
19466 First.eraseFromParent();
19505 if ((
MI.getOpcode() != RISCV::Select_GPR_Using_CC_GPR &&
19506 MI.getOpcode() != RISCV::Select_GPR_Using_CC_Imm) &&
19507 Next != BB->
end() && Next->getOpcode() ==
MI.getOpcode() &&
19508 Next->getOperand(5).getReg() ==
MI.getOperand(0).getReg() &&
19509 Next->getOperand(5).isKill())
19514 if (
MI.getOperand(2).isReg())
19515 RHS =
MI.getOperand(2).getReg();
19520 SelectDests.
insert(
MI.getOperand(0).getReg());
19524 SequenceMBBI != E; ++SequenceMBBI) {
19525 if (SequenceMBBI->isDebugInstr())
19528 if (SequenceMBBI->getOperand(1).getReg() !=
LHS ||
19529 !SequenceMBBI->getOperand(2).isReg() ||
19530 SequenceMBBI->getOperand(2).getReg() !=
RHS ||
19531 SequenceMBBI->getOperand(3).getImm() !=
CC ||
19532 SelectDests.
count(SequenceMBBI->getOperand(4).getReg()) ||
19533 SelectDests.
count(SequenceMBBI->getOperand(5).getReg()))
19535 LastSelectPseudo = &*SequenceMBBI;
19537 SelectDests.
insert(SequenceMBBI->getOperand(0).getReg());
19540 if (SequenceMBBI->hasUnmodeledSideEffects() ||
19541 SequenceMBBI->mayLoadOrStore() ||
19542 SequenceMBBI->usesCustomInsertionHook())
19545 return MO.isReg() && MO.isUse() && SelectDests.count(MO.getReg());
19560 F->insert(
I, IfFalseMBB);
19561 F->insert(
I, TailMBB);
19564 unsigned CallFrameSize =
TII.getCallFrameSizeAt(*LastSelectPseudo);
19570 TailMBB->
push_back(DebugInstr->removeFromParent());
19574 TailMBB->
splice(TailMBB->
end(), HeadMBB,
19584 if (
MI.getOperand(2).isImm())
19587 .
addImm(
MI.getOperand(2).getImm())
19599 auto SelectMBBI =
MI.getIterator();
19600 auto SelectEnd = std::next(LastSelectPseudo->
getIterator());
19602 while (SelectMBBI != SelectEnd) {
19603 auto Next = std::next(SelectMBBI);
19607 TII.get(RISCV::PHI), SelectMBBI->getOperand(0).getReg())
19608 .
addReg(SelectMBBI->getOperand(4).getReg())
19610 .
addReg(SelectMBBI->getOperand(5).getReg())
19625 RISCVVInversePseudosTable::getBaseInfo(MCOpcode, LMul, SEW);
19626 assert(
Inverse &&
"Unexpected LMUL and SEW pair for instruction");
19628 RISCV::lookupMaskedIntrinsicByUnmasked(
Inverse->Pseudo);
19629 assert(
Masked &&
"Could not find masked instruction for LMUL and SEW pair");
19635 unsigned CVTXOpc) {
19641 Register SavedFFLAGS =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
19654 .
add(
MI.getOperand(1))
19655 .
add(
MI.getOperand(2))
19656 .
add(
MI.getOperand(3))
19658 .
add(
MI.getOperand(4))
19659 .
add(
MI.getOperand(5))
19660 .
add(
MI.getOperand(6))
19675 .
add(
MI.getOperand(0))
19676 .
add(
MI.getOperand(1))
19678 .
add(
MI.getOperand(3))
19680 .
add(
MI.getOperand(4))
19681 .
add(
MI.getOperand(5))
19682 .
add(
MI.getOperand(6))
19692 MI.eraseFromParent();
19698 unsigned CmpOpc, F2IOpc, I2FOpc, FSGNJOpc, FSGNJXOpc;
19700 switch (
MI.getOpcode()) {
19703 case RISCV::PseudoFROUND_H:
19704 CmpOpc = RISCV::FLT_H;
19705 F2IOpc = RISCV::FCVT_W_H;
19706 I2FOpc = RISCV::FCVT_H_W;
19707 FSGNJOpc = RISCV::FSGNJ_H;
19708 FSGNJXOpc = RISCV::FSGNJX_H;
19709 RC = &RISCV::FPR16RegClass;
19711 case RISCV::PseudoFROUND_H_INX:
19712 CmpOpc = RISCV::FLT_H_INX;
19713 F2IOpc = RISCV::FCVT_W_H_INX;
19714 I2FOpc = RISCV::FCVT_H_W_INX;
19715 FSGNJOpc = RISCV::FSGNJ_H_INX;
19716 FSGNJXOpc = RISCV::FSGNJX_H_INX;
19717 RC = &RISCV::GPRF16RegClass;
19719 case RISCV::PseudoFROUND_S:
19720 CmpOpc = RISCV::FLT_S;
19721 F2IOpc = RISCV::FCVT_W_S;
19722 I2FOpc = RISCV::FCVT_S_W;
19723 FSGNJOpc = RISCV::FSGNJ_S;
19724 FSGNJXOpc = RISCV::FSGNJX_S;
19725 RC = &RISCV::FPR32RegClass;
19727 case RISCV::PseudoFROUND_S_INX:
19728 CmpOpc = RISCV::FLT_S_INX;
19729 F2IOpc = RISCV::FCVT_W_S_INX;
19730 I2FOpc = RISCV::FCVT_S_W_INX;
19731 FSGNJOpc = RISCV::FSGNJ_S_INX;
19732 FSGNJXOpc = RISCV::FSGNJX_S_INX;
19733 RC = &RISCV::GPRF32RegClass;
19735 case RISCV::PseudoFROUND_D:
19737 CmpOpc = RISCV::FLT_D;
19738 F2IOpc = RISCV::FCVT_L_D;
19739 I2FOpc = RISCV::FCVT_D_L;
19740 FSGNJOpc = RISCV::FSGNJ_D;
19741 FSGNJXOpc = RISCV::FSGNJX_D;
19742 RC = &RISCV::FPR64RegClass;
19744 case RISCV::PseudoFROUND_D_INX:
19746 CmpOpc = RISCV::FLT_D_INX;
19747 F2IOpc = RISCV::FCVT_L_D_INX;
19748 I2FOpc = RISCV::FCVT_D_L_INX;
19749 FSGNJOpc = RISCV::FSGNJ_D_INX;
19750 FSGNJXOpc = RISCV::FSGNJX_D_INX;
19751 RC = &RISCV::GPRRegClass;
19763 F->insert(
I, CvtMBB);
19764 F->insert(
I, DoneMBB);
19775 Register DstReg =
MI.getOperand(0).getReg();
19776 Register SrcReg =
MI.getOperand(1).getReg();
19777 Register MaxReg =
MI.getOperand(2).getReg();
19778 int64_t FRM =
MI.getOperand(3).getImm();
19783 Register FabsReg =
MRI.createVirtualRegister(RC);
19787 Register CmpReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
19802 Register F2IReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
19824 MI.eraseFromParent();
19831 switch (
MI.getOpcode()) {
19834 case RISCV::ReadCounterWide:
19836 "ReadCounterWide is only to be used on riscv32");
19838 case RISCV::Select_GPR_Using_CC_GPR:
19839 case RISCV::Select_GPR_Using_CC_Imm:
19840 case RISCV::Select_FPR16_Using_CC_GPR:
19841 case RISCV::Select_FPR16INX_Using_CC_GPR:
19842 case RISCV::Select_FPR32_Using_CC_GPR:
19843 case RISCV::Select_FPR32INX_Using_CC_GPR:
19844 case RISCV::Select_FPR64_Using_CC_GPR:
19845 case RISCV::Select_FPR64INX_Using_CC_GPR:
19846 case RISCV::Select_FPR64IN32X_Using_CC_GPR:
19848 case RISCV::BuildPairF64Pseudo:
19850 case RISCV::SplitF64Pseudo:
19852 case RISCV::PseudoQuietFLE_H:
19854 case RISCV::PseudoQuietFLE_H_INX:
19855 return emitQuietFCMP(
MI, BB, RISCV::FLE_H_INX, RISCV::FEQ_H_INX, Subtarget);
19856 case RISCV::PseudoQuietFLT_H:
19858 case RISCV::PseudoQuietFLT_H_INX:
19859 return emitQuietFCMP(
MI, BB, RISCV::FLT_H_INX, RISCV::FEQ_H_INX, Subtarget);
19860 case RISCV::PseudoQuietFLE_S:
19862 case RISCV::PseudoQuietFLE_S_INX:
19863 return emitQuietFCMP(
MI, BB, RISCV::FLE_S_INX, RISCV::FEQ_S_INX, Subtarget);
19864 case RISCV::PseudoQuietFLT_S:
19866 case RISCV::PseudoQuietFLT_S_INX:
19867 return emitQuietFCMP(
MI, BB, RISCV::FLT_S_INX, RISCV::FEQ_S_INX, Subtarget);
19868 case RISCV::PseudoQuietFLE_D:
19870 case RISCV::PseudoQuietFLE_D_INX:
19871 return emitQuietFCMP(
MI, BB, RISCV::FLE_D_INX, RISCV::FEQ_D_INX, Subtarget);
19872 case RISCV::PseudoQuietFLE_D_IN32X:
19875 case RISCV::PseudoQuietFLT_D:
19877 case RISCV::PseudoQuietFLT_D_INX:
19878 return emitQuietFCMP(
MI, BB, RISCV::FLT_D_INX, RISCV::FEQ_D_INX, Subtarget);
19879 case RISCV::PseudoQuietFLT_D_IN32X:
19883 case RISCV::PseudoVFROUND_NOEXCEPT_V_M1_MASK:
19885 case RISCV::PseudoVFROUND_NOEXCEPT_V_M2_MASK:
19887 case RISCV::PseudoVFROUND_NOEXCEPT_V_M4_MASK:
19889 case RISCV::PseudoVFROUND_NOEXCEPT_V_M8_MASK:
19891 case RISCV::PseudoVFROUND_NOEXCEPT_V_MF2_MASK:
19893 case RISCV::PseudoVFROUND_NOEXCEPT_V_MF4_MASK:
19895 case RISCV::PseudoFROUND_H:
19896 case RISCV::PseudoFROUND_H_INX:
19897 case RISCV::PseudoFROUND_S:
19898 case RISCV::PseudoFROUND_S_INX:
19899 case RISCV::PseudoFROUND_D:
19900 case RISCV::PseudoFROUND_D_INX:
19901 case RISCV::PseudoFROUND_D_IN32X:
19903 case RISCV::PROBED_STACKALLOC_DYN:
19905 case TargetOpcode::STATEPOINT:
19911 MI.addOperand(*
MI.getMF(),
19917 case TargetOpcode::STACKMAP:
19918 case TargetOpcode::PATCHPOINT:
19921 "supported on 64-bit targets");
19939 if (
MI.readsRegister(RISCV::FRM,
nullptr))
19945void RISCVTargetLowering::analyzeInputArgs(
19949 unsigned NumArgs = Ins.size();
19952 for (
unsigned i = 0; i != NumArgs; ++i) {
19953 MVT ArgVT = Ins[i].VT;
19956 Type *ArgTy =
nullptr;
19959 else if (Ins[i].isOrigArg())
19960 ArgTy = FType->
getParamType(Ins[i].getOrigArgIndex());
19963 true, IsRet, ArgTy)) {
19964 LLVM_DEBUG(
dbgs() <<
"InputArg #" << i <<
" has unhandled type "
19971void RISCVTargetLowering::analyzeOutputArgs(
19975 unsigned NumArgs = Outs.
size();
19977 for (
unsigned i = 0; i != NumArgs; i++) {
19978 MVT ArgVT = Outs[i].VT;
19980 Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty :
nullptr;
19983 Outs[i].IsFixed, IsRet, OrigTy)) {
19984 LLVM_DEBUG(
dbgs() <<
"OutputArg #" << i <<
" has unhandled type "
20035 if (In.isOrigArg()) {
20040 if ((
BitWidth <= 32 && In.Flags.isSExt()) ||
20041 (
BitWidth < 32 && In.Flags.isZExt())) {
20063 if (LocVT == MVT::i64 && VA.
getValVT() == MVT::f32)
20112 ExtType,
DL, LocVT, Chain, FIN,
20129 Register LoVReg =
RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
20142 Register HiVReg =
RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
20157 switch (CallConv) {
20167 if (Subtarget.hasStdExtE())
20171 "(Zdinx/D) instruction set extensions");
20175 if (Func.hasFnAttribute(
"interrupt")) {
20176 if (!Func.arg_empty())
20178 "Functions with the interrupt attribute cannot have arguments!");
20183 if (!(Kind ==
"user" || Kind ==
"supervisor" || Kind ==
"machine"))
20185 "Function interrupt attribute argument not supported!");
20190 unsigned XLenInBytes = Subtarget.
getXLen() / 8;
20192 std::vector<SDValue> OutChains;
20201 analyzeInputArgs(MF, CCInfo, Ins,
false,
20205 for (
unsigned i = 0, e = ArgLocs.
size(), InsIdx = 0; i != e; ++i, ++InsIdx) {
20226 unsigned ArgIndex = Ins[InsIdx].OrigArgIndex;
20227 unsigned ArgPartOffset = Ins[InsIdx].PartOffset;
20229 while (i + 1 != e && Ins[InsIdx + 1].OrigArgIndex == ArgIndex) {
20231 unsigned PartOffset = Ins[InsIdx + 1].PartOffset - ArgPartOffset;
20260 int VarArgsSaveSize = XLenInBytes * (ArgRegs.
size() -
Idx);
20265 if (VarArgsSaveSize == 0) {
20269 int VaArgOffset = -VarArgsSaveSize;
20277 XLenInBytes, VaArgOffset -
static_cast<int>(XLenInBytes),
true);
20278 VarArgsSaveSize += XLenInBytes;
20285 for (
unsigned I =
Idx;
I < ArgRegs.
size(); ++
I) {
20290 Chain,
DL, ArgValue, FIN,
20292 OutChains.push_back(Store);
20306 if (!OutChains.empty()) {
20307 OutChains.push_back(Chain);
20317bool RISCVTargetLowering::isEligibleForTailCallOptimization(
20321 auto CalleeCC = CLI.CallConv;
20322 auto &Outs = CLI.Outs;
20324 auto CallerCC = Caller.getCallingConv();
20331 if (Caller.hasFnAttribute(
"interrupt"))
20346 for (
auto &VA : ArgLocs)
20352 auto IsCallerStructRet = Caller.hasStructRetAttr();
20353 auto IsCalleeStructRet = Outs.
empty() ?
false : Outs[0].Flags.isSRet();
20354 if (IsCallerStructRet || IsCalleeStructRet)
20359 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
20360 if (CalleeCC != CallerCC) {
20361 const uint32_t *CalleePreserved =
TRI->getCallPreservedMask(MF, CalleeCC);
20362 if (!
TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
20369 for (
auto &Arg : Outs)
20370 if (Arg.Flags.isByVal())
20405 if (Subtarget.hasStdExtE())
20409 analyzeOutputArgs(MF, ArgCCInfo, Outs,
false, &CLI,
20415 IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs);
20421 "site marked musttail");
20428 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
20430 if (!Flags.isByVal())
20434 unsigned Size = Flags.getByValSize();
20435 Align Alignment = Flags.getNonZeroByValAlign();
20442 Chain = DAG.
getMemcpy(Chain,
DL, FIPtr, Arg, SizeNode, Alignment,
20444 false,
nullptr, IsTailCall,
20456 for (
unsigned i = 0, j = 0, e = ArgLocs.
size(), OutIdx = 0; i != e;
20459 SDValue ArgValue = OutVals[OutIdx];
20479 if (!StackPtr.getNode())
20491 RegsToPass.
push_back(std::make_pair(RegHigh,
Hi));
20509 unsigned ArgIndex = Outs[OutIdx].OrigArgIndex;
20510 unsigned ArgPartOffset = Outs[OutIdx].PartOffset;
20516 while (i + 1 != e && Outs[OutIdx + 1].OrigArgIndex == ArgIndex) {
20517 SDValue PartValue = OutVals[OutIdx + 1];
20518 unsigned PartOffset = Outs[OutIdx + 1].PartOffset - ArgPartOffset;
20530 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
20532 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot,
20534 for (
const auto &Part : Parts) {
20535 SDValue PartValue = Part.first;
20536 SDValue PartOffset = Part.second;
20543 ArgValue = SpillSlot;
20549 if (Flags.isByVal())
20550 ArgValue = ByValArgs[j++];
20557 assert(!IsTailCall &&
"Tail call not allowed if stack is used "
20558 "for passing parameters");
20561 if (!StackPtr.getNode())
20575 if (!MemOpChains.
empty())
20581 for (
auto &Reg : RegsToPass) {
20582 Chain = DAG.
getCopyToReg(Chain,
DL, Reg.first, Reg.second, Glue);
20589 validateCCReservedRegs(RegsToPass, MF);
20593 "Return address register required, but has been reserved."});
20598 bool CalleeIsLargeExternalSymbol =
false;
20600 if (
auto *S = dyn_cast<GlobalAddressSDNode>(Callee))
20602 else if (
auto *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
20604 CalleeIsLargeExternalSymbol =
true;
20620 for (
auto &Reg : RegsToPass)
20625 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
20626 assert(Mask &&
"Missing call preserved mask for calling convention");
20634 "Unexpected CFI type for a direct call");
20642 bool NeedSWGuarded =
false;
20644 Subtarget.hasStdExtZicfilp() &&
20646 NeedSWGuarded =
true;
20660 Chain = DAG.
getNode(CallOpc,
DL, NodeTys, Ops);
20673 analyzeInputArgs(MF, RetCCInfo, Ins,
true,
CC_RISCV);
20676 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
20677 auto &VA = RVLocs[i];
20685 if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
20686 assert(VA.needsCustom());
20707 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
20709 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
20710 MVT VT = Outs[i].VT;
20713 true,
true,
nullptr))
20745 for (
unsigned i = 0, e = RVLocs.size(), OutIdx = 0; i < e; ++i, ++OutIdx) {
20746 SDValue Val = OutVals[OutIdx];
20755 DAG.
getVTList(MVT::i32, MVT::i32), Val);
20759 Register RegHi = RVLocs[++i].getLocReg();
20765 "Return value register required, but has been reserved."});
20781 "Return value register required, but has been reserved."});
20803 if (Func.hasFnAttribute(
"interrupt")) {
20804 if (!Func.getReturnType()->isVoidTy())
20806 "Functions with the interrupt attribute must have void return type!");
20812 if (Kind ==
"supervisor")
20818 return DAG.
getNode(RetOpc,
DL, MVT::Other, RetOps);
20821void RISCVTargetLowering::validateCCReservedRegs(
20822 const SmallVectorImpl<std::pair<llvm::Register, llvm::SDValue>> &Regs,
20831 F,
"Argument register required, but has been reserved."});
20837 if (
N->getNumValues() != 1)
20839 if (!
N->hasNUsesOfValue(1, 0))
20842 SDNode *Copy = *
N->user_begin();
20856 if (Copy->getOperand(Copy->getNumOperands() - 1).getValueType() == MVT::Glue)
20860 bool HasRet =
false;
20861 for (
SDNode *Node : Copy->users()) {
20869 Chain = Copy->getOperand(0);
20878#define NODE_NAME_CASE(NODE) \
20879 case RISCVISD::NODE: \
20880 return "RISCVISD::" #NODE;