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()) {
412 if (!Subtarget.hasVendorXTHeadCondMov())
415 static const unsigned FPLegalNodeTypes[] = {
429 static const unsigned FPOpToExpand[] = {
433 static const unsigned FPRndMode[] = {
437 static const unsigned ZfhminZfbfminPromoteOps[] = {
448 if (Subtarget.hasStdExtZfbfmin()) {
471 if (Subtarget.hasStdExtZfa())
498 Subtarget.hasStdExtZfh() && Subtarget.hasStdExtZfa() ?
Legal :
Promote);
540 if (Subtarget.hasStdExtZfa()) {
558 if (Subtarget.hasStdExtZfa()) {
640 if (Subtarget.hasStdExtZicbop()) {
644 if (Subtarget.hasStdExtA()) {
646 if (Subtarget.hasStdExtZabha() && Subtarget.hasStdExtZacas())
650 }
else if (Subtarget.hasForcedAtomics()) {
674 {MVT::i8, MVT::i16},
Custom);
685 static const unsigned IntegerVPOps[] = {
686 ISD::VP_ADD, ISD::VP_SUB, ISD::VP_MUL,
687 ISD::VP_SDIV, ISD::VP_UDIV, ISD::VP_SREM,
688 ISD::VP_UREM, ISD::VP_AND, ISD::VP_OR,
689 ISD::VP_XOR, ISD::VP_SRA, ISD::VP_SRL,
690 ISD::VP_SHL, ISD::VP_REDUCE_ADD, ISD::VP_REDUCE_AND,
691 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR, ISD::VP_REDUCE_SMAX,
692 ISD::VP_REDUCE_SMIN, ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN,
693 ISD::VP_MERGE, ISD::VP_SELECT, ISD::VP_FP_TO_SINT,
694 ISD::VP_FP_TO_UINT, ISD::VP_SETCC, ISD::VP_SIGN_EXTEND,
695 ISD::VP_ZERO_EXTEND, ISD::VP_TRUNCATE, ISD::VP_SMIN,
696 ISD::VP_SMAX, ISD::VP_UMIN, ISD::VP_UMAX,
697 ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE,
698 ISD::VP_SADDSAT, ISD::VP_UADDSAT, ISD::VP_SSUBSAT,
699 ISD::VP_USUBSAT, ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_UNDEF,
700 ISD::EXPERIMENTAL_VP_SPLAT};
702 static const unsigned FloatingPointVPOps[] = {
703 ISD::VP_FADD, ISD::VP_FSUB, ISD::VP_FMUL,
704 ISD::VP_FDIV, ISD::VP_FNEG, ISD::VP_FABS,
705 ISD::VP_FMA, ISD::VP_REDUCE_FADD, ISD::VP_REDUCE_SEQ_FADD,
706 ISD::VP_REDUCE_FMIN, ISD::VP_REDUCE_FMAX, ISD::VP_MERGE,
707 ISD::VP_SELECT, ISD::VP_SINT_TO_FP, ISD::VP_UINT_TO_FP,
708 ISD::VP_SETCC, ISD::VP_FP_ROUND, ISD::VP_FP_EXTEND,
709 ISD::VP_SQRT, ISD::VP_FMINNUM, ISD::VP_FMAXNUM,
710 ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND,
711 ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO,
712 ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS,
713 ISD::VP_FMINIMUM, ISD::VP_FMAXIMUM, ISD::VP_LRINT,
714 ISD::VP_LLRINT, ISD::EXPERIMENTAL_VP_REVERSE,
715 ISD::EXPERIMENTAL_VP_SPLICE, ISD::VP_REDUCE_FMINIMUM,
716 ISD::VP_REDUCE_FMAXIMUM, ISD::EXPERIMENTAL_VP_SPLAT};
718 static const unsigned IntegerVecReduceOps[] = {
723 static const unsigned FloatingPointVecReduceOps[] = {
727 static const unsigned FloatingPointLibCallOps[] = {
740 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR,
741 ISD::VP_REDUCE_SMAX, ISD::VP_REDUCE_SMIN,
742 ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN},
746 for (
MVT VT : BoolVecVTs) {
776 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
800 ISD::VP_TRUNCATE, ISD::VP_SETCC},
816 for (
MVT VT : IntVecVTs) {
827 if (VT.getVectorElementType() == MVT::i64 && !Subtarget.hasStdExtV())
877 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
878 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
902 if (Subtarget.hasStdExtZvkb()) {
910 if (Subtarget.hasStdExtZvbb()) {
914 ISD::VP_CTTZ_ZERO_UNDEF, ISD::VP_CTPOP},
920 ISD::VP_CTTZ_ZERO_UNDEF, ISD::VP_CTPOP},
929 ISD::VP_CTLZ_ZERO_UNDEF, ISD::VP_CTTZ_ZERO_UNDEF},
937 for (
MVT VT : VecTupleVTs) {
958 static const unsigned ZvfhminZvfbfminPromoteOps[] = {
968 static const unsigned ZvfhminZvfbfminPromoteVPOps[] = {
983 ISD::VP_FROUNDTOZERO,
989 ISD::VP_REDUCE_FMINIMUM,
990 ISD::VP_REDUCE_FMAXIMUM};
993 const auto SetCommonVFPActions = [&](
MVT VT) {
1028 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1029 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1062 const auto SetCommonVFPExtLoadTruncStoreActions =
1064 for (
auto SmallVT : SmallerVTs) {
1072 const auto SetCommonPromoteToF32Actions = [&](
MVT VT) {
1097 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1098 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1121 for (
MVT VT : F16VecVTs) {
1124 SetCommonVFPActions(VT);
1127 for (
MVT VT : F16VecVTs) {
1130 SetCommonPromoteToF32Actions(VT);
1135 for (
MVT VT : BF16VecVTs) {
1138 SetCommonPromoteToF32Actions(VT);
1143 for (
MVT VT : F32VecVTs) {
1146 SetCommonVFPActions(VT);
1147 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1148 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1153 for (
MVT VT : F64VecVTs) {
1156 SetCommonVFPActions(VT);
1157 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1158 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1159 SetCommonVFPExtLoadTruncStoreActions(VT, F32VecVTs);
1165 if (!useRVVForFixedLengthVectorVT(VT))
1211 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1238 ISD::VP_SETCC, ISD::VP_TRUNCATE},
1262 ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1263 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1300 if (Subtarget.hasStdExtZvkb())
1303 if (Subtarget.hasStdExtZvbb()) {
1327 if (!useRVVForFixedLengthVectorVT(VT))
1348 ISD::VP_SCATTER, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1349 ISD::EXPERIMENTAL_VP_STRIDED_STORE},
1365 if (Subtarget.hasStdExtZfhmin()) {
1389 if (Subtarget.hasStdExtZfbfmin()) {
1449 if (Subtarget.hasStdExtZfbfmin())
1458 if (Subtarget.hasStdExtA())
1461 if (Subtarget.hasForcedAtomics()) {
1471 if (Subtarget.hasVendorXTHeadMemIdx()) {
1487 if (Subtarget.hasVendorXCVmem() && !Subtarget.
is64Bit()) {
1513 if (Subtarget.hasStdExtZbb())
1516 if ((Subtarget.hasStdExtZbs() && Subtarget.
is64Bit()) ||
1520 if (Subtarget.hasStdExtZbkb())
1531 ISD::EXPERIMENTAL_VP_REVERSE,
ISD::MUL,
1534 if (Subtarget.hasVendorXTHeadMemPair())
1577MVT RISCVTargetLowering::getVPExplicitVectorLengthTy()
const {
1582bool RISCVTargetLowering::shouldExpandGetVectorLength(
EVT TripCountVT,
1584 bool IsScalable)
const {
1591 if (TripCountVT != MVT::i32 && TripCountVT != Subtarget.
getXLenVT())
1616 unsigned Intrinsic)
const {
1617 auto &
DL =
I.getDataLayout();
1619 auto SetRVVLoadStoreInfo = [&](
unsigned PtrOp,
bool IsStore,
1620 bool IsUnitStrided,
bool UsePtrVal =
false) {
1625 Info.ptrVal =
I.getArgOperand(PtrOp);
1627 Info.fallbackAddressSpace =
1628 I.getArgOperand(PtrOp)->getType()->getPointerAddressSpace();
1632 MemTy =
I.getArgOperand(0)->getType();
1635 MemTy =
I.getType();
1645 if (cast<TargetExtType>(MemTy)->
getName() ==
"riscv.vector.tuple")
1648 1 << cast<ConstantInt>(
I.getArgOperand(
I.arg_size() - 1))
1650 Info.align =
DL.getABITypeAlign(MemTy);
1660 if (
I.hasMetadata(LLVMContext::MD_nontemporal))
1664 switch (Intrinsic) {
1667 case Intrinsic::riscv_masked_atomicrmw_xchg_i32:
1668 case Intrinsic::riscv_masked_atomicrmw_add_i32:
1669 case Intrinsic::riscv_masked_atomicrmw_sub_i32:
1670 case Intrinsic::riscv_masked_atomicrmw_nand_i32:
1671 case Intrinsic::riscv_masked_atomicrmw_max_i32:
1672 case Intrinsic::riscv_masked_atomicrmw_min_i32:
1673 case Intrinsic::riscv_masked_atomicrmw_umax_i32:
1674 case Intrinsic::riscv_masked_atomicrmw_umin_i32:
1675 case Intrinsic::riscv_masked_cmpxchg_i32:
1677 Info.memVT = MVT::i32;
1678 Info.ptrVal =
I.getArgOperand(0);
1684 case Intrinsic::riscv_seg2_load:
1685 case Intrinsic::riscv_seg3_load:
1686 case Intrinsic::riscv_seg4_load:
1687 case Intrinsic::riscv_seg5_load:
1688 case Intrinsic::riscv_seg6_load:
1689 case Intrinsic::riscv_seg7_load:
1690 case Intrinsic::riscv_seg8_load:
1691 return SetRVVLoadStoreInfo( 0,
false,
1693 case Intrinsic::riscv_seg2_store:
1694 case Intrinsic::riscv_seg3_store:
1695 case Intrinsic::riscv_seg4_store:
1696 case Intrinsic::riscv_seg5_store:
1697 case Intrinsic::riscv_seg6_store:
1698 case Intrinsic::riscv_seg7_store:
1699 case Intrinsic::riscv_seg8_store:
1701 return SetRVVLoadStoreInfo(
I.arg_size() - 2,
1704 case Intrinsic::riscv_vle:
1705 case Intrinsic::riscv_vle_mask:
1706 case Intrinsic::riscv_vleff:
1707 case Intrinsic::riscv_vleff_mask:
1708 return SetRVVLoadStoreInfo( 1,
1712 case Intrinsic::riscv_vse:
1713 case Intrinsic::riscv_vse_mask:
1714 return SetRVVLoadStoreInfo( 1,
1718 case Intrinsic::riscv_vlse:
1719 case Intrinsic::riscv_vlse_mask:
1720 case Intrinsic::riscv_vloxei:
1721 case Intrinsic::riscv_vloxei_mask:
1722 case Intrinsic::riscv_vluxei:
1723 case Intrinsic::riscv_vluxei_mask:
1724 return SetRVVLoadStoreInfo( 1,
1727 case Intrinsic::riscv_vsse:
1728 case Intrinsic::riscv_vsse_mask:
1729 case Intrinsic::riscv_vsoxei:
1730 case Intrinsic::riscv_vsoxei_mask:
1731 case Intrinsic::riscv_vsuxei:
1732 case Intrinsic::riscv_vsuxei_mask:
1733 return SetRVVLoadStoreInfo( 1,
1736 case Intrinsic::riscv_vlseg2:
1737 case Intrinsic::riscv_vlseg3:
1738 case Intrinsic::riscv_vlseg4:
1739 case Intrinsic::riscv_vlseg5:
1740 case Intrinsic::riscv_vlseg6:
1741 case Intrinsic::riscv_vlseg7:
1742 case Intrinsic::riscv_vlseg8:
1743 case Intrinsic::riscv_vlseg2ff:
1744 case Intrinsic::riscv_vlseg3ff:
1745 case Intrinsic::riscv_vlseg4ff:
1746 case Intrinsic::riscv_vlseg5ff:
1747 case Intrinsic::riscv_vlseg6ff:
1748 case Intrinsic::riscv_vlseg7ff:
1749 case Intrinsic::riscv_vlseg8ff:
1750 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
1753 case Intrinsic::riscv_vlseg2_mask:
1754 case Intrinsic::riscv_vlseg3_mask:
1755 case Intrinsic::riscv_vlseg4_mask:
1756 case Intrinsic::riscv_vlseg5_mask:
1757 case Intrinsic::riscv_vlseg6_mask:
1758 case Intrinsic::riscv_vlseg7_mask:
1759 case Intrinsic::riscv_vlseg8_mask:
1760 case Intrinsic::riscv_vlseg2ff_mask:
1761 case Intrinsic::riscv_vlseg3ff_mask:
1762 case Intrinsic::riscv_vlseg4ff_mask:
1763 case Intrinsic::riscv_vlseg5ff_mask:
1764 case Intrinsic::riscv_vlseg6ff_mask:
1765 case Intrinsic::riscv_vlseg7ff_mask:
1766 case Intrinsic::riscv_vlseg8ff_mask:
1767 return SetRVVLoadStoreInfo(
I.arg_size() - 5,
1770 case Intrinsic::riscv_vlsseg2:
1771 case Intrinsic::riscv_vlsseg3:
1772 case Intrinsic::riscv_vlsseg4:
1773 case Intrinsic::riscv_vlsseg5:
1774 case Intrinsic::riscv_vlsseg6:
1775 case Intrinsic::riscv_vlsseg7:
1776 case Intrinsic::riscv_vlsseg8:
1777 case Intrinsic::riscv_vloxseg2:
1778 case Intrinsic::riscv_vloxseg3:
1779 case Intrinsic::riscv_vloxseg4:
1780 case Intrinsic::riscv_vloxseg5:
1781 case Intrinsic::riscv_vloxseg6:
1782 case Intrinsic::riscv_vloxseg7:
1783 case Intrinsic::riscv_vloxseg8:
1784 case Intrinsic::riscv_vluxseg2:
1785 case Intrinsic::riscv_vluxseg3:
1786 case Intrinsic::riscv_vluxseg4:
1787 case Intrinsic::riscv_vluxseg5:
1788 case Intrinsic::riscv_vluxseg6:
1789 case Intrinsic::riscv_vluxseg7:
1790 case Intrinsic::riscv_vluxseg8:
1791 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
1794 case Intrinsic::riscv_vlsseg2_mask:
1795 case Intrinsic::riscv_vlsseg3_mask:
1796 case Intrinsic::riscv_vlsseg4_mask:
1797 case Intrinsic::riscv_vlsseg5_mask:
1798 case Intrinsic::riscv_vlsseg6_mask:
1799 case Intrinsic::riscv_vlsseg7_mask:
1800 case Intrinsic::riscv_vlsseg8_mask:
1801 case Intrinsic::riscv_vloxseg2_mask:
1802 case Intrinsic::riscv_vloxseg3_mask:
1803 case Intrinsic::riscv_vloxseg4_mask:
1804 case Intrinsic::riscv_vloxseg5_mask:
1805 case Intrinsic::riscv_vloxseg6_mask:
1806 case Intrinsic::riscv_vloxseg7_mask:
1807 case Intrinsic::riscv_vloxseg8_mask:
1808 case Intrinsic::riscv_vluxseg2_mask:
1809 case Intrinsic::riscv_vluxseg3_mask:
1810 case Intrinsic::riscv_vluxseg4_mask:
1811 case Intrinsic::riscv_vluxseg5_mask:
1812 case Intrinsic::riscv_vluxseg6_mask:
1813 case Intrinsic::riscv_vluxseg7_mask:
1814 case Intrinsic::riscv_vluxseg8_mask:
1815 return SetRVVLoadStoreInfo(
I.arg_size() - 6,
1818 case Intrinsic::riscv_vsseg2:
1819 case Intrinsic::riscv_vsseg3:
1820 case Intrinsic::riscv_vsseg4:
1821 case Intrinsic::riscv_vsseg5:
1822 case Intrinsic::riscv_vsseg6:
1823 case Intrinsic::riscv_vsseg7:
1824 case Intrinsic::riscv_vsseg8:
1825 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
1828 case Intrinsic::riscv_vsseg2_mask:
1829 case Intrinsic::riscv_vsseg3_mask:
1830 case Intrinsic::riscv_vsseg4_mask:
1831 case Intrinsic::riscv_vsseg5_mask:
1832 case Intrinsic::riscv_vsseg6_mask:
1833 case Intrinsic::riscv_vsseg7_mask:
1834 case Intrinsic::riscv_vsseg8_mask:
1835 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
1838 case Intrinsic::riscv_vssseg2:
1839 case Intrinsic::riscv_vssseg3:
1840 case Intrinsic::riscv_vssseg4:
1841 case Intrinsic::riscv_vssseg5:
1842 case Intrinsic::riscv_vssseg6:
1843 case Intrinsic::riscv_vssseg7:
1844 case Intrinsic::riscv_vssseg8:
1845 case Intrinsic::riscv_vsoxseg2:
1846 case Intrinsic::riscv_vsoxseg3:
1847 case Intrinsic::riscv_vsoxseg4:
1848 case Intrinsic::riscv_vsoxseg5:
1849 case Intrinsic::riscv_vsoxseg6:
1850 case Intrinsic::riscv_vsoxseg7:
1851 case Intrinsic::riscv_vsoxseg8:
1852 case Intrinsic::riscv_vsuxseg2:
1853 case Intrinsic::riscv_vsuxseg3:
1854 case Intrinsic::riscv_vsuxseg4:
1855 case Intrinsic::riscv_vsuxseg5:
1856 case Intrinsic::riscv_vsuxseg6:
1857 case Intrinsic::riscv_vsuxseg7:
1858 case Intrinsic::riscv_vsuxseg8:
1859 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
1862 case Intrinsic::riscv_vssseg2_mask:
1863 case Intrinsic::riscv_vssseg3_mask:
1864 case Intrinsic::riscv_vssseg4_mask:
1865 case Intrinsic::riscv_vssseg5_mask:
1866 case Intrinsic::riscv_vssseg6_mask:
1867 case Intrinsic::riscv_vssseg7_mask:
1868 case Intrinsic::riscv_vssseg8_mask:
1869 case Intrinsic::riscv_vsoxseg2_mask:
1870 case Intrinsic::riscv_vsoxseg3_mask:
1871 case Intrinsic::riscv_vsoxseg4_mask:
1872 case Intrinsic::riscv_vsoxseg5_mask:
1873 case Intrinsic::riscv_vsoxseg6_mask:
1874 case Intrinsic::riscv_vsoxseg7_mask:
1875 case Intrinsic::riscv_vsoxseg8_mask:
1876 case Intrinsic::riscv_vsuxseg2_mask:
1877 case Intrinsic::riscv_vsuxseg3_mask:
1878 case Intrinsic::riscv_vsuxseg4_mask:
1879 case Intrinsic::riscv_vsuxseg5_mask:
1880 case Intrinsic::riscv_vsuxseg6_mask:
1881 case Intrinsic::riscv_vsuxseg7_mask:
1882 case Intrinsic::riscv_vsuxseg8_mask:
1883 return SetRVVLoadStoreInfo(
I.arg_size() - 5,
1924 return isInt<12>(Imm);
1928 return isInt<12>(Imm);
1941 return (SrcBits == 64 && DestBits == 32);
1952 return (SrcBits == 64 && DestBits == 32);
1963 if (SrcBits == DestBits * 2) {
1974 if (
auto *LD = dyn_cast<LoadSDNode>(Val)) {
1975 EVT MemVT = LD->getMemoryVT();
1976 if ((MemVT == MVT::i8 || MemVT == MVT::i16) &&
1986 return Subtarget.
is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
1994 return Subtarget.hasStdExtZbb() ||
1995 (Subtarget.hasVendorXCVbitmanip() && !Subtarget.
is64Bit());
1999 return Subtarget.hasStdExtZbb() || Subtarget.hasVendorXTHeadBb() ||
2000 (Subtarget.hasVendorXCVbitmanip() && !Subtarget.
is64Bit());
2011 if (!Subtarget.hasStdExtZbs() && !Subtarget.hasVendorXTHeadBs())
2016 return !Mask->getValue().isSignedIntN(12) && Mask->getValue().isPowerOf2();
2020 EVT VT =
Y.getValueType();
2026 return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
2027 (!isa<ConstantSDNode>(
Y) || cast<ConstantSDNode>(
Y)->isOpaque());
2032 if (Subtarget.hasStdExtZbs())
2033 return X.getValueType().isScalarInteger();
2034 auto *
C = dyn_cast<ConstantSDNode>(
Y);
2036 if (Subtarget.hasVendorXTHeadBs())
2037 return C !=
nullptr;
2039 return C &&
C->getAPIntValue().ule(10);
2059 if (BitSize > Subtarget.
getXLen())
2063 int64_t Val = Imm.getSExtValue();
2071 if (!Subtarget.enableUnalignedScalarMem())
2087 unsigned OldShiftOpcode,
unsigned NewShiftOpcode,
2094 if (XC && OldShiftOpcode ==
ISD::SRL && XC->isOne())
2098 if (NewShiftOpcode ==
ISD::SRL &&
CC->isOne())
2142 if (!Subtarget.hasStdExtZfa())
2145 bool IsSupportedVT =
false;
2146 if (VT == MVT::f16) {
2147 IsSupportedVT = Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZvfh();
2148 }
else if (VT == MVT::f32) {
2149 IsSupportedVT =
true;
2150 }
else if (VT == MVT::f64) {
2151 assert(Subtarget.hasStdExtD() &&
"Expect D extension");
2152 IsSupportedVT =
true;
2162 bool ForCodeSize)
const {
2163 bool IsLegalVT =
false;
2166 else if (VT == MVT::f32)
2168 else if (VT == MVT::f64)
2170 else if (VT == MVT::bf16)
2171 IsLegalVT = Subtarget.hasStdExtZfbfmin();
2183 return Imm.isZero();
2187 if (Imm.isNegZero())
2192 const int FmvCost = Subtarget.hasStdExtZfinx() ? 0 : 1;
2195 Subtarget.
getXLen(), Subtarget);
2201 unsigned Index)
const {
2214 if (EltVT == MVT::i1)
2227 if (Index + ResElts <= MinVLMAX && Index < 31)
2236 return (ResElts * 2) == SrcElts && (Index == 0 || Index == ResElts);
2255 std::optional<MVT> RegisterVT)
const {
2257 if (VT == (Subtarget.
is64Bit() ? MVT::i128 : MVT::i64) && RegisterVT &&
2258 *RegisterVT == MVT::Untyped)
2278 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
2280 Context,
CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
2295 isa<ConstantSDNode>(
LHS.getOperand(1))) {
2301 ShAmt =
LHS.getValueSizeInBits() - 1 -
Log2_64(Mask);
2314 if (
auto *RHSC = dyn_cast<ConstantSDNode>(
RHS)) {
2315 int64_t
C = RHSC->getSExtValue();
2353 if (VT.
SimpleTy >= MVT::riscv_nxv1i8x2 &&
2354 VT.
SimpleTy <= MVT::riscv_nxv1i8x8)
2356 if (VT.
SimpleTy >= MVT::riscv_nxv2i8x2 &&
2357 VT.
SimpleTy <= MVT::riscv_nxv2i8x8)
2359 if (VT.
SimpleTy >= MVT::riscv_nxv4i8x2 &&
2360 VT.
SimpleTy <= MVT::riscv_nxv4i8x8)
2362 if (VT.
SimpleTy >= MVT::riscv_nxv8i8x2 &&
2363 VT.
SimpleTy <= MVT::riscv_nxv8i8x8)
2365 if (VT.
SimpleTy >= MVT::riscv_nxv16i8x2 &&
2366 VT.
SimpleTy <= MVT::riscv_nxv16i8x4)
2368 if (VT.
SimpleTy == MVT::riscv_nxv32i8x2)
2378 switch (KnownSize) {
2406 return RISCV::VRRegClassID;
2408 return RISCV::VRM2RegClassID;
2410 return RISCV::VRM4RegClassID;
2412 return RISCV::VRM8RegClassID;
2422 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
2423 "Unexpected subreg numbering");
2424 return RISCV::sub_vrm1_0 + Index;
2427 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
2428 "Unexpected subreg numbering");
2429 return RISCV::sub_vrm2_0 + Index;
2432 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
2433 "Unexpected subreg numbering");
2434 return RISCV::sub_vrm4_0 + Index;
2442 unsigned RegsPerField =
2445 switch (RegsPerField) {
2448 return RISCV::VRN2M1RegClassID;
2450 return RISCV::VRN3M1RegClassID;
2452 return RISCV::VRN4M1RegClassID;
2454 return RISCV::VRN5M1RegClassID;
2456 return RISCV::VRN6M1RegClassID;
2458 return RISCV::VRN7M1RegClassID;
2460 return RISCV::VRN8M1RegClassID;
2464 return RISCV::VRN2M2RegClassID;
2466 return RISCV::VRN3M2RegClassID;
2468 return RISCV::VRN4M2RegClassID;
2472 return RISCV::VRN2M4RegClassID;
2480 return RISCV::VRRegClassID;
2489std::pair<unsigned, unsigned>
2491 MVT VecVT,
MVT SubVecVT,
unsigned InsertExtractIdx,
2493 static_assert((RISCV::VRM8RegClassID > RISCV::VRM4RegClassID &&
2494 RISCV::VRM4RegClassID > RISCV::VRM2RegClassID &&
2495 RISCV::VRM2RegClassID > RISCV::VRRegClassID),
2496 "Register classes not ordered");
2503 if (VecRegClassID == SubRegClassID)
2504 return {RISCV::NoSubRegister, 0};
2507 "Only allow scalable vector subvector.");
2509 "Invalid vector tuple insert/extract for vector and subvector with "
2520 unsigned SubRegIdx = RISCV::NoSubRegister;
2521 for (
const unsigned RCID :
2522 {RISCV::VRM4RegClassID, RISCV::VRM2RegClassID, RISCV::VRRegClassID})
2523 if (VecRegClassID > RCID && SubRegClassID <= RCID) {
2527 SubRegIdx =
TRI->composeSubRegIndices(SubRegIdx,
2532 return {SubRegIdx, InsertExtractIdx};
2537bool RISCVTargetLowering::mergeStoresAfterLegalization(
EVT VT)
const {
2568unsigned RISCVTargetLowering::combineRepeatedFPDivisors()
const {
2575 "Unexpected opcode");
2577 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
2579 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
2582 return Op.getOperand(
II->VLOperand + 1 + HasChain);
2656bool RISCVTargetLowering::useRVVForFixedLengthVectorVT(
MVT VT)
const {
2657 return ::useRVVForFixedLengthVectorVT(VT, Subtarget);
2666 "Expected legal fixed length vector!");
2669 unsigned MaxELen = Subtarget.
getELen();
2703 return ::getContainerForFixedLengthVector(*
this, VT,
getSubtarget());
2710 "Expected to convert into a scalable vector!");
2711 assert(V.getValueType().isFixedLengthVector() &&
2712 "Expected a fixed length vector operand!");
2722 "Expected to convert into a fixed length vector!");
2723 assert(V.getValueType().isScalableVector() &&
2724 "Expected a scalable vector operand!");
2747static std::pair<SDValue, SDValue>
2756static std::pair<SDValue, SDValue>
2769static std::pair<SDValue, SDValue>
2786std::pair<unsigned, unsigned>
2802 return std::make_pair(MinVLMAX, MaxVLMAX);
2814 EVT VT,
unsigned DefinedValues)
const {
2828 std::tie(LMul, Fractional) =
2831 Cost = LMul <= DLenFactor ? (DLenFactor / LMul) : 1;
2833 Cost = (LMul * DLenFactor);
2876 Op.getValueType() == MVT::bf16) {
2877 bool IsStrict =
Op->isStrictFPOpcode();
2882 {Op.getOperand(0), Op.getOperand(1)});
2884 {
Op.getValueType(), MVT::Other},
2890 DAG.
getNode(
Op.getOpcode(),
DL, MVT::f32,
Op.getOperand(0)),
2905 MVT DstVT =
Op.getSimpleValueType();
2906 EVT SatVT = cast<VTSDNode>(
Op.getOperand(1))->getVT();
2914 Src.getValueType() == MVT::bf16) {
2921 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
2929 Opc,
DL, DstVT, Src,
2943 MVT SrcVT = Src.getSimpleValueType();
2949 if (SatVT != DstEltVT)
2952 MVT DstContainerVT = DstVT;
2953 MVT SrcContainerVT = SrcVT;
2959 "Expected same element count");
2968 {Src, Src, DAG.getCondCode(ISD::SETNE),
2969 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
2973 if (DstEltSize > (2 * SrcEltSize)) {
2979 MVT CvtContainerVT = DstContainerVT;
2980 MVT CvtEltVT = DstEltVT;
2981 if (SrcEltSize > (2 * DstEltSize)) {
2990 while (CvtContainerVT != DstContainerVT) {
2996 Res = DAG.
getNode(ClipOpc,
DL, CvtContainerVT, Res, Mask, VL);
3003 Res, DAG.
getUNDEF(DstContainerVT), VL);
3013 bool IsStrict =
Op->isStrictFPOpcode();
3014 SDValue SrcVal =
Op.getOperand(IsStrict ? 1 : 0);
3024 {
Op.getOperand(0), SrcVal});
3025 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
3026 {Ext.getValue(1), Ext.getValue(0)});
3040 case ISD::VP_FROUNDEVEN:
3044 case ISD::VP_FROUNDTOZERO:
3048 case ISD::VP_FFLOOR:
3056 case ISD::VP_FROUND:
3073 MVT VT =
Op.getSimpleValueType();
3080 MVT ContainerVT = VT;
3087 if (
Op->isVPOpcode()) {
3088 Mask =
Op.getOperand(1);
3092 VL =
Op.getOperand(2);
3114 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3128 switch (
Op.getOpcode()) {
3136 case ISD::VP_FFLOOR:
3139 case ISD::VP_FROUND:
3140 case ISD::VP_FROUNDEVEN:
3141 case ISD::VP_FROUNDTOZERO: {
3153 case ISD::VP_FNEARBYINT:
3166 Src, Src, Mask, VL);
3181 MVT VT =
Op.getSimpleValueType();
3185 MVT ContainerVT = VT;
3197 MVT MaskVT = Mask.getSimpleValueType();
3200 {Chain, Src, Src, DAG.getCondCode(ISD::SETUNE),
3201 DAG.getUNDEF(MaskVT), Mask, VL});
3205 {Chain, Src, Src, Src, Unorder, VL});
3206 Chain = Src.getValue(1);
3222 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3234 switch (
Op.getOpcode()) {
3245 {Chain, Src, Mask, DAG.getTargetConstant(FRM, DL, XLenVT), VL});
3251 DAG.
getVTList(IntVT, MVT::Other), Chain, Src, Mask, VL);
3255 DAG.
getVTList(ContainerVT, MVT::Other), Chain, Src,
3264 DAG.
getVTList(ContainerVT, MVT::Other), Chain,
3265 Truncated, Mask, VL);
3271 Src, Src, Mask, VL);
3281 MVT VT =
Op.getSimpleValueType();
3309 MVT VT =
Op.getSimpleValueType();
3314 MVT ContainerVT = VT;
3359 "Unexpected vector MVT");
3387 return std::nullopt;
3405 unsigned EltSizeInBits) {
3408 return std::nullopt;
3409 bool IsInteger =
Op.getValueType().isInteger();
3411 std::optional<unsigned> SeqStepDenom;
3412 std::optional<APInt> SeqStepNum;
3413 std::optional<APInt> SeqAddend;
3414 std::optional<std::pair<APInt, unsigned>> PrevElt;
3415 assert(EltSizeInBits >=
Op.getValueType().getScalarSizeInBits());
3420 const unsigned OpSize =
Op.getScalarValueSizeInBits();
3422 if (Elt.isUndef()) {
3423 Elts[
Idx] = std::nullopt;
3427 Elts[
Idx] = Elt->getAsAPIntVal().trunc(OpSize).zext(EltSizeInBits);
3432 return std::nullopt;
3433 Elts[
Idx] = *ExactInteger;
3446 unsigned IdxDiff =
Idx - PrevElt->second;
3447 APInt ValDiff = *Elt - PrevElt->first;
3455 int64_t Remainder = ValDiff.
srem(IdxDiff);
3460 return std::nullopt;
3461 ValDiff = ValDiff.
sdiv(IdxDiff);
3466 SeqStepNum = ValDiff;
3467 else if (ValDiff != SeqStepNum)
3468 return std::nullopt;
3471 SeqStepDenom = IdxDiff;
3472 else if (IdxDiff != *SeqStepDenom)
3473 return std::nullopt;
3477 if (!PrevElt || PrevElt->first != *Elt)
3478 PrevElt = std::make_pair(*Elt,
Idx);
3482 if (!SeqStepNum || !SeqStepDenom)
3483 return std::nullopt;
3491 (
APInt(EltSizeInBits,
Idx,
false,
true) *
3493 .sdiv(*SeqStepDenom);
3495 APInt Addend = *Elt - ExpectedVal;
3498 else if (Addend != SeqAddend)
3499 return std::nullopt;
3502 assert(SeqAddend &&
"Must have an addend if we have a step");
3504 return VIDSequence{SeqStepNum->getSExtValue(), *SeqStepDenom,
3505 SeqAddend->getSExtValue()};
3520 if (EltTy == MVT::i1 ||
3533 MVT ContainerVT = VT;
3562 MVT VT =
Op.getSimpleValueType();
3574 unsigned MostCommonCount = 0;
3576 unsigned NumUndefElts =
3584 unsigned NumScalarLoads = 0;
3590 unsigned &Count = ValueCounts[V];
3592 if (
auto *CFP = dyn_cast<ConstantFPSDNode>(V))
3593 NumScalarLoads += !CFP->isExactlyValue(+0.0);
3598 if (++Count >= MostCommonCount) {
3600 MostCommonCount = Count;
3604 assert(DominantValue &&
"Not expecting an all-undef BUILD_VECTOR");
3605 unsigned NumDefElts = NumElts - NumUndefElts;
3606 unsigned DominantValueCountThreshold = NumDefElts <= 2 ? 0 : NumDefElts - 2;
3612 ((MostCommonCount > DominantValueCountThreshold) ||
3625 !LastOp.isUndef() && ValueCounts[LastOp] == 1 &&
3626 LastOp != DominantValue) {
3635 Processed.insert(LastOp);
3640 const SDValue &V = OpIdx.value();
3641 if (V.isUndef() || !Processed.insert(V).second)
3643 if (ValueCounts[V] == 1) {
3652 return DAG.getConstant(V == V1, DL, XLenVT);
3668 MVT VT =
Op.getSimpleValueType();
3698 unsigned NumViaIntegerBits = std::clamp(NumElts, 8u, Subtarget.
getXLen());
3699 NumViaIntegerBits = std::min(NumViaIntegerBits, Subtarget.
getELen());
3707 unsigned IntegerViaVecElts =
divideCeil(NumElts, NumViaIntegerBits);
3708 MVT IntegerViaVecVT =
3713 unsigned BitPos = 0, IntegerEltIdx = 0;
3716 for (
unsigned I = 0;
I < NumElts;) {
3718 bool BitValue = !V.isUndef() && V->getAsZExtVal();
3719 Bits |= ((
uint64_t)BitValue << BitPos);
3725 if (
I % NumViaIntegerBits == 0 ||
I == NumElts) {
3726 if (NumViaIntegerBits <= 32)
3727 Bits = SignExtend64<32>(Bits);
3729 Elts[IntegerEltIdx] = Elt;
3738 if (NumElts < NumViaIntegerBits) {
3742 assert(IntegerViaVecVT == MVT::v1i8 &&
"Unexpected mask vector type");
3770 int64_t StepNumerator = SimpleVID->StepNumerator;
3771 unsigned StepDenominator = SimpleVID->StepDenominator;
3772 int64_t Addend = SimpleVID->Addend;
3774 assert(StepNumerator != 0 &&
"Invalid step");
3775 bool Negate =
false;
3776 int64_t SplatStepVal = StepNumerator;
3780 if (StepNumerator != 1 && StepNumerator !=
INT64_MIN &&
3782 Negate = StepNumerator < 0;
3784 SplatStepVal =
Log2_64(std::abs(StepNumerator));
3791 if (((StepOpcode ==
ISD::MUL && isInt<12>(SplatStepVal)) ||
3792 (StepOpcode ==
ISD::SHL && isUInt<5>(SplatStepVal))) &&
3794 (SplatStepVal >= 0 || StepDenominator == 1) && isInt<5>(Addend)) {
3797 MVT VIDContainerVT =
3805 if ((StepOpcode ==
ISD::MUL && SplatStepVal != 1) ||
3806 (StepOpcode ==
ISD::SHL && SplatStepVal != 0)) {
3808 VID = DAG.
getNode(StepOpcode,
DL, VIDVT, VID, SplatStep);
3810 if (StepDenominator != 1) {
3815 if (Addend != 0 || Negate) {
3834 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32) &&
3835 "Unexpected sequence type");
3839 unsigned ViaVecLen =
3843 uint64_t EltMask = maskTrailingOnes<uint64_t>(EltBitSize);
3846 for (
const auto &OpIdx :
enumerate(
Op->op_values())) {
3847 const auto &SeqV = OpIdx.value();
3848 if (!SeqV.isUndef())
3850 ((SeqV->getAsZExtVal() & EltMask) << (OpIdx.index() * EltBitSize));
3856 if (ViaIntVT == MVT::i32)
3857 SplatValue = SignExtend64<32>(SplatValue);
3879 const auto *BV = cast<BuildVectorSDNode>(
Op);
3882 BV->getRepeatedSequence(Sequence) &&
3883 (Sequence.size() * EltBitSize) <= Subtarget.
getELen()) {
3884 unsigned SeqLen = Sequence.size();
3886 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32 ||
3887 ViaIntVT == MVT::i64) &&
3888 "Unexpected sequence type");
3893 const unsigned RequiredVL = NumElts / SeqLen;
3894 const unsigned ViaVecLen =
3896 NumElts : RequiredVL;
3899 unsigned EltIdx = 0;
3900 uint64_t EltMask = maskTrailingOnes<uint64_t>(EltBitSize);
3904 for (
const auto &SeqV : Sequence) {
3905 if (!SeqV.isUndef())
3907 ((SeqV->getAsZExtVal() & EltMask) << (EltIdx * EltBitSize));
3914 if (ViaIntVT == MVT::i32)
3915 SplatValue = SignExtend64<32>(SplatValue);
3921 (!Subtarget.
is64Bit() && ViaIntVT == MVT::i64)) &&
3922 "Unexpected bitcast sequence");
3923 if (ViaIntVT.
bitsLE(XLenVT) || isInt<32>(SplatValue)) {
3926 MVT ViaContainerVT =
3933 if (ViaVecLen != RequiredVL)
3953 Source, DAG, Subtarget);
3973 return RISCV::PACKH;
3975 return Subtarget.
is64Bit() ? RISCV::PACKW : RISCV::PACK;
3990 MVT VT =
Op.getSimpleValueType();
3998 if (!Subtarget.hasStdExtZbb() || !Subtarget.hasStdExtZba())
4003 if (ElemSizeInBits >= std::min(Subtarget.
getELen(), Subtarget.
getXLen()) ||
4017 if (Subtarget.hasStdExtZbkb())
4022 ElemDL, XLenVT,
A,
B),
4034 NewOperands.
reserve(NumElts / 2);
4036 NewOperands.
push_back(pack(
Op.getOperand(i),
Op.getOperand(i + 1)));
4046 MVT VT =
Op.getSimpleValueType();
4057 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) || EltVT == MVT::bf16) {
4062 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4063 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin())) {
4066 if (
auto *
C = dyn_cast<ConstantFPSDNode>(Elem)) {
4150 auto OneVRegOfOps =
ArrayRef(BuildVectorOps).
slice(i, ElemsPerVReg);
4154 unsigned InsertIdx = (i / ElemsPerVReg) * NumOpElts;
4177 unsigned NumUndefElts =
4179 unsigned NumDefElts = NumElts - NumUndefElts;
4180 if (NumDefElts >= 8 && NumDefElts > NumElts / 2 &&
4187 for (
unsigned i = 0; i < NumElts; i++) {
4189 if (i < NumElts / 2) {
4196 bool SelectMaskVal = (i < NumElts / 2);
4199 assert(SubVecAOps.
size() == NumElts && SubVecBOps.
size() == NumElts &&
4200 MaskVals.
size() == NumElts);
4235 unsigned UndefCount = 0;
4242 LinearBudget -= PerSlideCost;
4245 LinearBudget -= PerSlideCost;
4248 LinearBudget -= PerSlideCost;
4251 if (LinearBudget < 0)
4256 "Illegal type which will result in reserved encoding");
4281 Vec,
Offset, Mask, VL, Policy);
4294 Vec,
Offset, Mask, VL, Policy);
4304 if (isa<ConstantSDNode>(
Lo) && isa<ConstantSDNode>(
Hi)) {
4305 int32_t LoC = cast<ConstantSDNode>(
Lo)->getSExtValue();
4306 int32_t HiC = cast<ConstantSDNode>(
Hi)->getSExtValue();
4309 if ((LoC >> 31) == HiC)
4320 (isa<RegisterSDNode>(VL) &&
4321 cast<RegisterSDNode>(VL)->
getReg() == RISCV::X0))
4323 else if (isa<ConstantSDNode>(VL) && isUInt<4>(VL->
getAsZExtVal()))
4338 isa<ConstantSDNode>(
Hi.getOperand(1)) &&
4339 Hi.getConstantOperandVal(1) == 31)
4358 assert(Scalar.getValueType() == MVT::i64 &&
"Unexpected VT!");
4370 bool HasPassthru = Passthru && !Passthru.
isUndef();
4371 if (!HasPassthru && !Passthru)
4378 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) ||
4379 EltVT == MVT::bf16) {
4380 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4381 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
4395 if (Scalar.getValueType().bitsLE(XLenVT)) {
4402 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
4406 assert(XLenVT == MVT::i32 && Scalar.getValueType() == MVT::i64 &&
4407 "Unexpected scalar for splat lowering!");
4431 SDValue ExtractedVal = Scalar.getOperand(0);
4436 MVT ExtractedContainerVT = ExtractedVT;
4439 DAG, ExtractedContainerVT, Subtarget);
4441 ExtractedVal, DAG, Subtarget);
4443 if (ExtractedContainerVT.
bitsLE(VT))
4458 if (!Scalar.getValueType().bitsLE(XLenVT))
4461 VT,
DL, DAG, Subtarget);
4469 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
4489 if (Src != V2.getOperand(0))
4494 if (Src.getValueType().getVectorNumElements() != (NumElts * 2))
4499 V2.getConstantOperandVal(1) != NumElts)
4517 int Size = Mask.size();
4519 assert(
Size == (
int)NumElts &&
"Unexpected mask size");
4525 EvenSrc = StartIndexes[0];
4526 OddSrc = StartIndexes[1];
4529 if (EvenSrc != 0 && OddSrc != 0)
4539 int HalfNumElts = NumElts / 2;
4540 return ((EvenSrc % HalfNumElts) == 0) && ((OddSrc % HalfNumElts) == 0);
4556 int Size = Mask.size();
4568 for (
int i = 0; i !=
Size; ++i) {
4574 int StartIdx = i - (M %
Size);
4582 int CandidateRotation = StartIdx < 0 ? -StartIdx :
Size - StartIdx;
4585 Rotation = CandidateRotation;
4586 else if (Rotation != CandidateRotation)
4591 int MaskSrc = M <
Size ? 0 : 1;
4596 int &TargetSrc = StartIdx < 0 ? HiSrc : LoSrc;
4601 TargetSrc = MaskSrc;
4602 else if (TargetSrc != MaskSrc)
4609 assert(Rotation != 0 &&
"Failed to locate a viable rotation!");
4610 assert((LoSrc >= 0 || HiSrc >= 0) &&
4611 "Failed to find a rotated input vector!");
4625 ElementCount SrcEC = Src.getValueType().getVectorElementCount();
4632 unsigned Shift = Index * EltBits;
4659 auto findNonEXTRACT_SUBVECTORParent =
4660 [](
SDValue Parent) -> std::pair<SDValue, uint64_t> {
4665 Parent.getOperand(0).getSimpleValueType().isFixedLengthVector()) {
4666 Offset += Parent.getConstantOperandVal(1);
4667 Parent = Parent.getOperand(0);
4669 return std::make_pair(Parent,
Offset);
4672 auto [V1Src, V1IndexOffset] = findNonEXTRACT_SUBVECTORParent(V1);
4673 auto [V2Src, V2IndexOffset] = findNonEXTRACT_SUBVECTORParent(V2);
4682 for (
size_t i = 0; i != NewMask.
size(); ++i) {
4683 if (NewMask[i] == -1)
4686 if (
static_cast<size_t>(NewMask[i]) < NewMask.
size()) {
4687 NewMask[i] = NewMask[i] + V1IndexOffset;
4691 NewMask[i] = NewMask[i] - NewMask.
size() + V2IndexOffset;
4697 if (NewMask[0] <= 0)
4701 for (
unsigned i = 1; i != NewMask.
size(); ++i)
4702 if (NewMask[i - 1] + 1 != NewMask[i])
4706 MVT SrcVT = Src.getSimpleValueType();
4737 int NumSubElts, Index;
4742 bool OpsSwapped = Mask[Index] < (int)NumElts;
4743 SDValue InPlace = OpsSwapped ? V2 : V1;
4744 SDValue ToInsert = OpsSwapped ? V1 : V2;
4754 if (NumSubElts + Index >= (
int)NumElts)
4768 Res =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, InPlace, ToInsert,
4780 bool OpsSwapped =
false;
4781 if (!isa<BuildVectorSDNode>(V1)) {
4782 if (!isa<BuildVectorSDNode>(V2))
4787 SDValue Splat = cast<BuildVectorSDNode>(V1)->getSplatValue();
4795 const unsigned E = Mask.size() - ((
Offset > 0) ?
Offset : 0);
4796 for (
unsigned i = S; i != E; ++i)
4797 if (Mask[i] >= 0 && (
unsigned)Mask[i] !=
Base + i +
Offset)
4803 bool IsVSlidedown = isSlideMask(Mask, OpsSwapped ? 0 : NumElts, 1);
4804 if (!IsVSlidedown && !isSlideMask(Mask, OpsSwapped ? 0 : NumElts, -1))
4807 const int InsertIdx = Mask[IsVSlidedown ? (NumElts - 1) : 0];
4809 if (InsertIdx < 0 || InsertIdx / NumElts != (
unsigned)OpsSwapped)
4832 auto OpCode = IsVSlidedown ?
4837 auto Vec = DAG.
getNode(OpCode,
DL, ContainerVT,
4840 Splat, TrueMask, VL);
4851 for (
unsigned i = 0; i < Mask.size(); i++)
4852 LaneIsUndef[i % Factor] &= (Mask[i] == -1);
4855 for (
unsigned i = 0; i < Factor; i++) {
4866 for (
unsigned i = 0; i < Mask.size() / Factor; i++) {
4867 unsigned j = i * Factor + Index;
4868 if (Mask[j] != -1 && (
unsigned)Mask[j] != i)
4881 MVT VT = V.getSimpleValueType();
4896 EC.multiplyCoefficientBy(Factor));
4915 MVT VecContainerVT = VecVT;
4932 MVT WideContainerVT = WideVT;
4938 EvenV = DAG.
getBitcast(VecContainerVT, EvenV);
4945 if (Subtarget.hasStdExtZvbb()) {
4950 OffsetVec, Passthru, Mask, VL);
4952 Interleaved, EvenV, Passthru, Mask, VL);
4960 OddV, Passthru, Mask, VL);
4966 OddV, AllOnesVec, Passthru, Mask, VL);
4974 Interleaved, OddsMul, Passthru, Mask, VL);
4981 Interleaved = DAG.
getBitcast(ResultContainerVT, Interleaved);
5027 if (ViaEltSize > NumElts)
5036 if (ViaEltSize > NumElts)
5042 if (ViaEltSize > NumElts)
5051 MVT &RotateVT,
unsigned &RotateAmt) {
5057 unsigned NumSubElts;
5059 NumElts, NumSubElts, RotateAmt))
5062 NumElts / NumSubElts);
5124 unsigned VRegsPerSrc = NumElts / ElemsPerVReg;
5127 OutMasks(VRegsPerSrc, {-1, {}});
5132 for (
unsigned DstIdx = 0; DstIdx < Mask.size(); DstIdx++) {
5133 int DstVecIdx = DstIdx / ElemsPerVReg;
5134 int DstSubIdx = DstIdx % ElemsPerVReg;
5135 int SrcIdx = Mask[DstIdx];
5136 if (SrcIdx < 0 || (
unsigned)SrcIdx >= 2 * NumElts)
5138 int SrcVecIdx = SrcIdx / ElemsPerVReg;
5139 int SrcSubIdx = SrcIdx % ElemsPerVReg;
5140 if (OutMasks[DstVecIdx].first == -1)
5141 OutMasks[DstVecIdx].first = SrcVecIdx;
5142 if (OutMasks[DstVecIdx].first != SrcVecIdx)
5148 OutMasks[DstVecIdx].second.resize(ElemsPerVReg, -1);
5149 OutMasks[DstVecIdx].second[DstSubIdx] = SrcSubIdx;
5163 for (
unsigned DstVecIdx = 0 ; DstVecIdx < OutMasks.size(); DstVecIdx++) {
5164 auto &[SrcVecIdx, SrcSubMask] = OutMasks[DstVecIdx];
5165 if (SrcVecIdx == -1)
5167 unsigned ExtractIdx = (SrcVecIdx % VRegsPerSrc) * NumOpElts;
5174 unsigned InsertIdx = DstVecIdx * NumOpElts;
5186 bool SawUndef =
false;
5187 for (
unsigned i = 0; i < Mask.size(); i++) {
5188 if (Mask[i] == -1) {
5194 if (i > (
unsigned)Mask[i])
5196 if (Mask[i] <=
Last)
5227 for (
int Idx : Mask) {
5230 unsigned SrcIdx =
Idx % Mask.size();
5232 if (Srcs[SrcIdx] == -1)
5235 else if (Srcs[SrcIdx] != Src)
5241 for (
int Lane : Srcs) {
5254 for (
unsigned I = 0;
I < Mask.size();
I++) {
5258 NewMask[
I] = Mask[
I] % Mask.size();
5272 MVT VT =
Op.getSimpleValueType();
5280 if (ElementSize > 32)
5303 MVT VT =
Op.getSimpleValueType();
5318 V2 = V2.isUndef() ? DAG.
getUNDEF(WidenVT)
5342 V.getOperand(0).getSimpleValueType().getVectorNumElements();
5343 V = V.getOperand(
Offset / OpElements);
5349 auto *Ld = cast<LoadSDNode>(V);
5359 SDValue Ops[] = {Ld->getChain(),
5373 MVT SplatVT = ContainerVT;
5376 if (SVT == MVT::bf16 ||
5377 (SVT == MVT::f16 && !Subtarget.hasStdExtZfh())) {
5386 V = DAG.
getLoad(SVT,
DL, Ld->getChain(), NewAddr,
5387 Ld->getPointerInfo().getWithOffset(
Offset),
5388 Ld->getOriginalAlign(),
5392 Ld->getPointerInfo().getWithOffset(
Offset), SVT,
5393 Ld->getOriginalAlign(),
5394 Ld->getMemOperand()->getFlags());
5406 assert(Lane < (
int)NumElts &&
"Unexpected lane!");
5409 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
5431 if (Subtarget.hasStdExtZvkb())
5442 LoV = LoSrc == 0 ? V1 : V2;
5446 HiV = HiSrc == 0 ? V1 : V2;
5452 unsigned InvRotate = NumElts - Rotation;
5462 Res =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, Res, LoV,
5480 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
5481 for (
unsigned Factor = 2; Factor <= MaxFactor; Factor <<= 1) {
5497 int EvenSrc, OddSrc;
5505 bool LaneIsUndef[2] = {
true,
true};
5506 for (
unsigned i = 0; i < Mask.size(); i++)
5507 LaneIsUndef[i % 2] &= (Mask[i] == -1);
5509 int Size = Mask.size();
5511 if (LaneIsUndef[0]) {
5514 assert(EvenSrc >= 0 &&
"Undef source?");
5515 EvenV = (EvenSrc /
Size) == 0 ? V1 : V2;
5520 if (LaneIsUndef[1]) {
5523 assert(OddSrc >= 0 &&
"Undef source?");
5524 OddV = (OddSrc /
Size) == 0 ? V1 : V2;
5534 assert(!V1.
isUndef() &&
"Unexpected shuffle canonicalization");
5554 for (
auto Idx : Mask) {
5570 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
5571 for (
unsigned Factor = 4; Factor <= MaxFactor; Factor <<= 1) {
5584 any_of(Mask, [&](
const auto &
Idx) {
return Idx > 255; })) {
5613 MVT IndexContainerVT =
5618 for (
int MaskIndex : Mask) {
5619 bool IsLHSIndex = MaskIndex < (int)NumElts && MaskIndex >= 0;
5628 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
5638 for (
int MaskIndex : Mask) {
5639 bool IsLHSOrUndefIndex = MaskIndex < (int)NumElts;
5640 ShuffleMaskLHS.
push_back(IsLHSOrUndefIndex && MaskIndex >= 0
5642 ShuffleMaskRHS.
push_back(IsLHSOrUndefIndex ? -1 : (MaskIndex - NumElts));
5673 for (
int MaskIndex : Mask) {
5674 bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ !SwapOps;
5678 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
5710RISCVTargetLowering::lowerCTLZ_CTTZ_ZERO_UNDEF(
SDValue Op,
5712 MVT VT =
Op.getSimpleValueType();
5716 MVT ContainerVT = VT;
5719 if (
Op->isVPOpcode()) {
5720 Mask =
Op.getOperand(1);
5724 VL =
Op.getOperand(2);
5730 MVT FloatEltVT = (EltSize >= 32) ? MVT::f64 : MVT::f32;
5732 FloatEltVT = MVT::f32;
5739 "Expected legal float type!");
5746 }
else if (
Op.getOpcode() == ISD::VP_CTTZ_ZERO_UNDEF) {
5749 Src = DAG.
getNode(ISD::VP_AND,
DL, VT, Src, Neg, Mask, VL);
5754 if (FloatVT.
bitsGT(VT)) {
5755 if (
Op->isVPOpcode())
5756 FloatVal = DAG.
getNode(ISD::VP_UINT_TO_FP,
DL, FloatVT, Src, Mask, VL);
5765 if (!
Op->isVPOpcode())
5769 MVT ContainerFloatVT =
5772 Src, Mask, RTZRM, VL);
5779 unsigned ShiftAmt = FloatEltVT == MVT::f64 ? 52 : 23;
5783 if (
Op->isVPOpcode()) {
5792 else if (IntVT.
bitsGT(VT))
5797 unsigned ExponentBias = FloatEltVT == MVT::f64 ? 1023 : 127;
5802 if (
Op.getOpcode() == ISD::VP_CTTZ_ZERO_UNDEF)
5803 return DAG.
getNode(ISD::VP_SUB,
DL, VT, Exp,
5808 unsigned Adjust = ExponentBias + (EltSize - 1);
5810 if (
Op->isVPOpcode())
5820 else if (
Op.getOpcode() == ISD::VP_CTLZ)
5821 Res = DAG.
getNode(ISD::VP_UMIN,
DL, VT, Res,
5831 MVT SrcVT =
Source.getSimpleValueType();
5840 SrcVT = ContainerVT;
5853 if (
Op->getOpcode() == ISD::VP_CTTZ_ELTS_ZERO_UNDEF)
5870 auto *
Load = cast<LoadSDNode>(
Op);
5871 assert(Load &&
Load->getMemoryVT().isVector() &&
"Expected vector load");
5874 Load->getMemoryVT(),
5875 *
Load->getMemOperand()))
5879 MVT VT =
Op.getSimpleValueType();
5881 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
5882 "Unexpected unaligned RVV load type");
5886 "Expecting equally-sized RVV vector types to be legal");
5888 Load->getPointerInfo(),
Load->getOriginalAlign(),
5889 Load->getMemOperand()->getFlags());
5899 auto *
Store = cast<StoreSDNode>(
Op);
5900 assert(Store &&
Store->getValue().getValueType().isVector() &&
5901 "Expected vector store");
5904 Store->getMemoryVT(),
5905 *
Store->getMemOperand()))
5912 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
5913 "Unexpected unaligned RVV store type");
5917 "Expecting equally-sized RVV vector types to be legal");
5918 StoredVal = DAG.
getBitcast(NewVT, StoredVal);
5920 Store->getPointerInfo(),
Store->getOriginalAlign(),
5921 Store->getMemOperand()->getFlags());
5926 assert(
Op.getValueType() == MVT::i64 &&
"Unexpected VT");
5928 int64_t Imm = cast<ConstantSDNode>(
Op)->getSExtValue();
5955 unsigned ShiftAmt, AddOpc;
5966 MVT VT =
Op.getSimpleValueType();
5967 const APFloat &
Imm = cast<ConstantFPSDNode>(
Op)->getValueAPF();
5970 bool Negate =
false;
5974 if (Index < 0 &&
Imm.isNegative()) {
6002 if (Subtarget.hasStdExtZtso()) {
6026 MVT VT =
Op.getSimpleValueType();
6028 unsigned Check =
Op.getConstantOperandVal(1);
6029 unsigned TDCMask = 0;
6057 MVT VT0 =
Op.getOperand(0).getSimpleValueType();
6062 if (
Op.getOpcode() == ISD::VP_IS_FPCLASS) {
6064 VL =
Op.getOperand(3);
6067 VL,
Op->getFlags());
6082 if (
Op.getOpcode() == ISD::VP_IS_FPCLASS) {
6084 MVT MaskContainerVT =
6087 VL =
Op.getOperand(3);
6092 Mask, VL,
Op->getFlags());
6095 DAG.
getUNDEF(ContainerDstVT), TDCMaskV, VL);
6100 DAG.
getUNDEF(ContainerVT), Mask, VL});
6104 TDCMaskV, DAG.
getUNDEF(ContainerDstVT), Mask, VL);
6108 DAG.
getUNDEF(ContainerDstVT), SplatZero, VL);
6112 DAG.
getUNDEF(ContainerVT), Mask, VL});
6128 MVT VT =
Op.getSimpleValueType();
6155 return DAG.
getNode(Opc,
DL, VT, NewX, NewY);
6162 MVT ContainerVT = VT;
6170 if (
Op->isVPOpcode()) {
6171 Mask =
Op.getOperand(2);
6175 VL =
Op.getOperand(3);
6183 {X, X, DAG.getCondCode(ISD::SETOEQ),
6184 DAG.getUNDEF(ContainerVT), Mask, VL});
6192 {Y, Y, DAG.getCondCode(ISD::SETOEQ),
6193 DAG.getUNDEF(ContainerVT), Mask, VL});
6203 DAG.
getUNDEF(ContainerVT), Mask, VL);
6213 "Wrong opcode for lowering FABS or FNEG.");
6216 MVT VT =
Op.getSimpleValueType();
6217 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
6224 Mask = Mask.sext(Subtarget.
getXLen());
6237 MVT VT =
Op.getSimpleValueType();
6238 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
6248 if (SignSize == Subtarget.
getXLen()) {
6250 }
else if (SignSize == 16) {
6252 }
else if (SignSize == 32) {
6254 }
else if (SignSize == 64) {
6255 assert(XLenVT == MVT::i32 &&
"Unexpected type");
6265 if (ShiftAmount > 0) {
6268 }
else if (ShiftAmount < 0) {
6294#define OP_CASE(NODE) \
6296 return RISCVISD::NODE##_VL;
6297#define VP_CASE(NODE) \
6298 case ISD::VP_##NODE: \
6299 return RISCVISD::NODE##_VL;
6301 switch (
Op.getOpcode()) {
6379 case ISD::VP_CTLZ_ZERO_UNDEF:
6382 case ISD::VP_CTTZ_ZERO_UNDEF:
6391 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
6396 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
6401 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
6404 case ISD::VP_SELECT:
6413 case ISD::VP_SIGN_EXTEND:
6415 case ISD::VP_ZERO_EXTEND:
6417 case ISD::VP_FP_TO_SINT:
6419 case ISD::VP_FP_TO_UINT:
6422 case ISD::VP_FMINNUM:
6425 case ISD::VP_FMAXNUM:
6430 case ISD::VP_LLRINT:
6442 "not a RISC-V target specific op");
6446 "adding target specific op should update this function");
6466 "not a RISC-V target specific op");
6470 "adding target specific op should update this function");
6483 if (
Op.getValueType() == MVT::nxv32f16 &&
6487 if (
Op.getValueType() == MVT::nxv32bf16)
6500 if (!
Op.getOperand(j).getValueType().isVector()) {
6501 LoOperands[j] =
Op.getOperand(j);
6502 HiOperands[j] =
Op.getOperand(j);
6505 std::tie(LoOperands[j], HiOperands[j]) =
6510 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
6512 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
6527 std::tie(LoOperands[j], HiOperands[j]) =
6531 if (!
Op.getOperand(j).getValueType().isVector()) {
6532 LoOperands[j] =
Op.getOperand(j);
6533 HiOperands[j] =
Op.getOperand(j);
6536 std::tie(LoOperands[j], HiOperands[j]) =
6541 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
6543 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
6553 auto [EVLLo, EVLHi] =
6554 DAG.
SplitEVL(
Op.getOperand(3),
Op.getOperand(1).getValueType(),
DL);
6558 {Op.getOperand(0), Lo, MaskLo, EVLLo},
Op->getFlags());
6560 {ResLo, Hi, MaskHi, EVLHi},
Op->getFlags());
6578 if (!
Op.getOperand(j).getValueType().isVector()) {
6579 LoOperands[j] =
Op.getOperand(j);
6580 HiOperands[j] =
Op.getOperand(j);
6583 std::tie(LoOperands[j], HiOperands[j]) =
6588 DAG.
getNode(
Op.getOpcode(),
DL, LoVTs, LoOperands,
Op->getFlags());
6591 DAG.
getNode(
Op.getOpcode(),
DL, HiVTs, HiOperands,
Op->getFlags());
6600 switch (
Op.getOpcode()) {
6606 return lowerGlobalAddress(
Op, DAG);
6608 return lowerBlockAddress(
Op, DAG);
6610 return lowerConstantPool(
Op, DAG);
6612 return lowerJumpTable(
Op, DAG);
6614 return lowerGlobalTLSAddress(
Op, DAG);
6618 return lowerConstantFP(
Op, DAG);
6620 return lowerSELECT(
Op, DAG);
6622 return lowerBRCOND(
Op, DAG);
6624 return lowerVASTART(
Op, DAG);
6626 return lowerFRAMEADDR(
Op, DAG);
6628 return lowerRETURNADDR(
Op, DAG);
6630 return lowerShiftLeftParts(
Op, DAG);
6632 return lowerShiftRightParts(
Op, DAG,
true);
6634 return lowerShiftRightParts(
Op, DAG,
false);
6637 if (
Op.getValueType().isFixedLengthVector()) {
6638 assert(Subtarget.hasStdExtZvkb());
6639 return lowerToScalableOp(
Op, DAG);
6641 assert(Subtarget.hasVendorXTHeadBb() &&
6642 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
6643 "Unexpected custom legalization");
6645 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6650 EVT VT =
Op.getValueType();
6654 if (Op0VT == MVT::i16 &&
6656 (VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
6660 if (VT == MVT::f32 && Op0VT == MVT::i32 && Subtarget.
is64Bit() &&
6665 if (VT == MVT::f64 && Op0VT == MVT::i64 && !Subtarget.
is64Bit() &&
6681 "Unexpected types");
6715 return LowerINTRINSIC_WO_CHAIN(
Op, DAG);
6717 return LowerINTRINSIC_W_CHAIN(
Op, DAG);
6719 return LowerINTRINSIC_VOID(
Op, DAG);
6721 return LowerIS_FPCLASS(
Op, DAG);
6723 MVT VT =
Op.getSimpleValueType();
6725 assert(Subtarget.hasStdExtZvbb());
6726 return lowerToScalableOp(
Op, DAG);
6729 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected custom legalization");
6739 if (!
Op.getSimpleValueType().isVector())
6741 return lowerVectorTruncLike(
Op, DAG);
6744 if (
Op.getOperand(0).getValueType().isVector() &&
6745 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
6746 return lowerVectorMaskExt(
Op, DAG, 1);
6749 if (
Op.getOperand(0).getValueType().isVector() &&
6750 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
6751 return lowerVectorMaskExt(
Op, DAG, -1);
6754 return lowerSPLAT_VECTOR_PARTS(
Op, DAG);
6756 return lowerINSERT_VECTOR_ELT(
Op, DAG);
6758 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
6760 MVT VT =
Op.getSimpleValueType();
6768 MVT ContainerVT = VT;
6776 DAG.
getUNDEF(ContainerVT), Scalar, VL);
6780 DAG.
getUNDEF(ContainerVT), Scalar, VL);
6788 MVT VT =
Op.getSimpleValueType();
6808 }
else if ((Val % 8) == 0) {
6824 if (
Op.getValueType() == MVT::f16 && Subtarget.
is64Bit() &&
6825 Op.getOperand(1).getValueType() == MVT::i32) {
6842 return lowerVectorFPExtendOrRoundLike(
Op, DAG);
6845 return lowerStrictFPExtendOrRoundLike(
Op, DAG);
6848 if (
Op.getValueType().isVector() &&
6849 ((
Op.getValueType().getScalarType() == MVT::f16 &&
6852 Op.getValueType().getScalarType() == MVT::bf16)) {
6868 Op1.getValueType().isVector() &&
6869 ((Op1.getValueType().getScalarType() == MVT::f16 &&
6872 Op1.getValueType().getScalarType() == MVT::bf16)) {
6878 Op1.getValueType().getVectorElementCount());
6881 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), WidenVec);
6891 MVT VT =
Op.getSimpleValueType();
6894 bool IsStrict =
Op->isStrictFPOpcode();
6895 SDValue Src =
Op.getOperand(0 + IsStrict);
6896 MVT SrcVT = Src.getSimpleValueType();
6907 "Unexpected vector element types");
6911 if (EltSize > (2 * SrcEltSize)) {
6923 Op.getOperand(0), Ext);
6927 assert(SrcEltVT == MVT::f16 &&
"Unexpected FP_TO_[US]INT lowering");
6932 auto [FExt, Chain] =
6934 return DAG.
getNode(
Op.getOpcode(),
DL,
Op->getVTList(), Chain, FExt);
6941 if (SrcEltSize > (2 * EltSize)) {
6944 assert(EltVT == MVT::f16 &&
"Unexpected [US]_TO_FP lowering");
6949 Op.getOperand(0), Src);
6964 Op.getOperand(0), Src);
6978 unsigned RVVOpc = 0;
6979 switch (
Op.getOpcode()) {
7011 "Expected same element count");
7018 Op.getOperand(0), Src, Mask, VL);
7022 Src = DAG.
getNode(RVVOpc,
DL, ContainerVT, Src, Mask, VL);
7037 makeLibCall(DAG, LC, MVT::f32,
Op.getOperand(0), CallOptions,
DL).first;
7044 MVT VT =
Op.getSimpleValueType();
7064 bool IsStrict =
Op->isStrictFPOpcode();
7065 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
7069 std::tie(Res, Chain) =
7070 makeLibCall(DAG, LC, MVT::f32, Op0, CallOptions,
DL, Chain);
7085 bool IsStrict =
Op->isStrictFPOpcode();
7086 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
7092 std::tie(Res, Chain) =
makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MVT::f32, Arg,
7093 CallOptions,
DL, Chain);
7110 if (
Op.getValueType().isVector())
7115 assert(
Op.getOperand(0).getValueType() == MVT::f16 &&
7116 "Unexpected custom legalisation");
7119 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), Ext);
7125 assert(
Op.getOperand(1).getValueType() == MVT::f16 &&
7126 "Unexpected custom legalisation");
7129 {
Op.getOperand(0),
Op.getOperand(1)});
7130 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
7131 {Ext.getValue(1), Ext.getValue(0)});
7138 return lowerVECREDUCE(
Op, DAG);
7142 if (
Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
7143 return lowerVectorMaskVecReduction(
Op, DAG,
false);
7144 return lowerVECREDUCE(
Op, DAG);
7151 return lowerFPVECREDUCE(
Op, DAG);
7152 case ISD::VP_REDUCE_ADD:
7153 case ISD::VP_REDUCE_UMAX:
7154 case ISD::VP_REDUCE_SMAX:
7155 case ISD::VP_REDUCE_UMIN:
7156 case ISD::VP_REDUCE_SMIN:
7157 case ISD::VP_REDUCE_FADD:
7158 case ISD::VP_REDUCE_SEQ_FADD:
7159 case ISD::VP_REDUCE_FMIN:
7160 case ISD::VP_REDUCE_FMAX:
7161 case ISD::VP_REDUCE_FMINIMUM:
7162 case ISD::VP_REDUCE_FMAXIMUM:
7165 return lowerVPREDUCE(
Op, DAG);
7166 case ISD::VP_REDUCE_AND:
7167 case ISD::VP_REDUCE_OR:
7168 case ISD::VP_REDUCE_XOR:
7169 if (
Op.getOperand(1).getValueType().getVectorElementType() == MVT::i1)
7170 return lowerVectorMaskVecReduction(
Op, DAG,
true);
7171 return lowerVPREDUCE(
Op, DAG);
7172 case ISD::VP_CTTZ_ELTS:
7173 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
7174 return lowerVPCttzElements(
Op, DAG);
7178 DAG.
getUNDEF(ContainerVT), DAG, Subtarget);
7181 return lowerINSERT_SUBVECTOR(
Op, DAG);
7183 return lowerEXTRACT_SUBVECTOR(
Op, DAG);
7185 return lowerVECTOR_DEINTERLEAVE(
Op, DAG);
7187 return lowerVECTOR_INTERLEAVE(
Op, DAG);
7189 return lowerSTEP_VECTOR(
Op, DAG);
7191 return lowerVECTOR_REVERSE(
Op, DAG);
7193 return lowerVECTOR_SPLICE(
Op, DAG);
7197 MVT VT =
Op.getSimpleValueType();
7199 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) ||
7200 EltVT == MVT::bf16) {
7203 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
7204 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
7214 if (EltVT == MVT::i1)
7215 return lowerVectorMaskSplat(
Op, DAG);
7224 MVT VT =
Op.getSimpleValueType();
7225 MVT ContainerVT = VT;
7243 Op->ops().take_front(HalfNumOps));
7245 Op->ops().drop_front(HalfNumOps));
7249 unsigned NumOpElts =
7250 Op.getOperand(0).getSimpleValueType().getVectorMinNumElements();
7253 SDValue SubVec = OpIdx.value();
7264 auto *Load = cast<LoadSDNode>(
Op);
7265 EVT VecTy = Load->getMemoryVT();
7272 unsigned NumElts = Sz / (NF * 8);
7273 int Log2LMUL =
Log2_64(NumElts) - 3;
7276 Flag.setNoUnsignedWrap(
true);
7278 SDValue BasePtr = Load->getBasePtr();
7286 for (
unsigned i = 0; i < NF; ++i) {
7299 if (
auto V = expandUnalignedRVVLoad(
Op, DAG))
7301 if (
Op.getValueType().isFixedLengthVector())
7302 return lowerFixedLengthVectorLoadToRVV(
Op, DAG);
7306 auto *Store = cast<StoreSDNode>(
Op);
7307 SDValue StoredVal = Store->getValue();
7315 unsigned NumElts = Sz / (NF * 8);
7316 int Log2LMUL =
Log2_64(NumElts) - 3;
7319 Flag.setNoUnsignedWrap(
true);
7321 SDValue Chain = Store->getChain();
7322 SDValue BasePtr = Store->getBasePtr();
7329 for (
unsigned i = 0; i < NF; ++i) {
7333 Ret = DAG.
getStore(Chain,
DL, Extract, BasePtr,
7335 Store->getOriginalAlign(),
7336 Store->getMemOperand()->getFlags());
7337 Chain = Ret.getValue(0);
7343 if (
auto V = expandUnalignedRVVStore(
Op, DAG))
7345 if (
Op.getOperand(1).getValueType().isFixedLengthVector())
7346 return lowerFixedLengthVectorStoreToRVV(
Op, DAG);
7351 return lowerMaskedLoad(
Op, DAG);
7354 return lowerMaskedStore(
Op, DAG);
7356 return lowerVectorCompress(
Op, DAG);
7365 EVT VT =
Op.getValueType();
7376 MVT OpVT =
Op.getOperand(0).getSimpleValueType();
7378 MVT VT =
Op.getSimpleValueType();
7383 "Unexpected CondCode");
7391 if (isa<ConstantSDNode>(
RHS)) {
7392 int64_t Imm = cast<ConstantSDNode>(
RHS)->getSExtValue();
7393 if (Imm != 0 && isInt<12>((
uint64_t)Imm + 1)) {
7415 return lowerFixedLengthVectorSetccToRVV(
Op, DAG);
7431 return lowerToScalableOp(
Op, DAG);
7435 if (
Op.getSimpleValueType().isFixedLengthVector())
7436 return lowerToScalableOp(
Op, DAG);
7438 assert(
Op.getOperand(1).getValueType() == MVT::i32 && Subtarget.
is64Bit() &&
7439 "Unexpected custom legalisation");
7443 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
7469 return lowerToScalableOp(
Op, DAG);
7473 EVT VT =
Op->getValueType(0);
7488 return lowerABS(
Op, DAG);
7493 if (Subtarget.hasStdExtZvbb())
7494 return lowerToScalableOp(
Op, DAG);
7496 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
7498 return lowerFixedLengthVectorSelectToRVV(
Op, DAG);
7500 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
7504 return lowerFixedLengthVectorFCOPYSIGNToRVV(
Op, DAG);
7513 return lowerToScalableOp(
Op, DAG);
7516 return lowerVectorStrictFSetcc(
Op, DAG);
7526 case ISD::VP_GATHER:
7527 return lowerMaskedGather(
Op, DAG);
7529 case ISD::VP_SCATTER:
7530 return lowerMaskedScatter(
Op, DAG);
7532 return lowerGET_ROUNDING(
Op, DAG);
7534 return lowerSET_ROUNDING(
Op, DAG);
7536 return lowerEH_DWARF_CFA(
Op, DAG);
7538 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7539 return lowerVPMergeMask(
Op, DAG);
7541 case ISD::VP_SELECT:
7549 case ISD::VP_UADDSAT:
7550 case ISD::VP_USUBSAT:
7551 case ISD::VP_SADDSAT:
7552 case ISD::VP_SSUBSAT:
7554 case ISD::VP_LLRINT:
7555 return lowerVPOp(
Op, DAG);
7559 return lowerLogicVPOp(
Op, DAG);
7568 case ISD::VP_FMINNUM:
7569 case ISD::VP_FMAXNUM:
7570 case ISD::VP_FCOPYSIGN:
7577 return lowerVPOp(
Op, DAG);
7578 case ISD::VP_IS_FPCLASS:
7579 return LowerIS_FPCLASS(
Op, DAG);
7580 case ISD::VP_SIGN_EXTEND:
7581 case ISD::VP_ZERO_EXTEND:
7582 if (
Op.getOperand(0).getSimpleValueType().getVectorElementType() == MVT::i1)
7583 return lowerVPExtMaskOp(
Op, DAG);
7584 return lowerVPOp(
Op, DAG);
7585 case ISD::VP_TRUNCATE:
7586 return lowerVectorTruncLike(
Op, DAG);
7587 case ISD::VP_FP_EXTEND:
7588 case ISD::VP_FP_ROUND:
7589 return lowerVectorFPExtendOrRoundLike(
Op, DAG);
7590 case ISD::VP_SINT_TO_FP:
7591 case ISD::VP_UINT_TO_FP:
7592 if (
Op.getValueType().isVector() &&
7593 ((
Op.getValueType().getScalarType() == MVT::f16 &&
7596 Op.getValueType().getScalarType() == MVT::bf16)) {
7609 case ISD::VP_FP_TO_SINT:
7610 case ISD::VP_FP_TO_UINT:
7612 Op1.getValueType().isVector() &&
7613 ((Op1.getValueType().getScalarType() == MVT::f16 &&
7616 Op1.getValueType().getScalarType() == MVT::bf16)) {
7622 Op1.getValueType().getVectorElementCount());
7626 {WidenVec, Op.getOperand(1), Op.getOperand(2)});
7628 return lowerVPFPIntConvOp(
Op, DAG);
7632 if (
Op.getOperand(0).getSimpleValueType().getVectorElementType() == MVT::i1)
7633 return lowerVPSetCCMaskOp(
Op, DAG);
7639 case ISD::VP_BITREVERSE:
7641 return lowerVPOp(
Op, DAG);
7643 case ISD::VP_CTLZ_ZERO_UNDEF:
7644 if (Subtarget.hasStdExtZvbb())
7645 return lowerVPOp(
Op, DAG);
7646 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
7648 case ISD::VP_CTTZ_ZERO_UNDEF:
7649 if (Subtarget.hasStdExtZvbb())
7650 return lowerVPOp(
Op, DAG);
7651 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
7653 return lowerVPOp(
Op, DAG);
7654 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
7655 return lowerVPStridedLoad(
Op, DAG);
7656 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
7657 return lowerVPStridedStore(
Op, DAG);
7659 case ISD::VP_FFLOOR:
7661 case ISD::VP_FNEARBYINT:
7662 case ISD::VP_FROUND:
7663 case ISD::VP_FROUNDEVEN:
7664 case ISD::VP_FROUNDTOZERO:
7668 case ISD::VP_FMAXIMUM:
7669 case ISD::VP_FMINIMUM:
7673 case ISD::EXPERIMENTAL_VP_SPLICE:
7674 return lowerVPSpliceExperimental(
Op, DAG);
7675 case ISD::EXPERIMENTAL_VP_REVERSE:
7676 return lowerVPReverseExperimental(
Op, DAG);
7677 case ISD::EXPERIMENTAL_VP_SPLAT:
7678 return lowerVPSplatExperimental(
Op, DAG);
7681 "llvm.clear_cache only needs custom lower on Linux targets");
7684 return emitFlushICache(DAG,
Op.getOperand(0),
Op.getOperand(1),
7685 Op.getOperand(2), Flags,
DL);
7688 return lowerINIT_TRAMPOLINE(
Op, DAG);
7690 return lowerADJUST_TRAMPOLINE(
Op, DAG);
7697 MakeLibCallOptions CallOptions;
7698 std::pair<SDValue, SDValue> CallResult =
7699 makeLibCall(DAG, RTLIB::RISCV_FLUSH_ICACHE, MVT::isVoid,
7700 {Start,
End, Flags}, CallOptions,
DL, InChain);
7703 return CallResult.second;
7716 std::unique_ptr<MCCodeEmitter> CodeEmitter(
7723 const Value *TrmpAddr = cast<SrcValueSDNode>(
Op.getOperand(4))->getValue();
7735 constexpr unsigned StaticChainOffset = 16;
7736 constexpr unsigned FunctionAddressOffset = 24;
7740 auto GetEncoding = [&](
const MCInst &MC) {
7743 CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI);
7753 GetEncoding(
MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)),
7758 MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(
7759 FunctionAddressOffset)),
7763 MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(
7764 StaticChainOffset)),
7783 SDValue FunctionAddress =
Op.getOperand(2);
7787 struct OffsetValuePair {
7791 } OffsetValues[] = {
7792 {StaticChainOffset, StaticChain},
7793 {FunctionAddressOffset, FunctionAddress},
7798 DAG.
getConstant(OffsetValue.Offset, dl, MVT::i64));
7799 OffsetValue.Addr =
Addr;
7800 OutChains[
Idx + 4] =
7809 SDValue EndOfTrmp = OffsetValues[0].Addr;
7823 return Op.getOperand(0);
7840 N->getOffset(), Flags);
7869template <
class NodeTy>
7871 bool IsLocal,
bool IsExternWeak)
const {
7881 if (IsLocal && !Subtarget.allowTaggedGlobals())
7951 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
7960 return getAddr(
N, DAG);
7967 return getAddr(
N, DAG);
7974 return getAddr(
N, DAG);
7979 bool UseGOT)
const {
8043 Args.push_back(Entry);
8076 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
8090 Addr = getStaticTLSAddr(
N, DAG,
false);
8093 Addr = getStaticTLSAddr(
N, DAG,
true);
8098 : getDynamicTLSAddr(
N, DAG);
8115 if (
LHS == LHS2 &&
RHS == RHS2) {
8120 }
else if (
LHS == RHS2 &&
RHS == LHS2) {
8128 return std::nullopt;
8136 MVT VT =
N->getSimpleValueType(0);
8166 if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
8169 if (~TrueVal == FalseVal) {
8209 if (Subtarget.hasShortForwardBranchOpt())
8212 unsigned SelOpNo = 0;
8222 unsigned ConstSelOpNo = 1;
8223 unsigned OtherSelOpNo = 2;
8224 if (!dyn_cast<ConstantSDNode>(Sel->
getOperand(ConstSelOpNo))) {
8229 ConstantSDNode *ConstSelOpNode = dyn_cast<ConstantSDNode>(ConstSelOp);
8230 if (!ConstSelOpNode || ConstSelOpNode->
isOpaque())
8234 ConstantSDNode *ConstBinOpNode = dyn_cast<ConstantSDNode>(ConstBinOp);
8235 if (!ConstBinOpNode || ConstBinOpNode->
isOpaque())
8241 SDValue NewConstOps[2] = {ConstSelOp, ConstBinOp};
8243 std::swap(NewConstOps[0], NewConstOps[1]);
8255 SDValue NewNonConstOps[2] = {OtherSelOp, ConstBinOp};
8257 std::swap(NewNonConstOps[0], NewNonConstOps[1]);
8260 SDValue NewT = (ConstSelOpNo == 1) ? NewConstOp : NewNonConstOp;
8261 SDValue NewF = (ConstSelOpNo == 1) ? NewNonConstOp : NewConstOp;
8270 MVT VT =
Op.getSimpleValueType();
8284 if ((Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps()) &&
8312 if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
8316 TrueVal, Subtarget.
getXLen(), Subtarget,
true);
8318 FalseVal, Subtarget.
getXLen(), Subtarget,
true);
8319 bool IsCZERO_NEZ = TrueValCost <= FalseValCost;
8321 IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal,
DL, VT);
8326 DL, VT, LHSVal, CondV);
8342 if (
Op.hasOneUse()) {
8343 unsigned UseOpc =
Op->user_begin()->getOpcode();
8352 return lowerSELECT(NewSel, DAG);
8381 SDValue Ops[] = {CondV,
Zero, SetNE, TrueV, FalseV};
8402 if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV) &&
8406 if (TrueVal - 1 == FalseVal)
8408 if (TrueVal + 1 == FalseVal)
8415 RHS == TrueV && LHS == FalseV) {
8432 if (isa<ConstantSDNode>(TrueV) && !isa<ConstantSDNode>(FalseV)) {
8458 LHS, RHS, TargetCC,
Op.getOperand(2));
8476 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
8488 int XLenInBytes = Subtarget.
getXLen() / 8;
8490 EVT VT =
Op.getValueType();
8493 unsigned Depth =
Op.getConstantOperandVal(0);
8495 int Offset = -(XLenInBytes * 2);
8512 int XLenInBytes = Subtarget.
getXLen() / 8;
8517 EVT VT =
Op.getValueType();
8519 unsigned Depth =
Op.getConstantOperandVal(0);
8521 int Off = -XLenInBytes;
8522 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
8541 EVT VT =
Lo.getValueType();
8580 EVT VT =
Lo.getValueType();
8631 MVT VT =
Op.getSimpleValueType();
8657 MVT VecVT =
Op.getSimpleValueType();
8659 "Unexpected SPLAT_VECTOR_PARTS lowering");
8665 MVT ContainerVT = VecVT;
8685 int64_t ExtTrueVal)
const {
8687 MVT VecVT =
Op.getSimpleValueType();
8690 assert(Src.getValueType().isVector() &&
8691 Src.getValueType().getVectorElementType() == MVT::i1);
8712 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
8714 DAG.
getUNDEF(ContainerVT), SplatTrueVal, VL);
8717 SplatZero, DAG.
getUNDEF(ContainerVT), VL);
8722SDValue RISCVTargetLowering::lowerFixedLengthVectorExtendToRVV(
8724 MVT ExtVT =
Op.getSimpleValueType();
8728 MVT VT =
Op.getOperand(0).getSimpleValueType();
8754 bool IsVPTrunc =
Op.getOpcode() == ISD::VP_TRUNCATE;
8756 EVT MaskVT =
Op.getValueType();
8759 "Unexpected type for vector mask lowering");
8761 MVT VecVT = Src.getSimpleValueType();
8765 VL =
Op.getOperand(2);
8768 MVT ContainerVT = VecVT;
8774 MVT MaskContainerVT =
8781 std::tie(Mask, VL) =
8789 DAG.
getUNDEF(ContainerVT), SplatOne, VL);
8791 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
8795 DAG.
getUNDEF(ContainerVT), Mask, VL);
8798 DAG.
getUNDEF(MaskContainerVT), Mask, VL});
8806 unsigned Opc =
Op.getOpcode();
8807 bool IsVPTrunc = Opc == ISD::VP_TRUNCATE;
8810 MVT VT =
Op.getSimpleValueType();
8812 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
8816 return lowerVectorMaskTruncLike(
Op, DAG);
8824 MVT SrcVT = Src.getSimpleValueType();
8829 "Unexpected vector truncate lowering");
8831 MVT ContainerVT = SrcVT;
8835 VL =
Op.getOperand(2);
8848 std::tie(Mask, VL) =
8864 }
while (SrcEltVT != DstEltVT);
8873RISCVTargetLowering::lowerStrictFPExtendOrRoundLike(
SDValue Op,
8878 MVT VT =
Op.getSimpleValueType();
8879 MVT SrcVT = Src.getSimpleValueType();
8880 MVT ContainerVT = VT;
8903 Chain, Src, Mask, VL);
8904 Chain = Src.getValue(1);
8911 Chain, Src, Mask, VL);
8922RISCVTargetLowering::lowerVectorFPExtendOrRoundLike(
SDValue Op,
8925 Op.getOpcode() == ISD::VP_FP_ROUND ||
Op.getOpcode() == ISD::VP_FP_EXTEND;
8932 MVT VT =
Op.getSimpleValueType();
8934 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
8937 MVT SrcVT = Src.getSimpleValueType();
8939 bool IsDirectExtend =
8947 bool IsDirectConv = IsDirectExtend || IsDirectTrunc;
8950 MVT ContainerVT = VT;
8954 VL =
Op.getOperand(2);
8968 std::tie(Mask, VL) =
8974 Src = DAG.
getNode(ConvOpc,
DL, ContainerVT, Src, Mask, VL);
8980 unsigned InterConvOpc =
8985 DAG.
getNode(InterConvOpc,
DL, InterVT, Src, Mask, VL);
8987 DAG.
getNode(ConvOpc,
DL, ContainerVT, IntermediateConv, Mask, VL);
8998static std::optional<MVT>
9004 const unsigned MinVLMAX = VectorBitsMin / EltSize;
9006 if (MaxIdx < MinVLMAX)
9008 else if (MaxIdx < MinVLMAX * 2)
9010 else if (MaxIdx < MinVLMAX * 4)
9015 return std::nullopt;
9028 MVT VecVT =
Op.getSimpleValueType();
9045 ValVT == MVT::bf16) {
9054 MVT ContainerVT = VecVT;
9063 MVT OrigContainerVT = ContainerVT;
9066 if (
auto *IdxC = dyn_cast<ConstantSDNode>(
Idx)) {
9067 const unsigned OrigIdx = IdxC->getZExtValue();
9070 DL, DAG, Subtarget)) {
9071 ContainerVT = *ShrunkVT;
9080 VLEN && ContainerVT.
bitsGT(M1VT)) {
9083 unsigned RemIdx = OrigIdx % ElemsPerVReg;
9084 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
9085 unsigned ExtractIdx =
9102 if (!IsLegalInsert && isa<ConstantSDNode>(Val)) {
9103 const auto *CVal = cast<ConstantSDNode>(Val);
9104 if (isInt<32>(CVal->getSExtValue())) {
9105 IsLegalInsert =
true;
9114 if (IsLegalInsert) {
9120 Vec = DAG.
getNode(Opc,
DL, ContainerVT, Vec, Val, VL);
9136 std::tie(ValLo, ValHi) = DAG.
SplitScalar(Val,
DL, MVT::i32, MVT::i32);
9137 MVT I32ContainerVT =
9148 Vec, Vec, ValLo, I32Mask, InsertI64VL);
9153 Tail, ValInVec, ValHi, I32Mask, InsertI64VL);
9155 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
9160 ValInVec, AlignedIdx);
9170 DAG.
getUNDEF(I32ContainerVT), ValLo,
9171 I32Mask, InsertI64VL);
9173 DAG.
getUNDEF(I32ContainerVT), ValInVec, ValHi,
9174 I32Mask, InsertI64VL);
9176 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
9189 Idx, Mask, InsertVL, Policy);
9193 Slideup, AlignedIdx);
9208 EVT EltVT =
Op.getValueType();
9215 MVT ContainerVT = VecVT;
9231 unsigned WidenVecLen;
9234 unsigned MaxEEW = Subtarget.
getELen();
9239 "the number of elements should be power of 2");
9243 ExtractBitIdx =
Idx;
9245 WideEltVT = LargestEltVT;
9248 ExtractElementIdx = DAG.
getNode(
9259 Vec, ExtractElementIdx);
9275 EltVT == MVT::bf16) {
9285 MVT ContainerVT = VecVT;
9296 if (
auto *IdxC = dyn_cast<ConstantSDNode>(
Idx);
9297 IdxC && VLen && VecVT.
getSizeInBits().getKnownMinValue() > *VLen) {
9299 unsigned OrigIdx = IdxC->getZExtValue();
9302 unsigned RemIdx = OrigIdx % ElemsPerVReg;
9303 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
9304 unsigned ExtractIdx =
9314 std::optional<uint64_t> MaxIdx;
9317 if (
auto *IdxC = dyn_cast<ConstantSDNode>(
Idx))
9318 MaxIdx = IdxC->getZExtValue();
9320 if (
auto SmallerVT =
9322 ContainerVT = *SmallerVT;
9369 "Unexpected opcode");
9376 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
9381 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
9382 if (!
II || !
II->hasScalarOperand())
9385 unsigned SplatOp =
II->ScalarOperand + 1 + HasChain;
9398 if (OpVT.
bitsLT(XLenVT)) {
9405 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
9415 assert(
II->ScalarOperand > 0 &&
"Unexpected splat operand!");
9416 MVT VT =
Op.getOperand(SplatOp - 1).getSimpleValueType();
9419 assert(XLenVT == MVT::i32 && OpVT == MVT::i64 &&
9430 case Intrinsic::riscv_vslide1up:
9431 case Intrinsic::riscv_vslide1down:
9432 case Intrinsic::riscv_vslide1up_mask:
9433 case Intrinsic::riscv_vslide1down_mask: {
9436 bool IsMasked = NumOps == 7;
9442 std::tie(ScalarLo, ScalarHi) =
9450 if (isa<ConstantSDNode>(AVL)) {
9451 const auto [MinVLMAX, MaxVLMAX] =
9455 if (AVLInt <= MinVLMAX) {
9457 }
else if (AVLInt >= 2 * MaxVLMAX) {
9491 if (IntNo == Intrinsic::riscv_vslide1up ||
9492 IntNo == Intrinsic::riscv_vslide1up_mask) {
9494 ScalarHi, I32Mask, I32VL);
9496 ScalarLo, I32Mask, I32VL);
9499 ScalarLo, I32Mask, I32VL);
9501 ScalarHi, I32Mask, I32VL);
9550 const unsigned ElementWidth = 8;
9555 [[maybe_unused]]
unsigned MinVF =
9558 [[maybe_unused]]
unsigned VF =
N->getConstantOperandVal(2);
9562 bool Fractional = VF < LMul1VF;
9563 unsigned LMulVal = Fractional ? LMul1VF / VF : VF / LMul1VF;
9584 MVT ContainerVT = OpVT;
9611 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
9615 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
9616 if (!
II || !
II->hasScalarOperand())
9619 unsigned SplatOp =
II->ScalarOperand + 1;
9632 if (OpVT.
bitsLT(XLenVT)) {
9635 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
9646 EVT ValType = V.getValueType();
9647 if (ValType.isVector() && ValType.isFloatingPoint()) {
9650 ValType.getVectorElementCount());
9653 if (ValType.isFixedLengthVector()) {
9655 DAG, V.getSimpleValueType(), Subtarget);
9671 unsigned IntNo =
Op.getConstantOperandVal(0);
9678 case Intrinsic::riscv_tuple_insert: {
9686 case Intrinsic::riscv_tuple_extract: {
9693 case Intrinsic::thread_pointer: {
9697 case Intrinsic::riscv_orc_b:
9698 case Intrinsic::riscv_brev8:
9699 case Intrinsic::riscv_sha256sig0:
9700 case Intrinsic::riscv_sha256sig1:
9701 case Intrinsic::riscv_sha256sum0:
9702 case Intrinsic::riscv_sha256sum1:
9703 case Intrinsic::riscv_sm3p0:
9704 case Intrinsic::riscv_sm3p1: {
9717 return DAG.
getNode(Opc,
DL, XLenVT,
Op.getOperand(1));
9719 case Intrinsic::riscv_sm4ks:
9720 case Intrinsic::riscv_sm4ed: {
9724 return DAG.
getNode(Opc,
DL, XLenVT,
Op.getOperand(1),
Op.getOperand(2),
9727 case Intrinsic::riscv_zip:
9728 case Intrinsic::riscv_unzip: {
9731 return DAG.
getNode(Opc,
DL, XLenVT,
Op.getOperand(1));
9733 case Intrinsic::riscv_mopr:
9737 case Intrinsic::riscv_moprr: {
9739 Op.getOperand(2),
Op.getOperand(3));
9741 case Intrinsic::riscv_clmul:
9744 case Intrinsic::riscv_clmulh:
9745 case Intrinsic::riscv_clmulr: {
9748 return DAG.
getNode(Opc,
DL, XLenVT,
Op.getOperand(1),
Op.getOperand(2));
9750 case Intrinsic::experimental_get_vector_length:
9752 case Intrinsic::experimental_cttz_elts:
9754 case Intrinsic::riscv_vmv_x_s: {
9758 case Intrinsic::riscv_vfmv_f_s:
9761 case Intrinsic::riscv_vmv_v_x:
9763 Op.getOperand(3),
Op.getSimpleValueType(),
DL, DAG,
9765 case Intrinsic::riscv_vfmv_v_f:
9767 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
9768 case Intrinsic::riscv_vmv_s_x: {
9771 if (
Scalar.getValueType().bitsLE(XLenVT)) {
9774 Op.getOperand(1), Scalar,
Op.getOperand(3));
9777 assert(
Scalar.getValueType() == MVT::i64 &&
"Unexpected scalar VT!");
9794 MVT VT =
Op.getSimpleValueType();
9799 if (
Op.getOperand(1).isUndef())
9815 case Intrinsic::riscv_vfmv_s_f:
9817 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
9819 case Intrinsic::riscv_vaesdf_vv:
9820 case Intrinsic::riscv_vaesdf_vs:
9821 case Intrinsic::riscv_vaesdm_vv:
9822 case Intrinsic::riscv_vaesdm_vs:
9823 case Intrinsic::riscv_vaesef_vv:
9824 case Intrinsic::riscv_vaesef_vs:
9825 case Intrinsic::riscv_vaesem_vv:
9826 case Intrinsic::riscv_vaesem_vs:
9827 case Intrinsic::riscv_vaeskf1:
9828 case Intrinsic::riscv_vaeskf2:
9829 case Intrinsic::riscv_vaesz_vs:
9830 case Intrinsic::riscv_vsm4k:
9831 case Intrinsic::riscv_vsm4r_vv:
9832 case Intrinsic::riscv_vsm4r_vs: {
9833 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
9834 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
9835 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
9840 case Intrinsic::riscv_vsm3c:
9841 case Intrinsic::riscv_vsm3me: {
9842 if (!
isValidEGW(8,
Op.getSimpleValueType(), Subtarget) ||
9843 !
isValidEGW(8,
Op->getOperand(1).getSimpleValueType(), Subtarget))
9848 case Intrinsic::riscv_vsha2ch:
9849 case Intrinsic::riscv_vsha2cl:
9850 case Intrinsic::riscv_vsha2ms: {
9851 if (
Op->getSimpleValueType(0).getScalarSizeInBits() == 64 &&
9852 !Subtarget.hasStdExtZvknhb())
9854 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
9855 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
9856 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
9860 case Intrinsic::riscv_sf_vc_v_x:
9861 case Intrinsic::riscv_sf_vc_v_i:
9862 case Intrinsic::riscv_sf_vc_v_xv:
9863 case Intrinsic::riscv_sf_vc_v_iv:
9864 case Intrinsic::riscv_sf_vc_v_vv:
9865 case Intrinsic::riscv_sf_vc_v_fv:
9866 case Intrinsic::riscv_sf_vc_v_xvv:
9867 case Intrinsic::riscv_sf_vc_v_ivv:
9868 case Intrinsic::riscv_sf_vc_v_vvv:
9869 case Intrinsic::riscv_sf_vc_v_fvv:
9870 case Intrinsic::riscv_sf_vc_v_xvw:
9871 case Intrinsic::riscv_sf_vc_v_ivw:
9872 case Intrinsic::riscv_sf_vc_v_vvw:
9873 case Intrinsic::riscv_sf_vc_v_fvw: {
9874 MVT VT =
Op.getSimpleValueType();
9911 MVT VT =
Op.getSimpleValueType();
9915 if (VT.isFloatingPoint()) {
9920 if (VT.isFixedLengthVector())
9930 if (VT.isFixedLengthVector())
9932 if (VT.isFloatingPoint())
9951 unsigned IntNo =
Op.getConstantOperandVal(1);
9955 case Intrinsic::riscv_seg2_load:
9956 case Intrinsic::riscv_seg3_load:
9957 case Intrinsic::riscv_seg4_load:
9958 case Intrinsic::riscv_seg5_load:
9959 case Intrinsic::riscv_seg6_load:
9960 case Intrinsic::riscv_seg7_load:
9961 case Intrinsic::riscv_seg8_load: {
9964 Intrinsic::riscv_vlseg2, Intrinsic::riscv_vlseg3,
9965 Intrinsic::riscv_vlseg4, Intrinsic::riscv_vlseg5,
9966 Intrinsic::riscv_vlseg6, Intrinsic::riscv_vlseg7,
9967 Intrinsic::riscv_vlseg8};
9968 unsigned NF =
Op->getNumValues() - 1;
9969 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
9971 MVT VT =
Op->getSimpleValueType(0);
9979 auto *
Load = cast<MemIntrinsicSDNode>(
Op);
9991 Load->getMemoryVT(),
Load->getMemOperand());
9993 for (
unsigned int RetIdx = 0; RetIdx < NF; RetIdx++) {
10002 case Intrinsic::riscv_sf_vc_v_x_se:
10004 case Intrinsic::riscv_sf_vc_v_i_se:
10006 case Intrinsic::riscv_sf_vc_v_xv_se:
10008 case Intrinsic::riscv_sf_vc_v_iv_se:
10010 case Intrinsic::riscv_sf_vc_v_vv_se:
10012 case Intrinsic::riscv_sf_vc_v_fv_se:
10014 case Intrinsic::riscv_sf_vc_v_xvv_se:
10016 case Intrinsic::riscv_sf_vc_v_ivv_se:
10018 case Intrinsic::riscv_sf_vc_v_vvv_se:
10020 case Intrinsic::riscv_sf_vc_v_fvv_se:
10022 case Intrinsic::riscv_sf_vc_v_xvw_se:
10024 case Intrinsic::riscv_sf_vc_v_ivw_se:
10026 case Intrinsic::riscv_sf_vc_v_vvw_se:
10028 case Intrinsic::riscv_sf_vc_v_fvw_se:
10037 unsigned IntNo =
Op.getConstantOperandVal(1);
10041 case Intrinsic::riscv_seg2_store:
10042 case Intrinsic::riscv_seg3_store:
10043 case Intrinsic::riscv_seg4_store:
10044 case Intrinsic::riscv_seg5_store:
10045 case Intrinsic::riscv_seg6_store:
10046 case Intrinsic::riscv_seg7_store:
10047 case Intrinsic::riscv_seg8_store: {
10050 Intrinsic::riscv_vsseg2, Intrinsic::riscv_vsseg3,
10051 Intrinsic::riscv_vsseg4, Intrinsic::riscv_vsseg5,
10052 Intrinsic::riscv_vsseg6, Intrinsic::riscv_vsseg7,
10053 Intrinsic::riscv_vsseg8};
10056 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
10058 MVT VT =
Op->getOperand(2).getSimpleValueType();
10068 auto *FixedIntrinsic = cast<MemIntrinsicSDNode>(
Op);
10071 for (
unsigned i = 0; i < NF; i++)
10075 ContainerVT, FixedIntrinsic->getOperand(2 + i), DAG, Subtarget),
10079 FixedIntrinsic->getChain(),
10088 FixedIntrinsic->getMemoryVT(), FixedIntrinsic->getMemOperand());
10090 case Intrinsic::riscv_sf_vc_xv_se:
10092 case Intrinsic::riscv_sf_vc_iv_se:
10094 case Intrinsic::riscv_sf_vc_vv_se:
10096 case Intrinsic::riscv_sf_vc_fv_se:
10098 case Intrinsic::riscv_sf_vc_xvv_se:
10100 case Intrinsic::riscv_sf_vc_ivv_se:
10102 case Intrinsic::riscv_sf_vc_vvv_se:
10104 case Intrinsic::riscv_sf_vc_fvv_se:
10106 case Intrinsic::riscv_sf_vc_xvw_se:
10108 case Intrinsic::riscv_sf_vc_ivw_se:
10110 case Intrinsic::riscv_sf_vc_vvw_se:
10112 case Intrinsic::riscv_sf_vc_fvw_se:
10120 switch (ISDOpcode) {
10123 case ISD::VP_REDUCE_ADD:
10126 case ISD::VP_REDUCE_UMAX:
10129 case ISD::VP_REDUCE_SMAX:
10132 case ISD::VP_REDUCE_UMIN:
10135 case ISD::VP_REDUCE_SMIN:
10138 case ISD::VP_REDUCE_AND:
10141 case ISD::VP_REDUCE_OR:
10144 case ISD::VP_REDUCE_XOR:
10147 case ISD::VP_REDUCE_FADD:
10149 case ISD::VP_REDUCE_SEQ_FADD:
10151 case ISD::VP_REDUCE_FMAX:
10152 case ISD::VP_REDUCE_FMAXIMUM:
10154 case ISD::VP_REDUCE_FMIN:
10155 case ISD::VP_REDUCE_FMINIMUM:
10165 SDValue Vec =
Op.getOperand(IsVP ? 1 : 0);
10170 Op.getOpcode() == ISD::VP_REDUCE_AND ||
10171 Op.getOpcode() == ISD::VP_REDUCE_OR ||
10172 Op.getOpcode() == ISD::VP_REDUCE_XOR) &&
10173 "Unexpected reduction lowering");
10177 MVT ContainerVT = VecVT;
10185 Mask =
Op.getOperand(2);
10186 VL =
Op.getOperand(3);
10188 std::tie(Mask, VL) =
10193 switch (
Op.getOpcode()) {
10197 case ISD::VP_REDUCE_AND: {
10209 case ISD::VP_REDUCE_OR:
10215 case ISD::VP_REDUCE_XOR: {
10239 return DAG.
getNode(BaseOpc,
DL,
Op.getValueType(), SetCC,
Op.getOperand(0));
10243 auto *RegisterAVL = dyn_cast<RegisterSDNode>(AVL);
10244 auto *ImmAVL = dyn_cast<ConstantSDNode>(AVL);
10245 return (RegisterAVL && RegisterAVL->getReg() == RISCV::X0) ||
10246 (ImmAVL && ImmAVL->getZExtValue() >= 1);
10262 auto InnerVT = VecVT.
bitsLE(M1VT) ? VecVT : M1VT;
10266 auto InnerVL = NonZeroAVL ? VL : DAG.
getConstant(1,
DL, XLenVT);
10269 if (M1VT != InnerVT)
10275 SDValue Ops[] = {PassThru, Vec, InitialValue, Mask, VL, Policy};
10294 VecEVT =
Lo.getValueType();
10307 MVT ContainerVT = VecVT;
10327 Mask, VL,
DL, DAG, Subtarget);
10333static std::tuple<unsigned, SDValue, SDValue>
10337 auto Flags =
Op->getFlags();
10338 unsigned Opcode =
Op.getOpcode();
10362 return std::make_tuple(RVVOpc,
Op.getOperand(0), Front);
10370 MVT VecEltVT =
Op.getSimpleValueType();
10372 unsigned RVVOpcode;
10373 SDValue VectorVal, ScalarVal;
10374 std::tie(RVVOpcode, VectorVal, ScalarVal) =
10378 MVT ContainerVT = VecVT;
10384 MVT ResVT =
Op.getSimpleValueType();
10387 VL,
DL, DAG, Subtarget);
10392 if (
Op->getFlags().hasNoNaNs())
10398 {VectorVal, VectorVal, DAG.getCondCode(ISD::SETNE),
10399 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
10405 DL, ResVT, NoNaNs, Res,
10412 unsigned Opc =
Op.getOpcode();
10435 Vec, Mask, VL,
DL, DAG, Subtarget);
10436 if ((Opc != ISD::VP_REDUCE_FMINIMUM && Opc != ISD::VP_REDUCE_FMAXIMUM) ||
10437 Op->getFlags().hasNoNaNs())
10454 DL, ResVT, NoNaNs, Res,
10467 unsigned OrigIdx =
Op.getConstantOperandVal(2);
10470 if (OrigIdx == 0 && Vec.
isUndef())
10481 assert(OrigIdx % 8 == 0 &&
"Invalid index");
10484 "Unexpected mask vector lowering");
10516 MVT ContainerVT = VecVT;
10523 DAG.
getUNDEF(ContainerVT), SubVec,
10540 if (OrigIdx == 0) {
10545 SubVec =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, Vec, SubVec,
10546 SlideupAmt, Mask, VL, Policy);
10554 MVT ContainerVecVT = VecVT;
10560 MVT ContainerSubVecVT = SubVecVT;
10566 unsigned SubRegIdx;
10576 ContainerVecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
10577 SubRegIdx = Decompose.first;
10579 (OrigIdx % Vscale));
10583 ContainerVecVT, ContainerSubVecVT, OrigIdx,
TRI);
10584 SubRegIdx = Decompose.first;
10591 bool ExactlyVecRegSized =
10593 .isKnownMultipleOf(Subtarget.
expandVScale(VecRegSize));
10608 if (RemIdx.
isZero() && (ExactlyVecRegSized || Vec.
isUndef())) {
10612 if (SubRegIdx == RISCV::NoSubRegister) {
10635 MVT InterSubVT = ContainerVecVT;
10636 SDValue AlignedExtract = Vec;
10676 SubVec =
getVSlideup(DAG, Subtarget,
DL, InterSubVT, AlignedExtract, SubVec,
10677 SlideupAmt, Mask, VL, Policy);
10682 if (ContainerVecVT.
bitsGT(InterSubVT))
10691 return DAG.
getBitcast(
Op.getSimpleValueType(), SubVec);
10697 MVT SubVecVT =
Op.getSimpleValueType();
10702 unsigned OrigIdx =
Op.getConstantOperandVal(1);
10718 assert(OrigIdx % 8 == 0 &&
"Invalid index");
10721 "Unexpected mask vector lowering");
10755 MVT ContainerVT = VecVT;
10763 if (
auto ShrunkVT =
10765 ContainerVT = *ShrunkVT;
10778 DAG.
getUNDEF(ContainerVT), Vec, SlidedownAmt, Mask, VL);
10790 MVT ContainerSubVecVT = SubVecVT;
10794 unsigned SubRegIdx;
10804 VecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
10805 SubRegIdx = Decompose.first;
10807 (OrigIdx % Vscale));
10811 VecVT, ContainerSubVecVT, OrigIdx,
TRI);
10812 SubRegIdx = Decompose.first;
10839 MVT InterSubVT = VecVT;
10844 assert(SubRegIdx != RISCV::NoSubRegister);
10864 Vec, SlidedownAmt, Mask, VL);
10873 return DAG.
getBitcast(
Op.getSimpleValueType(), Slidedown);
10880 MVT VT =
N.getSimpleValueType();
10884 assert(
Op.getSimpleValueType() == VT &&
10885 "Operands and result must be same type");
10889 unsigned NumVals =
N->getNumValues();
10892 NumVals,
N.getValueType().changeVectorElementType(MVT::i8)));
10895 for (
unsigned I = 0;
I < NumVals;
I++) {
10901 if (TruncVals.
size() > 1)
10903 return TruncVals.
front();
10909 MVT VecVT =
Op.getSimpleValueType();
10912 "vector_interleave on non-scalable vector!");
10923 EVT SplitVT = Op0Lo.getValueType();
10926 DAG.
getVTList(SplitVT, SplitVT), Op0Lo, Op0Hi);
10928 DAG.
getVTList(SplitVT, SplitVT), Op1Lo, Op1Hi);
10942 Op.getOperand(0),
Op.getOperand(1));
10961 EvenSplat = DAG.
getBitcast(MVT::nxv64i1, EvenSplat);
10966 OddSplat = DAG.
getBitcast(MVT::nxv64i1, OddSplat);
10972 EvenMask, DAG.
getUNDEF(ConcatVT));
10988 MVT VecVT =
Op.getSimpleValueType();
10991 "vector_interleave on non-scalable vector!");
11004 EVT SplitVT = Op0Lo.getValueType();
11007 DAG.
getVTList(SplitVT, SplitVT), Op0Lo, Op1Lo);
11009 DAG.
getVTList(SplitVT, SplitVT), Op0Hi, Op1Hi);
11031 Op.getOperand(0),
Op.getOperand(1));
11079 MVT VT =
Op.getSimpleValueType();
11084 uint64_t StepValImm =
Op.getConstantOperandVal(0);
11085 if (StepValImm != 1) {
11094 VL, VT,
DL, DAG, Subtarget);
11109 MVT VecVT =
Op.getSimpleValueType();
11118 MVT ContainerVT = VecVT;
11172 unsigned MaxVLMAX =
11182 if (MaxVLMAX > 256 && EltSize == 8) {
11211 assert(isUInt<16>(MaxVLMAX - 1));
11237 DAG.
getUNDEF(ContainerVT), Mask, VL);
11249 MVT VecVT =
Op.getSimpleValueType();
11253 int64_t ImmValue = cast<ConstantSDNode>(
Op.getOperand(2))->getSExtValue();
11254 SDValue DownOffset, UpOffset;
11255 if (ImmValue >= 0) {
11271 DownOffset, TrueMask, UpOffset);
11272 return getVSlideup(DAG, Subtarget,
DL, VecVT, SlideDown, V2, UpOffset,
11278RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(
SDValue Op,
11281 auto *
Load = cast<LoadSDNode>(
Op);
11284 Load->getMemoryVT(),
11285 *
Load->getMemOperand()) &&
11286 "Expecting a correctly-aligned load");
11288 MVT VT =
Op.getSimpleValueType();
11294 const auto [MinVLMAX, MaxVLMAX] =
11297 getLMUL1VT(ContainerVT).bitsLE(ContainerVT)) {
11311 IsMaskOp ? Intrinsic::riscv_vlm : Intrinsic::riscv_vle,
DL, XLenVT);
11314 Ops.push_back(DAG.
getUNDEF(ContainerVT));
11315 Ops.push_back(
Load->getBasePtr());
11320 Load->getMemoryVT(),
Load->getMemOperand());
11327RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(
SDValue Op,
11330 auto *
Store = cast<StoreSDNode>(
Op);
11333 Store->getMemoryVT(),
11334 *
Store->getMemOperand()) &&
11335 "Expecting a correctly-aligned store");
11356 const auto [MinVLMAX, MaxVLMAX] =
11359 getLMUL1VT(ContainerVT).bitsLE(ContainerVT)) {
11370 IsMaskOp ? Intrinsic::riscv_vsm : Intrinsic::riscv_vse,
DL, XLenVT);
11373 {Store->getChain(), IntID, NewValue, Store->getBasePtr(), VL},
11374 Store->getMemoryVT(),
Store->getMemOperand());
11380 MVT VT =
Op.getSimpleValueType();
11382 const auto *MemSD = cast<MemSDNode>(
Op);
11383 EVT MemVT = MemSD->getMemoryVT();
11385 SDValue Chain = MemSD->getChain();
11389 bool IsExpandingLoad =
false;
11390 if (
const auto *VPLoad = dyn_cast<VPLoadSDNode>(
Op)) {
11391 Mask = VPLoad->getMask();
11393 VL = VPLoad->getVectorLength();
11395 const auto *MLoad = cast<MaskedLoadSDNode>(
Op);
11396 Mask = MLoad->getMask();
11397 PassThru = MLoad->getPassThru();
11398 IsExpandingLoad = MLoad->isExpandingLoad();
11405 MVT ContainerVT = VT;
11419 if (!IsUnmasked && IsExpandingLoad) {
11426 unsigned IntID = IsUnmasked || IsExpandingLoad ? Intrinsic::riscv_vle
11427 : Intrinsic::riscv_vle_mask;
11429 if (IntID == Intrinsic::riscv_vle)
11430 Ops.push_back(DAG.
getUNDEF(ContainerVT));
11432 Ops.push_back(PassThru);
11433 Ops.push_back(BasePtr);
11434 if (IntID == Intrinsic::riscv_vle_mask)
11435 Ops.push_back(Mask);
11437 if (IntID == Intrinsic::riscv_vle_mask)
11444 Chain =
Result.getValue(1);
11446 MVT IndexVT = ContainerVT;
11451 bool UseVRGATHEREI16 =
false;
11459 UseVRGATHEREI16 =
true;
11465 DAG.
getUNDEF(IndexVT), Mask, ExpandingVL);
11469 DL, ContainerVT, Result, Iota, PassThru, Mask, ExpandingVL);
11482 const auto *MemSD = cast<MemSDNode>(
Op);
11483 EVT MemVT = MemSD->getMemoryVT();
11485 SDValue Chain = MemSD->getChain();
11489 bool IsCompressingStore =
false;
11490 if (
const auto *VPStore = dyn_cast<VPStoreSDNode>(
Op)) {
11491 Val = VPStore->getValue();
11492 Mask = VPStore->getMask();
11493 VL = VPStore->getVectorLength();
11495 const auto *MStore = cast<MaskedStoreSDNode>(
Op);
11496 Val = MStore->getValue();
11497 Mask = MStore->getMask();
11498 IsCompressingStore = MStore->isCompressingStore();
11507 MVT ContainerVT = VT;
11512 if (!IsUnmasked || IsCompressingStore) {
11521 if (IsCompressingStore) {
11524 DAG.
getUNDEF(ContainerVT), Val, Mask, VL);
11531 IsUnmasked ? Intrinsic::riscv_vse : Intrinsic::riscv_vse_mask;
11533 Ops.push_back(Val);
11534 Ops.push_back(BasePtr);
11536 Ops.push_back(Mask);
11540 DAG.
getVTList(MVT::Other), Ops, MemVT, MMO);
11552 MVT ContainerVT = VT;
11565 Passthru, Val, Mask, VL);
11574RISCVTargetLowering::lowerFixedLengthVectorSetccToRVV(
SDValue Op,
11576 MVT InVT =
Op.getOperand(0).getSimpleValueType();
11579 MVT VT =
Op.getSimpleValueType();
11593 {Op1, Op2,
Op.getOperand(2), DAG.
getUNDEF(MaskVT), Mask, VL});
11600 unsigned Opc =
Op.getOpcode();
11607 MVT VT =
Op.getSimpleValueType();
11640 MVT ContainerInVT = InVT;
11659 {Chain, Op1, Op1, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
11663 {Chain, Op2, Op2, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
11671 {Chain, Op1, Op2, CC, Mask, Mask, VL});
11676 {Chain, Op1, Op2, CC, DAG.getUNDEF(MaskVT), Mask, VL});
11689 MVT VT =
Op.getSimpleValueType();
11693 "Unexpected type for ISD::ABS");
11695 MVT ContainerVT = VT;
11702 if (
Op->getOpcode() == ISD::VP_ABS) {
11703 Mask =
Op->getOperand(1);
11707 VL =
Op->getOperand(2);
11715 DAG.
getUNDEF(ContainerVT), Mask, VL);
11717 DAG.
getUNDEF(ContainerVT), Mask, VL);
11724SDValue RISCVTargetLowering::lowerFixedLengthVectorFCOPYSIGNToRVV(
11727 MVT VT =
Op.getSimpleValueType();
11731 "Can only handle COPYSIGN with matching types.");
11740 Sign, DAG.
getUNDEF(ContainerVT), Mask, VL);
11745SDValue RISCVTargetLowering::lowerFixedLengthVectorSelectToRVV(
11747 MVT VT =
Op.getSimpleValueType();
11750 MVT I1ContainerVT =
11764 Op2, DAG.
getUNDEF(ContainerVT), VL);
11775 MVT VT =
Op.getSimpleValueType();
11780 for (
const SDValue &V :
Op->op_values()) {
11781 assert(!isa<VTSDNode>(V) &&
"Unexpected VTSDNode node!");
11784 if (!
V.getValueType().isVector()) {
11790 assert(useRVVForFixedLengthVectorVT(
V.getSimpleValueType()) &&
11791 "Only fixed length vectors are supported!");
11805 if (
Op->isStrictFPOpcode()) {
11814 DAG.
getNode(NewOpc,
DL, ContainerVT, Ops,
Op->getFlags());
11828 MVT VT =
Op.getSimpleValueType();
11831 MVT ContainerVT = VT;
11837 assert(!isa<VTSDNode>(V) &&
"Unexpected VTSDNode node!");
11840 if (HasPassthruOp) {
11843 if (*MaskIdx == OpIdx.index())
11847 if (
Op.getOpcode() == ISD::VP_MERGE) {
11851 assert(
Op.getOpcode() == ISD::VP_SELECT);
11863 if (!
V.getValueType().isFixedLengthVector()) {
11868 MVT OpVT =
V.getSimpleValueType();
11870 assert(useRVVForFixedLengthVectorVT(OpVT) &&
11871 "Only fixed length vectors are supported!");
11876 return DAG.
getNode(RISCVISDOpc,
DL, VT, Ops,
Op->getFlags());
11886 MVT VT =
Op.getSimpleValueType();
11892 MVT ContainerVT = VT;
11902 DAG.
getUNDEF(ContainerVT), Zero, VL);
11905 Op.getOpcode() == ISD::VP_ZERO_EXTEND ? 1 : -1,
DL, XLenVT);
11907 DAG.
getUNDEF(ContainerVT), SplatValue, VL);
11910 ZeroSplat, DAG.
getUNDEF(ContainerVT), VL);
11919 MVT VT =
Op.getSimpleValueType();
11923 ISD::CondCode Condition = cast<CondCodeSDNode>(
Op.getOperand(2))->get();
11927 MVT ContainerVT = VT;
11937 switch (Condition) {
12005 MVT DstVT =
Op.getSimpleValueType();
12006 MVT SrcVT = Src.getSimpleValueType();
12019 if (DstEltSize >= SrcEltSize) {
12028 if (SrcEltSize == 1) {
12039 ZeroSplat, DAG.
getUNDEF(IntVT), VL);
12040 }
else if (DstEltSize > (2 * SrcEltSize)) {
12044 Src = DAG.
getNode(RISCVISDExtOpc,
DL, IntVT, Src, Mask, VL);
12050 "Wrong input/output vector types");
12053 if (DstEltSize > (2 * SrcEltSize)) {
12069 MVT InterimFVT = DstVT;
12070 if (SrcEltSize > (2 * DstEltSize)) {
12071 assert(SrcEltSize == (4 * DstEltSize) &&
"Unexpected types!");
12078 if (InterimFVT != DstVT) {
12084 "Wrong input/output vector types");
12088 if (DstEltSize == 1) {
12091 assert(SrcEltSize >= 16 &&
"Unexpected FP type!");
12101 DAG.
getUNDEF(InterimIVT), SplatZero, VL);
12111 while (InterimIVT != DstVT) {
12123 MVT VT =
Op.getSimpleValueType();
12132 MVT VT =
Op.getSimpleValueType();
12146 MVT ContainerVT = VT;
12167 SplatZero, DAG.
getUNDEF(PromotedVT), VL);
12170 SplatOne, SplatZero, DAG.
getUNDEF(PromotedVT), VLMax);
12174 TrueVal, FalseVal, FalseVal, VL);
12189RISCVTargetLowering::lowerVPSpliceExperimental(
SDValue Op,
12201 MVT VT =
Op.getSimpleValueType();
12202 MVT ContainerVT = VT;
12212 if (IsMaskVector) {
12223 SplatZeroOp1, DAG.
getUNDEF(ContainerVT), EVL1);
12232 SplatZeroOp2, DAG.
getUNDEF(ContainerVT), EVL2);
12235 int64_t ImmValue = cast<ConstantSDNode>(
Offset)->getSExtValue();
12236 SDValue DownOffset, UpOffset;
12237 if (ImmValue >= 0) {
12251 Op1, DownOffset, Mask, UpOffset);
12255 if (IsMaskVector) {
12259 {Result, DAG.getConstant(0, DL, ContainerVT),
12260 DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(getMaskTypeFor(ContainerVT)),
12275 MVT VT =
Op.getSimpleValueType();
12277 MVT ContainerVT = VT;
12293RISCVTargetLowering::lowerVPReverseExperimental(
SDValue Op,
12296 MVT VT =
Op.getSimpleValueType();
12303 MVT ContainerVT = VT;
12311 MVT GatherVT = ContainerVT;
12315 if (IsMaskVector) {
12326 SplatZero, DAG.
getUNDEF(IndicesVT), EVL);
12332 unsigned MaxVLMAX =
12341 if (MaxVLMAX > 256 && EltSize == 8) {
12369 DAG.
getUNDEF(GatherVT), Result, Diff, Mask, EVL);
12371 if (IsMaskVector) {
12394 DAG.
getUNDEF(IndicesVT), VecLen, EVL);
12396 DAG.
getUNDEF(IndicesVT), Mask, EVL);
12398 DAG.
getUNDEF(GatherVT), Mask, EVL);
12400 if (IsMaskVector) {
12415 MVT VT =
Op.getSimpleValueType();
12417 return lowerVPOp(
Op, DAG);
12424 MVT ContainerVT = VT;
12443 MVT VT =
Op.getSimpleValueType();
12444 MVT ContainerVT = VT;
12450 auto *VPNode = cast<VPStridedLoadSDNode>(
Op);
12456 : Intrinsic::riscv_vlse_mask,
12459 DAG.
getUNDEF(ContainerVT), VPNode->getBasePtr(),
12460 VPNode->getStride()};
12468 Ops.
push_back(VPNode->getVectorLength());
12476 VPNode->getMemoryVT(), VPNode->getMemOperand());
12490 auto *VPNode = cast<VPStridedStoreSDNode>(
Op);
12491 SDValue StoreVal = VPNode->getValue();
12493 MVT ContainerVT = VT;
12504 : Intrinsic::riscv_vsse_mask,
12507 VPNode->getBasePtr(), VPNode->getStride()};
12515 Ops.
push_back(VPNode->getVectorLength());
12518 Ops, VPNode->getMemoryVT(),
12519 VPNode->getMemOperand());
12531 MVT VT =
Op.getSimpleValueType();
12533 const auto *MemSD = cast<MemSDNode>(
Op.getNode());
12534 EVT MemVT = MemSD->getMemoryVT();
12536 SDValue Chain = MemSD->getChain();
12542 if (
auto *VPGN = dyn_cast<VPGatherSDNode>(
Op.getNode())) {
12543 Index = VPGN->getIndex();
12544 Mask = VPGN->getMask();
12546 VL = VPGN->getVectorLength();
12551 auto *MGN = cast<MaskedGatherSDNode>(
Op.getNode());
12552 Index = MGN->getIndex();
12553 Mask = MGN->getMask();
12554 PassThru = MGN->getPassThru();
12558 MVT IndexVT =
Index.getSimpleValueType();
12562 "Unexpected VTs!");
12563 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
12566 "Unexpected extending MGATHER/VP_GATHER");
12572 MVT ContainerVT = VT;
12596 IsUnmasked ? Intrinsic::riscv_vluxei : Intrinsic::riscv_vluxei_mask;
12613 Chain =
Result.getValue(1);
12630 const auto *MemSD = cast<MemSDNode>(
Op.getNode());
12631 EVT MemVT = MemSD->getMemoryVT();
12633 SDValue Chain = MemSD->getChain();
12636 [[maybe_unused]]
bool IsTruncatingStore =
false;
12639 if (
auto *VPSN = dyn_cast<VPScatterSDNode>(
Op.getNode())) {
12640 Index = VPSN->getIndex();
12641 Mask = VPSN->getMask();
12642 Val = VPSN->getValue();
12643 VL = VPSN->getVectorLength();
12645 IsTruncatingStore =
false;
12648 auto *MSN = cast<MaskedScatterSDNode>(
Op.getNode());
12649 Index = MSN->getIndex();
12650 Mask = MSN->getMask();
12651 Val = MSN->getValue();
12652 IsTruncatingStore = MSN->isTruncatingStore();
12656 MVT IndexVT =
Index.getSimpleValueType();
12660 "Unexpected VTs!");
12661 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
12664 assert(!IsTruncatingStore &&
"Unexpected truncating MSCATTER/VP_SCATTER");
12670 MVT ContainerVT = VT;
12694 IsUnmasked ? Intrinsic::riscv_vsoxei : Intrinsic::riscv_vsoxei_mask;
12704 DAG.
getVTList(MVT::Other), Ops, MemVT, MMO);
12720 static const int Table =
12749 static const unsigned Table =
12772 bool isRISCV64 = Subtarget.
is64Bit();
12836 switch (
N->getOpcode()) {
12838 llvm_unreachable(
"Don't know how to custom type legalize this operation!");
12844 "Unexpected custom legalisation");
12845 bool IsStrict =
N->isStrictFPOpcode();
12848 SDValue Op0 = IsStrict ?
N->getOperand(1) :
N->getOperand(0);
12866 Opc,
DL, VTs, Chain, Op0,
12900 std::tie(Result, Chain) =
12901 makeLibCall(DAG, LC,
N->getValueType(0), Op0, CallOptions,
DL, Chain);
12929 Op0.
getValueType() == MVT::f64 ? RTLIB::LROUND_F64 : RTLIB::LROUND_F32;
12940 assert(!Subtarget.
is64Bit() &&
"READCYCLECOUNTER/READSTEADYCOUNTER only "
12941 "has custom type legalization on riscv32");
12943 SDValue LoCounter, HiCounter;
12954 N->getOperand(0), LoCounter, HiCounter);
12978 unsigned Size =
N->getSimpleValueType(0).getSizeInBits();
12979 unsigned XLen = Subtarget.
getXLen();
12982 assert(
Size == (XLen * 2) &&
"Unexpected custom legalisation");
12990 if (LHSIsU == RHSIsU)
13007 if (RHSIsU && LHSIsS && !RHSIsS)
13009 else if (LHSIsU && RHSIsS && !LHSIsS)
13019 "Unexpected custom legalisation");
13026 "Unexpected custom legalisation");
13029 if (
N->getOpcode() ==
ISD::SHL && Subtarget.hasStdExtZbs() &&
13055 "Unexpected custom legalisation");
13056 assert((Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb() ||
13057 Subtarget.hasVendorXTHeadBb()) &&
13058 "Unexpected custom legalization");
13059 if (!isa<ConstantSDNode>(
N->getOperand(1)) &&
13060 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()))
13069 "Unexpected custom legalisation");
13083 MVT VT =
N->getSimpleValueType(0);
13084 assert((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) &&
13085 Subtarget.
is64Bit() && Subtarget.hasStdExtM() &&
13086 "Unexpected custom legalisation");
13098 if (VT != MVT::i32)
13107 "Unexpected custom legalisation");
13111 if (!isa<ConstantSDNode>(
N->getOperand(1)))
13128 EVT OType =
N->getValueType(1);
13141 "Unexpected custom legalisation");
13158 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res,
13162 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1),
N->getOperand(0),
13180 !Subtarget.hasStdExtZbb() &&
"Unexpected custom legalisation");
13189 "Unexpected custom legalisation");
13195 "Unexpected custom legalisation");
13197 if (Subtarget.hasStdExtZbb()) {
13231 EVT VT =
N->getValueType(0);
13236 if (VT == MVT::i16 &&
13238 (Op0VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
13241 }
else if (VT == MVT::i32 && Op0VT == MVT::f32 && Subtarget.
is64Bit() &&
13246 }
else if (VT == MVT::i64 && Op0VT == MVT::f64 && !Subtarget.
is64Bit() &&
13249 DAG.
getVTList(MVT::i32, MVT::i32), Op0);
13270 MVT VT =
N->getSimpleValueType(0);
13272 assert((VT == MVT::i16 || (VT == MVT::i32 && Subtarget.
is64Bit())) &&
13273 "Unexpected custom legalisation");
13276 "Unexpected extension");
13302 assert(!Subtarget.
is64Bit() &&
N->getValueType(0) == MVT::i64 &&
13304 "Unexpected EXTRACT_VECTOR_ELT legalization");
13307 MVT ContainerVT = VecVT;
13335 DAG.
getUNDEF(ContainerVT), Mask, VL);
13343 unsigned IntNo =
N->getConstantOperandVal(0);
13347 "Don't know how to custom type legalize this intrinsic!");
13348 case Intrinsic::experimental_get_vector_length: {
13353 case Intrinsic::experimental_cttz_elts: {
13359 case Intrinsic::riscv_orc_b:
13360 case Intrinsic::riscv_brev8:
13361 case Intrinsic::riscv_sha256sig0:
13362 case Intrinsic::riscv_sha256sig1:
13363 case Intrinsic::riscv_sha256sum0:
13364 case Intrinsic::riscv_sha256sum1:
13365 case Intrinsic::riscv_sm3p0:
13366 case Intrinsic::riscv_sm3p1: {
13367 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13387 case Intrinsic::riscv_sm4ks:
13388 case Intrinsic::riscv_sm4ed: {
13396 DAG.
getNode(Opc,
DL, MVT::i64, NewOp0, NewOp1,
N->getOperand(3));
13400 case Intrinsic::riscv_mopr: {
13401 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13411 case Intrinsic::riscv_moprr: {
13412 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13424 case Intrinsic::riscv_clmul: {
13425 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13436 case Intrinsic::riscv_clmulh:
13437 case Intrinsic::riscv_clmulr: {
13438 if (!Subtarget.
is64Bit() ||
N->getValueType(0) != MVT::i32)
13466 case Intrinsic::riscv_vmv_x_s: {
13467 EVT VT =
N->getValueType(0);
13469 if (VT.
bitsLT(XLenVT)) {
13478 "Unexpected custom legalization");
13516 case ISD::VP_REDUCE_ADD:
13517 case ISD::VP_REDUCE_AND:
13518 case ISD::VP_REDUCE_OR:
13519 case ISD::VP_REDUCE_XOR:
13520 case ISD::VP_REDUCE_SMAX:
13521 case ISD::VP_REDUCE_UMAX:
13522 case ISD::VP_REDUCE_SMIN:
13523 case ISD::VP_REDUCE_UMIN:
13587 const EVT VT =
N->getValueType(0);
13588 const unsigned Opc =
N->getOpcode();
13595 (Opc !=
ISD::FADD || !
N->getFlags().hasAllowReassociation()))
13600 "Inconsistent mappings");
13611 !isa<ConstantSDNode>(
RHS.getOperand(1)))
13614 uint64_t RHSIdx = cast<ConstantSDNode>(
RHS.getOperand(1))->getLimitedValue();
13629 LHS.getOperand(0) == SrcVec && isa<ConstantSDNode>(
LHS.getOperand(1))) {
13631 cast<ConstantSDNode>(
LHS.getOperand(1))->getLimitedValue();
13632 if (0 == std::min(LHSIdx, RHSIdx) && 1 == std::max(LHSIdx, RHSIdx)) {
13636 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
N->getFlags());
13643 if (
LHS.getOpcode() != ReduceOpc)
13658 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
13659 ReduceVec->
getFlags() &
N->getFlags());
13669 auto BinOpToRVVReduce = [](
unsigned Opc) {
13698 auto IsReduction = [&BinOpToRVVReduce](
SDValue V,
unsigned Opc) {
13701 V.getOperand(0).getOpcode() == BinOpToRVVReduce(Opc);
13704 unsigned Opc =
N->getOpcode();
13705 unsigned ReduceIdx;
13706 if (IsReduction(
N->getOperand(0), Opc))
13708 else if (IsReduction(
N->getOperand(1), Opc))
13714 if (Opc ==
ISD::FADD && !
N->getFlags().hasAllowReassociation())
13717 SDValue Extract =
N->getOperand(ReduceIdx);
13749 SDValue NewStart =
N->getOperand(1 - ReduceIdx);
13776 if (!Subtarget.hasStdExtZba())
13780 EVT VT =
N->getValueType(0);
13792 auto *N0C = dyn_cast<ConstantSDNode>(N0->
getOperand(1));
13793 auto *N1C = dyn_cast<ConstantSDNode>(N1->
getOperand(1));
13796 int64_t C0 = N0C->getSExtValue();
13797 int64_t C1 = N1C->getSExtValue();
13798 if (C0 <= 0 || C1 <= 0)
13802 int64_t Bits = std::min(C0, C1);
13803 int64_t Diff = std::abs(C0 - C1);
13804 if (Diff != 1 && Diff != 2 && Diff != 3)
13831 EVT VT =
N->getValueType(0);
13839 if ((!Subtarget.hasStdExtZicond() &&
13840 !Subtarget.hasVendorXVentanaCondOps()) ||
13862 bool SwapSelectOps;
13868 SwapSelectOps =
false;
13869 NonConstantVal = FalseVal;
13871 SwapSelectOps =
true;
13872 NonConstantVal = TrueVal;
13878 FalseVal = DAG.
getNode(
N->getOpcode(),
SDLoc(
N), VT, OtherOp, NonConstantVal);
13926 EVT VT =
N->getValueType(0);
13934 auto *N0C = dyn_cast<ConstantSDNode>(N0->
getOperand(1));
13935 auto *N1C = dyn_cast<ConstantSDNode>(
N->getOperand(1));
13941 if (!N0C->hasOneUse())
13943 int64_t C0 = N0C->getSExtValue();
13944 int64_t C1 = N1C->getSExtValue();
13946 if (C0 == -1 || C0 == 0 || C0 == 1 || isInt<12>(C1))
13949 if ((C1 / C0) != 0 && isInt<12>(C1 / C0) && isInt<12>(C1 % C0) &&
13950 !isInt<12>(C0 * (C1 / C0))) {
13953 }
else if ((C1 / C0 + 1) != 0 && isInt<12>(C1 / C0 + 1) &&
13954 isInt<12>(C1 % C0 - C0) && !isInt<12>(C0 * (C1 / C0 + 1))) {
13957 }
else if ((C1 / C0 - 1) != 0 && isInt<12>(C1 / C0 - 1) &&
13958 isInt<12>(C1 % C0 + C0) && !isInt<12>(C0 * (C1 / C0 - 1))) {
13985 EVT VT =
N->getValueType(0);
14016 unsigned OuterExtend =
14020 OuterExtend,
SDLoc(
N), VT,
14028 EVT VT =
N->getValueType(0);
14076 EVT VT =
N->getValueType(0);
14080 auto *N0C = dyn_cast<ConstantSDNode>(N0);
14086 APInt ImmValMinus1 = N0C->getAPIntValue() - 1;
14096 if (!isIntEqualitySetCC(CCVal) || !SetCCOpVT.
isInteger())
14119 if (!Subtarget.hasStdExtZbb())
14122 EVT VT =
N->getValueType(0);
14124 if (VT != Subtarget.
getXLenVT() && VT != MVT::i32 && VT != MVT::i16)
14133 auto *ShAmtCLeft = dyn_cast<ConstantSDNode>(N0.
getOperand(1));
14136 unsigned ShiftedAmount = 8 - ShAmtCLeft->getZExtValue();
14138 if (ShiftedAmount >= 8)
14142 SDValue RightShiftOperand = N1;
14144 if (ShiftedAmount != 0) {
14147 auto *ShAmtCRight = dyn_cast<ConstantSDNode>(N1.
getOperand(1));
14148 if (!ShAmtCRight || ShAmtCRight->getZExtValue() != ShiftedAmount)
14157 if (LeftShiftOperand != RightShiftOperand)
14161 Mask <<= ShiftedAmount;
14175 EVT VT =
N->getValueType(0);
14206 bool IsAnd =
N->getOpcode() ==
ISD::AND;
14230 EVT VT =
N->getValueType(0);
14254 EVT VT =
N->getValueType(0);
14281 if (CondLHS != True)
14288 if (!CondRHSC || CondRHSC->
getAPIntValue() != (1ULL << ScalarBits))
14300 if (!FalseRHSC || !FalseRHSC->
isZero())
14320 EVT VT =
N->getValueType(0);
14327 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() && VT == MVT::i1 &&
14354 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
14406 EVT VT =
N->getValueType(0);
14452 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
14477 auto *ConstN00 = dyn_cast<ConstantSDNode>(N0.
getOperand(0));
14482 const APInt &Imm = ConstN00->getAPIntValue();
14483 if ((Imm + 1).isSignedIntN(12))
14504 EVT VT =
N->getValueType(0);
14516 const bool HasShlAdd =
14517 Subtarget.hasStdExtZba() || Subtarget.hasVendorXTHeadBa();
14531 for (
uint64_t Divisor : {3, 5, 9}) {
14532 if (MulAmt % Divisor != 0)
14534 uint64_t MulAmt2 = MulAmt / Divisor;
14541 if (
X.getOpcode() ==
ISD::AND && isa<ConstantSDNode>(
X.getOperand(1)) &&
14542 X.getConstantOperandVal(1) == UINT64_C(0xffffffff)) {
14559 if (MulAmt2 == 3 || MulAmt2 == 5 || MulAmt2 == 9) {
14575 if (ScaleShift >= 1 && ScaleShift < 4) {
14576 unsigned ShiftAmt =
Log2_64((MulAmt & (MulAmt - 1)));
14590 for (
uint64_t Divisor : {3, 5, 9}) {
14595 if ((
C >> TZ) == Divisor && (TZ == 1 || TZ == 2 || TZ == 3)) {
14606 if (MulAmt > 2 &&
isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
14608 if (ScaleShift >= 1 && ScaleShift < 4) {
14609 unsigned ShiftAmt =
Log2_64(((MulAmt - 1) & (MulAmt - 2)));
14635 uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
14637 uint64_t ShiftAmt1 = MulAmt + MulAmtLowBit;
14648 for (
uint64_t Divisor : {3, 5, 9}) {
14649 if (MulAmt % Divisor != 0)
14651 uint64_t MulAmt2 = MulAmt / Divisor;
14654 for (
uint64_t Divisor2 : {3, 5, 9}) {
14655 if (MulAmt2 % Divisor2 != 0)
14657 uint64_t MulAmt3 = MulAmt2 / Divisor2;
14680 EVT VT =
N->getValueType(0);
14687 if (
N->getOperand(0).getOpcode() !=
ISD::AND ||
14688 N->getOperand(0).getOperand(0).getOpcode() !=
ISD::SRL)
14701 if (!V1.
isMask(HalfSize) || V2 != (1ULL | 1ULL << HalfSize) ||
14702 V3 != (HalfSize - 1))
14718 EVT VT =
N->getValueType(0);
14726 unsigned AddSubOpc;
14732 auto IsAddSubWith1 = [&](
SDValue V) ->
bool {
14733 AddSubOpc = V->getOpcode();
14735 SDValue Opnd = V->getOperand(1);
14736 MulOper = V->getOperand(0);
14745 if (IsAddSubWith1(N0)) {
14747 return DAG.
getNode(AddSubOpc,
DL, VT, N1, MulVal);
14750 if (IsAddSubWith1(N1)) {
14752 return DAG.
getNode(AddSubOpc,
DL, VT, N0, MulVal);
14767 if (isIndexTypeSigned(IndexType))
14770 if (!
N->hasOneUse())
14773 EVT VT =
N.getValueType();
14812 EVT SrcVT = Src.getValueType();
14816 NewElen = std::max(NewElen, 8U);
14839 EVT VT =
N->getValueType(0);
14842 if (OpVT != MVT::i64 || !Subtarget.
is64Bit())
14846 auto *N1C = dyn_cast<ConstantSDNode>(N1);
14858 if (!isIntEqualitySetCC(
Cond))
14867 const APInt &C1 = N1C->getAPIntValue();
14885 EVT VT =
N->getValueType(0);
14886 EVT SrcVT = cast<VTSDNode>(
N->getOperand(1))->
getVT();
14887 unsigned Opc = Src.getOpcode();
14892 Subtarget.hasStdExtZfhmin())
14894 Src.getOperand(0));
14898 VT == MVT::i64 && !isa<ConstantSDNode>(Src.getOperand(1)) &&
14901 Src.getOperand(1));
14909struct CombineResult;
14911enum ExtKind :
uint8_t { ZExt = 1 << 0, SExt = 1 << 1, FPExt = 1 << 2 };
14938struct NodeExtensionHelper {
14947 bool SupportsFPExt;
14950 bool EnforceOneUse;
14965 return OrigOperand;
14976 unsigned getExtOpc(ExtKind SupportsExt)
const {
14977 switch (SupportsExt) {
14978 case ExtKind::SExt:
14980 case ExtKind::ZExt:
14982 case ExtKind::FPExt:
14993 std::optional<ExtKind> SupportsExt)
const {
14994 if (!SupportsExt.has_value())
14995 return OrigOperand;
14997 MVT NarrowVT = getNarrowType(Root, *SupportsExt);
15001 if (
Source.getValueType() == NarrowVT)
15005 if (
Source.getValueType().getVectorElementType() == MVT::bf16) {
15011 unsigned ExtOpc = getExtOpc(*SupportsExt);
15015 auto [
Mask, VL] = getMaskAndVL(Root, DAG, Subtarget);
15022 return DAG.
getNode(ExtOpc,
DL, NarrowVT, Source, Mask, VL);
15034 DAG.
getUNDEF(NarrowVT), Source, VL);
15047 static MVT getNarrowType(
const SDNode *Root, ExtKind SupportsExt) {
15053 MVT EltVT = SupportsExt == ExtKind::FPExt
15055 :
MVT::getIntegerVT(NarrowSize);
15057 assert((
int)NarrowSize >= (SupportsExt == ExtKind::FPExt ? 16 : 8) &&
15058 "Trying to extend something we can't represent");
15065 static unsigned getSExtOpcode(
unsigned Opcode) {
15088 static unsigned getZExtOpcode(
unsigned Opcode) {
15114 static unsigned getFPExtOpcode(
unsigned Opcode) {
15139 static unsigned getSUOpcode(
unsigned Opcode) {
15141 "SU is only supported for MUL");
15147 static unsigned getWOpcode(
unsigned Opcode, ExtKind SupportsExt) {
15167 using CombineToTry = std::function<std::optional<CombineResult>(
15168 SDNode * ,
const NodeExtensionHelper & ,
15173 bool needToPromoteOtherUsers()
const {
return EnforceOneUse; }
15177 unsigned Opc = OrigOperand.
getOpcode();
15181 "Unexpected Opcode");
15194 unsigned ScalarBits =
Op.getValueSizeInBits();
15196 if (ScalarBits < EltBits) {
15199 !Subtarget.
is64Bit() &&
"Unexpected splat");
15201 SupportsSExt =
true;
15205 SupportsZExt =
true;
15207 EnforceOneUse =
false;
15211 unsigned NarrowSize = EltBits / 2;
15214 if (NarrowSize < 8)
15218 SupportsSExt =
true;
15222 SupportsZExt =
true;
15224 EnforceOneUse =
false;
15227 bool isSupportedFPExtend(
SDNode *Root,
MVT NarrowEltVT,
15234 if (NarrowEltVT == MVT::bf16 && (!Subtarget.hasStdExtZvfbfwma() ||
15244 SupportsZExt =
false;
15245 SupportsSExt =
false;
15246 SupportsFPExt =
false;
15247 EnforceOneUse =
true;
15248 unsigned Opc = OrigOperand.
getOpcode();
15270 SupportsZExt =
true;
15273 SupportsSExt =
true;
15278 if (!isSupportedFPExtend(Root, NarrowEltVT, Subtarget))
15280 SupportsFPExt =
true;
15285 fillUpExtensionSupportForSplat(Root, DAG, Subtarget);
15297 if (!isSupportedFPExtend(Root,
Op.getOperand(0).getSimpleValueType(),
15302 unsigned ScalarBits =
Op.getOperand(0).getValueSizeInBits();
15303 if (NarrowSize != ScalarBits)
15306 SupportsFPExt =
true;
15315 static bool isSupportedRoot(
const SDNode *Root,
15344 Subtarget.hasStdExtZvbb();
15346 return Subtarget.hasStdExtZvbb();
15360 assert(isSupportedRoot(Root, Subtarget) &&
15361 "Trying to build an helper with an "
15362 "unsupported root");
15363 assert(OperandIdx < 2 &&
"Requesting something else than LHS or RHS");
15379 if (OperandIdx == 1) {
15388 EnforceOneUse =
false;
15393 fillUpExtensionSupport(Root, DAG, Subtarget);
15399 static std::pair<SDValue, SDValue>
15402 assert(isSupportedRoot(Root, Subtarget) &&
"Unexpected root");
15421 switch (
N->getOpcode()) {
15463struct CombineResult {
15465 unsigned TargetOpcode;
15467 std::optional<ExtKind> LHSExt;
15468 std::optional<ExtKind> RHSExt;
15472 NodeExtensionHelper
LHS;
15474 NodeExtensionHelper
RHS;
15476 CombineResult(
unsigned TargetOpcode,
SDNode *Root,
15477 const NodeExtensionHelper &
LHS, std::optional<ExtKind> LHSExt,
15478 const NodeExtensionHelper &
RHS, std::optional<ExtKind> RHSExt)
15479 : TargetOpcode(TargetOpcode), LHSExt(LHSExt), RHSExt(RHSExt), Root(Root),
15488 std::tie(Mask, VL) =
15489 NodeExtensionHelper::getMaskAndVL(Root, DAG, Subtarget);
15503 LHS.getOrCreateExtendedOp(Root, DAG, Subtarget, LHSExt),
15504 RHS.getOrCreateExtendedOp(Root, DAG, Subtarget, RHSExt),
15505 Passthru, Mask, VL);
15519static std::optional<CombineResult>
15520canFoldToVWWithSameExtensionImpl(
SDNode *Root,
const NodeExtensionHelper &LHS,
15521 const NodeExtensionHelper &RHS,
15524 if ((AllowExtMask & ExtKind::ZExt) &&
LHS.SupportsZExt &&
RHS.SupportsZExt)
15525 return CombineResult(NodeExtensionHelper::getZExtOpcode(Root->
getOpcode()),
15526 Root, LHS, {ExtKind::ZExt}, RHS,
15528 if ((AllowExtMask & ExtKind::SExt) &&
LHS.SupportsSExt &&
RHS.SupportsSExt)
15529 return CombineResult(NodeExtensionHelper::getSExtOpcode(Root->
getOpcode()),
15530 Root, LHS, {ExtKind::SExt}, RHS,
15532 if ((AllowExtMask & ExtKind::FPExt) &&
LHS.SupportsFPExt &&
RHS.SupportsFPExt)
15533 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
15534 Root, LHS, {ExtKind::FPExt}, RHS,
15536 return std::nullopt;
15545static std::optional<CombineResult>
15546canFoldToVWWithSameExtension(
SDNode *Root,
const NodeExtensionHelper &LHS,
15549 return canFoldToVWWithSameExtensionImpl(
15550 Root, LHS, RHS, ExtKind::ZExt | ExtKind::SExt | ExtKind::FPExt, DAG,
15558static std::optional<CombineResult>
15559canFoldToVW_W(
SDNode *Root,
const NodeExtensionHelper &LHS,
15562 if (
RHS.SupportsFPExt)
15563 return CombineResult(
15564 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::FPExt),
15565 Root, LHS, std::nullopt, RHS, {ExtKind::FPExt});
15572 return CombineResult(
15573 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::ZExt), Root,
15574 LHS, std::nullopt, RHS, {ExtKind::ZExt});
15576 return CombineResult(
15577 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::SExt), Root,
15578 LHS, std::nullopt, RHS, {ExtKind::SExt});
15579 return std::nullopt;
15586static std::optional<CombineResult>
15587canFoldToVWWithSEXT(
SDNode *Root,
const NodeExtensionHelper &LHS,
15590 return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::SExt, DAG,
15598static std::optional<CombineResult>
15599canFoldToVWWithZEXT(
SDNode *Root,
const NodeExtensionHelper &LHS,
15602 return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::ZExt, DAG,
15610static std::optional<CombineResult>
15611canFoldToVWWithFPEXT(
SDNode *Root,
const NodeExtensionHelper &LHS,
15614 return canFoldToVWWithSameExtensionImpl(Root, LHS, RHS, ExtKind::FPExt, DAG,
15622static std::optional<CombineResult>
15623canFoldToVW_SU(
SDNode *Root,
const NodeExtensionHelper &LHS,
15627 if (!
LHS.SupportsSExt || !
RHS.SupportsZExt)
15628 return std::nullopt;
15629 return CombineResult(NodeExtensionHelper::getSUOpcode(Root->
getOpcode()),
15630 Root, LHS, {ExtKind::SExt}, RHS,
15635NodeExtensionHelper::getSupportedFoldings(
const SDNode *Root) {
15646 Strategies.
push_back(canFoldToVWWithSameExtension);
15655 Strategies.
push_back(canFoldToVWWithSameExtension);
15660 Strategies.
push_back(canFoldToVWWithSameExtension);
15667 Strategies.
push_back(canFoldToVWWithZEXT);
15672 Strategies.
push_back(canFoldToVWWithSEXT);
15677 Strategies.
push_back(canFoldToVWWithZEXT);
15682 Strategies.
push_back(canFoldToVWWithFPEXT);
15711 if (!NodeExtensionHelper::isSupportedRoot(
N, Subtarget))
15717 Inserted.insert(
N);
15720 while (!Worklist.
empty()) {
15723 NodeExtensionHelper
LHS(Root, 0, DAG, Subtarget);
15724 NodeExtensionHelper
RHS(Root, 1, DAG, Subtarget);
15725 auto AppendUsersIfNeeded = [&Worklist, &Subtarget,
15726 &Inserted](
const NodeExtensionHelper &
Op) {
15727 if (
Op.needToPromoteOtherUsers()) {
15730 if (!NodeExtensionHelper::isSupportedRoot(TheUser, Subtarget))
15735 if (Inserted.insert(TheUser).second)
15748 NodeExtensionHelper::getSupportedFoldings(Root);
15750 assert(!FoldingStrategies.
empty() &&
"Nothing to be folded");
15751 bool Matched =
false;
15752 for (
int Attempt = 0;
15753 (Attempt != 1 + NodeExtensionHelper::isCommutative(Root)) && !Matched;
15756 for (NodeExtensionHelper::CombineToTry FoldingStrategy :
15757 FoldingStrategies) {
15758 std::optional<CombineResult> Res =
15759 FoldingStrategy(Root,
LHS,
RHS, DAG, Subtarget);
15766 if (Res->LHSExt.has_value())
15767 if (!AppendUsersIfNeeded(
LHS))
15769 if (Res->RHSExt.has_value())
15770 if (!AppendUsersIfNeeded(
RHS))
15782 SDValue InputRootReplacement;
15789 for (CombineResult Res : CombinesToApply) {
15790 SDValue NewValue = Res.materialize(DAG, Subtarget);
15791 if (!InputRootReplacement) {
15793 "First element is expected to be the current node");
15794 InputRootReplacement = NewValue;
15799 for (std::pair<SDValue, SDValue> OldNewValues : ValuesToReplace) {
15803 return InputRootReplacement;
15810 unsigned Opc =
N->getOpcode();
15815 SDValue MergeOp =
N->getOperand(1);
15816 unsigned MergeOpc = MergeOp.
getOpcode();
15827 SDValue Passthru =
N->getOperand(2);
15841 Z = Z.getOperand(1);
15847 {Y, X, Y, MergeOp->getOperand(0), N->getOperand(4)},
15854 [[maybe_unused]]
unsigned Opc =
N->getOpcode();
15883 EVT NewMemVT = (MemVT == MVT::i32) ? MVT::i64 : MVT::i128;
15889 auto Ext = cast<LoadSDNode>(LSNode1)->getExtensionType();
15891 if (MemVT == MVT::i32)
15897 Opcode,
SDLoc(LSNode1), DAG.
getVTList({XLenVT, XLenVT, MVT::Other}),
15932 if (!Subtarget.hasVendorXTHeadMemPair())
15944 auto ExtractBaseAndOffset = [](
SDValue Ptr) -> std::pair<SDValue, uint64_t> {
15946 if (
auto *C1 = dyn_cast<ConstantSDNode>(
Ptr->getOperand(1)))
15947 return {
Ptr->getOperand(0), C1->getZExtValue()};
15951 auto [Base1, Offset1] = ExtractBaseAndOffset(LSNode1->
getOperand(OpNum));
15972 auto [Base2, Offset2] = ExtractBaseAndOffset(LSNode2->
getOperand(OpNum));
15975 if (Base1 != Base2)
15979 bool Valid =
false;
15980 if (MemVT == MVT::i32) {
15982 if ((Offset1 + 4 == Offset2) && isShiftedUInt<2, 3>(Offset1))
15984 }
else if (MemVT == MVT::i64) {
15986 if ((Offset1 + 8 == Offset2) && isShiftedUInt<2, 4>(Offset1))
16020 if (Src->isStrictFPOpcode())
16028 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
16038 EVT VT =
N->getValueType(0);
16041 MVT SrcVT = Src.getSimpleValueType();
16042 MVT SrcContainerVT = SrcVT;
16044 SDValue XVal = Src.getOperand(0);
16071 FpToInt = DAG.
getNode(Opc,
DL, ContainerVT, XVal, Mask, VL);
16075 FpToInt = DAG.
getNode(Opc,
DL, ContainerVT, XVal, Mask,
16088 if (VT != MVT::i32 && VT != XLenVT)
16118 EVT DstVT =
N->getValueType(0);
16119 if (DstVT != XLenVT)
16125 if (Src->isStrictFPOpcode())
16133 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
16136 EVT SatVT = cast<VTSDNode>(
N->getOperand(1))->getVT();
16145 if (SatVT == DstVT)
16147 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
16153 Src = Src.getOperand(0);
16174 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected extension");
16180 EVT VT =
N->getValueType(0);
16235 unsigned Offset = IsStrict ? 1 : 0;
16242 auto invertIfNegative = [&Mask, &VL](
SDValue &V) {
16244 V.getOperand(2) == VL) {
16246 V = V.getOperand(0);
16253 bool NegA = invertIfNegative(
A);
16254 bool NegB = invertIfNegative(
B);
16255 bool NegC = invertIfNegative(
C);
16258 if (!NegA && !NegB && !NegC)
16264 {N->getOperand(0), A, B, C, Mask, VL});
16288 EVT VT =
N->getValueType(0);
16293 if (!isa<ConstantSDNode>(
N->getOperand(1)))
16295 uint64_t ShAmt =
N->getConstantOperandVal(1);
16303 cast<VTSDNode>(N0.
getOperand(1))->getVT().getSizeInBits();
16308 if (LShAmt < ExtSize) {
16321 if (ShAmt > 32 || VT != MVT::i64)
16337 AddC = dyn_cast<ConstantSDNode>(N0.
getOperand(IsAdd ? 1 : 0));
16350 !isa<ConstantSDNode>(U->getOperand(1)) ||
16351 U->getConstantOperandVal(1) > 32)
16406 if (!
Cond.hasOneUse())
16425 EVT VT =
Cond.getValueType();
16470 LHS =
LHS.getOperand(0);
16480 LHS.getOperand(0).getValueType() == Subtarget.
getXLenVT()) {
16484 CCVal = cast<CondCodeSDNode>(
LHS.getOperand(2))->get();
16488 RHS =
LHS.getOperand(1);
16489 LHS =
LHS.getOperand(0);
16498 RHS =
LHS.getOperand(1);
16499 LHS =
LHS.getOperand(0);
16515 ShAmt =
LHS.getValueSizeInBits() - 1 - ShAmt;
16556 bool Commutative =
true;
16557 unsigned Opc = TrueVal.getOpcode();
16565 Commutative =
false;
16573 if (!TrueVal.hasOneUse() || isa<ConstantSDNode>(FalseVal))
16577 if (FalseVal == TrueVal.getOperand(0))
16579 else if (Commutative && FalseVal == TrueVal.getOperand(1))
16584 EVT VT =
N->getValueType(0);
16586 SDValue OtherOp = TrueVal.getOperand(1 - OpToFold);
16592 assert(IdentityOperand &&
"No identity operand!");
16597 DAG.
getSelect(
DL, OtherOpVT,
N->getOperand(0), OtherOp, IdentityOperand);
16598 return DAG.
getNode(TrueVal.getOpcode(),
DL, VT, FalseVal, NewSel);
16619 CountZeroes =
N->getOperand(2);
16620 ValOnZero =
N->getOperand(1);
16622 CountZeroes =
N->getOperand(1);
16623 ValOnZero =
N->getOperand(2);
16642 if (
Cond->getOperand(0) != CountZeroesArgument)
16658 CountZeroes, BitWidthMinusOne);
16668 EVT VT =
N->getValueType(0);
16669 EVT CondVT =
Cond.getValueType();
16677 (Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps())) {
16683 const APInt &MaskVal =
LHS.getConstantOperandAPInt(1);
16704 SDValue TrueVal =
N->getOperand(1);
16705 SDValue FalseVal =
N->getOperand(2);
16720 EVT VT =
N->getValueType(0);
16727 const unsigned Opcode =
N->op_begin()->getNode()->getOpcode();
16742 if (
Op.isUndef()) {
16755 if (
Op.getOpcode() != Opcode || !
Op.hasOneUse())
16759 if (!isa<ConstantSDNode>(
Op.getOperand(1)) &&
16760 !isa<ConstantFPSDNode>(
Op.getOperand(1)))
16764 if (
Op.getOperand(0).getValueType() !=
Op.getOperand(1).getValueType())
16792 const unsigned InVecOpcode = InVec->
getOpcode();
16802 if (!isa<ConstantSDNode>(InValRHS) && !isa<ConstantFPSDNode>(InValRHS))
16809 InVecLHS, InValLHS, EltNo);
16811 InVecRHS, InValRHS, EltNo);
16820 auto *IndexC = dyn_cast<ConstantSDNode>(EltNo);
16823 unsigned Elt = IndexC->getZExtValue();
16831 unsigned ConcatOpIdx = Elt / ConcatNumElts;
16834 ConcatOp, InVal, NewIdx);
16838 ConcatOps[ConcatOpIdx] = ConcatOp;
16850 EVT VT =
N->getValueType(0);
16860 auto *BaseLd = dyn_cast<LoadSDNode>(
N->getOperand(0));
16862 !
SDValue(BaseLd, 0).hasOneUse())
16865 EVT BaseLdVT = BaseLd->getValueType(0);
16872 auto *Ld = dyn_cast<LoadSDNode>(
Op);
16873 if (!Ld || !Ld->isSimple() || !
Op.hasOneUse() ||
16875 Ld->getValueType(0) != BaseLdVT)
16884 using PtrDiff = std::pair<std::variant<int64_t, SDValue>,
bool>;
16886 LoadSDNode *Ld2) -> std::optional<PtrDiff> {
16891 if (BIO1.equalBaseIndex(BIO2, DAG))
16896 SDValue P2 = Ld2->getBasePtr();
16902 return std::nullopt;
16906 auto BaseDiff = GetPtrDiff(Lds[0], Lds[1]);
16911 for (
auto *It = Lds.
begin() + 1; It != Lds.
end() - 1; It++)
16912 if (GetPtrDiff(*It, *std::next(It)) != BaseDiff)
16920 unsigned WideScalarBitWidth =
16933 auto [StrideVariant, MustNegateStride] = *BaseDiff;
16935 std::holds_alternative<SDValue>(StrideVariant)
16936 ? std::get<SDValue>(StrideVariant)
16939 if (MustNegateStride)
16947 if (
auto *ConstStride = dyn_cast<ConstantSDNode>(Stride);
16948 ConstStride && ConstStride->getSExtValue() >= 0)
16952 ConstStride->getSExtValue() * (
N->getNumOperands() - 1);
16958 BaseLd->getPointerInfo(), BaseLd->getMemOperand()->getFlags(), MemSize,
16962 WideVecVT,
DL, BaseLd->getChain(), BaseLd->getBasePtr(), Stride,
16977 if (
N->getValueType(0).isFixedLengthVector())
16980 SDValue Addend =
N->getOperand(0);
16984 SDValue AddPassthruOp =
N->getOperand(2);
16985 if (!AddPassthruOp.
isUndef())
16989 auto IsVWMulOpc = [](
unsigned Opc) {
17008 if (!MulPassthruOp.
isUndef())
17018 return std::make_pair(
N->getOperand(3),
N->getOperand(4));
17019 }(
N, DAG, Subtarget);
17024 if (AddMask != MulMask || AddVL != MulVL)
17029 "Unexpected opcode after VWMACC_VL");
17031 "Unexpected opcode after VWMACC_VL!");
17033 "Unexpected opcode after VWMUL_VL!");
17035 "Unexpected opcode after VWMUL_VL!");
17038 EVT VT =
N->getValueType(0);
17054 const EVT IndexVT = Index.getValueType();
17058 if (!isIndexTypeSigned(IndexType))
17090 for (
unsigned i = 0; i < Index->getNumOperands(); i++) {
17093 if (Index->getOperand(i)->isUndef())
17095 uint64_t C = Index->getConstantOperandVal(i);
17096 if (
C % ElementSize != 0)
17098 C =
C / ElementSize;
17102 ActiveLanes.
set(
C);
17104 return ActiveLanes.
all();
17122 if (NumElems % 2 != 0)
17126 const unsigned WiderElementSize = ElementSize * 2;
17127 if (WiderElementSize > ST.getELen()/8)
17130 if (!ST.enableUnalignedVectorMem() && BaseAlign < WiderElementSize)
17133 for (
unsigned i = 0; i < Index->getNumOperands(); i++) {
17136 if (Index->getOperand(i)->isUndef())
17140 uint64_t C = Index->getConstantOperandVal(i);
17142 if (
C % WiderElementSize != 0)
17147 if (
C !=
Last + ElementSize)
17164 (isa<RegisterSDNode>(VL) &&
17165 cast<RegisterSDNode>(VL)->getReg() == RISCV::X0);
17167 Mask.getOperand(0) != VL)
17170 auto IsTruncNode = [&](
SDValue V) {
17172 V.getOperand(1) == Mask && V.getOperand(2) == VL;
17179 while (IsTruncNode(
Op)) {
17180 if (!
Op.hasOneUse())
17182 Op =
Op.getOperand(0);
17217 MVT VT =
N->getSimpleValueType(0);
17222 auto MatchMinMax = [&VL, &Mask](
SDValue V,
unsigned Opc,
unsigned OpcVL,
17224 if (V.getOpcode() != Opc &&
17225 !(V.getOpcode() == OpcVL && V.getOperand(2).isUndef() &&
17226 V.getOperand(3) == Mask && V.getOperand(4) == VL))
17234 Op.getOperand(1).getValueType().isFixedLengthVector() &&
17236 Op.getOperand(1).getOperand(0).getValueType() ==
Op.getValueType() &&
17238 Op =
Op.getOperand(1).getOperand(0);
17241 return V.getOperand(0);
17244 Op.getOperand(2) == VL) {
17245 if (
auto *Op1 = dyn_cast<ConstantSDNode>(
Op.getOperand(1))) {
17247 Op1->getAPIntValue().sextOrTrunc(
Op.getScalarValueSizeInBits());
17248 return V.getOperand(0);
17257 auto DetectUSatPattern = [&](
SDValue V) {
17282 V.getOperand(1), DAG.
getUNDEF(V.getValueType()),
17288 auto DetectSSatPattern = [&](
SDValue V) {
17290 unsigned NumSrcBits = V.getScalarValueSizeInBits();
17298 if (HiC == SignedMax && LoC == SignedMin)
17304 if (HiC == SignedMax && LoC == SignedMin)
17314 Src.getOperand(1) == Mask && Src.getOperand(2) == VL &&
17316 Src = Src.getOperand(0);
17320 if ((Val = DetectUSatPattern(Src)))
17322 else if ((Val = DetectSSatPattern(Src)))
17332 Val = DAG.
getNode(ClipOpc,
DL, ValVT, Val, Mask, VL);
17333 }
while (ValVT != VT);
17347 EVT VT =
N->getValueType(0);
17355 Src = Src.getOperand(0);
17360 Src = Src.getOperand(0);
17361 EVT SrcEVT = Src.getValueType();
17393 auto SimplifyDemandedLowBitsHelper = [&](
unsigned OpNo,
unsigned LowBits) {
17404 switch (
N->getOpcode()) {
17424 APInt V =
C->getValueAPF().bitcastToAPInt();
17459 if (SimplifyDemandedLowBitsHelper(0, 32) ||
17460 SimplifyDemandedLowBitsHelper(1, 5))
17468 if (SimplifyDemandedLowBitsHelper(0, 32))
17485 MVT VT =
N->getSimpleValueType(0);
17488 if (
auto *CFP = dyn_cast<ConstantFPSDNode>(Op0)) {
17501 "Unexpected value type!");
17506 cast<LoadSDNode>(Op0)->isSimple()) {
17508 auto *LN0 = cast<LoadSDNode>(Op0);
17511 LN0->getBasePtr(), IVT, LN0->getMemOperand());
17535 EVT VT =
N->getValueType(0);
17588 if (!
C || !
C->getValueAPF().isExactlyValue(+1.0))
17590 EVT VT =
N->getValueType(0);
17619 if (
N->getValueType(0) == MVT::i64 && Subtarget.
is64Bit()) {
17624 Src.getOperand(0));
17629 Src.getOperand(0), Src.getOperand(1));
17650 unsigned Opc =
N->getOpcode();
17665 return DAG.
getNode(InvOpc,
SDLoc(
N),
N->getValueType(0), Val, NewCond);
17675 N->getValueType(0), Val,
Cond.getOperand(0));
17686 SDValue FalseV =
N->getOperand(4);
17688 EVT VT =
N->getValueType(0);
17691 if (TrueV == FalseV)
17696 if (!Subtarget.hasShortForwardBranchOpt() && isa<ConstantSDNode>(TrueV) &&
17702 int64_t TrueSImm = cast<ConstantSDNode>(TrueV)->getSExtValue();
17703 int64_t FalseSImm = cast<ConstantSDNode>(FalseV)->getSExtValue();
17706 if (isInt<12>(TrueSImm) && isInt<12>(FalseSImm) &&
17707 isInt<12>(TrueSImm - FalseSImm)) {
17723 {LHS, RHS, CC, TrueV, FalseV});
17790 N->getOperand(0),
LHS,
RHS,
CC,
N->getOperand(4));
17803 EVT VT =
N->getValueType(0);
17827 const auto *MGN = cast<MaskedGatherSDNode>(
N);
17828 const EVT VT =
N->getValueType(0);
17829 SDValue Index = MGN->getIndex();
17830 SDValue ScaleOp = MGN->getScale();
17832 assert(!MGN->isIndexScaled() &&
17833 "Scaled gather/scatter should not be formed");
17838 N->getVTList(), MGN->getMemoryVT(),
DL,
17839 {MGN->getChain(), MGN->getPassThru(), MGN->getMask(),
17840 MGN->getBasePtr(), Index, ScaleOp},
17841 MGN->getMemOperand(), IndexType, MGN->getExtensionType());
17845 N->getVTList(), MGN->getMemoryVT(),
DL,
17846 {MGN->getChain(), MGN->getPassThru(), MGN->getMask(),
17847 MGN->getBasePtr(), Index, ScaleOp},
17848 MGN->getMemOperand(), IndexType, MGN->getExtensionType());
17854 if (std::optional<VIDSequence> SimpleVID =
17856 SimpleVID && SimpleVID->StepDenominator == 1) {
17857 const int64_t StepNumerator = SimpleVID->StepNumerator;
17858 const int64_t Addend = SimpleVID->Addend;
17865 assert(MGN->getBasePtr()->getValueType(0) == PtrVT);
17873 VT,
DL, MGN->getChain(), BasePtr,
17875 EVL, MGN->getMemOperand());
17877 StridedLoad, MGN->getPassThru(), EVL);
17887 MGN->getBasePtr(), DAG.
getUNDEF(XLenVT),
17889 MGN->getMemoryVT(), MGN->getMemOperand(),
17898 MGN->getMemOperand()->getBaseAlign(), Subtarget)) {
17900 for (
unsigned i = 0; i < Index->getNumOperands(); i += 2)
17901 NewIndices.
push_back(Index.getOperand(i));
17902 EVT IndexVT = Index.getValueType()
17903 .getHalfNumVectorElementsVT(*DAG.
getContext());
17909 assert(EltCnt.isKnownEven() &&
"Splitting vector, but not in half!");
17911 EltCnt.divideCoefficientBy(2));
17914 EltCnt.divideCoefficientBy(2));
17919 {MGN->getChain(), Passthru, Mask, MGN->getBasePtr(),
17928 const auto *MSN = cast<MaskedScatterSDNode>(
N);
17929 SDValue Index = MSN->getIndex();
17930 SDValue ScaleOp = MSN->getScale();
17932 assert(!MSN->isIndexScaled() &&
17933 "Scaled gather/scatter should not be formed");
17938 N->getVTList(), MSN->getMemoryVT(),
DL,
17939 {MSN->getChain(), MSN->getValue(), MSN->getMask(), MSN->getBasePtr(),
17941 MSN->getMemOperand(), IndexType, MSN->isTruncatingStore());
17945 N->getVTList(), MSN->getMemoryVT(),
DL,
17946 {MSN->getChain(), MSN->getValue(), MSN->getMask(), MSN->getBasePtr(),
17948 MSN->getMemOperand(), IndexType, MSN->isTruncatingStore());
17950 EVT VT = MSN->getValue()->getValueType(0);
17952 if (!MSN->isTruncatingStore() &&
17956 return DAG.
getMaskedStore(MSN->getChain(),
DL, Shuffle, MSN->getBasePtr(),
17957 DAG.
getUNDEF(XLenVT), MSN->getMask(),
17958 MSN->getMemoryVT(), MSN->getMemOperand(),
17963 case ISD::VP_GATHER: {
17964 const auto *VPGN = cast<VPGatherSDNode>(
N);
17965 SDValue Index = VPGN->getIndex();
17966 SDValue ScaleOp = VPGN->getScale();
17968 assert(!VPGN->isIndexScaled() &&
17969 "Scaled gather/scatter should not be formed");
17974 {VPGN->getChain(), VPGN->getBasePtr(), Index,
17975 ScaleOp, VPGN->getMask(),
17976 VPGN->getVectorLength()},
17977 VPGN->getMemOperand(), IndexType);
17981 {VPGN->getChain(), VPGN->getBasePtr(), Index,
17982 ScaleOp, VPGN->getMask(),
17983 VPGN->getVectorLength()},
17984 VPGN->getMemOperand(), IndexType);
17988 case ISD::VP_SCATTER: {
17989 const auto *VPSN = cast<VPScatterSDNode>(
N);
17990 SDValue Index = VPSN->getIndex();
17991 SDValue ScaleOp = VPSN->getScale();
17993 assert(!VPSN->isIndexScaled() &&
17994 "Scaled gather/scatter should not be formed");
17999 {VPSN->getChain(), VPSN->getValue(),
18000 VPSN->getBasePtr(), Index, ScaleOp,
18001 VPSN->getMask(), VPSN->getVectorLength()},
18002 VPSN->getMemOperand(), IndexType);
18006 {VPSN->getChain(), VPSN->getValue(),
18007 VPSN->getBasePtr(), Index, ScaleOp,
18008 VPSN->getMask(), VPSN->getVectorLength()},
18009 VPSN->getMemOperand(), IndexType);
18023 EVT VT =
N->getValueType(0);
18026 return DAG.
getNode(
N->getOpcode(),
DL, VT,
N->getOperand(0), ShAmt,
18027 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
18045 EVT VT =
N->getValueType(0);
18049 return DAG.
getNode(
N->getOpcode(),
DL, VT,
N->getOperand(0), ShAmt);
18089 auto *Store = cast<StoreSDNode>(
N);
18090 SDValue Chain = Store->getChain();
18091 EVT MemVT = Store->getMemoryVT();
18092 SDValue Val = Store->getValue();
18095 bool IsScalarizable =
18097 Store->isSimple() &&
18127 NewVT, *Store->getMemOperand())) {
18129 return DAG.
getStore(Chain,
DL, NewV, Store->getBasePtr(),
18130 Store->getPointerInfo(), Store->getOriginalAlign(),
18131 Store->getMemOperand()->getFlags());
18139 if (
auto *L = dyn_cast<LoadSDNode>(Val);
18141 L->hasNUsesOfValue(1, 0) && L->hasNUsesOfValue(1, 1) &&
18143 L->getMemoryVT() == MemVT) {
18146 NewVT, *Store->getMemOperand()) &&
18148 NewVT, *L->getMemOperand())) {
18150 L->getPointerInfo(), L->getOriginalAlign(),
18151 L->getMemOperand()->getFlags());
18152 return DAG.
getStore(Chain,
DL, NewL, Store->getBasePtr(),
18153 Store->getPointerInfo(), Store->getOriginalAlign(),
18154 Store->getMemOperand()->getFlags());
18166 MVT VecVT = Src.getSimpleValueType();
18173 Store->getChain(),
DL, Src, Store->getBasePtr(), Store->getOffset(),
18176 Store->getMemOperand(), Store->getAddressingMode(),
18177 Store->isTruncatingStore(),
false);
18184 EVT VT =
N->getValueType(0);
18206 const MVT VT =
N->getSimpleValueType(0);
18207 SDValue Passthru =
N->getOperand(0);
18208 SDValue Scalar =
N->getOperand(1);
18217 const MVT VT =
N->getSimpleValueType(0);
18218 SDValue Passthru =
N->getOperand(0);
18219 SDValue Scalar =
N->getOperand(1);
18224 unsigned ScalarSize = Scalar.getValueSizeInBits();
18226 if (ScalarSize > EltWidth && Passthru.
isUndef())
18227 if (SimplifyDemandedLowBitsHelper(1, EltWidth))
18234 (!Const || Const->isZero() ||
18235 !Const->getAPIntValue().sextOrTrunc(EltWidth).isSignedIntN(5)))
18245 if (
N->getOperand(0).isUndef() &&
18248 Src.getOperand(0).getValueType().isScalableVector()) {
18249 EVT VT =
N->getValueType(0);
18250 EVT SrcVT = Src.getOperand(0).getValueType();
18254 return Src.getOperand(0);
18260 const MVT VT =
N->getSimpleValueType(0);
18261 SDValue Passthru =
N->getOperand(0);
18262 SDValue Scalar =
N->getOperand(1);
18266 Scalar.getOperand(0).getValueType() ==
N->getValueType(0))
18267 return Scalar.getOperand(0);
18276 DAG.
getNode(
N->getOpcode(),
DL, M1VT, M1Passthru, Scalar, VL);
18286 Const && !Const->isZero() && isInt<5>(Const->getSExtValue()) &&
18294 MVT VecVT =
N->getOperand(0).getSimpleValueType();
18296 if (M1VT.
bitsLT(VecVT)) {
18307 unsigned IntNo =
N->getConstantOperandVal(IntOpNo);
18312 case Intrinsic::riscv_vcpop:
18313 case Intrinsic::riscv_vcpop_mask:
18314 case Intrinsic::riscv_vfirst:
18315 case Intrinsic::riscv_vfirst_mask: {
18317 if (IntNo == Intrinsic::riscv_vcpop_mask ||
18318 IntNo == Intrinsic::riscv_vfirst_mask)
18319 VL =
N->getOperand(3);
18324 EVT VT =
N->getValueType(0);
18325 if (IntNo == Intrinsic::riscv_vfirst ||
18326 IntNo == Intrinsic::riscv_vfirst_mask)
18335 EVT VT =
N->getValueType(0);
18346 for (
unsigned i = 0; i < NF; ++i)
18353 if ((SrcVT == MVT::v1i1 || SrcVT == MVT::v2i1 || SrcVT == MVT::v4i1) &&
18376 EVT XVT,
unsigned KeptBits)
const {
18381 if (XVT != MVT::i32 && XVT != MVT::i64)
18385 if (KeptBits == 32 || KeptBits == 64)
18389 return Subtarget.hasStdExtZbb() &&
18390 ((KeptBits == 8 && XVT == MVT::i64 && !Subtarget.
is64Bit()) ||
18398 "Expected shift op");
18416 if (!isa<StoreSDNode>(
Use) && !isa<LoadSDNode>(
Use))
18425 return isUsedByLdSt(N0.
getNode(),
N);
18427 auto *C1 = dyn_cast<ConstantSDNode>(N0->
getOperand(1));
18428 auto *C2 = dyn_cast<ConstantSDNode>(
N->getOperand(1));
18431 if (Subtarget.hasStdExtZba() && C2 && C2->getZExtValue() >= 1 &&
18432 C2->getZExtValue() <= 3 &&
N->hasOneUse() &&
18433 N->user_begin()->getOpcode() ==
ISD::ADD &&
18434 !isUsedByLdSt(*
N->user_begin(),
nullptr) &&
18435 !isa<ConstantSDNode>(
N->user_begin()->getOperand(1)))
18439 const APInt &C1Int = C1->getAPIntValue();
18440 APInt ShiftedC1Int = C1Int << C2->getAPIntValue();
18466 if (C1Cost < ShiftedC1Cost)
18489 EVT VT =
Op.getValueType();
18493 unsigned Opcode =
Op.getOpcode();
18501 const APInt &Mask =
C->getAPIntValue();
18510 auto IsLegalMask = [ShrunkMask, ExpandedMask](
const APInt &Mask) ->
bool {
18511 return ShrunkMask.
isSubsetOf(Mask) && Mask.isSubsetOf(ExpandedMask);
18513 auto UseMask = [Mask,
Op, &TLO](
const APInt &NewMask) ->
bool {
18514 if (NewMask == Mask)
18519 Op.getOperand(0), NewC);
18532 APInt NewMask =
APInt(Mask.getBitWidth(), 0xffff);
18533 if (IsLegalMask(NewMask))
18534 return UseMask(NewMask);
18537 if (VT == MVT::i64) {
18539 if (IsLegalMask(NewMask))
18540 return UseMask(NewMask);
18555 APInt NewMask = ShrunkMask;
18556 if (MinSignedBits <= 12)
18558 else if (!
C->isOpaque() && MinSignedBits <= 32 && !ShrunkMask.
isSignedIntN(32))
18564 assert(IsLegalMask(NewMask));
18565 return UseMask(NewMask);
18569 static const uint64_t GREVMasks[] = {
18570 0x5555555555555555ULL, 0x3333333333333333ULL, 0x0F0F0F0F0F0F0F0FULL,
18571 0x00FF00FF00FF00FFULL, 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL};
18573 for (
unsigned Stage = 0; Stage != 6; ++Stage) {
18574 unsigned Shift = 1 << Stage;
18575 if (ShAmt & Shift) {
18577 uint64_t Res = ((x & Mask) << Shift) | ((x >> Shift) & Mask);
18589 const APInt &DemandedElts,
18591 unsigned Depth)
const {
18593 unsigned Opc =
Op.getOpcode();
18598 "Should use MaskedValueIsZero if you don't know whether Op"
18599 " is a target node!");
18682 assert(MinVLenB > 0 &&
"READ_VLENB without vector extension enabled?");
18685 if (MaxVLenB == MinVLenB)
18702 case Intrinsic::riscv_vsetvli:
18703 case Intrinsic::riscv_vsetvlimax: {
18704 bool HasAVL = IntNo == Intrinsic::riscv_vsetvli;
18705 unsigned VSEW =
Op.getConstantOperandVal(HasAVL + 1);
18711 MaxVL = (Fractional) ? MaxVL / LMul : MaxVL * LMul;
18714 if (HasAVL && isa<ConstantSDNode>(
Op.getOperand(1)))
18715 MaxVL = std::min(MaxVL,
Op.getConstantOperandVal(1));
18717 unsigned KnownZeroFirstBit =
Log2_32(MaxVL) + 1;
18730 unsigned Depth)
const {
18731 switch (
Op.getOpcode()) {
18737 if (Tmp == 1)
return 1;
18740 return std::min(Tmp, Tmp2);
18752 if (Tmp < 33)
return 1;
18777 unsigned XLen = Subtarget.
getXLen();
18778 unsigned EltBits =
Op.getOperand(0).getScalarValueSizeInBits();
18779 if (EltBits <= XLen)
18780 return XLen - EltBits + 1;
18784 unsigned IntNo =
Op.getConstantOperandVal(1);
18788 case Intrinsic::riscv_masked_atomicrmw_xchg_i64:
18789 case Intrinsic::riscv_masked_atomicrmw_add_i64:
18790 case Intrinsic::riscv_masked_atomicrmw_sub_i64:
18791 case Intrinsic::riscv_masked_atomicrmw_nand_i64:
18792 case Intrinsic::riscv_masked_atomicrmw_max_i64:
18793 case Intrinsic::riscv_masked_atomicrmw_min_i64:
18794 case Intrinsic::riscv_masked_atomicrmw_umax_i64:
18795 case Intrinsic::riscv_masked_atomicrmw_umin_i64:
18796 case Intrinsic::riscv_masked_cmpxchg_i64:
18804 assert(Subtarget.hasStdExtA());
18819 switch (
Op.getOpcode()) {
18825 return !
Op.getValueType().isInteger();
18833 assert(Ld &&
"Unexpected null LoadSDNode");
18841 auto *CNode = dyn_cast<ConstantPoolSDNode>(
Ptr);
18842 if (!CNode || CNode->isMachineConstantPoolEntry() ||
18843 CNode->getOffset() != 0)
18851 auto *CNode = GetSupportedConstantPool(
Ptr);
18852 if (!CNode || CNode->getTargetFlags() != 0)
18855 return CNode->getConstVal();
18863 auto *CNodeLo = GetSupportedConstantPool(
Ptr.getOperand(1));
18864 auto *CNodeHi = GetSupportedConstantPool(
Ptr.getOperand(0).getOperand(0));
18870 if (CNodeLo->getConstVal() != CNodeHi->getConstVal())
18873 return CNodeLo->getConstVal();
18878 assert(
MI.getOpcode() == RISCV::ReadCounterWide &&
"Unexpected instruction");
18910 Register ReadAgainReg =
RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
18913 int64_t LoCounter =
MI.getOperand(2).getImm();
18914 int64_t HiCounter =
MI.getOperand(3).getImm();
18924 BuildMI(LoopMBB,
DL,
TII->get(RISCV::CSRRS), ReadAgainReg)
18936 MI.eraseFromParent();
18944 assert(
MI.getOpcode() == RISCV::SplitF64Pseudo &&
"Unexpected instruction");
18952 Register SrcReg =
MI.getOperand(2).getReg();
18972 MI.eraseFromParent();
18979 assert(
MI.getOpcode() == RISCV::BuildPairF64Pseudo &&
18980 "Unexpected instruction");
18986 Register DstReg =
MI.getOperand(0).getReg();
19009 MI.eraseFromParent();
19014 switch (
MI.getOpcode()) {
19017 case RISCV::Select_GPR_Using_CC_GPR:
19018 case RISCV::Select_GPR_Using_CC_Imm:
19019 case RISCV::Select_FPR16_Using_CC_GPR:
19020 case RISCV::Select_FPR16INX_Using_CC_GPR:
19021 case RISCV::Select_FPR32_Using_CC_GPR:
19022 case RISCV::Select_FPR32INX_Using_CC_GPR:
19023 case RISCV::Select_FPR64_Using_CC_GPR:
19024 case RISCV::Select_FPR64INX_Using_CC_GPR:
19025 case RISCV::Select_FPR64IN32X_Using_CC_GPR:
19031 unsigned RelOpcode,
unsigned EqOpcode,
19034 Register DstReg =
MI.getOperand(0).getReg();
19035 Register Src1Reg =
MI.getOperand(1).getReg();
19036 Register Src2Reg =
MI.getOperand(2).getReg();
19038 Register SavedFFlags =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
19062 MI.eraseFromParent();
19113 F->insert(It, FirstMBB);
19114 F->insert(It, SecondMBB);
19115 F->insert(It, SinkMBB);
19164 First.eraseFromParent();
19203 if ((
MI.getOpcode() != RISCV::Select_GPR_Using_CC_GPR &&
19204 MI.getOpcode() != RISCV::Select_GPR_Using_CC_Imm) &&
19205 Next != BB->
end() && Next->getOpcode() ==
MI.getOpcode() &&
19206 Next->getOperand(5).getReg() ==
MI.getOperand(0).getReg() &&
19207 Next->getOperand(5).isKill())
19212 if (
MI.getOperand(2).isReg())
19213 RHS =
MI.getOperand(2).getReg();
19218 SelectDests.
insert(
MI.getOperand(0).getReg());
19222 SequenceMBBI != E; ++SequenceMBBI) {
19223 if (SequenceMBBI->isDebugInstr())
19226 if (SequenceMBBI->getOperand(1).getReg() !=
LHS ||
19227 !SequenceMBBI->getOperand(2).isReg() ||
19228 SequenceMBBI->getOperand(2).getReg() !=
RHS ||
19229 SequenceMBBI->getOperand(3).getImm() !=
CC ||
19230 SelectDests.
count(SequenceMBBI->getOperand(4).getReg()) ||
19231 SelectDests.
count(SequenceMBBI->getOperand(5).getReg()))
19233 LastSelectPseudo = &*SequenceMBBI;
19235 SelectDests.
insert(SequenceMBBI->getOperand(0).getReg());
19238 if (SequenceMBBI->hasUnmodeledSideEffects() ||
19239 SequenceMBBI->mayLoadOrStore() ||
19240 SequenceMBBI->usesCustomInsertionHook())
19243 return MO.isReg() && MO.isUse() && SelectDests.count(MO.getReg());
19258 F->insert(
I, IfFalseMBB);
19259 F->insert(
I, TailMBB);
19262 unsigned CallFrameSize =
TII.getCallFrameSizeAt(*LastSelectPseudo);
19268 TailMBB->
push_back(DebugInstr->removeFromParent());
19272 TailMBB->
splice(TailMBB->
end(), HeadMBB,
19282 if (
MI.getOperand(2).isImm())
19285 .
addImm(
MI.getOperand(2).getImm())
19297 auto SelectMBBI =
MI.getIterator();
19298 auto SelectEnd = std::next(LastSelectPseudo->
getIterator());
19300 while (SelectMBBI != SelectEnd) {
19301 auto Next = std::next(SelectMBBI);
19305 TII.get(RISCV::PHI), SelectMBBI->getOperand(0).getReg())
19306 .
addReg(SelectMBBI->getOperand(4).getReg())
19308 .
addReg(SelectMBBI->getOperand(5).getReg())
19323 RISCVVInversePseudosTable::getBaseInfo(MCOpcode, LMul, SEW);
19324 assert(
Inverse &&
"Unexpected LMUL and SEW pair for instruction");
19326 RISCV::lookupMaskedIntrinsicByUnmasked(
Inverse->Pseudo);
19327 assert(
Masked &&
"Could not find masked instruction for LMUL and SEW pair");
19333 unsigned CVTXOpc) {
19339 Register SavedFFLAGS =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
19352 .
add(
MI.getOperand(1))
19353 .
add(
MI.getOperand(2))
19354 .
add(
MI.getOperand(3))
19356 .
add(
MI.getOperand(4))
19357 .
add(
MI.getOperand(5))
19358 .
add(
MI.getOperand(6))
19373 .
add(
MI.getOperand(0))
19374 .
add(
MI.getOperand(1))
19376 .
add(
MI.getOperand(3))
19378 .
add(
MI.getOperand(4))
19379 .
add(
MI.getOperand(5))
19380 .
add(
MI.getOperand(6))
19390 MI.eraseFromParent();
19396 unsigned CmpOpc, F2IOpc, I2FOpc, FSGNJOpc, FSGNJXOpc;
19398 switch (
MI.getOpcode()) {
19401 case RISCV::PseudoFROUND_H:
19402 CmpOpc = RISCV::FLT_H;
19403 F2IOpc = RISCV::FCVT_W_H;
19404 I2FOpc = RISCV::FCVT_H_W;
19405 FSGNJOpc = RISCV::FSGNJ_H;
19406 FSGNJXOpc = RISCV::FSGNJX_H;
19407 RC = &RISCV::FPR16RegClass;
19409 case RISCV::PseudoFROUND_H_INX:
19410 CmpOpc = RISCV::FLT_H_INX;
19411 F2IOpc = RISCV::FCVT_W_H_INX;
19412 I2FOpc = RISCV::FCVT_H_W_INX;
19413 FSGNJOpc = RISCV::FSGNJ_H_INX;
19414 FSGNJXOpc = RISCV::FSGNJX_H_INX;
19415 RC = &RISCV::GPRF16RegClass;
19417 case RISCV::PseudoFROUND_S:
19418 CmpOpc = RISCV::FLT_S;
19419 F2IOpc = RISCV::FCVT_W_S;
19420 I2FOpc = RISCV::FCVT_S_W;
19421 FSGNJOpc = RISCV::FSGNJ_S;
19422 FSGNJXOpc = RISCV::FSGNJX_S;
19423 RC = &RISCV::FPR32RegClass;
19425 case RISCV::PseudoFROUND_S_INX:
19426 CmpOpc = RISCV::FLT_S_INX;
19427 F2IOpc = RISCV::FCVT_W_S_INX;
19428 I2FOpc = RISCV::FCVT_S_W_INX;
19429 FSGNJOpc = RISCV::FSGNJ_S_INX;
19430 FSGNJXOpc = RISCV::FSGNJX_S_INX;
19431 RC = &RISCV::GPRF32RegClass;
19433 case RISCV::PseudoFROUND_D:
19435 CmpOpc = RISCV::FLT_D;
19436 F2IOpc = RISCV::FCVT_L_D;
19437 I2FOpc = RISCV::FCVT_D_L;
19438 FSGNJOpc = RISCV::FSGNJ_D;
19439 FSGNJXOpc = RISCV::FSGNJX_D;
19440 RC = &RISCV::FPR64RegClass;
19442 case RISCV::PseudoFROUND_D_INX:
19444 CmpOpc = RISCV::FLT_D_INX;
19445 F2IOpc = RISCV::FCVT_L_D_INX;
19446 I2FOpc = RISCV::FCVT_D_L_INX;
19447 FSGNJOpc = RISCV::FSGNJ_D_INX;
19448 FSGNJXOpc = RISCV::FSGNJX_D_INX;
19449 RC = &RISCV::GPRRegClass;
19461 F->insert(
I, CvtMBB);
19462 F->insert(
I, DoneMBB);
19473 Register DstReg =
MI.getOperand(0).getReg();
19474 Register SrcReg =
MI.getOperand(1).getReg();
19475 Register MaxReg =
MI.getOperand(2).getReg();
19476 int64_t FRM =
MI.getOperand(3).getImm();
19481 Register FabsReg =
MRI.createVirtualRegister(RC);
19485 Register CmpReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
19500 Register F2IReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
19522 MI.eraseFromParent();
19529 switch (
MI.getOpcode()) {
19532 case RISCV::ReadCounterWide:
19534 "ReadCounterWide is only to be used on riscv32");
19536 case RISCV::Select_GPR_Using_CC_GPR:
19537 case RISCV::Select_GPR_Using_CC_Imm:
19538 case RISCV::Select_FPR16_Using_CC_GPR:
19539 case RISCV::Select_FPR16INX_Using_CC_GPR:
19540 case RISCV::Select_FPR32_Using_CC_GPR:
19541 case RISCV::Select_FPR32INX_Using_CC_GPR:
19542 case RISCV::Select_FPR64_Using_CC_GPR:
19543 case RISCV::Select_FPR64INX_Using_CC_GPR:
19544 case RISCV::Select_FPR64IN32X_Using_CC_GPR:
19546 case RISCV::BuildPairF64Pseudo:
19548 case RISCV::SplitF64Pseudo:
19550 case RISCV::PseudoQuietFLE_H:
19552 case RISCV::PseudoQuietFLE_H_INX:
19553 return emitQuietFCMP(
MI, BB, RISCV::FLE_H_INX, RISCV::FEQ_H_INX, Subtarget);
19554 case RISCV::PseudoQuietFLT_H:
19556 case RISCV::PseudoQuietFLT_H_INX:
19557 return emitQuietFCMP(
MI, BB, RISCV::FLT_H_INX, RISCV::FEQ_H_INX, Subtarget);
19558 case RISCV::PseudoQuietFLE_S:
19560 case RISCV::PseudoQuietFLE_S_INX:
19561 return emitQuietFCMP(
MI, BB, RISCV::FLE_S_INX, RISCV::FEQ_S_INX, Subtarget);
19562 case RISCV::PseudoQuietFLT_S:
19564 case RISCV::PseudoQuietFLT_S_INX:
19565 return emitQuietFCMP(
MI, BB, RISCV::FLT_S_INX, RISCV::FEQ_S_INX, Subtarget);
19566 case RISCV::PseudoQuietFLE_D:
19568 case RISCV::PseudoQuietFLE_D_INX:
19569 return emitQuietFCMP(
MI, BB, RISCV::FLE_D_INX, RISCV::FEQ_D_INX, Subtarget);
19570 case RISCV::PseudoQuietFLE_D_IN32X:
19573 case RISCV::PseudoQuietFLT_D:
19575 case RISCV::PseudoQuietFLT_D_INX:
19576 return emitQuietFCMP(
MI, BB, RISCV::FLT_D_INX, RISCV::FEQ_D_INX, Subtarget);
19577 case RISCV::PseudoQuietFLT_D_IN32X:
19581 case RISCV::PseudoVFROUND_NOEXCEPT_V_M1_MASK:
19583 case RISCV::PseudoVFROUND_NOEXCEPT_V_M2_MASK:
19585 case RISCV::PseudoVFROUND_NOEXCEPT_V_M4_MASK:
19587 case RISCV::PseudoVFROUND_NOEXCEPT_V_M8_MASK:
19589 case RISCV::PseudoVFROUND_NOEXCEPT_V_MF2_MASK:
19591 case RISCV::PseudoVFROUND_NOEXCEPT_V_MF4_MASK:
19593 case RISCV::PseudoFROUND_H:
19594 case RISCV::PseudoFROUND_H_INX:
19595 case RISCV::PseudoFROUND_S:
19596 case RISCV::PseudoFROUND_S_INX:
19597 case RISCV::PseudoFROUND_D:
19598 case RISCV::PseudoFROUND_D_INX:
19599 case RISCV::PseudoFROUND_D_IN32X:
19601 case TargetOpcode::STATEPOINT:
19607 MI.addOperand(*
MI.getMF(),
19613 case TargetOpcode::STACKMAP:
19614 case TargetOpcode::PATCHPOINT:
19617 "supported on 64-bit targets");
19635 if (
MI.readsRegister(RISCV::FRM,
nullptr))
19641void RISCVTargetLowering::analyzeInputArgs(
19645 unsigned NumArgs = Ins.size();
19648 for (
unsigned i = 0; i != NumArgs; ++i) {
19649 MVT ArgVT = Ins[i].VT;
19652 Type *ArgTy =
nullptr;
19655 else if (Ins[i].isOrigArg())
19656 ArgTy = FType->
getParamType(Ins[i].getOrigArgIndex());
19659 true, IsRet, ArgTy)) {
19660 LLVM_DEBUG(
dbgs() <<
"InputArg #" << i <<
" has unhandled type "
19667void RISCVTargetLowering::analyzeOutputArgs(
19671 unsigned NumArgs = Outs.
size();
19673 for (
unsigned i = 0; i != NumArgs; i++) {
19674 MVT ArgVT = Outs[i].VT;
19676 Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty :
nullptr;
19679 Outs[i].IsFixed, IsRet, OrigTy)) {
19680 LLVM_DEBUG(
dbgs() <<
"OutputArg #" << i <<
" has unhandled type "
19731 if (In.isOrigArg()) {
19736 if ((
BitWidth <= 32 && In.Flags.isSExt()) ||
19737 (
BitWidth < 32 && In.Flags.isZExt())) {
19759 if (LocVT == MVT::i64 && VA.
getValVT() == MVT::f32)
19808 ExtType,
DL, LocVT, Chain, FIN,
19825 Register LoVReg =
RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
19838 Register HiVReg =
RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
19853 switch (CallConv) {
19863 if (Subtarget.hasStdExtE())
19867 "(Zdinx/D) instruction set extensions");
19871 if (Func.hasFnAttribute(
"interrupt")) {
19872 if (!Func.arg_empty())
19874 "Functions with the interrupt attribute cannot have arguments!");
19879 if (!(Kind ==
"user" || Kind ==
"supervisor" || Kind ==
"machine"))
19881 "Function interrupt attribute argument not supported!");
19886 unsigned XLenInBytes = Subtarget.
getXLen() / 8;
19888 std::vector<SDValue> OutChains;
19897 analyzeInputArgs(MF, CCInfo, Ins,
false,
19901 for (
unsigned i = 0, e = ArgLocs.
size(), InsIdx = 0; i != e; ++i, ++InsIdx) {
19922 unsigned ArgIndex = Ins[InsIdx].OrigArgIndex;
19923 unsigned ArgPartOffset = Ins[InsIdx].PartOffset;
19925 while (i + 1 != e && Ins[InsIdx + 1].OrigArgIndex == ArgIndex) {
19927 unsigned PartOffset = Ins[InsIdx + 1].PartOffset - ArgPartOffset;
19956 int VarArgsSaveSize = XLenInBytes * (ArgRegs.
size() -
Idx);
19961 if (VarArgsSaveSize == 0) {
19965 int VaArgOffset = -VarArgsSaveSize;
19973 XLenInBytes, VaArgOffset -
static_cast<int>(XLenInBytes),
true);
19974 VarArgsSaveSize += XLenInBytes;
19981 for (
unsigned I =
Idx;
I < ArgRegs.
size(); ++
I) {
19986 Chain,
DL, ArgValue, FIN,
19988 OutChains.push_back(Store);
20002 if (!OutChains.empty()) {
20003 OutChains.push_back(Chain);
20013bool RISCVTargetLowering::isEligibleForTailCallOptimization(
20017 auto CalleeCC = CLI.CallConv;
20018 auto &Outs = CLI.Outs;
20020 auto CallerCC = Caller.getCallingConv();
20027 if (Caller.hasFnAttribute(
"interrupt"))
20042 for (
auto &VA : ArgLocs)
20048 auto IsCallerStructRet = Caller.hasStructRetAttr();
20049 auto IsCalleeStructRet = Outs.
empty() ?
false : Outs[0].Flags.isSRet();
20050 if (IsCallerStructRet || IsCalleeStructRet)
20055 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
20056 if (CalleeCC != CallerCC) {
20057 const uint32_t *CalleePreserved =
TRI->getCallPreservedMask(MF, CalleeCC);
20058 if (!
TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
20065 for (
auto &Arg : Outs)
20066 if (Arg.Flags.isByVal())
20101 if (Subtarget.hasStdExtE())
20105 analyzeOutputArgs(MF, ArgCCInfo, Outs,
false, &CLI,
20111 IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs);
20117 "site marked musttail");
20124 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
20126 if (!Flags.isByVal())
20130 unsigned Size = Flags.getByValSize();
20131 Align Alignment = Flags.getNonZeroByValAlign();
20138 Chain = DAG.
getMemcpy(Chain,
DL, FIPtr, Arg, SizeNode, Alignment,
20140 false,
nullptr, IsTailCall,
20152 for (
unsigned i = 0, j = 0, e = ArgLocs.
size(), OutIdx = 0; i != e;
20155 SDValue ArgValue = OutVals[OutIdx];
20175 if (!StackPtr.getNode())
20187 RegsToPass.
push_back(std::make_pair(RegHigh,
Hi));
20205 unsigned ArgIndex = Outs[OutIdx].OrigArgIndex;
20206 unsigned ArgPartOffset = Outs[OutIdx].PartOffset;
20212 while (i + 1 != e && Outs[OutIdx + 1].OrigArgIndex == ArgIndex) {
20213 SDValue PartValue = OutVals[OutIdx + 1];
20214 unsigned PartOffset = Outs[OutIdx + 1].PartOffset - ArgPartOffset;
20226 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
20228 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot,
20230 for (
const auto &Part : Parts) {
20231 SDValue PartValue = Part.first;
20232 SDValue PartOffset = Part.second;
20239 ArgValue = SpillSlot;
20245 if (Flags.isByVal())
20246 ArgValue = ByValArgs[j++];
20253 assert(!IsTailCall &&
"Tail call not allowed if stack is used "
20254 "for passing parameters");
20257 if (!StackPtr.getNode())
20271 if (!MemOpChains.
empty())
20277 for (
auto &Reg : RegsToPass) {
20278 Chain = DAG.
getCopyToReg(Chain,
DL, Reg.first, Reg.second, Glue);
20285 validateCCReservedRegs(RegsToPass, MF);
20289 "Return address register required, but has been reserved."});
20294 bool CalleeIsLargeExternalSymbol =
false;
20296 if (
auto *S = dyn_cast<GlobalAddressSDNode>(Callee))
20298 else if (
auto *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
20300 CalleeIsLargeExternalSymbol =
true;
20316 for (
auto &Reg : RegsToPass)
20321 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
20322 assert(Mask &&
"Missing call preserved mask for calling convention");
20330 "Unexpected CFI type for a direct call");
20338 bool NeedSWGuarded =
false;
20340 Subtarget.hasStdExtZicfilp() &&
20342 NeedSWGuarded =
true;
20356 Chain = DAG.
getNode(CallOpc,
DL, NodeTys, Ops);
20369 analyzeInputArgs(MF, RetCCInfo, Ins,
true,
CC_RISCV);
20372 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
20373 auto &VA = RVLocs[i];
20381 if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
20382 assert(VA.needsCustom());
20402 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
20404 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
20405 MVT VT = Outs[i].VT;
20408 true,
true,
nullptr))
20440 for (
unsigned i = 0, e = RVLocs.size(), OutIdx = 0; i < e; ++i, ++OutIdx) {
20441 SDValue Val = OutVals[OutIdx];
20450 DAG.
getVTList(MVT::i32, MVT::i32), Val);
20454 Register RegHi = RVLocs[++i].getLocReg();
20460 "Return value register required, but has been reserved."});
20476 "Return value register required, but has been reserved."});
20498 if (Func.hasFnAttribute(
"interrupt")) {
20499 if (!Func.getReturnType()->isVoidTy())
20501 "Functions with the interrupt attribute must have void return type!");
20507 if (Kind ==
"supervisor")
20513 return DAG.
getNode(RetOpc,
DL, MVT::Other, RetOps);
20516void RISCVTargetLowering::validateCCReservedRegs(
20517 const SmallVectorImpl<std::pair<llvm::Register, llvm::SDValue>> &Regs,
20526 F,
"Argument register required, but has been reserved."});
20532 if (
N->getNumValues() != 1)
20534 if (!
N->hasNUsesOfValue(1, 0))
20537 SDNode *Copy = *
N->user_begin();
20551 if (Copy->getOperand(Copy->getNumOperands() - 1).getValueType() == MVT::Glue)
20555 bool HasRet =
false;
20556 for (
SDNode *Node : Copy->users()) {
20564 Chain = Copy->getOperand(0);
20573#define NODE_NAME_CASE(NODE) \
20574 case RISCVISD::NODE: \
20575 return "RISCVISD::" #NODE;
20836#undef NODE_NAME_CASE
20843 if (Constraint.
size() == 1) {
20844 switch (Constraint[0]) {
20861 if (Constraint ==
"vr" || Constraint ==
"vd" || Constraint ==
"vm")
20863 if (Constraint ==
"cr" || Constraint ==
"cf")
20869std::pair<unsigned, const TargetRegisterClass *>
20875 if (Constraint.
size() == 1) {
20876 switch (Constraint[0]) {
20881 if (VT == MVT::f16 && Subtarget.hasStdExtZhinxmin())
20882 return std::make_pair(0U, &RISCV::GPRF16NoX0RegClass);
20883 if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
20884 return std::make_pair(0U, &RISCV::GPRF32NoX0RegClass);
20885 if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.
is64Bit())
20886 return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
20887 return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
20889 if (VT == MVT::f16) {
20890 if (Subtarget.hasStdExtZfhmin())
20891 return std::make_pair(0U, &RISCV::FPR16RegClass);
20892 if (Subtarget.hasStdExtZhinxmin())
20893 return std::make_pair(0U, &RISCV::GPRF16NoX0RegClass);
20894 }
else if (VT == MVT::f32) {
20895 if (Subtarget.hasStdExtF())
20896 return std::make_pair(0U, &RISCV::FPR32RegClass);
20897 if (Subtarget.hasStdExtZfinx())
20898 return std::make_pair(0U, &RISCV::GPRF32NoX0RegClass);
20899 }
else if (VT == MVT::f64) {
20900 if (Subtarget.hasStdExtD())
20901 return std::make_pair(0U, &RISCV::FPR64RegClass);
20902 if (Subtarget.hasStdExtZdinx() && !Subtarget.
is64Bit())
20903 return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
20904 if (Subtarget.hasStdExtZdinx() && Subtarget.
is64Bit())
20905 return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
20909 if (VT == MVT::f64 && !Subtarget.
is64Bit() && Subtarget.hasStdExtZdinx())
20910 return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
20911 return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
20915 }
else if (Constraint ==
"vr") {
20916 for (
const auto *RC :
20917 {&RISCV::VRRegClass, &RISCV::VRM2RegClass, &RISCV::VRM4RegClass,
20918 &RISCV::VRM8RegClass, &RISCV::VRN2M1RegClass, &RISCV::VRN3M1RegClass,
20919 &RISCV::VRN4M1RegClass, &RISCV::VRN5M1RegClass,
20920 &RISCV::VRN6M1RegClass, &RISCV::VRN7M1RegClass,
20921 &RISCV::VRN8M1RegClass, &RISCV::VRN2M2RegClass,
20922 &RISCV::VRN3M2RegClass, &RISCV::VRN4M2RegClass,
20923 &RISCV::VRN2M4RegClass}) {
20925 return std::make_pair(0U, RC);
20927 }
else if (Constraint ==
"vd") {
20928 for (
const auto *RC :
20929 {&RISCV::VRNoV0RegClass, &RISCV::VRM2NoV0RegClass,
20930 &RISCV::VRM4NoV0RegClass, &RISCV::VRM8NoV0RegClass,
20931 &RISCV::VRN2M1NoV0RegClass, &RISCV::VRN3M1NoV0RegClass,
20932 &RISCV::VRN4M1NoV0RegClass, &RISCV::VRN5M1NoV0RegClass,
20933 &RISCV::VRN6M1NoV0RegClass, &RISCV::VRN7M1NoV0RegClass,
20934 &RISCV::VRN8M1NoV0RegClass, &RISCV::VRN2M2NoV0RegClass,
20935 &RISCV::VRN3M2NoV0RegClass, &RISCV::VRN4M2NoV0RegClass,
20936 &RISCV::VRN2M4NoV0RegClass}) {
20938 return std::make_pair(0U, RC);
20940 }
else if (Constraint ==
"vm") {
20941 if (
TRI->isTypeLegalForClass(RISCV::VMV0RegClass, VT.
SimpleTy))
20942 return std::make_pair(0U, &RISCV::VMV0RegClass);
20943 }
else if (Constraint ==
"cr") {
20944 if (VT == MVT::f16 && Subtarget.hasStdExtZhinxmin())
20945 return std::make_pair(0U, &RISCV::GPRF16CRegClass);
20946 if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
20947 return std::make_pair(0U, &RISCV::GPRF32CRegClass);
20948 if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.
is64Bit())
20949 return std::make_pair(0U, &RISCV::GPRPairCRegClass);
20951 return std::make_pair(0U, &RISCV::GPRCRegClass);
20952 }
else if (Constraint ==
"cf") {
20953 if (VT == MVT::f16) {
20954 if (Subtarget.hasStdExtZfhmin())
20955 return std::make_pair(0U, &RISCV::FPR16CRegClass);
20956 if (Subtarget.hasStdExtZhinxmin())
20957 return std::make_pair(0U, &RISCV::GPRF16CRegClass);
20958 }
else if (VT == MVT::f32) {
20959 if (Subtarget.hasStdExtF())
20960 return std::make_pair(0U, &RISCV::FPR32CRegClass);
20961 if (Subtarget.hasStdExtZfinx())
20962 return std::make_pair(0U, &RISCV::GPRF32CRegClass);
20963 }
else if (VT == MVT::f64) {
20964 if (Subtarget.hasStdExtD())
20965 return std::make_pair(0U, &RISCV::FPR64CRegClass);
20966 if (Subtarget.hasStdExtZdinx() && !Subtarget.
is64Bit())
20967 return std::make_pair(0U, &RISCV::GPRPairCRegClass);
20968 if (Subtarget.hasStdExtZdinx() && Subtarget.
is64Bit())
20969 return std::make_pair(0U, &RISCV::GPRCRegClass);
20978 .
Case(
"{zero}", RISCV::X0)
20979 .
Case(
"{ra}", RISCV::X1)
20980 .
Case(
"{sp}", RISCV::X2)
20981 .
Case(
"{gp}", RISCV::X3)
20982 .
Case(
"{tp}", RISCV::X4)
20983 .
Case(
"{t0}", RISCV::X5)
20984 .
Case(
"{t1}", RISCV::X6)
20985 .
Case(
"{t2}", RISCV::X7)
20986 .
Cases(
"{s0}",
"{fp}", RISCV::X8)
20987 .
Case(
"{s1}", RISCV::X9)
20988 .
Case(
"{a0}", RISCV::X10)
20989 .
Case(
"{a1}", RISCV::X11)
20990 .
Case(
"{a2}", RISCV::X12)
20991 .
Case(
"{a3}", RISCV::X13)
20992 .
Case(
"{a4}", RISCV::X14)
20993 .
Case(
"{a5}", RISCV::X15)
20994 .
Case(
"{a6}", RISCV::X16)
20995 .
Case(
"{a7}", RISCV::X17)
20996 .
Case(
"{s2}", RISCV::X18)
20997 .
Case(
"{s3}", RISCV::X19)
20998 .
Case(
"{s4}", RISCV::X20)
20999 .
Case(
"{s5}", RISCV::X21)
21000 .
Case(
"{s6}", RISCV::X22)
21001 .
Case(
"{s7}", RISCV::X23)
21002 .
Case(
"{s8}", RISCV::X24)
21003 .
Case(
"{s9}", RISCV::X25)
21004 .
Case(
"{s10}", RISCV::X26)
21005 .
Case(
"{s11}", RISCV::X27)
21006 .
Case(
"{t3}", RISCV::X28)
21007 .
Case(
"{t4}", RISCV::X29)
21008 .
Case(
"{t5}", RISCV::X30)
21009 .
Case(
"{t6}", RISCV::X31)
21011 if (XRegFromAlias != RISCV::NoRegister)
21012 return std::make_pair(XRegFromAlias, &RISCV::GPRRegClass);
21021 if (Subtarget.hasStdExtF()) {
21023 .
Cases(
"{f0}",
"{ft0}", RISCV::F0_F)
21024 .
Cases(
"{f1}",
"{ft1}", RISCV::F1_F)
21025 .
Cases(
"{f2}",
"{ft2}", RISCV::F2_F)
21026 .
Cases(
"{f3}",
"{ft3}", RISCV::F3_F)
21027 .
Cases(
"{f4}",
"{ft4}", RISCV::F4_F)
21028 .
Cases(
"{f5}",
"{ft5}", RISCV::F5_F)
21029 .
Cases(
"{f6}",
"{ft6}", RISCV::F6_F)
21030 .
Cases(
"{f7}",
"{ft7}", RISCV::F7_F)
21031 .
Cases(
"{f8}",
"{fs0}", RISCV::F8_F)
21032 .
Cases(
"{f9}",
"{fs1}", RISCV::F9_F)
21033 .
Cases(
"{f10}",
"{fa0}", RISCV::F10_F)
21034 .
Cases(
"{f11}",
"{fa1}", RISCV::F11_F)
21035 .
Cases(
"{f12}",
"{fa2}", RISCV::F12_F)
21036 .
Cases(
"{f13}",
"{fa3}", RISCV::F13_F)
21037 .
Cases(
"{f14}",
"{fa4}", RISCV::F14_F)
21038 .
Cases(
"{f15}",
"{fa5}", RISCV::F15_F)
21039 .
Cases(
"{f16}",
"{fa6}", RISCV::F16_F)