42#include "llvm/IR/IntrinsicsRISCV.h"
56#define DEBUG_TYPE "riscv-lower"
62 cl::desc(
"Give the maximum size (in number of nodes) of the web of "
63 "instructions that we will consider for VW expansion"),
68 cl::desc(
"Allow the formation of VW_W operations (e.g., "
69 "VWADD_W) with splat constants"),
74 cl::desc(
"Set the minimum number of repetitions of a divisor to allow "
75 "transformation to multiplications by the reciprocal"),
80 cl::desc(
"Give the maximum number of instructions that we will "
81 "use for creating a floating-point immediate value"),
86 cl::desc(
"Swap add and addi in cases where the add may "
87 "be combined with a shift"),
92 ISD::VP_FNEG, ISD::VP_FABS, ISD::VP_FCOPYSIGN};
107 !Subtarget.hasStdExtF()) {
108 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
109 "doesn't support the F instruction set extension (ignoring "
113 !Subtarget.hasStdExtD()) {
114 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
115 "doesn't support the D instruction set extension (ignoring "
134 MVT XLenVT = Subtarget.getXLenVT();
139 if (Subtarget.hasStdExtZfhmin())
141 if (Subtarget.hasStdExtZfbfmin() || Subtarget.hasVendorXAndesBFHCvt())
143 if (Subtarget.hasStdExtF())
145 if (Subtarget.hasStdExtD())
147 if (Subtarget.hasStdExtZhinxmin())
149 if (Subtarget.hasStdExtZfinx())
151 if (Subtarget.hasStdExtZdinx()) {
152 if (Subtarget.is64Bit())
159 MVT::nxv1i1, MVT::nxv2i1, MVT::nxv4i1, MVT::nxv8i1,
160 MVT::nxv16i1, MVT::nxv32i1, MVT::nxv64i1};
162 MVT::nxv1i8, MVT::nxv2i8, MVT::nxv4i8, MVT::nxv8i8, MVT::nxv16i8,
163 MVT::nxv32i8, MVT::nxv64i8, MVT::nxv1i16, MVT::nxv2i16, MVT::nxv4i16,
164 MVT::nxv8i16, MVT::nxv16i16, MVT::nxv32i16, MVT::nxv1i32, MVT::nxv2i32,
165 MVT::nxv4i32, MVT::nxv8i32, MVT::nxv16i32, MVT::nxv1i64, MVT::nxv2i64,
166 MVT::nxv4i64, MVT::nxv8i64};
168 MVT::nxv1f16, MVT::nxv2f16, MVT::nxv4f16,
169 MVT::nxv8f16, MVT::nxv16f16, MVT::nxv32f16};
171 MVT::nxv1bf16, MVT::nxv2bf16, MVT::nxv4bf16,
172 MVT::nxv8bf16, MVT::nxv16bf16, MVT::nxv32bf16};
174 MVT::nxv1f32, MVT::nxv2f32, MVT::nxv4f32, MVT::nxv8f32, MVT::nxv16f32};
176 MVT::nxv1f64, MVT::nxv2f64, MVT::nxv4f64, MVT::nxv8f64};
178 MVT::riscv_nxv1i8x2, MVT::riscv_nxv1i8x3, MVT::riscv_nxv1i8x4,
179 MVT::riscv_nxv1i8x5, MVT::riscv_nxv1i8x6, MVT::riscv_nxv1i8x7,
180 MVT::riscv_nxv1i8x8, MVT::riscv_nxv2i8x2, MVT::riscv_nxv2i8x3,
181 MVT::riscv_nxv2i8x4, MVT::riscv_nxv2i8x5, MVT::riscv_nxv2i8x6,
182 MVT::riscv_nxv2i8x7, MVT::riscv_nxv2i8x8, MVT::riscv_nxv4i8x2,
183 MVT::riscv_nxv4i8x3, MVT::riscv_nxv4i8x4, MVT::riscv_nxv4i8x5,
184 MVT::riscv_nxv4i8x6, MVT::riscv_nxv4i8x7, MVT::riscv_nxv4i8x8,
185 MVT::riscv_nxv8i8x2, MVT::riscv_nxv8i8x3, MVT::riscv_nxv8i8x4,
186 MVT::riscv_nxv8i8x5, MVT::riscv_nxv8i8x6, MVT::riscv_nxv8i8x7,
187 MVT::riscv_nxv8i8x8, MVT::riscv_nxv16i8x2, MVT::riscv_nxv16i8x3,
188 MVT::riscv_nxv16i8x4, MVT::riscv_nxv32i8x2};
190 if (Subtarget.hasVInstructions()) {
191 auto addRegClassForRVV = [
this](
MVT VT) {
195 if (VT.getVectorMinNumElements() < MinElts)
198 unsigned Size = VT.getSizeInBits().getKnownMinValue();
201 RC = &RISCV::VRRegClass;
203 RC = &RISCV::VRM2RegClass;
205 RC = &RISCV::VRM4RegClass;
207 RC = &RISCV::VRM8RegClass;
214 for (
MVT VT : BoolVecVTs)
215 addRegClassForRVV(VT);
216 for (
MVT VT : IntVecVTs) {
217 if (VT.getVectorElementType() == MVT::i64 &&
218 !Subtarget.hasVInstructionsI64())
220 addRegClassForRVV(VT);
223 if (Subtarget.hasVInstructionsF16Minimal() ||
224 Subtarget.hasVendorXAndesVPackFPH())
225 for (
MVT VT : F16VecVTs)
226 addRegClassForRVV(VT);
228 if (Subtarget.hasVInstructionsBF16Minimal() ||
229 Subtarget.hasVendorXAndesVBFHCvt())
230 for (
MVT VT : BF16VecVTs)
231 addRegClassForRVV(VT);
233 if (Subtarget.hasVInstructionsF32())
234 for (
MVT VT : F32VecVTs)
235 addRegClassForRVV(VT);
237 if (Subtarget.hasVInstructionsF64())
238 for (
MVT VT : F64VecVTs)
239 addRegClassForRVV(VT);
241 if (Subtarget.useRVVForFixedLengthVectors()) {
242 auto addRegClassForFixedVectors = [
this](
MVT VT) {
249 if (useRVVForFixedLengthVectorVT(VT))
250 addRegClassForFixedVectors(VT);
253 if (useRVVForFixedLengthVectorVT(VT))
254 addRegClassForFixedVectors(VT);
292 if (Subtarget.enablePExtSIMDCodeGen()) {
293 if (Subtarget.is64Bit()) {
326 if (!(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
336 if (!Subtarget.hasVendorXTHeadBb() && !Subtarget.hasVendorXqcibm() &&
337 !Subtarget.hasVendorXAndesPerf())
342 if (!Subtarget.hasStdExtZbb() && !Subtarget.hasVendorXTHeadBb() &&
343 !Subtarget.hasVendorXqcibm() && !Subtarget.hasVendorXAndesPerf() &&
344 !(Subtarget.hasVendorXCValu() && !Subtarget.is64Bit()))
347 if (Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit()) {
352 if (Subtarget.is64Bit()) {
361 if (!Subtarget.hasStdExtZmmul()) {
363 }
else if (Subtarget.is64Bit()) {
370 if (!Subtarget.hasStdExtM()) {
373 }
else if (Subtarget.is64Bit()) {
375 {MVT::i8, MVT::i16, MVT::i32},
Custom);
385 if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) {
386 if (Subtarget.is64Bit())
388 }
else if (Subtarget.hasVendorXTHeadBb()) {
389 if (Subtarget.is64Bit())
392 }
else if (Subtarget.hasVendorXCVbitmanip() && !Subtarget.is64Bit()) {
398 if (Subtarget.hasStdExtP())
404 if ((Subtarget.hasVendorXCVbitmanip() || Subtarget.hasVendorXqcibm()) &&
405 !Subtarget.is64Bit()) {
411 if (Subtarget.hasStdExtZbkb())
415 if (Subtarget.hasStdExtZbb() ||
416 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
421 if (Subtarget.hasCTZLike()) {
422 if (Subtarget.is64Bit())
428 if (!Subtarget.hasCPOPLike()) {
431 if (Subtarget.is64Bit())
438 if (Subtarget.hasCLZLike()) {
442 if (Subtarget.is64Bit() &&
443 (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtP()))
449 if (Subtarget.hasStdExtP()) {
451 if (Subtarget.is64Bit())
455 if (Subtarget.hasStdExtP() ||
456 (Subtarget.hasVendorXCValu() && !Subtarget.is64Bit())) {
458 if (Subtarget.is64Bit())
460 }
else if (Subtarget.hasShortForwardBranchIALU()) {
463 }
else if (Subtarget.is64Bit()) {
467 if (!Subtarget.useMIPSCCMovInsn() && !Subtarget.hasVendorXTHeadCondMov())
470 if ((Subtarget.hasStdExtP() || Subtarget.hasVendorXqcia()) &&
471 !Subtarget.is64Bit()) {
476 }
else if (!Subtarget.hasStdExtZbb() && Subtarget.is64Bit()) {
481 if (Subtarget.hasVendorXqcia() && !Subtarget.is64Bit()) {
485 if ((Subtarget.hasStdExtP() || Subtarget.hasVendorXqcia()) &&
486 !Subtarget.is64Bit()) {
492 static const unsigned FPLegalNodeTypes[] = {
508 static const unsigned FPOpToLibCall[] = {
ISD::FREM};
510 static const unsigned FPRndMode[] = {
514 static const unsigned ZfhminZfbfminPromoteOps[] = {
525 if (Subtarget.enablePExtSIMDCodeGen()) {
529 static const MVT RV32VTs[] = {MVT::v2i16, MVT::v4i8};
530 static const MVT RV64VTs[] = {MVT::v2i32, MVT::v4i16, MVT::v8i8};
532 if (Subtarget.is64Bit()) {
569 if (Subtarget.hasStdExtZfbfmin()) {
584 if (Subtarget.hasStdExtZfhminOrZhinxmin()) {
585 if (Subtarget.hasStdExtZfhOrZhinx()) {
592 if (Subtarget.hasStdExtZfa())
608 if (!Subtarget.hasStdExtD()) {
628 Subtarget.hasStdExtZfh() && Subtarget.hasStdExtZfa() ?
Legal :
Promote);
644 if (Subtarget.is64Bit())
648 if (Subtarget.hasStdExtFOrZfinx()) {
671 if (Subtarget.hasStdExtZfa()) {
680 if (Subtarget.hasStdExtFOrZfinx() && Subtarget.is64Bit())
683 if (Subtarget.hasStdExtDOrZdinx()) {
686 if (!Subtarget.is64Bit())
689 if (Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
690 !Subtarget.is64Bit()) {
695 if (Subtarget.hasStdExtZfa()) {
701 if (Subtarget.is64Bit())
731 if (Subtarget.is64Bit()) {
738 if (Subtarget.hasStdExtFOrZfinx()) {
764 if (Subtarget.is64Bit())
774 if (Subtarget.is64Bit()) {
781 if (Subtarget.is64Bit())
784 if (Subtarget.hasVendorXMIPSCBOP())
786 else if (Subtarget.hasStdExtZicbop())
789 if (Subtarget.hasStdExtZalrsc()) {
791 if (Subtarget.hasStdExtZabha() && Subtarget.hasStdExtZacas())
795 }
else if (Subtarget.hasForcedAtomics()) {
810 if (Subtarget.hasVInstructions()) {
819 {MVT::i8, MVT::i16},
Custom);
820 if (Subtarget.is64Bit())
830 static const unsigned IntegerVPOps[] = {
831 ISD::VP_ADD, ISD::VP_SUB, ISD::VP_MUL,
832 ISD::VP_SDIV, ISD::VP_UDIV, ISD::VP_SREM,
833 ISD::VP_UREM, ISD::VP_AND, ISD::VP_OR,
834 ISD::VP_XOR, ISD::VP_SRA, ISD::VP_SRL,
835 ISD::VP_SHL, ISD::VP_REDUCE_ADD, ISD::VP_REDUCE_AND,
836 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR, ISD::VP_REDUCE_SMAX,
837 ISD::VP_REDUCE_SMIN, ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN,
838 ISD::VP_MERGE, ISD::VP_SELECT, ISD::VP_FP_TO_SINT,
839 ISD::VP_FP_TO_UINT, ISD::VP_SETCC, ISD::VP_SIGN_EXTEND,
840 ISD::VP_ZERO_EXTEND, ISD::VP_TRUNCATE, ISD::VP_SMIN,
841 ISD::VP_SMAX, ISD::VP_UMIN, ISD::VP_UMAX,
842 ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE,
843 ISD::VP_SADDSAT, ISD::VP_UADDSAT, ISD::VP_SSUBSAT,
844 ISD::VP_USUBSAT, ISD::VP_CTTZ_ELTS, ISD::VP_CTTZ_ELTS_ZERO_UNDEF};
846 static const unsigned FloatingPointVPOps[] = {
847 ISD::VP_FADD, ISD::VP_FSUB, ISD::VP_FMUL,
848 ISD::VP_FDIV, ISD::VP_FNEG, ISD::VP_FABS,
849 ISD::VP_FMA, ISD::VP_REDUCE_FADD, ISD::VP_REDUCE_SEQ_FADD,
850 ISD::VP_REDUCE_FMIN, ISD::VP_REDUCE_FMAX, ISD::VP_MERGE,
851 ISD::VP_SELECT, ISD::VP_SINT_TO_FP, ISD::VP_UINT_TO_FP,
852 ISD::VP_SETCC, ISD::VP_FP_ROUND, ISD::VP_FP_EXTEND,
853 ISD::VP_SQRT, ISD::VP_FMINNUM, ISD::VP_FMAXNUM,
854 ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND,
855 ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO,
856 ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS,
857 ISD::VP_FMINIMUM, ISD::VP_FMAXIMUM, ISD::VP_LRINT,
858 ISD::VP_LLRINT, ISD::VP_REDUCE_FMINIMUM,
859 ISD::VP_REDUCE_FMAXIMUM};
861 static const unsigned IntegerVecReduceOps[] = {
866 static const unsigned FloatingPointVecReduceOps[] = {
870 static const unsigned FloatingPointLibCallOps[] = {
874 if (!Subtarget.is64Bit()) {
883 ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR,
884 ISD::VP_REDUCE_SMAX, ISD::VP_REDUCE_SMIN,
885 ISD::VP_REDUCE_UMAX, ISD::VP_REDUCE_UMIN},
889 for (
MVT VT : BoolVecVTs) {
919 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
943 ISD::VP_TRUNCATE, ISD::VP_SETCC},
959 for (
MVT VT : IntVecVTs) {
970 if (VT.getVectorElementType() == MVT::i64 && !Subtarget.hasStdExtV())
1020 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1021 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1046 if (Subtarget.hasStdExtZvkb()) {
1054 if (Subtarget.hasStdExtZvbb()) {
1058 ISD::VP_CTTZ_ZERO_UNDEF, ISD::VP_CTPOP},
1064 ISD::VP_CTTZ_ZERO_UNDEF, ISD::VP_CTPOP},
1073 ISD::VP_CTLZ_ZERO_UNDEF, ISD::VP_CTTZ_ZERO_UNDEF},
1081 for (
MVT VT : VecTupleVTs) {
1102 static const unsigned ZvfhminZvfbfminPromoteOps[] = {
1136 static const unsigned ZvfbfaPromoteOps[] = {
ISD::FDIV,
1158 static const unsigned ZvfhminZvfbfminPromoteVPOps[] = {
1164 ISD::VP_REDUCE_FMIN,
1165 ISD::VP_REDUCE_FMAX,
1173 ISD::VP_FROUNDTOZERO,
1179 ISD::VP_REDUCE_FMINIMUM,
1180 ISD::VP_REDUCE_FMAXIMUM};
1183 const auto SetCommonVFPActions = [&](
MVT VT) {
1221 {ISD::VP_LOAD, ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1222 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER, ISD::VP_SCATTER},
1260 const auto SetCommonVFPExtLoadTruncStoreActions =
1262 for (
auto SmallVT : SmallerVTs) {
1270 const auto SetCommonPromoteToF32Actions = [&](
MVT VT) {
1297 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1298 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1323 const auto SetZvfbfaActions = [&](
MVT VT) {
1355 ISD::VP_STORE, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1356 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1375 if (Subtarget.hasVInstructionsF16()) {
1376 for (
MVT VT : F16VecVTs) {
1379 SetCommonVFPActions(VT);
1381 }
else if (Subtarget.hasVInstructionsF16Minimal()) {
1382 for (
MVT VT : F16VecVTs) {
1385 SetCommonPromoteToF32Actions(VT);
1389 if (Subtarget.hasVInstructionsBF16()) {
1390 for (
MVT VT : BF16VecVTs) {
1393 SetZvfbfaActions(VT);
1395 }
else if (Subtarget.hasVInstructionsBF16Minimal()) {
1396 for (
MVT VT : BF16VecVTs) {
1399 SetCommonPromoteToF32Actions(VT);
1403 if (Subtarget.hasVInstructionsF32()) {
1404 for (
MVT VT : F32VecVTs) {
1407 SetCommonVFPActions(VT);
1408 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1409 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1413 if (Subtarget.hasVInstructionsF64()) {
1414 for (
MVT VT : F64VecVTs) {
1417 SetCommonVFPActions(VT);
1418 SetCommonVFPExtLoadTruncStoreActions(VT, F16VecVTs);
1419 SetCommonVFPExtLoadTruncStoreActions(VT, BF16VecVTs);
1420 SetCommonVFPExtLoadTruncStoreActions(VT, F32VecVTs);
1424 if (Subtarget.useRVVForFixedLengthVectors()) {
1426 if (!useRVVForFixedLengthVectorVT(VT))
1475 {ISD::VP_REDUCE_AND, ISD::VP_REDUCE_OR, ISD::VP_REDUCE_XOR}, VT,
1502 ISD::VP_SETCC, ISD::VP_TRUNCATE},
1529 ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1530 ISD::EXPERIMENTAL_VP_STRIDED_STORE, ISD::VP_GATHER,
1568 if (Subtarget.hasStdExtZvkb())
1571 if (Subtarget.hasStdExtZvbb()) {
1595 if (!useRVVForFixedLengthVectorVT(VT))
1621 ISD::VP_SCATTER, ISD::EXPERIMENTAL_VP_STRIDED_LOAD,
1622 ISD::EXPERIMENTAL_VP_STRIDED_STORE},
1631 !Subtarget.hasVInstructionsF16()) {
1641 if (Subtarget.hasStdExtZfhmin()) {
1667 if (Subtarget.hasStdExtZfbfmin()) {
1674 if (Subtarget.hasStdExtZvfbfa()) {
1688 if (Subtarget.hasStdExtZvfbfa())
1734 if (Subtarget.is64Bit())
1736 if (Subtarget.hasStdExtZfhminOrZhinxmin())
1738 if (Subtarget.hasStdExtZfbfmin())
1740 if (Subtarget.hasStdExtFOrZfinx())
1742 if (Subtarget.hasStdExtDOrZdinx())
1747 if (Subtarget.hasStdExtZaamo())
1750 if (Subtarget.hasForcedAtomics()) {
1760 if (Subtarget.hasVendorXTHeadMemIdx()) {
1769 if (Subtarget.is64Bit()) {
1776 if (Subtarget.hasVendorXCVmem() && !Subtarget.is64Bit()) {
1787 if (Subtarget.hasStdExtZvqdotq() && Subtarget.getELen() >= 64) {
1797 if (Subtarget.useRVVForFixedLengthVectors()) {
1799 if (VT.getVectorElementType() != MVT::i32 ||
1800 !useRVVForFixedLengthVectorVT(VT))
1810 if (Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh()) {
1816 const Align FunctionAlignment(Subtarget.hasStdExtZca() ? 2 : 4);
1828 if (Subtarget.hasStdExtFOrZfinx())
1831 if (Subtarget.hasStdExtZbb())
1834 if ((Subtarget.hasStdExtZbs() && Subtarget.is64Bit()) ||
1835 Subtarget.hasVInstructions())
1838 if (Subtarget.hasStdExtZbkb())
1841 if (Subtarget.hasStdExtFOrZfinx())
1844 if (Subtarget.hasVInstructions())
1847 ISD::VP_GATHER, ISD::VP_SCATTER,
ISD::SRA,
1850 ISD::VP_STORE, ISD::VP_TRUNCATE, ISD::EXPERIMENTAL_VP_REVERSE,
1856 if (Subtarget.hasVendorXTHeadMemPair())
1858 if (Subtarget.useRVVForFixedLengthVectors())
1882 Subtarget.getMaxStoresPerMemmove(
true);
1891 if (Subtarget.is64Bit() && Subtarget.enablePExtSIMDCodeGen())
1892 if (VT == MVT::v2i16 || VT == MVT::v4i8)
1903 if (Subtarget.hasVInstructions() &&
1914bool RISCVTargetLowering::shouldExpandGetVectorLength(
EVT TripCountVT,
1916 bool IsScalable)
const {
1923 if (TripCountVT != MVT::i32 && TripCountVT != Subtarget.
getXLenVT())
1941 return !Subtarget.hasVInstructions() ||
1949 auto &
DL =
I.getDataLayout();
1951 auto SetRVVLoadStoreInfo = [&](
unsigned PtrOp,
bool IsStore,
1952 bool IsUnitStrided,
bool UsePtrVal =
false) {
1957 Info.ptrVal =
I.getArgOperand(PtrOp);
1959 Info.fallbackAddressSpace =
1960 I.getArgOperand(PtrOp)->getType()->getPointerAddressSpace();
1964 MemTy =
I.getArgOperand(0)->getType();
1967 MemTy =
I.getType();
1982 Info.align =
DL.getABITypeAlign(MemTy);
1992 if (
I.hasMetadata(LLVMContext::MD_nontemporal))
1999 case Intrinsic::riscv_masked_atomicrmw_xchg:
2000 case Intrinsic::riscv_masked_atomicrmw_add:
2001 case Intrinsic::riscv_masked_atomicrmw_sub:
2002 case Intrinsic::riscv_masked_atomicrmw_nand:
2003 case Intrinsic::riscv_masked_atomicrmw_max:
2004 case Intrinsic::riscv_masked_atomicrmw_min:
2005 case Intrinsic::riscv_masked_atomicrmw_umax:
2006 case Intrinsic::riscv_masked_atomicrmw_umin:
2007 case Intrinsic::riscv_masked_cmpxchg:
2014 Info.memVT = MVT::i32;
2015 Info.ptrVal =
I.getArgOperand(0);
2017 Info.align =
Align(4);
2021 case Intrinsic::riscv_seg2_load_mask:
2022 case Intrinsic::riscv_seg3_load_mask:
2023 case Intrinsic::riscv_seg4_load_mask:
2024 case Intrinsic::riscv_seg5_load_mask:
2025 case Intrinsic::riscv_seg6_load_mask:
2026 case Intrinsic::riscv_seg7_load_mask:
2027 case Intrinsic::riscv_seg8_load_mask:
2028 case Intrinsic::riscv_sseg2_load_mask:
2029 case Intrinsic::riscv_sseg3_load_mask:
2030 case Intrinsic::riscv_sseg4_load_mask:
2031 case Intrinsic::riscv_sseg5_load_mask:
2032 case Intrinsic::riscv_sseg6_load_mask:
2033 case Intrinsic::riscv_sseg7_load_mask:
2034 case Intrinsic::riscv_sseg8_load_mask:
2035 return SetRVVLoadStoreInfo( 0,
false,
2037 case Intrinsic::riscv_seg2_store_mask:
2038 case Intrinsic::riscv_seg3_store_mask:
2039 case Intrinsic::riscv_seg4_store_mask:
2040 case Intrinsic::riscv_seg5_store_mask:
2041 case Intrinsic::riscv_seg6_store_mask:
2042 case Intrinsic::riscv_seg7_store_mask:
2043 case Intrinsic::riscv_seg8_store_mask:
2045 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
2048 case Intrinsic::riscv_sseg2_store_mask:
2049 case Intrinsic::riscv_sseg3_store_mask:
2050 case Intrinsic::riscv_sseg4_store_mask:
2051 case Intrinsic::riscv_sseg5_store_mask:
2052 case Intrinsic::riscv_sseg6_store_mask:
2053 case Intrinsic::riscv_sseg7_store_mask:
2054 case Intrinsic::riscv_sseg8_store_mask:
2056 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
2059 case Intrinsic::riscv_vlm:
2060 return SetRVVLoadStoreInfo( 0,
2064 case Intrinsic::riscv_vle:
2065 case Intrinsic::riscv_vle_mask:
2066 case Intrinsic::riscv_vleff:
2067 case Intrinsic::riscv_vleff_mask:
2068 return SetRVVLoadStoreInfo( 1,
2072 case Intrinsic::riscv_vsm:
2073 case Intrinsic::riscv_vse:
2074 case Intrinsic::riscv_vse_mask:
2075 return SetRVVLoadStoreInfo( 1,
2079 case Intrinsic::riscv_vlse:
2080 case Intrinsic::riscv_vlse_mask:
2081 case Intrinsic::riscv_vloxei:
2082 case Intrinsic::riscv_vloxei_mask:
2083 case Intrinsic::riscv_vluxei:
2084 case Intrinsic::riscv_vluxei_mask:
2085 return SetRVVLoadStoreInfo( 1,
2088 case Intrinsic::riscv_vsse:
2089 case Intrinsic::riscv_vsse_mask:
2090 case Intrinsic::riscv_vsoxei:
2091 case Intrinsic::riscv_vsoxei_mask:
2092 case Intrinsic::riscv_vsuxei:
2093 case Intrinsic::riscv_vsuxei_mask:
2094 return SetRVVLoadStoreInfo( 1,
2097 case Intrinsic::riscv_vlseg2:
2098 case Intrinsic::riscv_vlseg3:
2099 case Intrinsic::riscv_vlseg4:
2100 case Intrinsic::riscv_vlseg5:
2101 case Intrinsic::riscv_vlseg6:
2102 case Intrinsic::riscv_vlseg7:
2103 case Intrinsic::riscv_vlseg8:
2104 case Intrinsic::riscv_vlseg2ff:
2105 case Intrinsic::riscv_vlseg3ff:
2106 case Intrinsic::riscv_vlseg4ff:
2107 case Intrinsic::riscv_vlseg5ff:
2108 case Intrinsic::riscv_vlseg6ff:
2109 case Intrinsic::riscv_vlseg7ff:
2110 case Intrinsic::riscv_vlseg8ff:
2111 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
2114 case Intrinsic::riscv_vlseg2_mask:
2115 case Intrinsic::riscv_vlseg3_mask:
2116 case Intrinsic::riscv_vlseg4_mask:
2117 case Intrinsic::riscv_vlseg5_mask:
2118 case Intrinsic::riscv_vlseg6_mask:
2119 case Intrinsic::riscv_vlseg7_mask:
2120 case Intrinsic::riscv_vlseg8_mask:
2121 case Intrinsic::riscv_vlseg2ff_mask:
2122 case Intrinsic::riscv_vlseg3ff_mask:
2123 case Intrinsic::riscv_vlseg4ff_mask:
2124 case Intrinsic::riscv_vlseg5ff_mask:
2125 case Intrinsic::riscv_vlseg6ff_mask:
2126 case Intrinsic::riscv_vlseg7ff_mask:
2127 case Intrinsic::riscv_vlseg8ff_mask:
2128 return SetRVVLoadStoreInfo(
I.arg_size() - 5,
2131 case Intrinsic::riscv_vlsseg2:
2132 case Intrinsic::riscv_vlsseg3:
2133 case Intrinsic::riscv_vlsseg4:
2134 case Intrinsic::riscv_vlsseg5:
2135 case Intrinsic::riscv_vlsseg6:
2136 case Intrinsic::riscv_vlsseg7:
2137 case Intrinsic::riscv_vlsseg8:
2138 case Intrinsic::riscv_vloxseg2:
2139 case Intrinsic::riscv_vloxseg3:
2140 case Intrinsic::riscv_vloxseg4:
2141 case Intrinsic::riscv_vloxseg5:
2142 case Intrinsic::riscv_vloxseg6:
2143 case Intrinsic::riscv_vloxseg7:
2144 case Intrinsic::riscv_vloxseg8:
2145 case Intrinsic::riscv_vluxseg2:
2146 case Intrinsic::riscv_vluxseg3:
2147 case Intrinsic::riscv_vluxseg4:
2148 case Intrinsic::riscv_vluxseg5:
2149 case Intrinsic::riscv_vluxseg6:
2150 case Intrinsic::riscv_vluxseg7:
2151 case Intrinsic::riscv_vluxseg8:
2152 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
2155 case Intrinsic::riscv_vlsseg2_mask:
2156 case Intrinsic::riscv_vlsseg3_mask:
2157 case Intrinsic::riscv_vlsseg4_mask:
2158 case Intrinsic::riscv_vlsseg5_mask:
2159 case Intrinsic::riscv_vlsseg6_mask:
2160 case Intrinsic::riscv_vlsseg7_mask:
2161 case Intrinsic::riscv_vlsseg8_mask:
2162 case Intrinsic::riscv_vloxseg2_mask:
2163 case Intrinsic::riscv_vloxseg3_mask:
2164 case Intrinsic::riscv_vloxseg4_mask:
2165 case Intrinsic::riscv_vloxseg5_mask:
2166 case Intrinsic::riscv_vloxseg6_mask:
2167 case Intrinsic::riscv_vloxseg7_mask:
2168 case Intrinsic::riscv_vloxseg8_mask:
2169 case Intrinsic::riscv_vluxseg2_mask:
2170 case Intrinsic::riscv_vluxseg3_mask:
2171 case Intrinsic::riscv_vluxseg4_mask:
2172 case Intrinsic::riscv_vluxseg5_mask:
2173 case Intrinsic::riscv_vluxseg6_mask:
2174 case Intrinsic::riscv_vluxseg7_mask:
2175 case Intrinsic::riscv_vluxseg8_mask:
2176 return SetRVVLoadStoreInfo(
I.arg_size() - 6,
2179 case Intrinsic::riscv_vsseg2:
2180 case Intrinsic::riscv_vsseg3:
2181 case Intrinsic::riscv_vsseg4:
2182 case Intrinsic::riscv_vsseg5:
2183 case Intrinsic::riscv_vsseg6:
2184 case Intrinsic::riscv_vsseg7:
2185 case Intrinsic::riscv_vsseg8:
2186 return SetRVVLoadStoreInfo(
I.arg_size() - 3,
2189 case Intrinsic::riscv_vsseg2_mask:
2190 case Intrinsic::riscv_vsseg3_mask:
2191 case Intrinsic::riscv_vsseg4_mask:
2192 case Intrinsic::riscv_vsseg5_mask:
2193 case Intrinsic::riscv_vsseg6_mask:
2194 case Intrinsic::riscv_vsseg7_mask:
2195 case Intrinsic::riscv_vsseg8_mask:
2196 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
2199 case Intrinsic::riscv_vssseg2:
2200 case Intrinsic::riscv_vssseg3:
2201 case Intrinsic::riscv_vssseg4:
2202 case Intrinsic::riscv_vssseg5:
2203 case Intrinsic::riscv_vssseg6:
2204 case Intrinsic::riscv_vssseg7:
2205 case Intrinsic::riscv_vssseg8:
2206 case Intrinsic::riscv_vsoxseg2:
2207 case Intrinsic::riscv_vsoxseg3:
2208 case Intrinsic::riscv_vsoxseg4:
2209 case Intrinsic::riscv_vsoxseg5:
2210 case Intrinsic::riscv_vsoxseg6:
2211 case Intrinsic::riscv_vsoxseg7:
2212 case Intrinsic::riscv_vsoxseg8:
2213 case Intrinsic::riscv_vsuxseg2:
2214 case Intrinsic::riscv_vsuxseg3:
2215 case Intrinsic::riscv_vsuxseg4:
2216 case Intrinsic::riscv_vsuxseg5:
2217 case Intrinsic::riscv_vsuxseg6:
2218 case Intrinsic::riscv_vsuxseg7:
2219 case Intrinsic::riscv_vsuxseg8:
2220 return SetRVVLoadStoreInfo(
I.arg_size() - 4,
2223 case Intrinsic::riscv_vssseg2_mask:
2224 case Intrinsic::riscv_vssseg3_mask:
2225 case Intrinsic::riscv_vssseg4_mask:
2226 case Intrinsic::riscv_vssseg5_mask:
2227 case Intrinsic::riscv_vssseg6_mask:
2228 case Intrinsic::riscv_vssseg7_mask:
2229 case Intrinsic::riscv_vssseg8_mask:
2230 case Intrinsic::riscv_vsoxseg2_mask:
2231 case Intrinsic::riscv_vsoxseg3_mask:
2232 case Intrinsic::riscv_vsoxseg4_mask:
2233 case Intrinsic::riscv_vsoxseg5_mask:
2234 case Intrinsic::riscv_vsoxseg6_mask:
2235 case Intrinsic::riscv_vsoxseg7_mask:
2236 case Intrinsic::riscv_vsoxseg8_mask:
2237 case Intrinsic::riscv_vsuxseg2_mask:
2238 case Intrinsic::riscv_vsuxseg3_mask:
2239 case Intrinsic::riscv_vsuxseg4_mask:
2240 case Intrinsic::riscv_vsuxseg5_mask:
2241 case Intrinsic::riscv_vsuxseg6_mask:
2242 case Intrinsic::riscv_vsuxseg7_mask:
2243 case Intrinsic::riscv_vsuxseg8_mask:
2244 return SetRVVLoadStoreInfo(
I.arg_size() - 5,
2247 case Intrinsic::riscv_sf_vlte8:
2248 case Intrinsic::riscv_sf_vlte16:
2249 case Intrinsic::riscv_sf_vlte32:
2250 case Intrinsic::riscv_sf_vlte64:
2252 Info.ptrVal =
I.getArgOperand(1);
2254 case Intrinsic::riscv_sf_vlte8:
2255 Info.memVT = MVT::i8;
2256 Info.align =
Align(1);
2258 case Intrinsic::riscv_sf_vlte16:
2259 Info.memVT = MVT::i16;
2260 Info.align =
Align(2);
2262 case Intrinsic::riscv_sf_vlte32:
2263 Info.memVT = MVT::i32;
2264 Info.align =
Align(4);
2266 case Intrinsic::riscv_sf_vlte64:
2267 Info.memVT = MVT::i64;
2268 Info.align =
Align(8);
2274 case Intrinsic::riscv_sf_vste8:
2275 case Intrinsic::riscv_sf_vste16:
2276 case Intrinsic::riscv_sf_vste32:
2277 case Intrinsic::riscv_sf_vste64:
2279 Info.ptrVal =
I.getArgOperand(1);
2281 case Intrinsic::riscv_sf_vste8:
2282 Info.memVT = MVT::i8;
2283 Info.align =
Align(1);
2285 case Intrinsic::riscv_sf_vste16:
2286 Info.memVT = MVT::i16;
2287 Info.align =
Align(2);
2289 case Intrinsic::riscv_sf_vste32:
2290 Info.memVT = MVT::i32;
2291 Info.align =
Align(4);
2293 case Intrinsic::riscv_sf_vste64:
2294 Info.memVT = MVT::i64;
2295 Info.align =
Align(8);
2352 if (Subtarget.is64Bit() || !SrcTy->isIntegerTy() || !DstTy->
isIntegerTy())
2354 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
2356 return (SrcBits == 64 && DestBits == 32);
2367 return (SrcBits == 64 && DestBits == 32);
2373 if (Subtarget.hasVInstructions() &&
2378 if (SrcBits == DestBits * 2) {
2390 EVT MemVT = LD->getMemoryVT();
2391 if ((MemVT == MVT::i8 || MemVT == MVT::i16) &&
2401 return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
2409 return Subtarget.hasCTZLike();
2413 return Subtarget.hasCLZLike();
2424 if (!Subtarget.hasBEXTILike())
2429 return !Mask->getValue().isSignedIntN(12) && Mask->getValue().isPowerOf2();
2433 EVT VT =
Y.getValueType();
2438 return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
2443 EVT VT =
Y.getValueType();
2448 return Subtarget.hasStdExtZvkb();
2453 if (Subtarget.hasStdExtZbs())
2454 return X.getValueType().isScalarInteger();
2457 if (Subtarget.hasVendorXTHeadBs())
2458 return C !=
nullptr;
2460 return C &&
C->getAPIntValue().ule(10);
2464 unsigned BinOpcode,
EVT VT,
unsigned SelectOpcode,
SDValue X,
2470 if (!VT.
isVector() || !Subtarget.hasVInstructions())
2481 assert(Ty->isIntegerTy());
2483 unsigned BitSize = Ty->getIntegerBitWidth();
2484 if (BitSize > Subtarget.getXLen())
2488 int64_t Val = Imm.getSExtValue();
2496 if (!Subtarget.enableUnalignedScalarMem())
2506 return Seq.
size() <= Subtarget.getMaxBuildIntsCost();
2512 unsigned OldShiftOpcode,
unsigned NewShiftOpcode,
2567 if (!Subtarget.hasStdExtZfa())
2570 bool IsSupportedVT =
false;
2571 if (VT == MVT::f16) {
2572 IsSupportedVT = Subtarget.hasStdExtZfh() || Subtarget.hasStdExtZvfh();
2573 }
else if (VT == MVT::f32) {
2574 IsSupportedVT =
true;
2575 }
else if (VT == MVT::f64) {
2576 assert(Subtarget.hasStdExtD() &&
"Expect D extension");
2577 IsSupportedVT =
true;
2587 bool ForCodeSize)
const {
2588 bool IsLegalVT =
false;
2590 IsLegalVT = Subtarget.hasStdExtZfhminOrZhinxmin();
2591 else if (VT == MVT::f32)
2592 IsLegalVT = Subtarget.hasStdExtFOrZfinx();
2593 else if (VT == MVT::f64)
2594 IsLegalVT = Subtarget.hasStdExtDOrZdinx();
2595 else if (VT == MVT::bf16)
2596 IsLegalVT = Subtarget.hasStdExtZfbfmin();
2612 return Imm.isZero();
2616 if (Imm.isNegZero())
2621 const int FmvCost = Subtarget.hasStdExtZfinx() ? 0 : 1;
2624 Subtarget.getXLen(), Subtarget);
2630 unsigned Index)
const {
2647 if (EltVT == MVT::i1)
2653 unsigned MinVLen = Subtarget.getRealMinVLen();
2660 if (Index + ResElts <= MinVLMAX && Index < 31)
2669 return (ResElts * 2) == SrcElts && Index == ResElts;
2677 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2678 !Subtarget.hasStdExtZfhminOrZhinxmin())
2686 std::optional<MVT> RegisterVT)
const {
2688 if (VT == (Subtarget.is64Bit() ? MVT::i128 : MVT::i64) && RegisterVT &&
2689 *RegisterVT == MVT::Untyped)
2700 if (VT == MVT::f16 && Subtarget.hasStdExtFOrZfinx() &&
2701 !Subtarget.hasStdExtZfhminOrZhinxmin())
2720 !Subtarget.hasVendorXAndesPerf()) {
2726 ShAmt =
LHS.getValueSizeInBits() - 1 -
Log2_64(Mask);
2740 int64_t
C = RHSC->getSExtValue();
2750 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
2776 if ((Subtarget.hasVendorXqcicm() || Subtarget.hasVendorXqcicli()) &&
2811 if (VT.
SimpleTy >= MVT::riscv_nxv1i8x2 &&
2812 VT.
SimpleTy <= MVT::riscv_nxv1i8x8)
2814 if (VT.
SimpleTy >= MVT::riscv_nxv2i8x2 &&
2815 VT.
SimpleTy <= MVT::riscv_nxv2i8x8)
2817 if (VT.
SimpleTy >= MVT::riscv_nxv4i8x2 &&
2818 VT.
SimpleTy <= MVT::riscv_nxv4i8x8)
2820 if (VT.
SimpleTy >= MVT::riscv_nxv8i8x2 &&
2821 VT.
SimpleTy <= MVT::riscv_nxv8i8x8)
2823 if (VT.
SimpleTy >= MVT::riscv_nxv16i8x2 &&
2824 VT.
SimpleTy <= MVT::riscv_nxv16i8x4)
2826 if (VT.
SimpleTy == MVT::riscv_nxv32i8x2)
2836 switch (KnownSize) {
2864 return RISCV::VRRegClassID;
2866 return RISCV::VRM2RegClassID;
2868 return RISCV::VRM4RegClassID;
2870 return RISCV::VRM8RegClassID;
2878 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
2879 "Unexpected subreg numbering");
2880 return RISCV::sub_vrm1_0 + Index;
2883 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
2884 "Unexpected subreg numbering");
2885 return RISCV::sub_vrm2_0 + Index;
2888 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
2889 "Unexpected subreg numbering");
2890 return RISCV::sub_vrm4_0 + Index;
2898 unsigned RegsPerField =
2901 switch (RegsPerField) {
2904 return RISCV::VRN2M1RegClassID;
2906 return RISCV::VRN3M1RegClassID;
2908 return RISCV::VRN4M1RegClassID;
2910 return RISCV::VRN5M1RegClassID;
2912 return RISCV::VRN6M1RegClassID;
2914 return RISCV::VRN7M1RegClassID;
2916 return RISCV::VRN8M1RegClassID;
2920 return RISCV::VRN2M2RegClassID;
2922 return RISCV::VRN3M2RegClassID;
2924 return RISCV::VRN4M2RegClassID;
2928 return RISCV::VRN2M4RegClassID;
2936 return RISCV::VRRegClassID;
2945std::pair<unsigned, unsigned>
2947 MVT VecVT,
MVT SubVecVT,
unsigned InsertExtractIdx,
2949 static_assert((RISCV::VRM8RegClassID > RISCV::VRM4RegClassID &&
2950 RISCV::VRM4RegClassID > RISCV::VRM2RegClassID &&
2951 RISCV::VRM2RegClassID > RISCV::VRRegClassID),
2952 "Register classes not ordered");
2959 if (VecRegClassID == SubRegClassID)
2960 return {RISCV::NoSubRegister, 0};
2963 "Only allow scalable vector subvector.");
2965 "Invalid vector tuple insert/extract for vector and subvector with "
2976 unsigned SubRegIdx = RISCV::NoSubRegister;
2977 for (
const unsigned RCID :
2978 {RISCV::VRM4RegClassID, RISCV::VRM2RegClassID, RISCV::VRRegClassID})
2979 if (VecRegClassID > RCID && SubRegClassID <= RCID) {
2983 SubRegIdx =
TRI->composeSubRegIndices(SubRegIdx,
2988 return {SubRegIdx, InsertExtractIdx};
2993bool RISCVTargetLowering::mergeStoresAfterLegalization(
EVT VT)
const {
3003 return Subtarget.is64Bit() ? Subtarget.hasVInstructionsI64() :
true;
3007 return Subtarget.hasVInstructions();
3009 return Subtarget.hasVInstructionsI64();
3011 return Subtarget.hasVInstructionsF16Minimal();
3013 return Subtarget.hasVInstructionsBF16Minimal();
3015 return Subtarget.hasVInstructionsF32();
3017 return Subtarget.hasVInstructionsF64();
3031 "Unexpected opcode");
3033 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
3035 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
3038 return Op.getOperand(
II->VLOperand + 1 + HasChain);
3112bool RISCVTargetLowering::useRVVForFixedLengthVectorVT(
MVT VT)
const {
3113 return ::useRVVForFixedLengthVectorVT(VT, Subtarget);
3122 "Expected legal fixed length vector!");
3125 unsigned MaxELen = Subtarget.
getELen();
3159 return ::getContainerForFixedLengthVector(*
this, VT,
getSubtarget());
3166 "Expected to convert into a scalable vector!");
3167 assert(V.getValueType().isFixedLengthVector() &&
3168 "Expected a fixed length vector operand!");
3177 "Expected to convert into a fixed length vector!");
3178 assert(V.getValueType().isScalableVector() &&
3179 "Expected a scalable vector operand!");
3198 return DAG.
getNode(RISCVISD::VMSET_VL,
DL, MaskVT, VL);
3201static std::pair<SDValue, SDValue>
3210static std::pair<SDValue, SDValue>
3223static std::pair<SDValue, SDValue>
3240std::pair<unsigned, unsigned>
3248 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
3252 unsigned VectorBitsMin = Subtarget.getRealMinVLen();
3256 return std::make_pair(MinVLMAX, MaxVLMAX);
3268 EVT VT,
unsigned DefinedValues)
const {
3277 unsigned DLenFactor = Subtarget.getDLenFactor();
3282 std::tie(LMul, Fractional) =
3285 Cost = LMul <= DLenFactor ? (DLenFactor / LMul) : 1;
3287 Cost = (LMul * DLenFactor);
3301 bool Log2CostModel =
3303 if (Log2CostModel && LMULCost.isValid()) {
3304 unsigned Log =
Log2_64(LMULCost.getValue());
3306 return LMULCost * Log;
3308 return LMULCost * LMULCost;
3339 Op.getValueType() == MVT::bf16) {
3340 bool IsStrict =
Op->isStrictFPOpcode();
3345 {Op.getOperand(0), Op.getOperand(1)});
3347 {
Op.getValueType(), MVT::Other},
3353 DAG.
getNode(
Op.getOpcode(),
DL, MVT::f32,
Op.getOperand(0)),
3368 MVT DstVT =
Op.getSimpleValueType();
3377 Src.getValueType() == MVT::bf16) {
3383 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
3384 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
3385 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
3392 Opc,
DL, DstVT, Src,
3395 if (
Opc == RISCVISD::FCVT_WU_RV64)
3406 MVT SrcVT = Src.getSimpleValueType();
3412 if (SatVT != DstEltVT)
3415 MVT DstContainerVT = DstVT;
3416 MVT SrcContainerVT = SrcVT;
3422 "Expected same element count");
3431 {Src, Src, DAG.getCondCode(ISD::SETNE),
3432 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
3436 if (DstEltSize > (2 * SrcEltSize)) {
3439 Src = DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, InterVT, Src, Mask, VL);
3442 MVT CvtContainerVT = DstContainerVT;
3443 MVT CvtEltVT = DstEltVT;
3444 if (SrcEltSize > (2 * DstEltSize)) {
3450 IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
3453 while (CvtContainerVT != DstContainerVT) {
3457 unsigned ClipOpc = IsSigned ? RISCVISD::TRUNCATE_VECTOR_VL_SSAT
3458 : RISCVISD::TRUNCATE_VECTOR_VL_USAT;
3459 Res = DAG.
getNode(ClipOpc,
DL, CvtContainerVT, Res, Mask, VL);
3463 RISCVISD::VMV_V_X_VL,
DL, DstContainerVT, DAG.
getUNDEF(DstContainerVT),
3465 Res = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, DstContainerVT, IsNan, SplatZero,
3466 Res, DAG.
getUNDEF(DstContainerVT), VL);
3476 bool IsStrict =
Op->isStrictFPOpcode();
3477 SDValue SrcVal =
Op.getOperand(IsStrict ? 1 : 0);
3487 {
Op.getOperand(0), SrcVal});
3488 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
3489 {Ext.getValue(1), Ext.getValue(0)});
3503 case ISD::VP_FROUNDEVEN:
3507 case ISD::VP_FROUNDTOZERO:
3511 case ISD::VP_FFLOOR:
3523 case ISD::VP_FROUND:
3533 case ISD::VP_LLRINT:
3547 MVT VT =
Op.getSimpleValueType();
3557 MVT ContainerVT = VT;
3564 if (
Op->isVPOpcode()) {
3565 Mask =
Op.getOperand(1);
3569 VL =
Op.getOperand(2);
3575 SDValue Abs = DAG.
getNode(RISCVISD::FABS_VL,
DL, ContainerVT, Src, Mask, VL);
3588 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3593 DAG.
getNode(RISCVISD::SETCC_VL,
DL, SetccVT,
3602 switch (
Op.getOpcode()) {
3610 case ISD::VP_FFLOOR:
3613 case ISD::VP_FROUND:
3614 case ISD::VP_FROUNDEVEN:
3615 case ISD::VP_FROUNDTOZERO: {
3618 Truncated = DAG.
getNode(RISCVISD::VFCVT_RM_X_F_VL,
DL, IntVT, Src, Mask,
3623 Truncated = DAG.
getNode(RISCVISD::VFCVT_RTZ_X_F_VL,
DL, IntVT, Src,
3627 case ISD::VP_FNEARBYINT:
3628 Truncated = DAG.
getNode(RISCVISD::VFROUND_NOEXCEPT_VL,
DL, ContainerVT, Src,
3634 if (Truncated.
getOpcode() != RISCVISD::VFROUND_NOEXCEPT_VL)
3635 Truncated = DAG.
getNode(RISCVISD::SINT_TO_FP_VL,
DL, ContainerVT, Truncated,
3639 Truncated = DAG.
getNode(RISCVISD::FCOPYSIGN_VL,
DL, ContainerVT, Truncated,
3640 Src, Src, Mask, VL);
3655 MVT VT =
Op.getSimpleValueType();
3659 MVT ContainerVT = VT;
3671 MVT MaskVT = Mask.getSimpleValueType();
3674 {Chain, Src, Src, DAG.getCondCode(ISD::SETUNE),
3675 DAG.getUNDEF(MaskVT), Mask, VL});
3677 Src = DAG.
getNode(RISCVISD::STRICT_FADD_VL,
DL,
3679 {Chain, Src, Src, Src, Unorder, VL});
3683 SDValue Abs = DAG.
getNode(RISCVISD::FABS_VL,
DL, ContainerVT, Src, Mask, VL);
3696 DAG.
getUNDEF(ContainerVT), MaxValNode, VL);
3700 RISCVISD::SETCC_VL,
DL, MaskVT,
3708 switch (
Op.getOpcode()) {
3718 RISCVISD::STRICT_VFCVT_RM_X_F_VL,
DL, DAG.
getVTList(IntVT, MVT::Other),
3719 {Chain, Src, Mask, DAG.getTargetConstant(FRM, DL, XLenVT), VL});
3724 DAG.
getNode(RISCVISD::STRICT_VFCVT_RTZ_X_F_VL,
DL,
3725 DAG.
getVTList(IntVT, MVT::Other), Chain, Src, Mask, VL);
3728 Truncated = DAG.
getNode(RISCVISD::STRICT_VFROUND_NOEXCEPT_VL,
DL,
3729 DAG.
getVTList(ContainerVT, MVT::Other), Chain, Src,
3737 Truncated = DAG.
getNode(RISCVISD::STRICT_SINT_TO_FP_VL,
DL,
3738 DAG.
getVTList(ContainerVT, MVT::Other), Chain,
3739 Truncated, Mask, VL);
3744 Truncated = DAG.
getNode(RISCVISD::FCOPYSIGN_VL,
DL, ContainerVT, Truncated,
3745 Src, Src, Mask, VL);
3755 MVT VT =
Op.getSimpleValueType();
3776 return DAG.
getNode(RISCVISD::FROUND,
DL, VT, Src, MaxValNode,
3784 MVT DstVT =
Op.getSimpleValueType();
3786 MVT SrcVT = Src.getSimpleValueType();
3791 MVT DstContainerVT = DstVT;
3792 MVT SrcContainerVT = SrcVT;
3804 if (SrcElemType == MVT::f16 || SrcElemType == MVT::bf16) {
3806 Src = DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, F32VT, Src, Mask, VL);
3810 DAG.
getNode(RISCVISD::VFCVT_RM_X_F_VL,
DL, DstContainerVT, Src, Mask,
3830 return DAG.
getNode(RISCVISD::VSLIDEDOWN_VL,
DL, VT,
Ops);
3842 return DAG.
getNode(RISCVISD::VSLIDEUP_VL,
DL, VT,
Ops);
3867 return std::nullopt;
3885 unsigned EltSizeInBits) {
3888 return std::nullopt;
3889 bool IsInteger =
Op.getValueType().isInteger();
3891 std::optional<unsigned> SeqStepDenom;
3892 std::optional<APInt> SeqStepNum;
3893 std::optional<APInt> SeqAddend;
3894 std::optional<std::pair<APInt, unsigned>> PrevElt;
3895 assert(EltSizeInBits >=
Op.getValueType().getScalarSizeInBits());
3900 const unsigned OpSize =
Op.getScalarValueSizeInBits();
3901 for (
auto [Idx, Elt] :
enumerate(
Op->op_values())) {
3902 if (Elt.isUndef()) {
3903 Elts[Idx] = std::nullopt;
3907 Elts[Idx] = Elt->getAsAPIntVal().trunc(OpSize).zext(EltSizeInBits);
3912 return std::nullopt;
3913 Elts[Idx] = *ExactInteger;
3917 for (
auto [Idx, Elt] :
enumerate(Elts)) {
3926 unsigned IdxDiff = Idx - PrevElt->second;
3927 APInt ValDiff = *Elt - PrevElt->first;
3935 int64_t Remainder = ValDiff.
srem(IdxDiff);
3940 return std::nullopt;
3941 ValDiff = ValDiff.
sdiv(IdxDiff);
3946 SeqStepNum = ValDiff;
3947 else if (ValDiff != SeqStepNum)
3948 return std::nullopt;
3951 SeqStepDenom = IdxDiff;
3952 else if (IdxDiff != *SeqStepDenom)
3953 return std::nullopt;
3957 if (!PrevElt || PrevElt->first != *Elt)
3958 PrevElt = std::make_pair(*Elt, Idx);
3962 if (!SeqStepNum || !SeqStepDenom)
3963 return std::nullopt;
3967 for (
auto [Idx, Elt] :
enumerate(Elts)) {
3971 (
APInt(EltSizeInBits, Idx,
false,
true) *
3973 .sdiv(*SeqStepDenom);
3975 APInt Addend = *Elt - ExpectedVal;
3978 else if (Addend != SeqAddend)
3979 return std::nullopt;
3982 assert(SeqAddend &&
"Must have an addend if we have a step");
3984 return VIDSequence{SeqStepNum->getSExtValue(), *SeqStepDenom,
3985 SeqAddend->getSExtValue()};
4000 if (EltTy == MVT::i1 ||
4003 MVT SrcVT = Src.getSimpleValueType();
4019 MVT ContainerVT = VT;
4023 MVT SrcContainerVT = SrcVT;
4038 SDValue Gather = DAG.
getNode(RISCVISD::VRGATHER_VX_VL,
DL, ContainerVT, Src,
4039 Idx, DAG.
getUNDEF(ContainerVT), Mask, VL);
4047 MVT VT =
Op.getSimpleValueType();
4056 int64_t StepNumerator = SimpleVID->StepNumerator;
4057 unsigned StepDenominator = SimpleVID->StepDenominator;
4058 int64_t Addend = SimpleVID->Addend;
4060 assert(StepNumerator != 0 &&
"Invalid step");
4061 bool Negate =
false;
4062 int64_t SplatStepVal = StepNumerator;
4066 if (StepNumerator != 1 && StepNumerator !=
INT64_MIN &&
4068 Negate = StepNumerator < 0;
4070 SplatStepVal =
Log2_64(std::abs(StepNumerator));
4080 (SplatStepVal >= 0 || StepDenominator == 1) &&
isInt<32>(Addend)) {
4083 MVT VIDContainerVT =
4091 if ((StepOpcode ==
ISD::MUL && SplatStepVal != 1) ||
4092 (StepOpcode ==
ISD::SHL && SplatStepVal != 0)) {
4094 VID = DAG.
getNode(StepOpcode,
DL, VIDVT, VID, SplatStep);
4096 if (StepDenominator != 1) {
4101 if (Addend != 0 || Negate) {
4127 MVT VT =
Op.getSimpleValueType();
4136 unsigned NumElts =
Op.getNumOperands();
4139 unsigned MostCommonCount = 0;
4141 unsigned NumUndefElts =
4149 unsigned NumScalarLoads = 0;
4155 unsigned &
Count = ValueCounts[V];
4158 NumScalarLoads += !CFP->isExactlyValue(+0.0);
4163 if (++
Count >= MostCommonCount) {
4165 MostCommonCount =
Count;
4169 assert(DominantValue &&
"Not expecting an all-undef BUILD_VECTOR");
4170 unsigned NumDefElts = NumElts - NumUndefElts;
4171 unsigned DominantValueCountThreshold = NumDefElts <= 2 ? 0 : NumDefElts - 2;
4177 ((MostCommonCount > DominantValueCountThreshold) ||
4189 if (
SDValue LastOp =
Op->getOperand(
Op->getNumOperands() - 1);
4190 !LastOp.isUndef() && ValueCounts[LastOp] == 1 &&
4191 LastOp != DominantValue) {
4194 VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL;
4200 Processed.
insert(LastOp);
4206 if (V.isUndef() || !Processed.
insert(V).second)
4208 if (ValueCounts[V] == 1) {
4216 return DAG.getConstant(V == V1, DL, XLenVT);
4232 MVT VT =
Op.getSimpleValueType();
4241 unsigned NumElts =
Op.getNumOperands();
4262 unsigned NumViaIntegerBits = std::clamp(NumElts, 8u, Subtarget.
getXLen());
4263 NumViaIntegerBits = std::min(NumViaIntegerBits, Subtarget.
getELen());
4271 unsigned IntegerViaVecElts =
divideCeil(NumElts, NumViaIntegerBits);
4272 MVT IntegerViaVecVT =
4277 unsigned BitPos = 0, IntegerEltIdx = 0;
4280 for (
unsigned I = 0;
I < NumElts;) {
4282 bool BitValue = !V.isUndef() && V->getAsZExtVal();
4283 Bits |= ((
uint64_t)BitValue << BitPos);
4289 if (
I % NumViaIntegerBits == 0 ||
I == NumElts) {
4290 if (NumViaIntegerBits <= 32)
4293 Elts[IntegerEltIdx] = Elt;
4302 if (NumElts < NumViaIntegerBits) {
4306 assert(IntegerViaVecVT == MVT::v1i8 &&
"Unexpected mask vector type");
4321 : RISCVISD::VMV_V_X_VL;
4341 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32) &&
4342 "Unexpected sequence type");
4346 unsigned ViaVecLen =
4354 const auto &SeqV =
OpIdx.value();
4355 if (!SeqV.isUndef())
4357 ((SeqV->getAsZExtVal() & EltMask) << (
OpIdx.index() * EltBitSize));
4363 if (ViaIntVT == MVT::i32)
4386 BV->getRepeatedSequence(Sequence) &&
4387 (Sequence.size() * EltBitSize) <= Subtarget.
getELen()) {
4388 unsigned SeqLen = Sequence.size();
4390 assert((ViaIntVT == MVT::i16 || ViaIntVT == MVT::i32 ||
4391 ViaIntVT == MVT::i64) &&
4392 "Unexpected sequence type");
4397 const unsigned RequiredVL = NumElts / SeqLen;
4398 const unsigned ViaVecLen =
4400 NumElts : RequiredVL;
4403 unsigned EltIdx = 0;
4408 for (
const auto &SeqV : Sequence) {
4409 if (!SeqV.isUndef())
4411 ((SeqV->getAsZExtVal() & EltMask) << (EltIdx * EltBitSize));
4418 if (ViaIntVT == MVT::i32)
4425 (!Subtarget.
is64Bit() && ViaIntVT == MVT::i64)) &&
4426 "Unexpected bitcast sequence");
4430 MVT ViaContainerVT =
4433 DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ViaContainerVT,
4437 if (ViaVecLen != RequiredVL)
4456 Source, DAG, Subtarget);
4457 SDValue Res = DAG.
getNode(RISCVISD::VSEXT_VL,
DL, ContainerVT, Source, Mask, VL);
4476 return RISCV::PACKH;
4478 return Subtarget.
is64Bit() ? RISCV::PACKW : RISCV::PACK;
4493 MVT VT =
Op.getSimpleValueType();
4501 if (!Subtarget.hasStdExtZbb() || !Subtarget.hasStdExtZba())
4506 if (ElemSizeInBits >= std::min(Subtarget.
getELen(), Subtarget.
getXLen()) ||
4520 if (Subtarget.hasStdExtZbkb())
4525 ElemDL, XLenVT,
A,
B),
4537 NewOperands.
reserve(NumElts / 2);
4539 NewOperands.
push_back(pack(
Op.getOperand(i),
Op.getOperand(i + 1)));
4549 MVT VT =
Op.getSimpleValueType();
4558 if (VT != MVT::v4i8)
4571 DAG.
getNode(RISCVISD::PPACK_DH,
DL, {MVT::v2i16, MVT::v2i16},
4572 {Val0, Val1, Val2, Val3});
4578 RISCV::PACK,
DL, MVT::i32,
4579 {DAG.getNode(ISD::BITCAST, DL, MVT::i32, PackDH.getValue(0)),
4580 DAG.getNode(ISD::BITCAST, DL, MVT::i32, PackDH.getValue(1))}),
4587 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) ||
4593 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4594 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin())) {
4604 NewOps[
I] = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Elem);
4654 [](
const SDUse &U) { return U.get().isUndef(); })) {
4695 auto OneVRegOfOps =
ArrayRef(BuildVectorOps).slice(i, ElemsPerVReg);
4699 unsigned InsertIdx = (i / ElemsPerVReg) * NumOpElts;
4721 unsigned NumUndefElts =
4723 unsigned NumDefElts = NumElts - NumUndefElts;
4724 if (NumDefElts >= 8 && NumDefElts > NumElts / 2 &&
4731 for (
const auto &[Idx, U] :
enumerate(
Op->ops())) {
4733 if (Idx < NumElts / 2) {
4740 bool SelectMaskVal = (Idx < NumElts / 2);
4743 assert(SubVecAOps.
size() == NumElts && SubVecBOps.
size() == NumElts &&
4744 MaskVals.
size() == NumElts);
4779 unsigned UndefCount = 0;
4786 LinearBudget -= PerSlideCost;
4789 LinearBudget -= PerSlideCost;
4792 LinearBudget -= PerSlideCost;
4795 if (LinearBudget < 0)
4800 "Illegal type which will result in reserved encoding");
4816 bool SlideUp =
false;
4841 if (EVecEltVT != ContainerEltVT)
4862 std::reverse(Operands.
begin(), Operands.
end());
4890 Vec = getVSlide(ContainerVT, DAG.
getUNDEF(ContainerVT), Vec,
Offset, Mask,
4897 Opcode = SlideUp ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VFSLIDE1DOWN_VL;
4899 Opcode = SlideUp ? RISCVISD::VSLIDE1UP_VL : RISCVISD::VSLIDE1DOWN_VL;
4908 Vec = getVSlide(ContainerVT, DAG.
getUNDEF(ContainerVT), Vec,
Offset, Mask,
4924 if ((LoC >> 31) == HiC)
4925 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
4937 auto InterVec = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, InterVT,
4946 Hi.getConstantOperandVal(1) == 31)
4947 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
4952 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru,
Lo, VL);
4955 return DAG.
getNode(RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL,
DL, VT, Passthru,
Lo,
4965 assert(Scalar.getValueType() == MVT::i64 &&
"Unexpected VT!");
4977 bool HasPassthru = Passthru && !Passthru.
isUndef();
4978 if (!HasPassthru && !Passthru)
4985 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) ||
4987 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
4988 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
4989 Scalar = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Scalar);
4998 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL, VT, Passthru, Scalar, VL);
5002 if (Scalar.getValueType().bitsLE(XLenVT)) {
5009 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
5010 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, VT, Passthru, Scalar, VL);
5013 assert(XLenVT == MVT::i32 && Scalar.getValueType() == MVT::i64 &&
5014 "Unexpected scalar for splat lowering!");
5017 return DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL, VT, Passthru,
5043 MVT ExtractedContainerVT = ExtractedVT;
5046 DAG, ExtractedContainerVT, Subtarget);
5048 ExtractedVal, DAG, Subtarget);
5050 if (ExtractedContainerVT.
bitsLE(VT))
5062 if (!Scalar.getValueType().bitsLE(XLenVT))
5065 VT,
DL, DAG, Subtarget);
5073 Scalar = DAG.
getNode(ExtOpc,
DL, XLenVT, Scalar);
5114 Src && Src.
getValueType().getVectorNumElements() == (NumElts * 2))
5131 !Subtarget.hasVendorXRivosVizip())
5134 int Size = Mask.size();
5136 assert(
Size == (
int)NumElts &&
"Unexpected mask size");
5142 EvenSrc = StartIndexes[0];
5143 OddSrc = StartIndexes[1];
5146 if (EvenSrc != 0 && OddSrc != 0)
5156 int HalfNumElts = NumElts / 2;
5157 return ((EvenSrc % HalfNumElts) == 0) && ((OddSrc % HalfNumElts) == 0);
5162 std::array<std::pair<int, int>, 2> &SrcInfo) {
5167 if (SrcInfo[0].second == 0 && SrcInfo[1].second == 0)
5171 if ((SrcInfo[0].second > 0 && SrcInfo[1].second < 0) ||
5172 SrcInfo[1].second == 0)
5174 assert(SrcInfo[0].first != -1 &&
"Must find one slide");
5182 if (SrcInfo[1].first == -1)
5184 return SrcInfo[0].second < 0 && SrcInfo[1].second > 0 &&
5185 SrcInfo[1].second - SrcInfo[0].second == (int)NumElts;
5190 bool RequiredPolarity) {
5191 int NumElts = Mask.size();
5192 for (
const auto &[Idx, M] :
enumerate(Mask)) {
5195 int Src = M >= NumElts;
5196 int Diff = (int)Idx - (M % NumElts);
5197 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
5198 assert(
C != (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
5199 "Must match exactly one of the two slides");
5200 if (RequiredPolarity != (
C == (Idx / Factor) % 2))
5211static bool isZipEven(
const std::array<std::pair<int, int>, 2> &SrcInfo,
5213 Factor = SrcInfo[1].second;
5215 Mask.size() % Factor == 0 &&
5226static bool isZipOdd(
const std::array<std::pair<int, int>, 2> &SrcInfo,
5228 Factor = -SrcInfo[1].second;
5230 Mask.size() % Factor == 0 &&
5243 ElementCount SrcEC = Src.getValueType().getVectorElementCount();
5250 unsigned Shift = Index * EltBits;
5275 std::optional<int> SplatIdx;
5277 if (M == -1 ||
I == (
unsigned)M)
5279 if (SplatIdx && *SplatIdx != M)
5288 for (
int MaskIndex : Mask) {
5289 bool SelectMaskVal = MaskIndex == *SplatIdx;
5292 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
5317 auto findNonEXTRACT_SUBVECTORParent =
5318 [](
SDValue Parent) -> std::pair<SDValue, uint64_t> {
5323 Parent.getOperand(0).getSimpleValueType().isFixedLengthVector()) {
5324 Offset += Parent.getConstantOperandVal(1);
5325 Parent = Parent.getOperand(0);
5327 return std::make_pair(Parent,
Offset);
5330 auto [V1Src, V1IndexOffset] = findNonEXTRACT_SUBVECTORParent(V1);
5331 auto [V2Src, V2IndexOffset] = findNonEXTRACT_SUBVECTORParent(V2);
5340 for (
size_t i = 0; i != NewMask.
size(); ++i) {
5341 if (NewMask[i] == -1)
5344 if (
static_cast<size_t>(NewMask[i]) < NewMask.
size()) {
5345 NewMask[i] = NewMask[i] + V1IndexOffset;
5349 NewMask[i] = NewMask[i] - NewMask.
size() + V2IndexOffset;
5355 if (NewMask[0] <= 0)
5359 for (
unsigned i = 1; i != NewMask.
size(); ++i)
5360 if (NewMask[i - 1] + 1 != NewMask[i])
5364 MVT SrcVT = Src.getSimpleValueType();
5393 int NumSubElts, Index;
5398 bool OpsSwapped = Mask[Index] < (int)NumElts;
5399 SDValue InPlace = OpsSwapped ? V2 : V1;
5400 SDValue ToInsert = OpsSwapped ? V1 : V2;
5411 if (NumSubElts + Index >= (
int)NumElts)
5422 Res = DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, ContainerVT, InPlace, ToInsert,
5425 Res =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, InPlace, ToInsert,
5437 bool OpsSwapped =
false;
5452 const unsigned E = Mask.size() - ((
Offset > 0) ?
Offset : 0);
5453 for (
unsigned i = S; i !=
E; ++i)
5454 if (Mask[i] >= 0 && (
unsigned)Mask[i] !=
Base + i +
Offset)
5460 bool IsVSlidedown = isSlideMask(Mask, OpsSwapped ? 0 : NumElts, 1);
5461 if (!IsVSlidedown && !isSlideMask(Mask, OpsSwapped ? 0 : NumElts, -1))
5464 const int InsertIdx = Mask[IsVSlidedown ? (NumElts - 1) : 0];
5466 if (InsertIdx < 0 || InsertIdx / NumElts != (
unsigned)OpsSwapped)
5483 IsVSlidedown ? RISCVISD::VSLIDE1DOWN_VL : RISCVISD::VSLIDE1UP_VL,
DL,
5489 auto OpCode = IsVSlidedown ?
5490 (VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1DOWN_VL : RISCVISD::VSLIDE1DOWN_VL) :
5491 (VT.
isFloatingPoint() ? RISCVISD::VFSLIDE1UP_VL : RISCVISD::VSLIDE1UP_VL);
5494 auto Vec = DAG.
getNode(OpCode,
DL, ContainerVT,
5497 Splat, TrueMask, VL);
5509 for (
unsigned i = 0; i < Mask.size(); i++)
5510 LaneIsUndef[i % Factor] &= (Mask[i] == -1);
5513 for (
unsigned i = 0; i < Factor; i++) {
5524 for (
unsigned i = 0; i < Mask.size() / Factor; i++) {
5525 unsigned j = i * Factor + Index;
5526 if (Mask[j] != -1 && (
unsigned)Mask[j] != i)
5535 assert(RISCVISD::RI_VZIPEVEN_VL ==
Opc || RISCVISD::RI_VZIPODD_VL ==
Opc ||
5536 RISCVISD::RI_VZIP2A_VL ==
Opc || RISCVISD::RI_VZIP2B_VL ==
Opc ||
5537 RISCVISD::RI_VUNZIP2A_VL ==
Opc || RISCVISD::RI_VUNZIP2B_VL ==
Opc);
5545 MVT ContainerVT = IntVT;
5552 MVT InnerVT = ContainerVT;
5556 (RISCVISD::RI_VUNZIP2A_VL ==
Opc || RISCVISD::RI_VUNZIP2B_VL ==
Opc)) {
5568 if (InnerVT.
bitsLT(ContainerVT))
5583 MVT VT = V.getSimpleValueType();
5598 EC.multiplyCoefficientBy(Factor));
5617 MVT VecContainerVT = VecVT;
5634 MVT WideContainerVT = WideVT;
5640 EvenV = DAG.
getBitcast(VecContainerVT, EvenV);
5647 if (Subtarget.hasStdExtZvbb()) {
5651 Interleaved = DAG.
getNode(RISCVISD::VWSLL_VL,
DL, WideContainerVT, OddV,
5652 OffsetVec, Passthru, Mask, VL);
5653 Interleaved = DAG.
getNode(RISCVISD::VWADDU_W_VL,
DL, WideContainerVT,
5654 Interleaved, EvenV, Passthru, Mask, VL);
5661 Interleaved = DAG.
getNode(RISCVISD::VWADDU_VL,
DL, WideContainerVT, EvenV,
5662 OddV, Passthru, Mask, VL);
5668 OddV, AllOnesVec, Passthru, Mask, VL);
5675 Interleaved = DAG.
getNode(RISCVISD::ADD_VL,
DL, WideContainerVT,
5676 Interleaved, OddsMul, Passthru, Mask, VL);
5683 Interleaved = DAG.
getBitcast(ResultContainerVT, Interleaved);
5729 if (ViaEltSize > NumElts)
5737 if (ViaEltSize > NumElts)
5743 if (ViaEltSize > NumElts)
5750 MVT &RotateVT,
unsigned &RotateAmt) {
5753 unsigned NumSubElts;
5755 NumElts, NumSubElts, RotateAmt))
5758 NumElts / NumSubElts);
5826 unsigned NumOfSrcRegs = NumElts / NumOpElts;
5827 unsigned NumOfDestRegs = NumElts / NumOpElts;
5836 Mask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs,
5838 [&](
ArrayRef<int> SrcSubMask,
unsigned SrcVecIdx,
unsigned DstVecIdx) {
5839 Operands.
emplace_back().emplace_back(SrcVecIdx, UINT_MAX,
5842 [&](
ArrayRef<int> SrcSubMask,
unsigned Idx1,
unsigned Idx2,
bool NewReg) {
5847 assert(Operands.
size() == NumOfDestRegs &&
"Whole vector must be processed");
5852 unsigned NumShuffles = std::accumulate(
5853 Operands.
begin(), Operands.
end(), 0u,
5859 for (const auto &P : Data) {
5860 unsigned Idx2 = std::get<1>(P);
5861 ArrayRef<int> Mask = std::get<2>(P);
5862 if (Idx2 != UINT_MAX)
5864 else if (ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
5869 if ((NumOfDestRegs > 2 && NumShuffles > NumOfDestRegs) ||
5870 (NumOfDestRegs <= 2 && NumShuffles >= 4))
5872 auto ExtractValue = [&, &DAG = DAG](
SDValue SrcVec,
unsigned ExtractIdx) {
5873 SDValue SubVec = DAG.getExtractSubvector(
DL, M1VT, SrcVec, ExtractIdx);
5877 auto PerformShuffle = [&, &DAG = DAG](
SDValue SubVec1,
SDValue SubVec2,
5879 SDValue SubVec = DAG.getVectorShuffle(OneRegVT,
DL, SubVec1, SubVec2, Mask);
5882 SDValue Vec = DAG.getUNDEF(ContainerVT);
5888 const auto &[Idx1, Idx2,
_] =
Data[
I];
5896 V = ExtractValue(Idx1 >= NumOfSrcRegs ? V2 : V1,
5897 (Idx1 % NumOfSrcRegs) * NumOpElts);
5898 if (Idx2 != UINT_MAX) {
5901 V = ExtractValue(Idx2 >= NumOfSrcRegs ? V2 : V1,
5902 (Idx2 % NumOfSrcRegs) * NumOpElts);
5906 for (
const auto &[Idx1, Idx2, Mask] :
Data) {
5908 SDValue V2 = Idx2 == UINT_MAX ? V1 : Values.
at(Idx2);
5909 V = PerformShuffle(V1, V2, Mask);
5913 unsigned InsertIdx =
I * NumOpElts;
5915 Vec = DAG.getInsertSubvector(
DL, Vec, V, InsertIdx);
5925 bool SawUndef =
false;
5926 for (
const auto &[Idx, M] :
enumerate(Mask)) {
5933 if (Idx > (
unsigned)M)
5966 for (
int Idx : Mask) {
5969 unsigned SrcIdx = Idx % Mask.size();
5970 int Src = (
uint32_t)Idx < Mask.size() ? 0 : 1;
5971 if (Srcs[SrcIdx] == -1)
5974 else if (Srcs[SrcIdx] != Src)
5980 for (
int Lane : Srcs) {
5993 for (
unsigned I = 0;
I < Mask.size();
I++) {
5997 NewMask[
I] = Mask[
I] % Mask.size();
6011 if ((M / Span) != (
int)(
I / Span))
6013 int SpanIdx =
I % Span;
6023 return all_of(Mask, [&](
const auto &Idx) {
return Idx == -1 || Idx < Span; });
6035 int SpanIdx =
I % Span;
6036 if (Mask[SpanIdx] != M)
6050 MVT VT =
Op.getSimpleValueType();
6058 if (ElementSize > 32)
6081 MVT VT =
Op.getSimpleValueType();
6109 auto [TrueMask, VL] = TrueMaskVL;
6124 V.getOperand(0).getSimpleValueType().getVectorNumElements();
6125 V = V.getOperand(
Offset / OpElements);
6155 MVT SplatVT = ContainerVT;
6158 if (SVT == MVT::bf16 ||
6159 (SVT == MVT::f16 && !Subtarget.hasStdExtZfh())) {
6168 V = DAG.
getLoad(SVT,
DL, Ld->getChain(), NewAddr,
6169 Ld->getPointerInfo().getWithOffset(
Offset),
6170 Ld->getBaseAlign(), Ld->getMemOperand()->
getFlags());
6173 Ld->getPointerInfo().getWithOffset(
Offset), SVT,
6175 Ld->getMemOperand()->getFlags());
6179 : RISCVISD::VMV_V_X_VL;
6187 assert(Lane < (
int)NumElts &&
"Unexpected lane!");
6190 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6212 if (Subtarget.hasStdExtZvkb())
6228 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
6229 for (
unsigned Factor = 2; Factor <= MaxFactor; Factor <<= 1) {
6232 1 <
count_if(Mask, [](
int Idx) {
return Idx != -1; })) {
6236 [&Mask](
int Idx) {
return Idx < (int)Mask.size(); }) &&
6237 1 <
count_if(Mask, [&Mask](
int Idx) {
6238 return Idx >= (int)Mask.size();
6268 if (Subtarget.hasVendorXRivosVizip() &&
6270 1 <
count_if(Mask, [](
int Idx) {
return Idx != -1; })) {
6272 Index == 0 ? RISCVISD::RI_VUNZIP2A_VL : RISCVISD::RI_VUNZIP2B_VL;
6288 [&Mask](
int Idx) {
return Idx < (int)Mask.size(); }) &&
6290 [&Mask](
int Idx) {
return Idx >= (int)Mask.size(); })) {
6294 if (NumElts < MinVLMAX) {
6318 int EvenSrc, OddSrc;
6328 bool LaneIsUndef[2] = {
true,
true};
6329 for (
const auto &[Idx, M] :
enumerate(Mask))
6330 LaneIsUndef[Idx % 2] &= (M == -1);
6332 int Size = Mask.size();
6334 if (LaneIsUndef[0]) {
6337 assert(EvenSrc >= 0 &&
"Undef source?");
6338 EvenV = (EvenSrc /
Size) == 0 ? V1 : V2;
6342 if (LaneIsUndef[1]) {
6345 assert(OddSrc >= 0 &&
"Undef source?");
6346 OddV = (OddSrc /
Size) == 0 ? V1 : V2;
6352 if (Subtarget.hasVendorXRivosVizip()) {
6355 return lowerVZIP(RISCVISD::RI_VZIP2A_VL, EvenV, OddV,
DL, DAG, Subtarget);
6366 std::array<std::pair<int, int>, 2> SrcInfo;
6373 auto GetSourceFor = [&](
const std::pair<int, int> &
Info) {
6374 int SrcIdx =
Info.first;
6375 assert(SrcIdx == 0 || SrcIdx == 1);
6376 SDValue &Src = Sources[SrcIdx];
6378 SDValue SrcV = SrcIdx == 0 ? V1 : V2;
6383 auto GetSlide = [&](
const std::pair<int, int> &Src,
SDValue Mask,
6385 auto [TrueMask, VL] = TrueMaskVL;
6386 SDValue SrcV = GetSourceFor(Src);
6387 int SlideAmt = Src.second;
6388 if (SlideAmt == 0) {
6390 assert(Mask == TrueMask);
6397 return getVSlideup(DAG, Subtarget,
DL, ContainerVT, Passthru, SrcV,
6402 if (SrcInfo[1].first == -1) {
6404 Res = GetSlide(SrcInfo[0], TrueMask, Res);
6408 if (Subtarget.hasVendorXRivosVizip()) {
6409 bool TryWiden =
false;
6413 SDValue Src1 = SrcInfo[0].first == 0 ? V1 : V2;
6414 SDValue Src2 = SrcInfo[1].first == 0 ? V1 : V2;
6415 return lowerVZIP(RISCVISD::RI_VZIPEVEN_VL, Src1, Src2,
DL, DAG,
6420 if (
isZipOdd(SrcInfo, Mask, Factor)) {
6422 SDValue Src1 = SrcInfo[1].first == 0 ? V1 : V2;
6423 SDValue Src2 = SrcInfo[0].first == 0 ? V1 : V2;
6424 return lowerVZIP(RISCVISD::RI_VZIPODD_VL, Src1, Src2,
DL, DAG,
6442 for (
const auto &[Idx, M] :
enumerate(Mask)) {
6444 (SrcInfo[1].second > 0 && Idx < (
unsigned)SrcInfo[1].second)) {
6448 int Src = M >= (int)NumElts;
6449 int Diff = (int)Idx - (M % NumElts);
6450 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
6451 assert(
C ^ (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
6452 "Must match exactly one of the two slides");
6455 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
6462 Res = GetSlide(SrcInfo[0], TrueMask, Res);
6463 Res = GetSlide(SrcInfo[1], SelectMask, Res);
6468 assert(!V1.
isUndef() &&
"Unexpected shuffle canonicalization");
6483 assert(MaxFactor == 2 || MaxFactor == 4 || MaxFactor == 8);
6484 for (
unsigned Factor = 4; Factor <= MaxFactor; Factor <<= 1) {
6499 if (NumElts > MinVLMAX) {
6500 unsigned MaxIdx = 0;
6504 MaxIdx = std::max(std::max((
unsigned)
I, (
unsigned)M), MaxIdx);
6506 unsigned NewNumElts =
6508 if (NewNumElts != NumElts) {
6512 Mask.take_front(NewNumElts));
6529 for (
auto Idx : Mask) {
6532 assert(Idx >= 0 && (
unsigned)Idx < NumElts);
6542 any_of(Mask, [&](
const auto &Idx) {
return Idx > 255; })) {
6552 unsigned GatherVVOpc = RISCVISD::VRGATHER_VV_VL;
6558 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
6567 GatherVVOpc = RISCVISD::VRGATHEREI16_VV_VL;
6571 MVT IndexContainerVT =
6576 for (
int MaskIndex : Mask) {
6577 bool IsLHSIndex = MaskIndex < (int)NumElts && MaskIndex >= 0;
6587 if (NumElts <= MinVLMAX) {
6589 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6595 auto [InnerTrueMask, InnerVL] =
6607 for (
int i = 0; i <
N; i++) {
6611 DAG.
getNode(GatherVVOpc,
DL, M1VT, SubV1, SubIndex,
6612 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
6629 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
6631 for (
int i = 0; i <
N; i++)
6647 for (
int i = 0; i <
N; i++) {
6650 DAG.
getUNDEF(IndexContainerVT), LHSIndices,
6651 SlideAmt, TrueMask, VL);
6655 DAG.
getNode(GatherVVOpc,
DL, M1VT, SubV1, SubIndex,
6656 DAG.
getUNDEF(M1VT), InnerTrueMask, InnerVL);
6666 DAG.
getUNDEF(ContainerVT), TrueMask, VL);
6676 for (
int MaskIndex : Mask) {
6677 bool IsLHSOrUndefIndex = MaskIndex < (int)NumElts;
6678 ShuffleMaskLHS.
push_back(IsLHSOrUndefIndex && MaskIndex >= 0
6680 ShuffleMaskRHS.
push_back(IsLHSOrUndefIndex ? -1 : (MaskIndex - NumElts));
6711 for (
int MaskIndex : Mask) {
6712 bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ !SwapOps;
6716 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
6734 const unsigned NumElts = M.size();
6741 std::array<std::pair<int, int>, 2> SrcInfo;
6752RISCVTargetLowering::lowerCTLZ_CTTZ_ZERO_UNDEF(
SDValue Op,
6754 MVT VT =
Op.getSimpleValueType();
6758 MVT ContainerVT = VT;
6761 if (
Op->isVPOpcode()) {
6762 Mask =
Op.getOperand(1);
6766 VL =
Op.getOperand(2);
6772 MVT FloatEltVT = (EltSize >= 32) ? MVT::f64 :
MVT::f32;
6774 FloatEltVT = MVT::f32;
6781 "Expected legal float type!");
6788 }
else if (
Op.getOpcode() == ISD::VP_CTTZ_ZERO_UNDEF) {
6791 Src = DAG.
getNode(ISD::VP_AND,
DL, VT, Src, Neg, Mask, VL);
6796 if (FloatVT.
bitsGT(VT)) {
6797 if (
Op->isVPOpcode())
6798 FloatVal = DAG.
getNode(ISD::VP_UINT_TO_FP,
DL, FloatVT, Src, Mask, VL);
6807 if (!
Op->isVPOpcode())
6811 MVT ContainerFloatVT =
6813 FloatVal = DAG.
getNode(RISCVISD::VFCVT_RM_F_XU_VL,
DL, ContainerFloatVT,
6814 Src, Mask, RTZRM, VL);
6821 unsigned ShiftAmt = FloatEltVT == MVT::f64 ? 52 : 23;
6825 if (
Op->isVPOpcode()) {
6834 else if (IntVT.
bitsGT(VT))
6839 unsigned ExponentBias = FloatEltVT == MVT::f64 ? 1023 : 127;
6844 if (
Op.getOpcode() == ISD::VP_CTTZ_ZERO_UNDEF)
6845 return DAG.
getNode(ISD::VP_SUB,
DL, VT, Exp,
6850 unsigned Adjust = ExponentBias + (EltSize - 1);
6852 if (
Op->isVPOpcode())
6862 else if (
Op.getOpcode() == ISD::VP_CTLZ)
6863 Res = DAG.
getNode(ISD::VP_UMIN,
DL, VT, Res,
6871 MVT XLenVT = Subtarget.getXLenVT();
6873 MVT SrcVT =
Source.getSimpleValueType();
6882 SrcVT = ContainerVT;
6894 SDValue Res = DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Source, Mask, EVL);
6895 if (
Op->getOpcode() == ISD::VP_CTTZ_ELTS_ZERO_UNDEF)
6913 assert(Load &&
Load->getMemoryVT().isVector() &&
"Expected vector load");
6916 Load->getMemoryVT(),
6917 *
Load->getMemOperand()))
6921 MVT VT =
Op.getSimpleValueType();
6923 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
6924 "Unexpected unaligned RVV load type");
6928 "Expecting equally-sized RVV vector types to be legal");
6930 Load->getPointerInfo(),
Load->getBaseAlign(),
6931 Load->getMemOperand()->getFlags());
6942 assert(Store &&
Store->getValue().getValueType().isVector() &&
6943 "Expected vector store");
6946 Store->getMemoryVT(),
6947 *
Store->getMemOperand()))
6954 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
6955 "Unexpected unaligned RVV store type");
6959 "Expecting equally-sized RVV vector types to be legal");
6960 StoredVal = DAG.
getBitcast(NewVT, StoredVal);
6962 Store->getPointerInfo(),
Store->getBaseAlign(),
6963 Store->getMemOperand()->getFlags());
6973 assert(Load &&
Load->getMemoryVT().isVector() &&
"Expected vector load");
6976 Load->getMemoryVT(),
6977 *
Load->getMemOperand()))
6987 MVT VT =
Op.getSimpleValueType();
6989 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
6990 "Unexpected unaligned RVV load type");
6994 "Expecting equally-sized RVV vector types to be legal");
7003 Load->getPointerInfo(),
Load->getBaseAlign(),
7004 Load->getMemOperand()->getFlags(), AAMDNodes());
7015 assert(Store &&
Store->getValue().getValueType().isVector() &&
7016 "Expected vector store");
7019 Store->getMemoryVT(),
7020 *
Store->getMemOperand()))
7033 assert((EltSizeBits == 16 || EltSizeBits == 32 || EltSizeBits == 64) &&
7034 "Unexpected unaligned RVV store type");
7038 "Expecting equally-sized RVV vector types to be legal");
7044 StoredVal = DAG.
getBitcast(NewVT, StoredVal);
7049 Store->getPointerInfo(),
Store->getMemOperand()->getFlags(),
Size,
7050 Store->getBaseAlign());
7061 assert(
Op.getValueType() == MVT::i64 &&
"Unexpected VT");
7090 unsigned ShiftAmt, AddOpc;
7101 MVT VT =
Op.getSimpleValueType();
7105 bool Negate =
false;
7109 if (Index < 0 &&
Imm.isNegative()) {
7132 unsigned IsData =
Op.getConstantOperandVal(4);
7135 if (Subtarget.hasVendorXMIPSCBOP() && !IsData)
7136 return Op.getOperand(0);
7148 if (Subtarget.hasStdExtZtso()) {
7172 MVT VT =
Op.getSimpleValueType();
7173 MVT XLenVT = Subtarget.getXLenVT();
7174 unsigned Check =
Op.getConstantOperandVal(1);
7175 unsigned TDCMask = 0;
7203 MVT VT0 =
Op.getOperand(0).getSimpleValueType();
7208 if (
Op.getOpcode() == ISD::VP_IS_FPCLASS) {
7210 VL =
Op.getOperand(3);
7213 VL,
Op->getFlags());
7228 if (
Op.getOpcode() == ISD::VP_IS_FPCLASS) {
7230 MVT MaskContainerVT =
7233 VL =
Op.getOperand(3);
7237 SDValue FPCLASS = DAG.
getNode(RISCVISD::FCLASS_VL,
DL, ContainerDstVT, Op0,
7238 Mask, VL,
Op->getFlags());
7240 TDCMaskV = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerDstVT,
7241 DAG.
getUNDEF(ContainerDstVT), TDCMaskV, VL);
7244 DAG.
getNode(RISCVISD::SETCC_VL,
DL, ContainerVT,
7250 TDCMaskV, DAG.
getUNDEF(ContainerDstVT), Mask, VL);
7253 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerDstVT,
7254 DAG.
getUNDEF(ContainerDstVT), SplatZero, VL);
7274 MVT VT =
Op.getSimpleValueType();
7308 MVT ContainerVT = VT;
7316 if (
Op->isVPOpcode()) {
7317 Mask =
Op.getOperand(2);
7321 VL =
Op.getOperand(3);
7328 SDValue XIsNonNan = DAG.
getNode(RISCVISD::SETCC_VL,
DL, Mask.getValueType(),
7329 {X, X, DAG.getCondCode(ISD::SETOEQ),
7330 DAG.getUNDEF(ContainerVT), Mask, VL});
7331 NewY = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, XIsNonNan,
Y,
X,
7337 SDValue YIsNonNan = DAG.
getNode(RISCVISD::SETCC_VL,
DL, Mask.getValueType(),
7338 {Y, Y, DAG.getCondCode(ISD::SETOEQ),
7339 DAG.getUNDEF(ContainerVT), Mask, VL});
7340 NewX = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, YIsNonNan,
X,
Y,
7346 ? RISCVISD::VFMAX_VL
7347 : RISCVISD::VFMIN_VL;
7349 DAG.
getUNDEF(ContainerVT), Mask, VL);
7359 "Wrong opcode for lowering FABS or FNEG.");
7362 MVT VT =
Op.getSimpleValueType();
7363 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
7367 DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT,
Op.getOperand(0));
7370 Mask = Mask.sext(Subtarget.
getXLen());
7375 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, Logic);
7383 MVT VT =
Op.getSimpleValueType();
7384 assert((VT == MVT::f16 || VT == MVT::bf16) &&
"Unexpected type");
7394 if (SignSize == Subtarget.
getXLen())
7398 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Sign);
7400 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, XLenVT, Sign);
7402 assert(XLenVT == MVT::i32 &&
"Unexpected type");
7405 return DAG.
getNode(RISCVISD::SplitF64,
DL, {MVT::i32, MVT::i32}, Sign)
7435 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, CopiedSign);
7440#define OP_CASE(NODE) \
7442 return RISCVISD::NODE##_VL;
7443#define VP_CASE(NODE) \
7444 case ISD::VP_##NODE: \
7445 return RISCVISD::NODE##_VL;
7447 switch (
Op.getOpcode()) {
7526 case ISD::VP_CTLZ_ZERO_UNDEF:
7527 return RISCVISD::CTLZ_VL;
7529 case ISD::VP_CTTZ_ZERO_UNDEF:
7530 return RISCVISD::CTTZ_VL;
7533 return RISCVISD::VFMADD_VL;
7535 return RISCVISD::STRICT_VFMADD_VL;
7538 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7539 return RISCVISD::VMAND_VL;
7540 return RISCVISD::AND_VL;
7543 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7544 return RISCVISD::VMOR_VL;
7545 return RISCVISD::OR_VL;
7548 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
7549 return RISCVISD::VMXOR_VL;
7550 return RISCVISD::XOR_VL;
7553 return RISCVISD::VZEXT_VL;
7555 return RISCVISD::VSEXT_VL;
7557 return RISCVISD::SETCC_VL;
7559 return RISCVISD::VMERGE_VL;
7560 case ISD::VP_SELECT:
7562 return RISCVISD::VMERGE_VL;
7564 return RISCVISD::SRA_VL;
7566 return RISCVISD::SRL_VL;
7568 return RISCVISD::FSQRT_VL;
7569 case ISD::VP_SIGN_EXTEND:
7570 return RISCVISD::VSEXT_VL;
7571 case ISD::VP_ZERO_EXTEND:
7572 return RISCVISD::VZEXT_VL;
7573 case ISD::VP_FP_TO_SINT:
7574 return RISCVISD::VFCVT_RTZ_X_F_VL;
7575 case ISD::VP_FP_TO_UINT:
7576 return RISCVISD::VFCVT_RTZ_XU_F_VL;
7579 case ISD::VP_FMINNUM:
7580 return RISCVISD::VFMIN_VL;
7583 case ISD::VP_FMAXNUM:
7584 return RISCVISD::VFMAX_VL;
7588 case ISD::VP_LLRINT:
7589 return RISCVISD::VFCVT_RM_X_F_VL;
7598 return (
Op.getValueType() == MVT::nxv32f16 &&
7601 (
Op.getValueType() == MVT::nxv32bf16 &&
7615 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
7616 if (!
Op.getOperand(j).getValueType().isVector()) {
7617 LoOperands[j] =
Op.getOperand(j);
7618 HiOperands[j] =
Op.getOperand(j);
7621 std::tie(LoOperands[j], HiOperands[j]) =
7626 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
7628 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
7641 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
7643 std::tie(LoOperands[j], HiOperands[j]) =
7647 if (!
Op.getOperand(j).getValueType().isVector()) {
7648 LoOperands[j] =
Op.getOperand(j);
7649 HiOperands[j] =
Op.getOperand(j);
7652 std::tie(LoOperands[j], HiOperands[j]) =
7657 DAG.
getNode(
Op.getOpcode(),
DL, LoVT, LoOperands,
Op->getFlags());
7659 DAG.
getNode(
Op.getOpcode(),
DL, HiVT, HiOperands,
Op->getFlags());
7669 auto [EVLLo, EVLHi] =
7670 DAG.
SplitEVL(
Op.getOperand(3),
Op.getOperand(1).getValueType(),
DL);
7674 {Op.getOperand(0), Lo, MaskLo, EVLLo},
Op->getFlags());
7676 {ResLo, Hi, MaskHi, EVLHi},
Op->getFlags());
7693 for (
unsigned j = 0; j !=
Op.getNumOperands(); ++j) {
7694 if (!
Op.getOperand(j).getValueType().isVector()) {
7695 LoOperands[j] =
Op.getOperand(j);
7696 HiOperands[j] =
Op.getOperand(j);
7699 std::tie(LoOperands[j], HiOperands[j]) =
7704 DAG.
getNode(
Op.getOpcode(),
DL, LoVTs, LoOperands,
Op->getFlags());
7707 DAG.
getNode(
Op.getOpcode(),
DL, HiVTs, HiOperands,
Op->getFlags());
7715RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Load(
SDValue Op,
7717 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
7718 "Unexpected bfloat16 load lowering");
7722 EVT MemVT =
LD->getMemoryVT();
7727 LD->getMemOperand());
7735 DAG.
getNode(RISCVISD::NDS_FMV_BF16_X,
DL, MVT::bf16, OrSixteenOne);
7740RISCVTargetLowering::lowerXAndesBfHCvtBFloat16Store(
SDValue Op,
7742 assert(Subtarget.hasVendorXAndesBFHCvt() && !Subtarget.hasStdExtZfh() &&
7743 "Unexpected bfloat16 store lowering");
7748 Subtarget.getXLenVT(),
ST->getValue());
7750 ST->getChain(),
DL, FMV,
ST->getBasePtr(),
7752 ST->getMemOperand());
7757 switch (
Op.getOpcode()) {
7760 "Unimplemented RISCVTargetLowering::LowerOperation Case");
7766 return lowerGlobalAddress(
Op, DAG);
7768 return lowerBlockAddress(
Op, DAG);
7770 return lowerConstantPool(
Op, DAG);
7772 return lowerJumpTable(
Op, DAG);
7774 return lowerGlobalTLSAddress(
Op, DAG);
7778 return lowerConstantFP(
Op, DAG);
7780 return lowerSELECT(
Op, DAG);
7782 return lowerBRCOND(
Op, DAG);
7784 return lowerVASTART(
Op, DAG);
7786 return lowerFRAMEADDR(
Op, DAG);
7788 return lowerRETURNADDR(
Op, DAG);
7790 return lowerShiftLeftParts(
Op, DAG);
7792 return lowerShiftRightParts(
Op, DAG,
true);
7794 return lowerShiftRightParts(
Op, DAG,
false);
7797 if (
Op.getValueType().isFixedLengthVector()) {
7798 assert(Subtarget.hasStdExtZvkb());
7799 return lowerToScalableOp(
Op, DAG);
7801 assert(Subtarget.hasVendorXTHeadBb() &&
7802 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) &&
7803 "Unexpected custom legalization");
7810 EVT VT =
Op.getValueType();
7813 MVT XLenVT = Subtarget.getXLenVT();
7814 if (Op0VT == MVT::i16 &&
7815 ((VT == MVT::f16 && Subtarget.hasStdExtZfhminOrZhinxmin()) ||
7816 (VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
7818 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, NewOp0);
7820 if (VT == MVT::f32 && Op0VT == MVT::i32 && Subtarget.is64Bit() &&
7821 Subtarget.hasStdExtFOrZfinx()) {
7823 return DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32, NewOp0);
7825 if (VT == MVT::f64 && Op0VT == MVT::i64 && !Subtarget.is64Bit() &&
7826 Subtarget.hasStdExtDOrZdinx()) {
7829 return DAG.
getNode(RISCVISD::BuildPairF64,
DL, MVT::f64,
Lo,
Hi);
7832 if (Subtarget.enablePExtSIMDCodeGen()) {
7834 (VT == MVT::i32 && (Op0VT == MVT::v4i8 || Op0VT == MVT::v2i16)) ||
7835 (Op0VT == MVT::i32 && (VT == MVT::v4i8 || VT == MVT::v2i16));
7837 (VT == MVT::i64 && (Op0VT == MVT::v8i8 || Op0VT == MVT::v4i16 ||
7838 Op0VT == MVT::v2i32)) ||
7839 (Op0VT == MVT::i64 &&
7840 (VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32));
7841 if (Is32BitCast || Is64BitCast)
7854 "Unexpected types");
7886 return LowerINTRINSIC_WO_CHAIN(
Op, DAG);
7888 return LowerINTRINSIC_W_CHAIN(
Op, DAG);
7890 return LowerINTRINSIC_VOID(
Op, DAG);
7892 return LowerIS_FPCLASS(
Op, DAG);
7894 MVT VT =
Op.getSimpleValueType();
7896 assert(Subtarget.hasStdExtZvbb());
7897 return lowerToScalableOp(
Op, DAG);
7900 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected custom legalization");
7904 return DAG.
getNode(RISCVISD::BREV8,
DL, VT, BSwap);
7910 if (!
Op.getSimpleValueType().isVector())
7912 return lowerVectorTruncLike(
Op, DAG);
7915 if (
Op.getOperand(0).getValueType().isVector() &&
7916 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
7917 return lowerVectorMaskExt(
Op, DAG, 1);
7918 if (
Op.getValueType().isScalableVector())
7920 return lowerToScalableOp(
Op, DAG);
7922 if (
Op.getOperand(0).getValueType().isVector() &&
7923 Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
7924 return lowerVectorMaskExt(
Op, DAG, -1);
7925 if (
Op.getValueType().isScalableVector())
7927 return lowerToScalableOp(
Op, DAG);
7929 return lowerSPLAT_VECTOR_PARTS(
Op, DAG);
7931 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7933 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7935 MVT VT =
Op.getSimpleValueType();
7943 MVT ContainerVT = VT;
7950 V = DAG.
getNode(RISCVISD::VFMV_S_F_VL,
DL, ContainerVT,
7951 DAG.
getUNDEF(ContainerVT), Scalar, VL);
7954 V = DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL, ContainerVT,
7955 DAG.
getUNDEF(ContainerVT), Scalar, VL);
7962 MVT XLenVT = Subtarget.getXLenVT();
7963 MVT VT =
Op.getSimpleValueType();
7982 }
else if (
Log2 > 3) {
7986 }
else if ((Val % 8) == 0) {
8004 if (
Op.getValueType() == MVT::f16 && Subtarget.is64Bit() &&
8005 Op.getOperand(1).getValueType() == MVT::i32) {
8022 return lowerVectorFPExtendOrRoundLike(
Op, DAG);
8025 return lowerStrictFPExtendOrRoundLike(
Op, DAG);
8028 if (
Op.getValueType().isVector() &&
8029 ((
Op.getValueType().getScalarType() == MVT::f16 &&
8030 (Subtarget.hasVInstructionsF16Minimal() &&
8031 !Subtarget.hasVInstructionsF16())) ||
8032 Op.getValueType().getScalarType() == MVT::bf16)) {
8048 Op1.getValueType().isVector() &&
8049 ((Op1.getValueType().getScalarType() == MVT::f16 &&
8050 (Subtarget.hasVInstructionsF16Minimal() &&
8051 !Subtarget.hasVInstructionsF16())) ||
8052 Op1.getValueType().getScalarType() == MVT::bf16)) {
8058 Op1.getValueType().getVectorElementCount());
8061 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), WidenVec);
8071 MVT VT =
Op.getSimpleValueType();
8074 bool IsStrict =
Op->isStrictFPOpcode();
8075 SDValue Src =
Op.getOperand(0 + IsStrict);
8076 MVT SrcVT = Src.getSimpleValueType();
8087 "Unexpected vector element types");
8091 if (EltSize > (2 * SrcEltSize)) {
8103 Op.getOperand(0), Ext);
8107 assert(SrcEltVT == MVT::f16 &&
"Unexpected FP_TO_[US]INT lowering");
8112 auto [FExt, Chain] =
8114 return DAG.
getNode(
Op.getOpcode(),
DL,
Op->getVTList(), Chain, FExt);
8121 if (SrcEltSize > (2 * EltSize)) {
8124 assert(EltVT == MVT::f16 &&
"Unexpected [US]_TO_FP lowering");
8129 Op.getOperand(0), Src);
8144 Op.getOperand(0), Src);
8158 unsigned RVVOpc = 0;
8159 switch (
Op.getOpcode()) {
8163 RVVOpc = RISCVISD::VFCVT_RTZ_X_F_VL;
8166 RVVOpc = RISCVISD::VFCVT_RTZ_XU_F_VL;
8169 RVVOpc = RISCVISD::SINT_TO_FP_VL;
8172 RVVOpc = RISCVISD::UINT_TO_FP_VL;
8175 RVVOpc = RISCVISD::STRICT_VFCVT_RTZ_X_F_VL;
8178 RVVOpc = RISCVISD::STRICT_VFCVT_RTZ_XU_F_VL;
8181 RVVOpc = RISCVISD::STRICT_SINT_TO_FP_VL;
8184 RVVOpc = RISCVISD::STRICT_UINT_TO_FP_VL;
8191 "Expected same element count");
8198 Op.getOperand(0), Src, Mask, VL);
8202 Src = DAG.
getNode(RVVOpc,
DL, ContainerVT, Src, Mask, VL);
8211 assert(!Subtarget.isSoftFPABI() &&
"Unexpected custom legalization");
8217 makeLibCall(DAG, LC, MVT::f32,
Op.getOperand(0), CallOptions,
DL).first;
8218 if (Subtarget.is64Bit())
8219 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Res);
8223 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalization");
8224 MVT VT =
Op.getSimpleValueType();
8229 SDValue Res = Subtarget.is64Bit()
8230 ? DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32,
Op)
8241 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalisation");
8244 bool IsStrict =
Op->isStrictFPOpcode();
8245 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
8249 std::tie(Res, Chain) =
8250 makeLibCall(DAG, LC, MVT::f32, Op0, CallOptions,
DL, Chain);
8251 if (Subtarget.is64Bit())
8252 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Res);
8262 assert(Subtarget.hasStdExtFOrZfinx() &&
"Unexpected custom legalisation");
8265 bool IsStrict =
Op->isStrictFPOpcode();
8266 SDValue Op0 = IsStrict ?
Op.getOperand(1) :
Op.getOperand(0);
8268 SDValue Arg = Subtarget.is64Bit()
8269 ? DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, MVT::f32, Op0)
8272 std::tie(Res, Chain) =
makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MVT::f32, Arg,
8273 CallOptions,
DL, Chain);
8292 if (
Op.getValueType().isVector())
8294 assert(
Op.getOperand(0).getValueType() == MVT::f16 &&
8295 "Unexpected custom legalisation");
8298 return DAG.
getNode(
Op.getOpcode(),
DL,
Op.getValueType(), Ext);
8304 assert(
Op.getOperand(1).getValueType() == MVT::f16 &&
8305 "Unexpected custom legalisation");
8308 {
Op.getOperand(0),
Op.getOperand(1)});
8309 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
8310 {Ext.getValue(1), Ext.getValue(0)});
8317 return lowerVECREDUCE(
Op, DAG);
8321 if (
Op.getOperand(0).getValueType().getVectorElementType() == MVT::i1)
8322 return lowerVectorMaskVecReduction(
Op, DAG,
false);
8323 return lowerVECREDUCE(
Op, DAG);
8330 return lowerFPVECREDUCE(
Op, DAG);
8331 case ISD::VP_REDUCE_ADD:
8332 case ISD::VP_REDUCE_UMAX:
8333 case ISD::VP_REDUCE_SMAX:
8334 case ISD::VP_REDUCE_UMIN:
8335 case ISD::VP_REDUCE_SMIN:
8336 case ISD::VP_REDUCE_FADD:
8337 case ISD::VP_REDUCE_SEQ_FADD:
8338 case ISD::VP_REDUCE_FMIN:
8339 case ISD::VP_REDUCE_FMAX:
8340 case ISD::VP_REDUCE_FMINIMUM:
8341 case ISD::VP_REDUCE_FMAXIMUM:
8344 return lowerVPREDUCE(
Op, DAG);
8345 case ISD::VP_REDUCE_AND:
8346 case ISD::VP_REDUCE_OR:
8347 case ISD::VP_REDUCE_XOR:
8348 if (
Op.getOperand(1).getValueType().getVectorElementType() == MVT::i1)
8349 return lowerVectorMaskVecReduction(
Op, DAG,
true);
8350 return lowerVPREDUCE(
Op, DAG);
8351 case ISD::VP_CTTZ_ELTS:
8352 case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
8353 return lowerVPCttzElements(
Op, DAG);
8357 DAG.
getUNDEF(ContainerVT), DAG, Subtarget);
8360 return lowerINSERT_SUBVECTOR(
Op, DAG);
8362 return lowerEXTRACT_SUBVECTOR(
Op, DAG);
8364 return lowerVECTOR_DEINTERLEAVE(
Op, DAG);
8366 return lowerVECTOR_INTERLEAVE(
Op, DAG);
8368 return lowerSTEP_VECTOR(
Op, DAG);
8370 return lowerVECTOR_REVERSE(
Op, DAG);
8373 return lowerVECTOR_SPLICE(
Op, DAG);
8375 MVT VT =
Op.getSimpleValueType();
8377 if (!Subtarget.is64Bit() && EltVT == MVT::i64)
8382 MVT VT =
Op.getSimpleValueType();
8384 if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) ||
8385 EltVT == MVT::bf16) {
8388 if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
8389 (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin()))
8390 Elt = DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, Subtarget.getXLenVT(),
8399 if (EltVT == MVT::i1)
8400 return lowerVectorMaskSplat(
Op, DAG);
8409 MVT VT =
Op.getSimpleValueType();
8410 MVT ContainerVT = VT;
8422 if (
Op.getNumOperands() > 2 &&
8426 size_t HalfNumOps =
Op.getNumOperands() / 2;
8428 Op->ops().take_front(HalfNumOps));
8430 Op->ops().drop_front(HalfNumOps));
8434 unsigned NumOpElts =
8435 Op.getOperand(0).getSimpleValueType().getVectorMinNumElements();
8448 EVT VT = Load->getValueType(0);
8449 if (VT == MVT::f64) {
8450 assert(Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
8451 !Subtarget.is64Bit() &&
"Unexpected custom legalisation");
8455 SDValue BasePtr = Load->getBasePtr();
8456 SDValue Chain = Load->getChain();
8459 DAG.
getLoad(MVT::i32,
DL, Chain, BasePtr, Load->getPointerInfo(),
8460 Load->getBaseAlign(), Load->getMemOperand()->getFlags());
8463 MVT::i32,
DL, Chain, BasePtr, Load->getPointerInfo().getWithOffset(4),
8464 Load->getBaseAlign(), Load->getMemOperand()->getFlags());
8469 if (!Subtarget.isLittleEndian())
8476 if (VT == MVT::bf16)
8477 return lowerXAndesBfHCvtBFloat16Load(
Op, DAG);
8482 MVT XLenVT = Subtarget.getXLenVT();
8485 unsigned NumElts = Sz / (NF * 8);
8486 int Log2LMUL =
Log2_64(NumElts) - 3;
8489 Flag.setNoUnsignedWrap(
true);
8491 SDValue BasePtr = Load->getBasePtr();
8499 for (
unsigned i = 0; i < NF; ++i) {
8504 Ret = DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL, VT, Ret, LoadVal,
8512 if (
auto V = expandUnalignedRVVLoad(
Op, DAG))
8514 if (
Op.getValueType().isFixedLengthVector())
8515 return lowerFixedLengthVectorLoadToRVV(
Op, DAG);
8520 SDValue StoredVal = Store->getValue();
8522 if (Subtarget.enablePExtSIMDCodeGen()) {
8523 if (VT == MVT::v2i16 || VT == MVT::v4i8) {
8527 DAG.
getStore(Store->getChain(),
DL, Cast, Store->getBasePtr(),
8528 Store->getPointerInfo(), Store->getBaseAlign(),
8529 Store->getMemOperand()->getFlags());
8533 if (VT == MVT::f64) {
8534 assert(Subtarget.hasStdExtZdinx() && !Subtarget.hasStdExtZilsd() &&
8535 !Subtarget.is64Bit() &&
"Unexpected custom legalisation");
8539 SDValue BasePtr = Store->getBasePtr();
8540 SDValue Chain = Store->getChain();
8542 DAG.
getVTList(MVT::i32, MVT::i32), StoredVal);
8548 if (!Subtarget.isLittleEndian())
8552 Chain,
DL,
Lo, BasePtr, Store->getPointerInfo(),
8553 Store->getBaseAlign(), Store->getMemOperand()->getFlags());
8556 Chain,
DL,
Hi, BasePtr, Store->getPointerInfo().getWithOffset(4),
8557 Store->getBaseAlign(), Store->getMemOperand()->getFlags());
8560 if (VT == MVT::i64) {
8561 assert(Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit() &&
8562 "Unexpected custom legalisation");
8563 if (Store->isTruncatingStore())
8566 if (Store->getAlign() < Subtarget.getZilsdAlign())
8577 {Store->getChain(), Lo, Hi, Store->getBasePtr()}, MVT::i64,
8578 Store->getMemOperand());
8581 if (VT == MVT::bf16)
8582 return lowerXAndesBfHCvtBFloat16Store(
Op, DAG);
8587 MVT XLenVT = Subtarget.getXLenVT();
8590 unsigned NumElts = Sz / (NF * 8);
8591 int Log2LMUL =
Log2_64(NumElts) - 3;
8594 Flag.setNoUnsignedWrap(
true);
8596 SDValue Chain = Store->getChain();
8597 SDValue BasePtr = Store->getBasePtr();
8604 for (
unsigned i = 0; i < NF; ++i) {
8606 DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL,
8609 Ret = DAG.
getStore(Chain,
DL, Extract, BasePtr,
8611 Store->getBaseAlign(),
8612 Store->getMemOperand()->getFlags());
8619 if (
auto V = expandUnalignedRVVStore(
Op, DAG))
8621 if (
Op.getOperand(1).getValueType().isFixedLengthVector())
8622 return lowerFixedLengthVectorStoreToRVV(
Op, DAG);
8626 if (
SDValue V = expandUnalignedVPLoad(
Op, DAG))
8630 return lowerMaskedLoad(
Op, DAG);
8631 case ISD::VP_LOAD_FF:
8632 return lowerLoadFF(
Op, DAG);
8634 if (
SDValue V = expandUnalignedVPStore(
Op, DAG))
8638 return lowerMaskedStore(
Op, DAG);
8640 return lowerVectorCompress(
Op, DAG);
8649 EVT VT =
Op.getValueType();
8660 MVT OpVT =
Op.getOperand(0).getSimpleValueType();
8662 MVT VT =
Op.getSimpleValueType();
8667 "Unexpected CondCode");
8700 return DAG.
getSetCC(
DL, VT, RHS, LHS, CCVal);
8706 return lowerToScalableOp(
Op, DAG);
8723 return lowerToScalableOp(
Op, DAG);
8727 if (
Op.getSimpleValueType().isFixedLengthVector()) {
8728 if (Subtarget.enablePExtSIMDCodeGen()) {
8738 return lowerToScalableOp(
Op, DAG);
8741 assert(
Op.getOperand(1).getValueType() == MVT::i32 && Subtarget.is64Bit() &&
8742 "Unexpected custom legalisation");
8746 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
8774 return lowerToScalableOp(
Op, DAG);
8778 EVT VT =
Op->getValueType(0);
8793 return lowerABS(
Op, DAG);
8798 if (Subtarget.hasStdExtZvbb())
8799 return lowerToScalableOp(
Op, DAG);
8801 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
8803 if (
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16)
8807 return lowerToScalableOp(
Op, DAG);
8816 return lowerToScalableOp(
Op, DAG);
8819 return lowerVectorStrictFSetcc(
Op, DAG);
8829 case ISD::VP_GATHER:
8830 return lowerMaskedGather(
Op, DAG);
8832 case ISD::VP_SCATTER:
8833 return lowerMaskedScatter(
Op, DAG);
8835 return lowerGET_ROUNDING(
Op, DAG);
8837 return lowerSET_ROUNDING(
Op, DAG);
8839 return lowerGET_FPENV(
Op, DAG);
8841 return lowerSET_FPENV(
Op, DAG);
8843 return lowerRESET_FPENV(
Op, DAG);
8845 return lowerGET_FPMODE(
Op, DAG);
8847 return lowerSET_FPMODE(
Op, DAG);
8849 return lowerRESET_FPMODE(
Op, DAG);
8851 return lowerEH_DWARF_CFA(
Op, DAG);
8853 if (
Op.getSimpleValueType().getVectorElementType() == MVT::i1)
8854 return lowerVPMergeMask(
Op, DAG);
8856 case ISD::VP_SELECT:
8864 case ISD::VP_UADDSAT:
8865 case ISD::VP_USUBSAT:
8866 case ISD::VP_SADDSAT:
8867 case ISD::VP_SSUBSAT:
8869 case ISD::VP_LLRINT:
8870 return lowerVPOp(
Op, DAG);
8874 return lowerLogicVPOp(
Op, DAG);
8883 case ISD::VP_FMINNUM:
8884 case ISD::VP_FMAXNUM:
8885 case ISD::VP_FCOPYSIGN:
8892 return lowerVPOp(
Op, DAG);
8893 case ISD::VP_IS_FPCLASS:
8894 return LowerIS_FPCLASS(
Op, DAG);
8895 case ISD::VP_SIGN_EXTEND:
8896 case ISD::VP_ZERO_EXTEND:
8897 if (
Op.getOperand(0).getSimpleValueType().getVectorElementType() == MVT::i1)
8898 return lowerVPExtMaskOp(
Op, DAG);
8899 return lowerVPOp(
Op, DAG);
8900 case ISD::VP_TRUNCATE:
8901 return lowerVectorTruncLike(
Op, DAG);
8902 case ISD::VP_FP_EXTEND:
8903 case ISD::VP_FP_ROUND:
8904 return lowerVectorFPExtendOrRoundLike(
Op, DAG);
8905 case ISD::VP_SINT_TO_FP:
8906 case ISD::VP_UINT_TO_FP:
8907 if (
Op.getValueType().isVector() &&
8908 ((
Op.getValueType().getScalarType() == MVT::f16 &&
8909 (Subtarget.hasVInstructionsF16Minimal() &&
8910 !Subtarget.hasVInstructionsF16())) ||
8911 Op.getValueType().getScalarType() == MVT::bf16)) {
8924 case ISD::VP_FP_TO_SINT:
8925 case ISD::VP_FP_TO_UINT:
8927 Op1.getValueType().isVector() &&
8928 ((Op1.getValueType().getScalarType() == MVT::f16 &&
8929 (Subtarget.hasVInstructionsF16Minimal() &&
8930 !Subtarget.hasVInstructionsF16())) ||
8931 Op1.getValueType().getScalarType() == MVT::bf16)) {
8937 Op1.getValueType().getVectorElementCount());
8941 {WidenVec, Op.getOperand(1), Op.getOperand(2)});
8943 return lowerVPFPIntConvOp(
Op, DAG);
8947 if (
Op.getOperand(0).getSimpleValueType().getVectorElementType() == MVT::i1)
8948 return lowerVPSetCCMaskOp(
Op, DAG);
8954 case ISD::VP_BITREVERSE:
8956 return lowerVPOp(
Op, DAG);
8958 case ISD::VP_CTLZ_ZERO_UNDEF:
8959 if (Subtarget.hasStdExtZvbb())
8960 return lowerVPOp(
Op, DAG);
8961 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
8963 case ISD::VP_CTTZ_ZERO_UNDEF:
8964 if (Subtarget.hasStdExtZvbb())
8965 return lowerVPOp(
Op, DAG);
8966 return lowerCTLZ_CTTZ_ZERO_UNDEF(
Op, DAG);
8968 return lowerVPOp(
Op, DAG);
8969 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
8970 return lowerVPStridedLoad(
Op, DAG);
8971 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
8972 return lowerVPStridedStore(
Op, DAG);
8974 case ISD::VP_FFLOOR:
8976 case ISD::VP_FNEARBYINT:
8977 case ISD::VP_FROUND:
8978 case ISD::VP_FROUNDEVEN:
8979 case ISD::VP_FROUNDTOZERO:
8983 case ISD::VP_FMAXIMUM:
8984 case ISD::VP_FMINIMUM:
8988 case ISD::EXPERIMENTAL_VP_SPLICE:
8989 return lowerVPSpliceExperimental(
Op, DAG);
8990 case ISD::EXPERIMENTAL_VP_REVERSE:
8991 return lowerVPReverseExperimental(
Op, DAG);
8994 "llvm.clear_cache only needs custom lower on Linux targets");
8997 return emitFlushICache(DAG,
Op.getOperand(0),
Op.getOperand(1),
8998 Op.getOperand(2), Flags,
DL);
9001 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
9003 return lowerINIT_TRAMPOLINE(
Op, DAG);
9005 return lowerADJUST_TRAMPOLINE(
Op, DAG);
9009 return lowerPARTIAL_REDUCE_MLA(
Op, DAG);
9016 MakeLibCallOptions CallOptions;
9017 std::pair<SDValue, SDValue> CallResult =
9018 makeLibCall(DAG, RTLIB::RISCV_FLUSH_ICACHE, MVT::isVoid,
9019 {Start, End, Flags}, CallOptions,
DL, InChain);
9022 return CallResult.second;
9027 if (!Subtarget.is64Bit())
9035 std::unique_ptr<MCCodeEmitter> CodeEmitter(
9063 const bool HasCFBranch =
9064 Subtarget.hasStdExtZicfilp() &&
9066 "cf-protection-branch");
9067 const unsigned StaticChainIdx = HasCFBranch ? 5 : 4;
9068 const unsigned StaticChainOffset = StaticChainIdx * 4;
9069 const unsigned FunctionAddressOffset = StaticChainOffset + 8;
9073 auto GetEncoding = [&](
const MCInst &MC) {
9076 CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI);
9083 SmallVector<uint32_t> Encodings;
9088 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)),
9092 GetEncoding(MCInstBuilder(RISCV::LD)
9095 .addImm(FunctionAddressOffset)),
9098 GetEncoding(MCInstBuilder(RISCV::LD)
9101 .addImm(StaticChainOffset)),
9104 GetEncoding(MCInstBuilder(RISCV::JALR)
9112 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X0).addImm(0)),
9115 GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X28).addImm(0)),
9119 GetEncoding(MCInstBuilder(RISCV::LD)
9122 .addImm(FunctionAddressOffset - 4)),
9125 GetEncoding(MCInstBuilder(RISCV::LD)
9128 .addImm(StaticChainOffset - 4)),
9131 GetEncoding(MCInstBuilder(RISCV::JALR)
9143 Root, dl, DAG.
getConstant(Encoding, dl, MVT::i64), Addr,
9144 MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32));
9148 SDValue FunctionAddress =
Op.getOperand(2);
9152 struct OffsetValuePair {
9156 } OffsetValues[] = {
9157 {StaticChainOffset, StaticChain},
9158 {FunctionAddressOffset, FunctionAddress},
9160 for (
auto &OffsetValue : OffsetValues) {
9163 DAG.
getConstant(OffsetValue.Offset, dl, MVT::i64));
9164 OffsetValue.Addr = Addr;
9166 DAG.
getStore(Root, dl, OffsetValue.Value, Addr,
9167 MachinePointerInfo(TrmpAddr, OffsetValue.Offset)));
9170 assert(OutChains.
size() == StaticChainIdx + 2 &&
9171 "Size of OutChains mismatch");
9176 SDValue EndOfTrmp = OffsetValues[0].Addr;
9187 if (!Subtarget.is64Bit())
9190 return Op.getOperand(0);
9199 MVT VT =
Op.getSimpleValueType();
9205 MVT ArgVT =
A.getSimpleValueType();
9206 assert(ArgVT ==
B.getSimpleValueType() &&
9216 MVT ContainerVT = VT;
9225 switch (
Op.getOpcode()) {
9227 Opc = RISCVISD::VQDOT_VL;
9230 Opc = RISCVISD::VQDOTU_VL;
9233 Opc = RISCVISD::VQDOTSU_VL;
9259 N->getOffset(), Flags);
9288template <
class NodeTy>
9290 bool IsLocal,
bool IsExternWeak)
const {
9300 if (IsLocal && !Subtarget.allowTaggedGlobals())
9304 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
9327 if (Subtarget.hasVendorXqcili()) {
9331 return DAG.
getNode(RISCVISD::QC_E_LI,
DL, Ty, Addr);
9338 return DAG.
getNode(RISCVISD::ADD_LO,
DL, Ty, MNHi, AddrLo);
9362 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
9370 return DAG.
getNode(RISCVISD::LLA,
DL, Ty, Addr);
9378 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
9379 const GlobalValue *GV =
N->getGlobal();
9387 return getAddr(
N, DAG);
9394 return getAddr(
N, DAG);
9401 return getAddr(
N, DAG);
9406 bool UseGOT)
const {
9409 const GlobalValue *GV =
N->getGlobal();
9410 MVT XLenVT = Subtarget.getXLenVT();
9447 DAG.
getNode(RISCVISD::ADD_TPREL,
DL, Ty, MNHi, TPReg, AddrAdd);
9448 return DAG.
getNode(RISCVISD::ADD_LO,
DL, Ty, MNAdd, AddrLo);
9456 const GlobalValue *GV =
N->getGlobal();
9467 Args.emplace_back(Load, CallTy);
9470 TargetLowering::CallLoweringInfo CLI(DAG);
9484 const GlobalValue *GV =
N->getGlobal();
9500 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
9514 Addr = getStaticTLSAddr(
N, DAG,
false);
9517 Addr = getStaticTLSAddr(
N, DAG,
true);
9522 : getDynamicTLSAddr(
N, DAG);
9539 if (
LHS == LHS2 &&
RHS == RHS2) {
9544 }
else if (
LHS == RHS2 &&
RHS == LHS2) {
9552 return std::nullopt;
9564 MVT VT =
N->getSimpleValueType(0);
9591 uint64_t TrueM1 = TrueC->getZExtValue() - 1;
9593 unsigned ShAmount =
Log2_64(TrueM1);
9595 return DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT, CondV,
9611 if (~TrueVal == FalseVal) {
9651 if (Subtarget.hasShortForwardBranchIALU())
9654 unsigned SelOpNo = 0;
9664 unsigned ConstSelOpNo = 1;
9665 unsigned OtherSelOpNo = 2;
9672 if (!ConstSelOpNode || ConstSelOpNode->
isOpaque())
9677 if (!ConstBinOpNode || ConstBinOpNode->
isOpaque())
9683 SDValue NewConstOps[2] = {ConstSelOp, ConstBinOp};
9685 std::swap(NewConstOps[0], NewConstOps[1]);
9697 SDValue NewNonConstOps[2] = {OtherSelOp, ConstBinOp};
9699 std::swap(NewNonConstOps[0], NewNonConstOps[1]);
9702 SDValue NewT = (ConstSelOpNo == 1) ? NewConstOp : NewNonConstOp;
9703 SDValue NewF = (ConstSelOpNo == 1) ? NewNonConstOp : NewConstOp;
9713 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
9714 return VT == MVT::v4i8 || VT == MVT::v2i16;
9722 MVT VT =
Op.getSimpleValueType();
9723 MVT XLenVT = Subtarget.getXLenVT();
9750 bool FPinGPR = Subtarget.hasStdExtZfinx();
9754 Subtarget.getXLenVT().getSizeInBits());
9756 bool UseZicondForFPSel = Subtarget.hasStdExtZicond() && FPinGPR &&
9759 if (UseZicondForFPSel) {
9767 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, V);
9769 if (VT == MVT::f32 && Subtarget.is64Bit())
9770 return DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, XLenVT, V);
9775 SDValue TrueVInt = CastToInt(TrueV);
9776 SDValue FalseVInt = CastToInt(FalseV);
9783 if (VT == MVT::f32 && Subtarget.is64Bit())
9784 return DAG.
getNode(RISCVISD::FMV_W_X_RV64,
DL, VT, ResultInt);
9787 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, VT, ResultInt);
9800 return DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV);
9803 return DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV);
9807 auto getNotOperand = [](
const SDValue &
Op) -> std::optional<const SDValue> {
9808 using namespace llvm::SDPatternMatch;
9813 return std::nullopt;
9819 auto NotOperand = (TrueV.
getOperand(0) == FalseV)
9821 : getNotOperand(TrueV.getOperand(0));
9824 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, *NotOperand, CondV);
9830 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV));
9837 auto NotOperand = (FalseV.
getOperand(0) == TrueV)
9839 : getNotOperand(FalseV.getOperand(0));
9842 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, *NotOperand, CondV);
9848 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV));
9865 int64_t TrueImm =
TrueVal.getSExtValue();
9866 int64_t FalseImm =
FalseVal.getSExtValue();
9885 if ((TrueVal - FalseVal).isPowerOf2() &&
FalseVal.isSignedIntN(12)) {
9890 if ((FalseVal - TrueVal).isPowerOf2() &&
TrueVal.isSignedIntN(12)) {
9897 auto getCost = [&](
const APInt &Delta,
const APInt &Addend) {
9899 Delta, Subtarget.getXLen(), Subtarget,
true);
9901 if (Addend.isSignedIntN(12))
9904 Addend, Subtarget.getXLen(), Subtarget,
true);
9905 return AddendCost + DeltaCost;
9907 bool IsCZERO_NEZ =
getCost(FalseVal - TrueVal, TrueVal) <=
9908 getCost(TrueVal - FalseVal, FalseVal);
9910 IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal,
DL, VT);
9912 DAG.
getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
9913 DL, VT, LHSVal, CondV);
9921 SDValue ConstVal = IsCZERO_NEZ ? TrueV : FalseV;
9922 SDValue RegV = IsCZERO_NEZ ? FalseV : TrueV;
9928 unsigned SubOpc = (RawConstVal == -0x800) ?
ISD::XOR : ISD::
SUB;
9929 unsigned AddOpc = (RawConstVal == -0x800) ?
ISD::XOR : ISD::
ADD;
9932 DAG.
getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
9933 DL, VT, SubOp, CondV);
9934 return DAG.
getNode(AddOpc,
DL, VT, CZERO, ConstVal);
9940 if (!Subtarget.hasConditionalMoveFusion())
9943 DAG.
getNode(RISCVISD::CZERO_EQZ,
DL, VT, TrueV, CondV),
9944 DAG.
getNode(RISCVISD::CZERO_NEZ,
DL, VT, FalseV, CondV),
9948 if (
Op.hasOneUse()) {
9949 unsigned UseOpc =
Op->user_begin()->getOpcode();
9951 SDNode *BinOp = *
Op->user_begin();
9958 return lowerSELECT(NewSel, DAG);
10012 if (TrueVal - 1 == FalseVal)
10014 if (TrueVal + 1 == FalseVal)
10021 RHS == TrueV &&
LHS == FalseV) {
10052 MVT XLenVT = Subtarget.getXLenVT();
10063 return DAG.
getNode(RISCVISD::BR_CC,
DL,
Op.getValueType(),
Op.getOperand(0),
10064 LHS,
RHS, TargetCC,
Op.getOperand(2));
10067 return DAG.
getNode(RISCVISD::BR_CC,
DL,
Op.getValueType(),
Op.getOperand(0),
10074 RISCVMachineFunctionInfo *FuncInfo = MF.
getInfo<RISCVMachineFunctionInfo>();
10084 MachinePointerInfo(SV));
10089 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
10094 int XLenInBytes = Subtarget.getXLen() / 8;
10096 EVT VT =
Op.getValueType();
10099 unsigned Depth =
Op.getConstantOperandVal(0);
10101 int Offset = -(XLenInBytes * 2);
10113 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
10117 MVT XLenVT = Subtarget.getXLenVT();
10118 int XLenInBytes = Subtarget.getXLen() / 8;
10120 EVT VT =
Op.getValueType();
10122 unsigned Depth =
Op.getConstantOperandVal(0);
10124 int Off = -XLenInBytes;
10125 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
10129 MachinePointerInfo());
10144 EVT VT =
Lo.getValueType();
10178 bool IsSRA)
const {
10183 EVT VT =
Lo.getValueType();
10234 MVT VT =
Op.getSimpleValueType();
10239 return DAG.
getNode(RISCVISD::VMSET_VL,
DL, VT, VL);
10243 return DAG.
getNode(RISCVISD::VMCLR_VL,
DL, VT, VL);
10260 MVT VecVT =
Op.getSimpleValueType();
10262 "Unexpected SPLAT_VECTOR_PARTS lowering");
10268 MVT ContainerVT = VecVT;
10288 int64_t ExtTrueVal)
const {
10290 MVT VecVT =
Op.getSimpleValueType();
10293 assert(Src.getValueType().isVector() &&
10294 Src.getValueType().getVectorElementType() == MVT::i1);
10299 if (Src.getOpcode() ==
ISD::XOR &&
10307 MVT I1ContainerVT =
10314 MVT XLenVT = Subtarget.getXLenVT();
10320 if (
Xor.getOpcode() == RISCVISD::VMXOR_VL) {
10332 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
10333 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
10334 SplatTrueVal = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
10335 DAG.
getUNDEF(ContainerVT), SplatTrueVal, VL);
10337 DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, CC, SplatTrueVal,
10338 SplatZero, DAG.
getUNDEF(ContainerVT), VL);
10348 bool IsVPTrunc =
Op.getOpcode() == ISD::VP_TRUNCATE;
10350 EVT MaskVT =
Op.getValueType();
10353 "Unexpected type for vector mask lowering");
10355 MVT VecVT = Src.getSimpleValueType();
10358 Mask =
Op.getOperand(1);
10359 VL =
Op.getOperand(2);
10362 MVT ContainerVT = VecVT;
10368 MVT MaskContainerVT =
10375 std::tie(Mask, VL) =
10382 SplatOne = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
10383 DAG.
getUNDEF(ContainerVT), SplatOne, VL);
10384 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, ContainerVT,
10385 DAG.
getUNDEF(ContainerVT), SplatZero, VL);
10388 SDValue Trunc = DAG.
getNode(RISCVISD::AND_VL,
DL, ContainerVT, Src, SplatOne,
10389 DAG.
getUNDEF(ContainerVT), Mask, VL);
10390 Trunc = DAG.
getNode(RISCVISD::SETCC_VL,
DL, MaskContainerVT,
10400 unsigned Opc =
Op.getOpcode();
10401 bool IsVPTrunc =
Opc == ISD::VP_TRUNCATE;
10404 MVT VT =
Op.getSimpleValueType();
10406 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
10410 return lowerVectorMaskTruncLike(
Op, DAG);
10418 MVT SrcVT = Src.getSimpleValueType();
10423 "Unexpected vector truncate lowering");
10425 MVT ContainerVT = SrcVT;
10428 Mask =
Op.getOperand(1);
10429 VL =
Op.getOperand(2);
10442 std::tie(Mask, VL) =
10448 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL_SSAT;
10450 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL_USAT;
10452 NewOpc = RISCVISD::TRUNCATE_VECTOR_VL;
10458 }
while (SrcEltVT != DstEltVT);
10467RISCVTargetLowering::lowerStrictFPExtendOrRoundLike(
SDValue Op,
10472 MVT VT =
Op.getSimpleValueType();
10473 MVT SrcVT = Src.getSimpleValueType();
10474 MVT ContainerVT = VT;
10493 ? RISCVISD::STRICT_FP_EXTEND_VL
10494 : RISCVISD::STRICT_VFNCVT_ROD_VL;
10497 Chain, Src, Mask, VL);
10498 Chain = Src.getValue(1);
10502 ? RISCVISD::STRICT_FP_EXTEND_VL
10503 : RISCVISD::STRICT_FP_ROUND_VL;
10505 Chain, Src, Mask, VL);
10516RISCVTargetLowering::lowerVectorFPExtendOrRoundLike(
SDValue Op,
10519 Op.getOpcode() == ISD::VP_FP_ROUND ||
Op.getOpcode() == ISD::VP_FP_EXTEND;
10526 MVT VT =
Op.getSimpleValueType();
10528 assert(VT.
isVector() &&
"Unexpected type for vector truncate lowering");
10531 MVT SrcVT = Src.getSimpleValueType();
10533 bool IsDirectExtend =
10541 bool IsDirectConv = IsDirectExtend || IsDirectTrunc;
10548 MVT ContainerVT = VT;
10551 Mask =
Op.getOperand(1);
10552 VL =
Op.getOperand(2);
10566 std::tie(Mask, VL) =
10569 unsigned ConvOpc = IsExtend ? RISCVISD::FP_EXTEND_VL : RISCVISD::FP_ROUND_VL;
10571 if (IsDirectConv) {
10572 Src = DAG.
getNode(ConvOpc,
DL, ContainerVT, Src, Mask, VL);
10578 unsigned InterConvOpc =
10579 IsExtend ? RISCVISD::FP_EXTEND_VL : RISCVISD::VFNCVT_ROD_VL;
10583 DAG.
getNode(InterConvOpc,
DL, InterVT, Src, Mask, VL);
10585 DAG.
getNode(ConvOpc,
DL, ContainerVT, IntermediateConv, Mask, VL);
10596static std::optional<MVT>
10602 const unsigned MinVLMAX = VectorBitsMin / EltSize;
10604 if (MaxIdx < MinVLMAX)
10606 else if (MaxIdx < MinVLMAX * 2)
10609 else if (MaxIdx < MinVLMAX * 4)
10614 return std::nullopt;
10622 return isUInt<5>(IdxC->getZExtValue());
10634 MVT VecVT =
Op.getSimpleValueType();
10635 MVT XLenVT = Subtarget.getXLenVT();
10650 if ((ValVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
10651 (ValVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
10656 DAG.
getNode(RISCVISD::FMV_X_ANYEXTH,
DL, XLenVT, Val), Idx);
10660 MVT ContainerVT = VecVT;
10670 std::optional<unsigned> AlignedIdx;
10672 const unsigned OrigIdx = IdxC->getZExtValue();
10675 DL, DAG, Subtarget)) {
10676 ContainerVT = *ShrunkVT;
10684 if (
auto VLEN = Subtarget.getRealVLen(); VLEN && ContainerVT.
bitsGT(M1VT)) {
10687 unsigned RemIdx = OrigIdx % ElemsPerVReg;
10688 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
10691 ContainerVT = M1VT;
10698 bool IsLegalInsert = Subtarget.is64Bit() || Val.
getValueType() != MVT::i64;
10706 IsLegalInsert =
true;
10715 if (IsLegalInsert) {
10717 VecVT.
isFloatingPoint() ? RISCVISD::VFMV_S_F_VL : RISCVISD::VMV_S_X_VL;
10721 Vec = DAG.
getNode(
Opc,
DL, ContainerVT, Vec, Val, VL);
10731 if (Subtarget.hasVendorXRivosVisni() && VecVT.
isInteger() &&
10736 Vec = DAG.
getNode(RISCVISD::RI_VINSERT_VL,
DL, ContainerVT, Vec, Val, Idx,
10752 std::tie(ValLo, ValHi) = DAG.
SplitScalar(Val,
DL, MVT::i32, MVT::i32);
10753 MVT I32ContainerVT =
10763 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
10764 Vec, Vec, ValLo, I32Mask, InsertI64VL);
10768 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
10769 Tail, ValInVec, ValHi, I32Mask, InsertI64VL);
10771 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
10782 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
10784 DAG.
getUNDEF(I32ContainerVT), ValLo,
10785 I32Mask, InsertI64VL);
10786 ValInVec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32ContainerVT,
10787 DAG.
getUNDEF(I32ContainerVT), ValInVec, ValHi,
10788 I32Mask, InsertI64VL);
10790 ValInVec = DAG.
getBitcast(ContainerVT, ValInVec);
10803 Idx, Mask, InsertVL, Policy);
10821 EVT EltVT =
Op.getValueType();
10823 MVT XLenVT = Subtarget.getXLenVT();
10828 MVT ContainerVT = VecVT;
10835 DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Vec, Mask, VL);
10842 if (NumElts >= 8) {
10844 unsigned WidenVecLen;
10847 unsigned MaxEEW = Subtarget.getELen();
10852 "the number of elements should be power of 2");
10856 ExtractBitIdx = Idx;
10858 WideEltVT = LargestEltVT;
10861 ExtractElementIdx = DAG.
getNode(
10872 Vec, ExtractElementIdx);
10887 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
10888 (EltVT == MVT::bf16 && !Subtarget.hasVInstructionsBF16())) {
10894 return DAG.
getNode(RISCVISD::FMV_H_X,
DL, EltVT, IntExtract);
10898 if (VecVT != MVT::v4i16 && VecVT != MVT::v2i16 && VecVT != MVT::v8i8 &&
10899 VecVT != MVT::v4i8 && VecVT != MVT::v2i32)
10909 MVT ContainerVT = VecVT;
10919 const auto VLen = Subtarget.getRealVLen();
10921 IdxC && VLen && VecVT.
getSizeInBits().getKnownMinValue() > *VLen) {
10923 unsigned OrigIdx = IdxC->getZExtValue();
10926 unsigned RemIdx = OrigIdx % ElemsPerVReg;
10927 unsigned SubRegIdx = OrigIdx / ElemsPerVReg;
10928 unsigned ExtractIdx =
10932 ContainerVT = M1VT;
10937 std::optional<uint64_t> MaxIdx;
10941 MaxIdx = IdxC->getZExtValue();
10943 if (
auto SmallerVT =
10945 ContainerVT = *SmallerVT;
10952 if (Subtarget.hasVendorXRivosVisni() && EltVT.
isInteger() &&
10980 DAG.
getUNDEF(ContainerVT), Vec, Idx, Mask, VL);
10999 "Unexpected opcode");
11006 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
11011 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
11012 if (!
II || !
II->hasScalarOperand())
11015 unsigned SplatOp =
II->ScalarOperand + 1 + HasChain;
11016 assert(SplatOp <
Op.getNumOperands());
11019 SDValue &ScalarOp = Operands[SplatOp];
11028 if (OpVT.
bitsLT(XLenVT)) {
11035 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
11036 return DAG.
getNode(
Op->getOpcode(),
DL,
Op->getVTList(), Operands);
11045 assert(
II->ScalarOperand > 0 &&
"Unexpected splat operand!");
11046 MVT VT =
Op.getOperand(SplatOp - 1).getSimpleValueType();
11049 assert(XLenVT == MVT::i32 && OpVT == MVT::i64 &&
11056 return DAG.
getNode(
Op->getOpcode(),
DL,
Op->getVTList(), Operands);
11060 case Intrinsic::riscv_vslide1up:
11061 case Intrinsic::riscv_vslide1down:
11062 case Intrinsic::riscv_vslide1up_mask:
11063 case Intrinsic::riscv_vslide1down_mask: {
11065 unsigned NumOps =
Op.getNumOperands();
11066 bool IsMasked =
NumOps == 7;
11072 std::tie(ScalarLo, ScalarHi) =
11081 const auto [MinVLMAX, MaxVLMAX] =
11085 if (AVLInt <= MinVLMAX) {
11087 }
else if (AVLInt >= 2 * MaxVLMAX) {
11119 Passthru = DAG.
getBitcast(I32VT, Operands[1]);
11121 if (IntNo == Intrinsic::riscv_vslide1up ||
11122 IntNo == Intrinsic::riscv_vslide1up_mask) {
11123 Vec = DAG.
getNode(RISCVISD::VSLIDE1UP_VL,
DL, I32VT, Passthru, Vec,
11124 ScalarHi, I32Mask, I32VL);
11125 Vec = DAG.
getNode(RISCVISD::VSLIDE1UP_VL,
DL, I32VT, Passthru, Vec,
11126 ScalarLo, I32Mask, I32VL);
11128 Vec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32VT, Passthru, Vec,
11129 ScalarLo, I32Mask, I32VL);
11130 Vec = DAG.
getNode(RISCVISD::VSLIDE1DOWN_VL,
DL, I32VT, Passthru, Vec,
11131 ScalarHi, I32Mask, I32VL);
11141 SDValue MaskedOff = Operands[1];
11149 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, Mask, Vec, MaskedOff,
11153 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, Mask, Vec, MaskedOff,
11162 return DAG.
getNode(
Op->getOpcode(),
DL,
Op->getVTList(), Operands);
11180 const unsigned ElementWidth = 8;
11185 [[maybe_unused]]
unsigned MinVF =
11188 [[maybe_unused]]
unsigned VF =
N->getConstantOperandVal(2);
11192 bool Fractional = VF < LMul1VF;
11193 unsigned LMulVal = Fractional ? LMul1VF / VF : VF / LMul1VF;
11214 MVT ContainerVT = OpVT;
11222 SDValue Res = DAG.
getNode(RISCVISD::VFIRST_VL,
DL, XLenVT, Op0, Mask, VL);
11230 return DAG.
getSelect(
DL, XLenVT, Setcc, VL, Res);
11241 unsigned IntNo =
Op.getConstantOperandVal(HasChain ? 1 : 0);
11245 RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntNo);
11246 if (!
II || !
II->hasScalarOperand())
11249 unsigned SplatOp =
II->ScalarOperand + 1;
11250 assert(SplatOp <
Op.getNumOperands());
11252 SDValue &ScalarOp = Operands[SplatOp];
11262 if (OpVT.
bitsLT(XLenVT)) {
11265 ScalarOp = DAG.
getNode(ExtOpc,
DL, XLenVT, ScalarOp);
11275 for (
SDValue &V : Operands) {
11276 EVT ValType = V.getValueType();
11277 if (ValType.isVector() && ValType.isFloatingPoint()) {
11280 ValType.getVectorElementCount());
11283 if (ValType.isFixedLengthVector()) {
11285 DAG, V.getSimpleValueType(), Subtarget);
11301 unsigned IntNo =
Op.getConstantOperandVal(0);
11303 MVT XLenVT = Subtarget.getXLenVT();
11308 case Intrinsic::riscv_tuple_insert: {
11313 return DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL,
Op.getValueType(), Vec,
11316 case Intrinsic::riscv_tuple_extract: {
11320 return DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL,
Op.getValueType(), Vec,
11323 case Intrinsic::thread_pointer: {
11327 case Intrinsic::riscv_orc_b:
11328 case Intrinsic::riscv_brev8:
11329 case Intrinsic::riscv_sha256sig0:
11330 case Intrinsic::riscv_sha256sig1:
11331 case Intrinsic::riscv_sha256sum0:
11332 case Intrinsic::riscv_sha256sum1:
11333 case Intrinsic::riscv_sm3p0:
11334 case Intrinsic::riscv_sm3p1: {
11337 case Intrinsic::riscv_orc_b:
Opc = RISCVISD::ORC_B;
break;
11338 case Intrinsic::riscv_brev8:
Opc = RISCVISD::BREV8;
break;
11339 case Intrinsic::riscv_sha256sig0:
Opc = RISCVISD::SHA256SIG0;
break;
11340 case Intrinsic::riscv_sha256sig1:
Opc = RISCVISD::SHA256SIG1;
break;
11341 case Intrinsic::riscv_sha256sum0:
Opc = RISCVISD::SHA256SUM0;
break;
11342 case Intrinsic::riscv_sha256sum1:
Opc = RISCVISD::SHA256SUM1;
break;
11343 case Intrinsic::riscv_sm3p0:
Opc = RISCVISD::SM3P0;
break;
11344 case Intrinsic::riscv_sm3p1:
Opc = RISCVISD::SM3P1;
break;
11349 case Intrinsic::riscv_sm4ks:
11350 case Intrinsic::riscv_sm4ed: {
11352 IntNo == Intrinsic::riscv_sm4ks ? RISCVISD::SM4KS : RISCVISD::SM4ED;
11357 case Intrinsic::riscv_zip:
11358 case Intrinsic::riscv_unzip: {
11360 IntNo == Intrinsic::riscv_zip ? RISCVISD::ZIP : RISCVISD::UNZIP;
11363 case Intrinsic::riscv_mopr:
11364 return DAG.
getNode(RISCVISD::MOP_R,
DL, XLenVT,
Op.getOperand(1),
11367 case Intrinsic::riscv_moprr: {
11368 return DAG.
getNode(RISCVISD::MOP_RR,
DL, XLenVT,
Op.getOperand(1),
11369 Op.getOperand(2),
Op.getOperand(3));
11371 case Intrinsic::riscv_clmul:
11372 return DAG.
getNode(RISCVISD::CLMUL,
DL, XLenVT,
Op.getOperand(1),
11374 case Intrinsic::riscv_clmulh:
11375 case Intrinsic::riscv_clmulr: {
11377 IntNo == Intrinsic::riscv_clmulh ? RISCVISD::CLMULH : RISCVISD::CLMULR;
11380 case Intrinsic::experimental_get_vector_length:
11382 case Intrinsic::experimental_cttz_elts:
11384 case Intrinsic::riscv_vmv_x_s: {
11388 case Intrinsic::riscv_vfmv_f_s:
11390 case Intrinsic::riscv_vmv_v_x:
11392 Op.getOperand(3),
Op.getSimpleValueType(),
DL, DAG,
11394 case Intrinsic::riscv_vfmv_v_f:
11395 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL,
Op.getValueType(),
11396 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
11397 case Intrinsic::riscv_vmv_s_x: {
11400 if (
Scalar.getValueType().bitsLE(XLenVT)) {
11402 return DAG.
getNode(RISCVISD::VMV_S_X_VL,
DL,
Op.getValueType(),
11403 Op.getOperand(1), Scalar,
Op.getOperand(3));
11406 assert(
Scalar.getValueType() == MVT::i64 &&
"Unexpected scalar VT!");
11423 MVT VT =
Op.getSimpleValueType();
11428 if (
Op.getOperand(1).isUndef())
11429 return SplattedVal;
11438 DAG.
getNode(RISCVISD::SETCC_VL,
DL, MaskVT,
11441 return DAG.
getNode(RISCVISD::VMERGE_VL,
DL, VT, SelectCond, SplattedVal,
11444 case Intrinsic::riscv_vfmv_s_f:
11445 return DAG.
getNode(RISCVISD::VFMV_S_F_VL,
DL,
Op.getSimpleValueType(),
11446 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
11448 case Intrinsic::riscv_vaesdf_vv:
11449 case Intrinsic::riscv_vaesdf_vs:
11450 case Intrinsic::riscv_vaesdm_vv:
11451 case Intrinsic::riscv_vaesdm_vs:
11452 case Intrinsic::riscv_vaesef_vv:
11453 case Intrinsic::riscv_vaesef_vs:
11454 case Intrinsic::riscv_vaesem_vv:
11455 case Intrinsic::riscv_vaesem_vs:
11456 case Intrinsic::riscv_vaeskf1:
11457 case Intrinsic::riscv_vaeskf2:
11458 case Intrinsic::riscv_vaesz_vs:
11459 case Intrinsic::riscv_vsm4k:
11460 case Intrinsic::riscv_vsm4r_vv:
11461 case Intrinsic::riscv_vsm4r_vs: {
11462 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
11463 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
11464 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
11469 case Intrinsic::riscv_vsm3c:
11470 case Intrinsic::riscv_vsm3me: {
11471 if (!
isValidEGW(8,
Op.getSimpleValueType(), Subtarget) ||
11472 !
isValidEGW(8,
Op->getOperand(1).getSimpleValueType(), Subtarget))
11477 case Intrinsic::riscv_vsha2ch:
11478 case Intrinsic::riscv_vsha2cl:
11479 case Intrinsic::riscv_vsha2ms: {
11480 if (
Op->getSimpleValueType(0).getScalarSizeInBits() == 64 &&
11481 !Subtarget.hasStdExtZvknhb())
11483 if (!
isValidEGW(4,
Op.getSimpleValueType(), Subtarget) ||
11484 !
isValidEGW(4,
Op->getOperand(1).getSimpleValueType(), Subtarget) ||
11485 !
isValidEGW(4,
Op->getOperand(2).getSimpleValueType(), Subtarget))
11489 case Intrinsic::riscv_sf_vc_v_x:
11490 case Intrinsic::riscv_sf_vc_v_i:
11491 case Intrinsic::riscv_sf_vc_v_xv:
11492 case Intrinsic::riscv_sf_vc_v_iv:
11493 case Intrinsic::riscv_sf_vc_v_vv:
11494 case Intrinsic::riscv_sf_vc_v_fv:
11495 case Intrinsic::riscv_sf_vc_v_xvv:
11496 case Intrinsic::riscv_sf_vc_v_ivv:
11497 case Intrinsic::riscv_sf_vc_v_vvv:
11498 case Intrinsic::riscv_sf_vc_v_fvv:
11499 case Intrinsic::riscv_sf_vc_v_xvw:
11500 case Intrinsic::riscv_sf_vc_v_ivw:
11501 case Intrinsic::riscv_sf_vc_v_vvw:
11502 case Intrinsic::riscv_sf_vc_v_fvw: {
11503 MVT VT =
Op.getSimpleValueType();
11540 MVT VT =
Op.getSimpleValueType();
11544 if (VT.isFloatingPoint()) {
11546 VT.getVectorElementCount());
11549 if (VT.isFixedLengthVector())
11559 if (VT.isFixedLengthVector())
11561 if (VT.isFloatingPoint())
11584 case Intrinsic::riscv_seg2_load_mask:
11585 case Intrinsic::riscv_seg3_load_mask:
11586 case Intrinsic::riscv_seg4_load_mask:
11587 case Intrinsic::riscv_seg5_load_mask:
11588 case Intrinsic::riscv_seg6_load_mask:
11589 case Intrinsic::riscv_seg7_load_mask:
11590 case Intrinsic::riscv_seg8_load_mask:
11593 case Intrinsic::riscv_sseg2_load_mask:
11594 case Intrinsic::riscv_sseg3_load_mask:
11595 case Intrinsic::riscv_sseg4_load_mask:
11596 case Intrinsic::riscv_sseg5_load_mask:
11597 case Intrinsic::riscv_sseg6_load_mask:
11598 case Intrinsic::riscv_sseg7_load_mask:
11599 case Intrinsic::riscv_sseg8_load_mask:
11607 Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
11608 Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
11609 Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
11610 Intrinsic::riscv_vlseg8_mask};
11612 Intrinsic::riscv_vlsseg2_mask, Intrinsic::riscv_vlsseg3_mask,
11613 Intrinsic::riscv_vlsseg4_mask, Intrinsic::riscv_vlsseg5_mask,
11614 Intrinsic::riscv_vlsseg6_mask, Intrinsic::riscv_vlsseg7_mask,
11615 Intrinsic::riscv_vlsseg8_mask};
11618 unsigned NF =
Op->getNumValues() - 1;
11619 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
11621 MVT VT =
Op->getSimpleValueType(0);
11629 SDValue VL =
Op.getOperand(
Op.getNumOperands() - 1);
11630 SDValue Mask =
Op.getOperand(
Op.getNumOperands() - 2);
11631 MVT MaskVT = Mask.getSimpleValueType();
11632 MVT MaskContainerVT =
11637 IsStrided ? VlssegInts[NF - 2] : VlsegInts[NF - 2],
DL, XLenVT);
11653 Ops.insert(std::next(
Ops.begin(), 4),
Op.getOperand(3));
11657 Load->getMemoryVT(), Load->getMemOperand());
11659 for (
unsigned int RetIdx = 0; RetIdx < NF; RetIdx++) {
11661 Result.getValue(0),
11665 Results.push_back(Result.getValue(1));
11671 unsigned IntNo =
Op.getConstantOperandVal(1);
11675 case Intrinsic::riscv_seg2_load_mask:
11676 case Intrinsic::riscv_seg3_load_mask:
11677 case Intrinsic::riscv_seg4_load_mask:
11678 case Intrinsic::riscv_seg5_load_mask:
11679 case Intrinsic::riscv_seg6_load_mask:
11680 case Intrinsic::riscv_seg7_load_mask:
11681 case Intrinsic::riscv_seg8_load_mask:
11682 case Intrinsic::riscv_sseg2_load_mask:
11683 case Intrinsic::riscv_sseg3_load_mask:
11684 case Intrinsic::riscv_sseg4_load_mask:
11685 case Intrinsic::riscv_sseg5_load_mask:
11686 case Intrinsic::riscv_sseg6_load_mask:
11687 case Intrinsic::riscv_sseg7_load_mask:
11688 case Intrinsic::riscv_sseg8_load_mask:
11691 case Intrinsic::riscv_sf_vc_v_x_se:
11693 case Intrinsic::riscv_sf_vc_v_i_se:
11695 case Intrinsic::riscv_sf_vc_v_xv_se:
11697 case Intrinsic::riscv_sf_vc_v_iv_se:
11699 case Intrinsic::riscv_sf_vc_v_vv_se:
11701 case Intrinsic::riscv_sf_vc_v_fv_se:
11703 case Intrinsic::riscv_sf_vc_v_xvv_se:
11705 case Intrinsic::riscv_sf_vc_v_ivv_se:
11707 case Intrinsic::riscv_sf_vc_v_vvv_se:
11709 case Intrinsic::riscv_sf_vc_v_fvv_se:
11711 case Intrinsic::riscv_sf_vc_v_xvw_se:
11713 case Intrinsic::riscv_sf_vc_v_ivw_se:
11715 case Intrinsic::riscv_sf_vc_v_vvw_se:
11717 case Intrinsic::riscv_sf_vc_v_fvw_se:
11730 case Intrinsic::riscv_seg2_store_mask:
11731 case Intrinsic::riscv_seg3_store_mask:
11732 case Intrinsic::riscv_seg4_store_mask:
11733 case Intrinsic::riscv_seg5_store_mask:
11734 case Intrinsic::riscv_seg6_store_mask:
11735 case Intrinsic::riscv_seg7_store_mask:
11736 case Intrinsic::riscv_seg8_store_mask:
11739 case Intrinsic::riscv_sseg2_store_mask:
11740 case Intrinsic::riscv_sseg3_store_mask:
11741 case Intrinsic::riscv_sseg4_store_mask:
11742 case Intrinsic::riscv_sseg5_store_mask:
11743 case Intrinsic::riscv_sseg6_store_mask:
11744 case Intrinsic::riscv_sseg7_store_mask:
11745 case Intrinsic::riscv_sseg8_store_mask:
11754 Intrinsic::riscv_vsseg2_mask, Intrinsic::riscv_vsseg3_mask,
11755 Intrinsic::riscv_vsseg4_mask, Intrinsic::riscv_vsseg5_mask,
11756 Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
11757 Intrinsic::riscv_vsseg8_mask};
11759 Intrinsic::riscv_vssseg2_mask, Intrinsic::riscv_vssseg3_mask,
11760 Intrinsic::riscv_vssseg4_mask, Intrinsic::riscv_vssseg5_mask,
11761 Intrinsic::riscv_vssseg6_mask, Intrinsic::riscv_vssseg7_mask,
11762 Intrinsic::riscv_vssseg8_mask};
11766 unsigned NF =
Op->getNumOperands() - (IsStrided ? 6 : 5);
11767 assert(NF >= 2 && NF <= 8 &&
"Unexpected seg number");
11769 MVT VT =
Op->getOperand(2).getSimpleValueType();
11775 SDValue VL =
Op.getOperand(
Op.getNumOperands() - 1);
11776 SDValue Mask =
Op.getOperand(
Op.getNumOperands() - 2);
11777 MVT MaskVT = Mask.getSimpleValueType();
11778 MVT MaskContainerVT =
11783 IsStrided ? VsssegInts[NF - 2] : VssegInts[NF - 2],
DL, XLenVT);
11789 for (
unsigned i = 0; i < NF; i++)
11791 RISCVISD::TUPLE_INSERT,
DL, VecTupTy, StoredVal,
11797 FixedIntrinsic->getChain(),
11806 Ops.insert(std::next(
Ops.begin(), 4),
11807 Op.getOperand(
Op.getNumOperands() - 3));
11811 FixedIntrinsic->getMemoryVT(), FixedIntrinsic->getMemOperand());
11816 unsigned IntNo =
Op.getConstantOperandVal(1);
11820 case Intrinsic::riscv_seg2_store_mask:
11821 case Intrinsic::riscv_seg3_store_mask:
11822 case Intrinsic::riscv_seg4_store_mask:
11823 case Intrinsic::riscv_seg5_store_mask:
11824 case Intrinsic::riscv_seg6_store_mask:
11825 case Intrinsic::riscv_seg7_store_mask:
11826 case Intrinsic::riscv_seg8_store_mask:
11827 case Intrinsic::riscv_sseg2_store_mask:
11828 case Intrinsic::riscv_sseg3_store_mask:
11829 case Intrinsic::riscv_sseg4_store_mask:
11830 case Intrinsic::riscv_sseg5_store_mask:
11831 case Intrinsic::riscv_sseg6_store_mask:
11832 case Intrinsic::riscv_sseg7_store_mask:
11833 case Intrinsic::riscv_sseg8_store_mask:
11836 case Intrinsic::riscv_sf_vc_xv_se:
11838 case Intrinsic::riscv_sf_vc_iv_se:
11840 case Intrinsic::riscv_sf_vc_vv_se:
11842 case Intrinsic::riscv_sf_vc_fv_se:
11844 case Intrinsic::riscv_sf_vc_xvv_se:
11846 case Intrinsic::riscv_sf_vc_ivv_se:
11848 case Intrinsic::riscv_sf_vc_vvv_se:
11850 case Intrinsic::riscv_sf_vc_fvv_se:
11852 case Intrinsic::riscv_sf_vc_xvw_se:
11854 case Intrinsic::riscv_sf_vc_ivw_se:
11856 case Intrinsic::riscv_sf_vc_vvw_se:
11858 case Intrinsic::riscv_sf_vc_fvw_se:
11866 switch (ISDOpcode) {
11869 case ISD::VP_REDUCE_ADD:
11871 return RISCVISD::VECREDUCE_ADD_VL;
11872 case ISD::VP_REDUCE_UMAX:
11874 return RISCVISD::VECREDUCE_UMAX_VL;
11875 case ISD::VP_REDUCE_SMAX:
11877 return RISCVISD::VECREDUCE_SMAX_VL;
11878 case ISD::VP_REDUCE_UMIN:
11880 return RISCVISD::VECREDUCE_UMIN_VL;
11881 case ISD::VP_REDUCE_SMIN:
11883 return RISCVISD::VECREDUCE_SMIN_VL;
11884 case ISD::VP_REDUCE_AND:
11886 return RISCVISD::VECREDUCE_AND_VL;
11887 case ISD::VP_REDUCE_OR:
11889 return RISCVISD::VECREDUCE_OR_VL;
11890 case ISD::VP_REDUCE_XOR:
11892 return RISCVISD::VECREDUCE_XOR_VL;
11893 case ISD::VP_REDUCE_FADD:
11894 return RISCVISD::VECREDUCE_FADD_VL;
11895 case ISD::VP_REDUCE_SEQ_FADD:
11896 return RISCVISD::VECREDUCE_SEQ_FADD_VL;
11897 case ISD::VP_REDUCE_FMAX:
11898 case ISD::VP_REDUCE_FMAXIMUM:
11899 return RISCVISD::VECREDUCE_FMAX_VL;
11900 case ISD::VP_REDUCE_FMIN:
11901 case ISD::VP_REDUCE_FMINIMUM:
11902 return RISCVISD::VECREDUCE_FMIN_VL;
11911 SDValue Vec =
Op.getOperand(IsVP ? 1 : 0);
11916 Op.getOpcode() == ISD::VP_REDUCE_AND ||
11917 Op.getOpcode() == ISD::VP_REDUCE_OR ||
11918 Op.getOpcode() == ISD::VP_REDUCE_XOR) &&
11919 "Unexpected reduction lowering");
11921 MVT XLenVT = Subtarget.getXLenVT();
11923 MVT ContainerVT = VecVT;
11931 Mask =
Op.getOperand(2);
11932 VL =
Op.getOperand(3);
11934 std::tie(Mask, VL) =
11939 switch (
Op.getOpcode()) {
11943 case ISD::VP_REDUCE_AND: {
11947 Vec = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Vec, TrueMask, VL);
11950 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
11955 case ISD::VP_REDUCE_OR:
11957 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
11961 case ISD::VP_REDUCE_XOR: {
11964 Vec = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Vec, Mask, VL);
11985 return DAG.
getNode(BaseOpc,
DL,
Op.getValueType(), SetCC,
Op.getOperand(0));
11991 return (RegisterAVL && RegisterAVL->getReg() == RISCV::X0) ||
11992 (ImmAVL && ImmAVL->getZExtValue() >= 1);
12008 auto InnerVT = VecVT.
bitsLE(M1VT) ? VecVT : M1VT;
12012 auto InnerVL = NonZeroAVL ? VL : DAG.
getConstant(1,
DL, XLenVT);
12015 if (M1VT != InnerVT)
12020 SDValue Ops[] = {PassThru, Vec, InitialValue, Mask, VL, Policy};
12038 VecEVT =
Lo.getValueType();
12051 MVT ContainerVT = VecVT;
12070 Mask, VL,
DL, DAG, Subtarget);
12076static std::tuple<unsigned, SDValue, SDValue>
12080 auto Flags =
Op->getFlags();
12081 unsigned Opcode =
Op.getOpcode();
12089 return std::make_tuple(RISCVISD::VECREDUCE_FADD_VL,
Op.getOperand(0), Zero);
12092 return std::make_tuple(RISCVISD::VECREDUCE_SEQ_FADD_VL,
Op.getOperand(1),
12101 ? RISCVISD::VECREDUCE_FMIN_VL
12102 : RISCVISD::VECREDUCE_FMAX_VL;
12103 return std::make_tuple(RVVOpc,
Op.getOperand(0), Front);
12111 MVT VecEltVT =
Op.getSimpleValueType();
12113 unsigned RVVOpcode;
12114 SDValue VectorVal, ScalarVal;
12115 std::tie(RVVOpcode, VectorVal, ScalarVal) =
12119 MVT ContainerVT = VecVT;
12125 MVT ResVT =
Op.getSimpleValueType();
12128 VL,
DL, DAG, Subtarget);
12133 if (
Op->getFlags().hasNoNaNs())
12139 {VectorVal, VectorVal, DAG.getCondCode(ISD::SETNE),
12140 DAG.getUNDEF(Mask.getValueType()), Mask, VL});
12141 MVT XLenVT = Subtarget.getXLenVT();
12142 SDValue CPop = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, IsNan, Mask, VL);
12146 DL, ResVT, NoNaNs, Res,
12153 unsigned Opc =
Op.getOpcode();
12157 MVT XLenVT = Subtarget.getXLenVT();
12176 Vec, Mask, VL,
DL, DAG, Subtarget);
12177 if ((
Opc != ISD::VP_REDUCE_FMINIMUM &&
Opc != ISD::VP_REDUCE_FMAXIMUM) ||
12178 Op->getFlags().hasNoNaNs())
12185 RISCVISD::SETCC_VL,
DL, PredVT,
12187 SDValue VCPop = DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, IsNaN, Mask, VL);
12195 DL, ResVT, NoNaNs, Res,
12207 MVT XLenVT = Subtarget.getXLenVT();
12208 unsigned OrigIdx =
Op.getConstantOperandVal(2);
12209 const RISCVRegisterInfo *
TRI = Subtarget.getRegisterInfo();
12211 if (OrigIdx == 0 && Vec.
isUndef())
12222 assert(OrigIdx % 8 == 0 &&
"Invalid index");
12225 "Unexpected mask vector lowering");
12255 const auto VLen = Subtarget.getRealVLen();
12257 MVT ContainerVT = VecVT;
12279 if (OrigIdx == 0) {
12281 DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, ContainerVT, Vec, SubVec, VL);
12284 SubVec =
getVSlideup(DAG, Subtarget,
DL, ContainerVT, Vec, SubVec,
12285 SlideupAmt, Mask, VL, Policy);
12293 MVT ContainerVecVT = VecVT;
12299 MVT ContainerSubVecVT = SubVecVT;
12305 unsigned SubRegIdx;
12306 ElementCount RemIdx;
12315 ContainerVecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
12316 SubRegIdx = Decompose.first;
12318 (OrigIdx % Vscale));
12322 ContainerVecVT, ContainerSubVecVT, OrigIdx,
TRI);
12323 SubRegIdx = Decompose.first;
12329 Subtarget.expandVScale(SubVecVT.
getSizeInBits()).getKnownMinValue()));
12330 bool ExactlyVecRegSized =
12332 .isKnownMultipleOf(Subtarget.expandVScale(VecRegSize));
12347 if (RemIdx.
isZero() && (ExactlyVecRegSized || Vec.
isUndef())) {
12351 if (SubRegIdx == RISCV::NoSubRegister) {
12373 MVT InterSubVT = ContainerVecVT;
12374 SDValue AlignedExtract = Vec;
12396 if (Subtarget.expandVScale(EndIndex) ==
12403 SubVec = DAG.
getNode(RISCVISD::VMV_V_V_VL,
DL, InterSubVT, AlignedExtract,
12411 SubVec =
getVSlideup(DAG, Subtarget,
DL, InterSubVT, AlignedExtract, SubVec,
12412 SlideupAmt, Mask, VL, Policy);
12417 if (ContainerVecVT.
bitsGT(InterSubVT))
12425 return DAG.
getBitcast(
Op.getSimpleValueType(), SubVec);
12431 MVT SubVecVT =
Op.getSimpleValueType();
12435 MVT XLenVT = Subtarget.getXLenVT();
12436 unsigned OrigIdx =
Op.getConstantOperandVal(1);
12437 const RISCVRegisterInfo *
TRI = Subtarget.getRegisterInfo();
12452 assert(OrigIdx % 8 == 0 &&
"Invalid index");
12455 "Unexpected mask vector lowering");
12481 const auto VLen = Subtarget.getRealVLen();
12489 MVT ContainerVT = VecVT;
12497 if (
auto ShrunkVT =
12499 ContainerVT = *ShrunkVT;
12511 DAG.
getUNDEF(ContainerVT), Vec, SlidedownAmt, Mask, VL);
12522 MVT ContainerSubVecVT = SubVecVT;
12526 unsigned SubRegIdx;
12527 ElementCount RemIdx;
12536 VecVT, ContainerSubVecVT, OrigIdx / Vscale,
TRI);
12537 SubRegIdx = Decompose.first;
12539 (OrigIdx % Vscale));
12543 VecVT, ContainerSubVecVT, OrigIdx,
TRI);
12544 SubRegIdx = Decompose.first;
12571 MVT InterSubVT = VecVT;
12576 assert(SubRegIdx != RISCV::NoSubRegister);
12595 Vec, SlidedownAmt, Mask, VL);
12603 return DAG.
getBitcast(
Op.getSimpleValueType(), Slidedown);
12610 MVT VT =
N.getSimpleValueType();
12614 assert(
Op.getSimpleValueType() == VT &&
12615 "Operands and result must be same type");
12619 unsigned NumVals =
N->getNumValues();
12623 N.getValueType().changeVectorElementType(*DAG.
getContext(), MVT::i8)));
12626 for (
unsigned I = 0;
I < NumVals;
I++) {
12632 if (TruncVals.
size() > 1)
12634 return TruncVals.
front();
12640 MVT VecVT =
Op.getSimpleValueType();
12642 const unsigned Factor =
Op->getNumValues();
12653 for (
unsigned i = 0U; i < Factor; ++i)
12662 for (
unsigned i = 0U; i < Factor; ++i)
12672 for (
unsigned i = 0; i != Factor; ++i) {
12675 Ops[i * 2 + 1] = OpHi;
12686 for (
unsigned i = 0; i != Factor; ++i)
12693 if (Subtarget.hasVendorXRivosVizip() && Factor == 2) {
12694 MVT VT =
Op->getSimpleValueType(0);
12719 lowerVZIP(RISCVISD::RI_VUNZIP2A_VL, V1, V2,
DL, DAG, Subtarget);
12721 lowerVZIP(RISCVISD::RI_VUNZIP2B_VL, V1, V2,
DL, DAG, Subtarget);
12754 EvenSplat = DAG.
getBitcast(MVT::nxv64i1, EvenSplat);
12758 OddSplat = DAG.
getBitcast(MVT::nxv64i1, OddSplat);
12763 EvenMask, DAG.
getUNDEF(ConcatVT));
12775 MVT XLenVT = Subtarget.getXLenVT();
12797 Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
12798 Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
12799 Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
12800 Intrinsic::riscv_vlseg8_mask};
12824 for (
unsigned i = 0U; i < Factor; ++i)
12825 Res[i] = DAG.
getNode(RISCVISD::TUPLE_EXTRACT,
DL, VecVT, Load,
12834 MVT VecVT =
Op.getSimpleValueType();
12847 for (
unsigned i = 0U; i < Factor; ++i)
12855 for (
unsigned i = 0U; i < Factor; ++i)
12861 MVT XLenVT = Subtarget.getXLenVT();
12868 for (
unsigned i = 0; i != Factor; ++i) {
12871 Ops[i + Factor] = OpHi;
12882 for (
unsigned i = 0; i != Factor; ++i) {
12883 unsigned IdxLo = 2 * i;
12884 unsigned IdxHi = 2 * i + 1;
12886 Res[IdxLo / Factor].getValue(IdxLo % Factor),
12887 Res[IdxHi / Factor].getValue(IdxHi % Factor));
12905 EVT PtrVT =
StackPtr.getValueType();
12911 Intrinsic::riscv_vsseg2_mask, Intrinsic::riscv_vsseg3_mask,
12912 Intrinsic::riscv_vsseg4_mask, Intrinsic::riscv_vsseg5_mask,
12913 Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
12914 Intrinsic::riscv_vsseg8_mask,
12922 for (
unsigned i = 0; i < Factor; i++)
12924 DAG.
getNode(RISCVISD::TUPLE_INSERT,
DL, VecTupTy, StoredVal,
12944 for (
unsigned i = 0; i != Factor; ++i) {
12948 Loads[i] = DAG.
getLoad(VecVT,
DL, Chain, StackPtr, PtrInfo);
12956 if (Subtarget.hasVendorXRivosVizip() && !
Op.getOperand(0).isUndef() &&
12957 !
Op.getOperand(1).isUndef()) {
12977 Op.getOperand(0),
Op.getOperand(1));
13001 DAG.
getNode(RISCVISD::ADD_VL,
DL, IdxVT, Idx, VLMax, Idx, OddMask, VL);
13006 Interleaved = DAG.
getNode(RISCVISD::VRGATHEREI16_VV_VL,
DL, ConcatVT,
13023 MVT VT =
Op.getSimpleValueType();
13025 MVT XLenVT = Subtarget.getXLenVT();
13028 uint64_t StepValImm =
Op.getConstantOperandVal(0);
13029 if (StepValImm != 1) {
13038 VL, VT,
DL, DAG, Subtarget);
13053 MVT VecVT =
Op.getSimpleValueType();
13062 MVT ContainerVT = VecVT;
13069 MVT XLenVT = Subtarget.getXLenVT();
13115 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
13116 unsigned MaxVLMAX =
13121 unsigned GatherOpc = RISCVISD::VRGATHER_VV_VL;
13126 if (MaxVLMAX > 256 && EltSize == 8) {
13142 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
13150 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
13175 DAG.
getUNDEF(ContainerVT), Mask, VL);
13187 MVT XLenVT = Subtarget.getXLenVT();
13188 MVT VecVT =
Op.getSimpleValueType();
13192 SDValue DownOffset, UpOffset;
13208 DAG, Subtarget,
DL, VecVT, DAG.
getUNDEF(VecVT), V1, DownOffset, TrueMask,
13209 Subtarget.hasVLDependentLatency() ? UpOffset
13211 return getVSlideup(DAG, Subtarget,
DL, VecVT, SlideDown, V2, UpOffset,
13217RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(
SDValue Op,
13223 Load->getMemoryVT(),
13224 *
Load->getMemOperand()) &&
13225 "Expecting a correctly-aligned load");
13227 MVT VT =
Op.getSimpleValueType();
13228 MVT XLenVT = Subtarget.getXLenVT();
13233 const auto [MinVLMAX, MaxVLMAX] =
13237 MachineMemOperand *MMO =
Load->getMemOperand();
13250 IsMaskOp ? Intrinsic::riscv_vlm : Intrinsic::riscv_vle,
DL, XLenVT);
13254 Ops.push_back(
Load->getBasePtr());
13256 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
13259 Load->getMemoryVT(),
Load->getMemOperand());
13266RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(
SDValue Op,
13272 Store->getMemoryVT(),
13273 *
Store->getMemOperand()) &&
13274 "Expecting a correctly-aligned store");
13278 MVT XLenVT = Subtarget.getXLenVT();
13294 const auto [MinVLMAX, MaxVLMAX] =
13298 MachineMemOperand *MMO =
Store->getMemOperand();
13308 IsMaskOp ? Intrinsic::riscv_vsm : Intrinsic::riscv_vse,
DL, XLenVT);
13311 {Store->getChain(), IntID, NewValue, Store->getBasePtr(), VL},
13312 Store->getMemoryVT(),
Store->getMemOperand());
13318 MVT VT =
Op.getSimpleValueType();
13321 EVT MemVT = MemSD->getMemoryVT();
13322 MachineMemOperand *MMO = MemSD->getMemOperand();
13323 SDValue Chain = MemSD->getChain();
13327 bool IsExpandingLoad =
false;
13329 Mask = VPLoad->getMask();
13331 VL = VPLoad->getVectorLength();
13335 PassThru =
MLoad->getPassThru();
13336 IsExpandingLoad =
MLoad->isExpandingLoad();
13341 MVT XLenVT = Subtarget.getXLenVT();
13343 MVT ContainerVT = VT;
13357 if (!IsUnmasked && IsExpandingLoad) {
13360 DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Mask,
13364 unsigned IntID = IsUnmasked || IsExpandingLoad ? Intrinsic::riscv_vle
13365 : Intrinsic::riscv_vle_mask;
13367 if (IntID == Intrinsic::riscv_vle)
13370 Ops.push_back(PassThru);
13371 Ops.push_back(BasePtr);
13372 if (IntID == Intrinsic::riscv_vle_mask)
13373 Ops.push_back(Mask);
13375 if (IntID == Intrinsic::riscv_vle_mask)
13378 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
13382 Chain =
Result.getValue(1);
13384 MVT IndexVT = ContainerVT;
13389 bool UseVRGATHEREI16 =
false;
13397 UseVRGATHEREI16 =
true;
13403 DAG.
getUNDEF(IndexVT), Mask, ExpandingVL);
13405 DAG.
getNode(UseVRGATHEREI16 ? RISCVISD::VRGATHEREI16_VV_VL
13406 : RISCVISD::VRGATHER_VV_VL,
13407 DL, ContainerVT, Result, Iota, PassThru, Mask, ExpandingVL);
13418 MVT VT =
Op->getSimpleValueType(0);
13421 EVT MemVT = VPLoadFF->getMemoryVT();
13422 MachineMemOperand *MMO = VPLoadFF->getMemOperand();
13423 SDValue Chain = VPLoadFF->getChain();
13427 SDValue VL = VPLoadFF->getVectorLength();
13429 MVT XLenVT = Subtarget.getXLenVT();
13431 MVT ContainerVT = VT;
13438 unsigned IntID = Intrinsic::riscv_vleff_mask;
13448 SDVTList VTs = DAG.
getVTList({ContainerVT,
Op->getValueType(1), MVT::Other});
13453 Chain =
Result.getValue(2);
13466 EVT MemVT = MemSD->getMemoryVT();
13467 MachineMemOperand *MMO = MemSD->getMemOperand();
13468 SDValue Chain = MemSD->getChain();
13472 bool IsCompressingStore =
false;
13474 Val = VPStore->getValue();
13475 Mask = VPStore->getMask();
13476 VL = VPStore->getVectorLength();
13479 Val = MStore->getValue();
13480 Mask = MStore->getMask();
13481 IsCompressingStore = MStore->isCompressingStore();
13488 MVT XLenVT = Subtarget.getXLenVT();
13490 MVT ContainerVT = VT;
13495 if (!IsUnmasked || IsCompressingStore) {
13504 if (IsCompressingStore) {
13508 DAG.
getUNDEF(ContainerVT), Val, Mask, VL);
13510 DAG.
getNode(RISCVISD::VCPOP_VL,
DL, XLenVT, Mask,
13515 IsUnmasked ? Intrinsic::riscv_vse : Intrinsic::riscv_vse_mask;
13517 Ops.push_back(Val);
13518 Ops.push_back(BasePtr);
13520 Ops.push_back(Mask);
13535 MVT XLenVT = Subtarget.getXLenVT();
13536 MVT ContainerVT = VT;
13549 Passthru, Val, Mask, VL);
13559 unsigned Opc =
Op.getOpcode();
13566 MVT VT =
Op.getSimpleValueType();
13574 SDVTList VTList =
Op->getVTList();
13599 MVT ContainerInVT = InVT;
13617 RISCVISD::STRICT_FSETCC_VL,
DL, DAG.
getVTList(MaskVT, MVT::Other),
13618 {Chain, Op1, Op1, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
13621 RISCVISD::STRICT_FSETCC_VL,
DL, DAG.
getVTList(MaskVT, MVT::Other),
13622 {Chain, Op2, Op2, DAG.getCondCode(ISD::SETOEQ), DAG.getUNDEF(MaskVT),
13625 DAG.
getNode(RISCVISD::VMAND_VL,
DL, MaskVT, OrderMask1, OrderMask2, VL);
13628 Res = DAG.
getNode(RISCVISD::STRICT_FSETCCS_VL,
DL,
13630 {Chain, Op1, Op2, CC, Mask, Mask, VL});
13633 : RISCVISD::STRICT_FSETCCS_VL;
13635 {Chain, Op1, Op2, CC, DAG.getUNDEF(MaskVT), Mask, VL});
13648 MVT VT =
Op.getSimpleValueType();
13652 "Unexpected type for ISD::ABS");
13654 MVT ContainerVT = VT;
13661 if (
Op->getOpcode() == ISD::VP_ABS) {
13662 Mask =
Op->getOperand(1);
13666 VL =
Op->getOperand(2);
13671 RISCVISD::VMV_V_X_VL,
DL, ContainerVT, DAG.
getUNDEF(ContainerVT),
13674 DAG.
getUNDEF(ContainerVT), Mask, VL);
13676 DAG.
getUNDEF(ContainerVT), Mask, VL);
13685 const auto &TSInfo =
13689 bool HasPassthruOp = TSInfo.hasPassthruOp(NewOpc);
13690 bool HasMask = TSInfo.hasMaskOp(NewOpc);
13692 MVT VT =
Op.getSimpleValueType();
13697 for (
const SDValue &V :
Op->op_values()) {
13701 if (!
V.getValueType().isVector()) {
13707 assert(useRVVForFixedLengthVectorVT(
V.getSimpleValueType()) &&
13708 "Only fixed length vectors are supported!");
13710 V.getSimpleValueType().getVectorElementType());
13719 Ops.push_back(Mask);
13724 if (
Op->isStrictFPOpcode()) {
13743 const auto &TSInfo =
13747 bool HasPassthruOp = TSInfo.hasPassthruOp(RISCVISDOpc);
13750 MVT VT =
Op.getSimpleValueType();
13753 MVT ContainerVT = VT;
13762 if (HasPassthruOp) {
13765 if (*MaskIdx ==
OpIdx.index())
13769 if (
Op.getOpcode() == ISD::VP_MERGE) {
13771 Ops.push_back(
Ops.back());
13773 assert(
Op.getOpcode() == ISD::VP_SELECT);
13780 if (RISCVISDOpc == RISCVISD::VFCVT_RM_X_F_VL &&
13783 Subtarget.getXLenVT()));
13785 if (!
V.getValueType().isFixedLengthVector()) {
13790 MVT OpVT =
V.getSimpleValueType();
13792 assert(useRVVForFixedLengthVectorVT(OpVT) &&
13793 "Only fixed length vectors are supported!");
13808 MVT VT =
Op.getSimpleValueType();
13814 MVT ContainerVT = VT;
13821 MVT XLenVT = Subtarget.getXLenVT();
13824 DAG.
getUNDEF(ContainerVT), Zero, VL);
13827 Op.getOpcode() == ISD::VP_ZERO_EXTEND ? 1 : -1,
DL, XLenVT);
13829 DAG.
getUNDEF(ContainerVT), SplatValue, VL);
13832 ZeroSplat, DAG.
getUNDEF(ContainerVT), VL);
13841 MVT VT =
Op.getSimpleValueType();
13849 MVT ContainerVT = VT;
13857 SDValue AllOneMask = DAG.
getNode(RISCVISD::VMSET_VL,
DL, ContainerVT, VL);
13859 switch (Condition) {
13864 Result = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op1, Op2, VL);
13869 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op1, Op2, VL);
13871 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Temp, AllOneMask, VL);
13879 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op1, AllOneMask, VL);
13880 Result = DAG.
getNode(RISCVISD::VMAND_VL,
DL, ContainerVT, Temp, Op2, VL);
13888 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op2, AllOneMask, VL);
13889 Result = DAG.
getNode(RISCVISD::VMAND_VL,
DL, ContainerVT, Op1, Temp, VL);
13897 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op1, AllOneMask, VL);
13898 Result = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Temp, Op2, VL);
13906 DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Op2, AllOneMask, VL);
13907 Result = DAG.
getNode(RISCVISD::VMXOR_VL,
DL, ContainerVT, Temp, Op1, VL);
13927 MVT DstVT =
Op.getSimpleValueType();
13928 MVT SrcVT = Src.getSimpleValueType();
13941 if (DstEltSize >= SrcEltSize) {
13945 unsigned RISCVISDExtOpc = RISCVISDOpc == RISCVISD::SINT_TO_FP_VL
13946 ? RISCVISD::VSEXT_VL
13947 : RISCVISD::VZEXT_VL;
13950 if (SrcEltSize == 1) {
13952 MVT XLenVT = Subtarget.getXLenVT();
13957 RISCVISDExtOpc == RISCVISD::VZEXT_VL ? 1 : -1,
DL, XLenVT);
13960 Src = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, IntVT, Src, OneSplat,
13961 ZeroSplat, DAG.
getUNDEF(IntVT), VL);
13962 }
else if (DstEltSize > (2 * SrcEltSize)) {
13966 Src = DAG.
getNode(RISCVISDExtOpc,
DL, IntVT, Src, Mask, VL);
13972 "Wrong input/output vector types");
13975 if (DstEltSize > (2 * SrcEltSize)) {
13980 DAG.
getNode(RISCVISD::FP_EXTEND_VL,
DL, InterimFVT, Src, Mask, VL);
13991 MVT InterimFVT = DstVT;
13992 if (SrcEltSize > (2 * DstEltSize)) {
13993 assert(SrcEltSize == (4 * DstEltSize) &&
"Unexpected types!");
14000 if (InterimFVT != DstVT) {
14002 Result = DAG.
getNode(RISCVISD::FP_ROUND_VL,
DL, DstVT, Src, Mask, VL);
14006 "Wrong input/output vector types");
14010 if (DstEltSize == 1) {
14013 assert(SrcEltSize >= 16 &&
"Unexpected FP type!");
14020 MVT XLenVT = Subtarget.getXLenVT();
14022 SplatZero = DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, InterimIVT,
14023 DAG.
getUNDEF(InterimIVT), SplatZero, VL);
14033 while (InterimIVT != DstVT) {
14045 MVT VT =
Op.getSimpleValueType();
14054 MVT VT =
Op.getSimpleValueType();
14055 MVT XLenVT = Subtarget.getXLenVT();
14068 MVT ContainerVT = VT;
14088 TrueVal = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, PromotedVT, TrueVal, SplatOne,
14089 SplatZero, DAG.
getUNDEF(PromotedVT), VL);
14092 SplatOne, SplatZero, DAG.
getUNDEF(PromotedVT), VLMax);
14096 TrueVal, FalseVal, FalseVal, VL);
14101 RISCVISD::SETCC_VL,
DL, ContainerVT,
14111RISCVTargetLowering::lowerVPSpliceExperimental(
SDValue Op,
14113 using namespace SDPatternMatch;
14124 const MVT XLenVT = Subtarget.getXLenVT();
14125 MVT VT =
Op.getSimpleValueType();
14126 MVT ContainerVT = VT;
14136 if (IsMaskVector) {
14146 Op1 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, Op1, SplatOneOp1,
14147 SplatZeroOp1, DAG.
getUNDEF(ContainerVT), EVL1);
14155 Op2 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, ContainerVT, Op2, SplatOneOp2,
14156 SplatZeroOp2, DAG.
getUNDEF(ContainerVT), EVL2);
14159 auto getVectorFirstEle = [](
SDValue Vec) {
14172 if (
auto FirstEle = getVectorFirstEle(
Op->getOperand(0))) {
14175 if ((EltVT == MVT::f16 && !Subtarget.hasVInstructionsF16()) ||
14176 EltVT == MVT::bf16) {
14184 : RISCVISD::VSLIDE1UP_VL,
14185 DL, ContainerVT, DAG.
getUNDEF(ContainerVT), Op2,
14186 FirstEle, Mask, EVL2);
14196 SDValue DownOffset, UpOffset;
14197 if (ImmValue >= 0) {
14211 DAG.
getUNDEF(ContainerVT), Op1, DownOffset, Mask,
14212 Subtarget.hasVLDependentLatency() ? UpOffset : EVL2);
14216 if (IsMaskVector) {
14220 {Result, DAG.getConstant(0, DL, ContainerVT),
14221 DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(getMaskTypeFor(ContainerVT)),
14231RISCVTargetLowering::lowerVPReverseExperimental(
SDValue Op,
14234 MVT VT =
Op.getSimpleValueType();
14235 MVT XLenVT = Subtarget.getXLenVT();
14241 MVT ContainerVT = VT;
14249 MVT GatherVT = ContainerVT;
14253 if (IsMaskVector) {
14263 Op1 = DAG.
getNode(RISCVISD::VMERGE_VL,
DL, IndicesVT, Op1, SplatOne,
14264 SplatZero, DAG.
getUNDEF(IndicesVT), EVL);
14269 unsigned VectorBitsMax = Subtarget.getRealMaxVLen();
14270 unsigned MaxVLMAX =
14273 unsigned GatherOpc = RISCVISD::VRGATHER_VV_VL;
14279 if (MaxVLMAX > 256 && EltSize == 8) {
14306 DAG.
getUNDEF(GatherVT), Result, Diff, Mask, EVL);
14308 if (IsMaskVector) {
14311 DAG.
getNode(RISCVISD::SETCC_VL,
DL, ContainerVT,
14324 GatherOpc = RISCVISD::VRGATHEREI16_VV_VL;
14331 DAG.
getUNDEF(IndicesVT), VecLen, EVL);
14332 SDValue VRSUB = DAG.
getNode(RISCVISD::SUB_VL,
DL, IndicesVT, VecLenSplat, VID,
14333 DAG.
getUNDEF(IndicesVT), Mask, EVL);
14335 DAG.
getUNDEF(GatherVT), Mask, EVL);
14337 if (IsMaskVector) {
14340 RISCVISD::SETCC_VL,
DL, ContainerVT,
14352 MVT VT =
Op.getSimpleValueType();
14354 return lowerVPOp(
Op, DAG);
14361 MVT ContainerVT = VT;
14379 MVT XLenVT = Subtarget.getXLenVT();
14380 MVT VT =
Op.getSimpleValueType();
14381 MVT ContainerVT = VT;
14385 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
14393 : Intrinsic::riscv_vlse_mask,
14396 DAG.
getUNDEF(ContainerVT), VPNode->getBasePtr(),
14397 VPNode->getStride()};
14403 Ops.push_back(Mask);
14405 Ops.push_back(VPNode->getVectorLength());
14409 Ops.push_back(Policy);
14414 VPNode->getMemoryVT(), VPNode->getMemOperand());
14426 MVT XLenVT = Subtarget.getXLenVT();
14429 SDValue StoreVal = VPNode->getValue();
14431 MVT ContainerVT = VT;
14442 : Intrinsic::riscv_vsse_mask,
14445 VPNode->getBasePtr(), VPNode->getStride()};
14451 Ops.push_back(Mask);
14453 Ops.push_back(VPNode->getVectorLength());
14456 Ops, VPNode->getMemoryVT(),
14457 VPNode->getMemOperand());
14469 MVT VT =
Op.getSimpleValueType();
14472 EVT MemVT = MemSD->getMemoryVT();
14473 MachineMemOperand *MMO = MemSD->getMemOperand();
14474 SDValue Chain = MemSD->getChain();
14481 Index = VPGN->getIndex();
14482 Mask = VPGN->getMask();
14484 VL = VPGN->getVectorLength();
14490 Index = MGN->getIndex();
14491 Mask = MGN->getMask();
14492 PassThru = MGN->getPassThru();
14496 MVT IndexVT =
Index.getSimpleValueType();
14497 MVT XLenVT = Subtarget.getXLenVT();
14500 "Unexpected VTs!");
14501 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
14504 "Unexpected extending MGATHER/VP_GATHER");
14510 MVT ContainerVT = VT;
14534 IsUnmasked ? Intrinsic::riscv_vluxei : Intrinsic::riscv_vluxei_mask;
14539 Ops.push_back(PassThru);
14540 Ops.push_back(BasePtr);
14541 Ops.push_back(Index);
14543 Ops.push_back(Mask);
14548 SDVTList VTs = DAG.
getVTList({ContainerVT, MVT::Other});
14551 Chain =
Result.getValue(1);
14569 EVT MemVT = MemSD->getMemoryVT();
14570 MachineMemOperand *MMO = MemSD->getMemOperand();
14571 SDValue Chain = MemSD->getChain();
14574 [[maybe_unused]]
bool IsTruncatingStore =
false;
14578 Index = VPSN->getIndex();
14579 Mask = VPSN->getMask();
14580 Val = VPSN->getValue();
14581 VL = VPSN->getVectorLength();
14583 IsTruncatingStore =
false;
14587 Index = MSN->getIndex();
14588 Mask = MSN->getMask();
14589 Val = MSN->getValue();
14590 IsTruncatingStore = MSN->isTruncatingStore();
14594 MVT IndexVT =
Index.getSimpleValueType();
14595 MVT XLenVT = Subtarget.getXLenVT();
14598 "Unexpected VTs!");
14599 assert(
BasePtr.getSimpleValueType() == XLenVT &&
"Unexpected pointer type");
14602 assert(!IsTruncatingStore &&
"Unexpected truncating MSCATTER/VP_SCATTER");
14608 MVT ContainerVT = VT;
14632 IsUnmasked ? Intrinsic::riscv_vsoxei : Intrinsic::riscv_vsoxei_mask;
14634 Ops.push_back(Val);
14635 Ops.push_back(BasePtr);
14636 Ops.push_back(Index);
14638 Ops.push_back(Mask);
14647 const MVT XLenVT = Subtarget.getXLenVT();
14651 SDVTList VTs = DAG.
getVTList(XLenVT, MVT::Other);
14658 static const int Table =
14677 const MVT XLenVT = Subtarget.getXLenVT();
14687 static const unsigned Table =
14702 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
14708 const MVT XLenVT = Subtarget.getXLenVT();
14712 SDVTList VTs = DAG.
getVTList(XLenVT, MVT::Other);
14713 return DAG.
getNode(RISCVISD::READ_CSR,
DL, VTs, Chain, SysRegNo);
14718 const MVT XLenVT = Subtarget.getXLenVT();
14725 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
14731 const MVT XLenVT = Subtarget.getXLenVT();
14737 return DAG.
getNode(RISCVISD::WRITE_CSR,
DL, MVT::Other, Chain, SysRegNo,
14751 SDValue Result = DAG.
getNode(RISCVISD::READ_CSR,
DL, VTs, Chain, SysRegNo);
14752 Chain = Result.getValue(1);
14758 const MVT XLenVT = Subtarget.getXLenVT();
14768 Chain = DAG.
getNode(RISCVISD::CLEAR_CSR,
DL, MVT::Other, Chain, SysRegNo,
14770 return DAG.
getNode(RISCVISD::SET_CSR,
DL, MVT::Other, Chain, SysRegNo,
14776 const MVT XLenVT = Subtarget.getXLenVT();
14783 return DAG.
getNode(RISCVISD::CLEAR_CSR,
DL, MVT::Other, Chain, SysRegNo,
14791 bool isRISCV64 = Subtarget.is64Bit();
14805 return RISCVISD::SLLW;
14807 return RISCVISD::SRAW;
14809 return RISCVISD::SRLW;
14811 return RISCVISD::DIVW;
14813 return RISCVISD::DIVUW;
14815 return RISCVISD::REMUW;
14817 return RISCVISD::ROLW;
14819 return RISCVISD::RORW;
14855 switch (
N->getOpcode()) {
14857 llvm_unreachable(
"Don't know how to custom type legalize this operation!");
14862 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
14863 "Unexpected custom legalisation");
14864 bool IsStrict =
N->isStrictFPOpcode();
14867 SDValue Op0 = IsStrict ?
N->getOperand(1) :
N->getOperand(0);
14876 !Subtarget.hasStdExtZfhOrZhinx()) {
14881 unsigned Opc = IsSigned ? RISCVISD::STRICT_FCVT_W_RV64
14882 : RISCVISD::STRICT_FCVT_WU_RV64;
14885 Opc,
DL, VTs, Chain, Op0,
14894 !Subtarget.hasStdExtZfhOrZhinx()) ||
14898 unsigned Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
14919 std::tie(Result, Chain) =
14920 makeLibCall(DAG, LC,
N->getValueType(0), Op0, CallOptions,
DL, Chain);
14935 if (Op0.
getValueType() == MVT::f16 && !Subtarget.hasStdExtZfhOrZhinx())
14939 DAG.
getNode(RISCVISD::FCVT_W_RV64,
DL, MVT::i64, Op0,
14947 RTLIB::Libcall LC =
14948 Op0.
getValueType() == MVT::f64 ? RTLIB::LROUND_F64 : RTLIB::LROUND_F32;
14959 assert(!Subtarget.is64Bit() &&
"READCYCLECOUNTER/READSTEADYCOUNTER only "
14960 "has custom type legalization on riscv32");
14962 SDValue LoCounter, HiCounter;
14963 MVT XLenVT = Subtarget.getXLenVT();
14973 N->getOperand(0), LoCounter, HiCounter);
14988 if (
N->getValueType(0) == MVT::i64) {
14989 assert(Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit() &&
14990 "Unexpected custom legalisation");
14992 if (Ld->
getAlign() < Subtarget.getZilsdAlign())
14997 RISCVISD::LD_RV32,
DL,
14998 DAG.
getVTList({MVT::i32, MVT::i32, MVT::Other}),
14999 {Ld->getChain(), Ld->getBasePtr()}, MVT::i64, Ld->
getMemOperand());
15003 Results.append({Pair, Result.getValue(2)});
15007 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15008 "Unexpected custom legalisation");
15019 unsigned Size =
N->getSimpleValueType(0).getSizeInBits();
15020 unsigned XLen = Subtarget.getXLen();
15023 assert(
Size == (XLen * 2) &&
"Unexpected custom legalisation");
15031 if (LHSIsU == RHSIsU)
15035 MVT XLenVT = Subtarget.getXLenVT();
15048 if (RHSIsU && LHSIsS && !RHSIsS)
15049 Results.push_back(MakeMULPair(LHS, RHS));
15050 else if (LHSIsU && RHSIsS && !LHSIsS)
15051 Results.push_back(MakeMULPair(RHS, LHS));
15059 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15060 "Unexpected custom legalisation");
15066 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15067 "Unexpected custom legalisation");
15070 if (
N->getOpcode() ==
ISD::SHL && Subtarget.hasStdExtZbs() &&
15095 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15096 "Unexpected custom legalisation");
15097 assert((Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb() ||
15098 Subtarget.hasVendorXTHeadBb()) &&
15099 "Unexpected custom legalization");
15101 !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()))
15110 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15111 "Unexpected custom legalisation");
15116 switch (
N->getOpcode()) {
15120 Opc = RISCVISD::CTZW;
15124 Opc = RISCVISD::CLZW;
15127 Opc = RISCVISD::CLSW;
15138 MVT VT =
N->getSimpleValueType(0);
15139 assert((VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) &&
15140 Subtarget.is64Bit() && Subtarget.hasStdExtM() &&
15141 "Unexpected custom legalisation");
15153 if (VT != MVT::i32)
15162 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15163 "Unexpected custom legalisation");
15185 EVT OType =
N->getValueType(1);
15202 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15203 "Unexpected custom legalisation");
15220 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res,
15224 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1),
N->getOperand(0),
15231 Overflow = DAG.
getSetCC(
DL,
N->getValueType(1), Res, LHS,
15241 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15242 !Subtarget.hasStdExtZbb() &&
"Unexpected custom legalisation");
15250 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15251 "Unexpected custom legalisation");
15256 assert(
N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
15257 "Unexpected custom legalisation");
15259 if (Subtarget.hasStdExtP()) {
15267 if (Subtarget.hasStdExtZbb()) {
15301 EVT VT =
N->getValueType(0);
15305 MVT XLenVT = Subtarget.getXLenVT();
15306 if (VT == MVT::i16 &&
15307 ((Op0VT == MVT::f16 && Subtarget.hasStdExtZfhminOrZhinxmin()) ||
15308 (Op0VT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()))) {
15311 }
else if (VT == MVT::i32 && Op0VT == MVT::f32 && Subtarget.is64Bit() &&
15312 Subtarget.hasStdExtFOrZfinx()) {
15314 DAG.
getNode(RISCVISD::FMV_X_ANYEXTW_RV64,
DL, MVT::i64, Op0);
15316 }
else if (VT == MVT::i64 && Op0VT == MVT::f64 && !Subtarget.is64Bit() &&
15317 Subtarget.hasStdExtDOrZdinx()) {
15319 DAG.
getVTList(MVT::i32, MVT::i32), Op0);
15323 if (!Subtarget.isLittleEndian())
15342 assert(
N->getValueType(0) == MVT::i8 && Subtarget.hasStdExtZbkb() &&
15343 "Unexpected custom legalisation");
15344 MVT XLenVT = Subtarget.getXLenVT();
15352 case RISCVISD::BREV8:
15353 case RISCVISD::ORC_B: {
15354 MVT VT =
N->getSimpleValueType(0);
15355 MVT XLenVT = Subtarget.getXLenVT();
15356 assert((VT == MVT::i16 || (VT == MVT::i32 && Subtarget.is64Bit())) &&
15357 "Unexpected custom legalisation");
15358 assert(((
N->getOpcode() == RISCVISD::BREV8 && Subtarget.hasStdExtZbkb()) ||
15359 (
N->getOpcode() == RISCVISD::ORC_B && Subtarget.hasStdExtZbb())) &&
15360 "Unexpected extension");
15368 case RISCVISD::PASUB:
15369 case RISCVISD::PASUBU:
15370 case RISCVISD::PMULHSU:
15371 case RISCVISD::PMULHR:
15372 case RISCVISD::PMULHRU:
15373 case RISCVISD::PMULHRSU: {
15374 MVT VT =
N->getSimpleValueType(0);
15377 unsigned Opcode =
N->getOpcode();
15379 [[maybe_unused]]
bool IsMulH =
15380 Opcode == RISCVISD::PMULHSU || Opcode == RISCVISD::PMULHR ||
15381 Opcode == RISCVISD::PMULHRU || Opcode == RISCVISD::PMULHRSU;
15382 assert(VT == MVT::v2i16 || (!IsMulH && VT == MVT::v4i8));
15383 MVT NewVT = MVT::v4i16;
15384 if (VT == MVT::v4i8)
15410 assert(!Subtarget.is64Bit() &&
N->getValueType(0) == MVT::i64 &&
15412 "Unexpected EXTRACT_VECTOR_ELT legalization");
15415 MVT ContainerVT = VecVT;
15421 MVT XLenVT = Subtarget.getXLenVT();
15430 DAG.
getUNDEF(ContainerVT), Vec, Idx, Mask, VL);
15442 DAG.
getNode(RISCVISD::SRL_VL,
DL, ContainerVT, Vec, ThirtyTwoV,
15443 DAG.
getUNDEF(ContainerVT), Mask, VL);
15451 unsigned IntNo =
N->getConstantOperandVal(0);
15455 "Don't know how to custom type legalize this intrinsic!");
15456 case Intrinsic::experimental_get_vector_length: {
15461 case Intrinsic::experimental_cttz_elts: {
15466 case Intrinsic::riscv_orc_b:
15467 case Intrinsic::riscv_brev8:
15468 case Intrinsic::riscv_sha256sig0:
15469 case Intrinsic::riscv_sha256sig1:
15470 case Intrinsic::riscv_sha256sum0:
15471 case Intrinsic::riscv_sha256sum1:
15472 case Intrinsic::riscv_sm3p0:
15473 case Intrinsic::riscv_sm3p1: {
15474 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15478 case Intrinsic::riscv_orc_b:
Opc = RISCVISD::ORC_B;
break;
15479 case Intrinsic::riscv_brev8:
Opc = RISCVISD::BREV8;
break;
15480 case Intrinsic::riscv_sha256sig0:
Opc = RISCVISD::SHA256SIG0;
break;
15481 case Intrinsic::riscv_sha256sig1:
Opc = RISCVISD::SHA256SIG1;
break;
15482 case Intrinsic::riscv_sha256sum0:
Opc = RISCVISD::SHA256SUM0;
break;
15483 case Intrinsic::riscv_sha256sum1:
Opc = RISCVISD::SHA256SUM1;
break;
15484 case Intrinsic::riscv_sm3p0:
Opc = RISCVISD::SM3P0;
break;
15485 case Intrinsic::riscv_sm3p1:
Opc = RISCVISD::SM3P1;
break;
15494 case Intrinsic::riscv_sm4ks:
15495 case Intrinsic::riscv_sm4ed: {
15497 IntNo == Intrinsic::riscv_sm4ks ? RISCVISD::SM4KS : RISCVISD::SM4ED;
15503 DAG.
getNode(
Opc,
DL, MVT::i64, NewOp0, NewOp1,
N->getOperand(3));
15507 case Intrinsic::riscv_mopr: {
15508 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15513 RISCVISD::MOP_R,
DL, MVT::i64, NewOp,
15518 case Intrinsic::riscv_moprr: {
15519 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15526 RISCVISD::MOP_RR,
DL, MVT::i64, NewOp0, NewOp1,
15531 case Intrinsic::riscv_clmul: {
15532 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15543 case Intrinsic::riscv_clmulh:
15544 case Intrinsic::riscv_clmulr: {
15545 if (!Subtarget.is64Bit() ||
N->getValueType(0) != MVT::i32)
15565 unsigned Opc = IntNo == Intrinsic::riscv_clmulh ? RISCVISD::CLMULH
15566 : RISCVISD::CLMULR;
15573 case Intrinsic::riscv_vmv_x_s: {
15574 EVT VT =
N->getValueType(0);
15575 MVT XLenVT = Subtarget.getXLenVT();
15576 if (VT.
bitsLT(XLenVT)) {
15579 Subtarget.getXLenVT(),
N->getOperand(1));
15584 assert(VT == MVT::i64 && !Subtarget.is64Bit() &&
15585 "Unexpected custom legalization");
15601 SDValue LShr32 = DAG.
getNode(RISCVISD::SRL_VL,
DL, VecVT, Vec, ThirtyTwoV,
15623 case ISD::VP_REDUCE_ADD:
15624 case ISD::VP_REDUCE_AND:
15625 case ISD::VP_REDUCE_OR:
15626 case ISD::VP_REDUCE_XOR:
15627 case ISD::VP_REDUCE_SMAX:
15628 case ISD::VP_REDUCE_UMAX:
15629 case ISD::VP_REDUCE_SMIN:
15630 case ISD::VP_REDUCE_UMIN:
15698 const EVT VT =
N->getValueType(0);
15699 const unsigned Opc =
N->getOpcode();
15709 if (!
N->getFlags().hasAllowReassociation())
15720 "Inconsistent mappings");
15724 if (!
LHS.hasOneUse() || !
RHS.hasOneUse())
15752 if (0 == std::min(LHSIdx, RHSIdx) && 1 == std::max(LHSIdx, RHSIdx)) {
15755 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
N->getFlags());
15762 if (
LHS.getOpcode() != ReduceOpc)
15776 return DAG.
getNode(ReduceOpc,
DL, VT, Vec,
15777 ReduceVec->
getFlags() &
N->getFlags());
15787 auto BinOpToRVVReduce = [](
unsigned Opc) {
15792 return RISCVISD::VECREDUCE_ADD_VL;
15794 return RISCVISD::VECREDUCE_UMAX_VL;
15796 return RISCVISD::VECREDUCE_SMAX_VL;
15798 return RISCVISD::VECREDUCE_UMIN_VL;
15800 return RISCVISD::VECREDUCE_SMIN_VL;
15802 return RISCVISD::VECREDUCE_AND_VL;
15804 return RISCVISD::VECREDUCE_OR_VL;
15806 return RISCVISD::VECREDUCE_XOR_VL;
15808 return RISCVISD::VECREDUCE_FADD_VL;
15810 return RISCVISD::VECREDUCE_FMAX_VL;
15812 return RISCVISD::VECREDUCE_FMIN_VL;
15816 auto IsReduction = [&BinOpToRVVReduce](
SDValue V,
unsigned Opc) {
15819 V.getOperand(0).getOpcode() == BinOpToRVVReduce(
Opc);
15822 unsigned Opc =
N->getOpcode();
15823 unsigned ReduceIdx;
15824 if (IsReduction(
N->getOperand(0),
Opc))
15826 else if (IsReduction(
N->getOperand(1),
Opc))
15832 if (
Opc ==
ISD::FADD && !
N->getFlags().hasAllowReassociation())
15835 SDValue Extract =
N->getOperand(ReduceIdx);
15848 if (ScalarV.
getOpcode() != RISCVISD::VFMV_S_F_VL &&
15849 ScalarV.
getOpcode() != RISCVISD::VMV_S_X_VL &&
15850 ScalarV.
getOpcode() != RISCVISD::VMV_V_X_VL)
15867 SDValue NewStart =
N->getOperand(1 - ReduceIdx);
15900 EVT VT =
N->getValueType(0);
15916 int64_t C0 = N0C->getSExtValue();
15917 int64_t C1 = N1C->getSExtValue();
15918 if (C0 <= 0 || C1 <= 0)
15921 int64_t Diff = std::abs(C0 - C1);
15927 int64_t Bits = std::min(C0, C1);
15959 if (VShift.
slt(1) || VShift.
sgt(3))
15963 EVT VT =
N->getValueType(0);
15983 EVT VT =
N->getValueType(0);
16011 EVT VT =
N->getValueType(0);
16032 Slct.
getOpcode() != RISCVISD::SELECT_CC) ||
16040 bool SwapSelectOps;
16041 unsigned OpOffset = Slct.
getOpcode() == RISCVISD::SELECT_CC ? 2 : 0;
16046 SwapSelectOps =
false;
16047 NonConstantVal = FalseVal;
16049 SwapSelectOps =
true;
16050 NonConstantVal = TrueVal;
16056 FalseVal = DAG.
getNode(
N->getOpcode(),
SDLoc(
N), VT, OtherOp, NonConstantVal);
16061 if (Slct.
getOpcode() == RISCVISD::SELECT_CC)
16104 EVT VT =
N->getValueType(0);
16119 if (!N0C->hasOneUse())
16121 int64_t C0 = N0C->getSExtValue();
16122 int64_t C1 = N1C->getSExtValue();
16124 if (C0 == -1 || C0 == 0 || C0 == 1 ||
isInt<12>(C1))
16131 }
else if ((C1 / C0 + 1) != 0 &&
isInt<12>(C1 / C0 + 1) &&
16135 }
else if ((C1 / C0 - 1) != 0 &&
isInt<12>(C1 / C0 - 1) &&
16163 EVT VT =
N->getValueType(0);
16194 unsigned OuterExtend =
16198 OuterExtend,
SDLoc(
N), VT,
16206 EVT VT =
N->getValueType(0);
16256 EVT VT =
N->getValueType(0);
16266 APInt ImmValMinus1 = N0C->getAPIntValue() - 1;
16276 if (!isIntEqualitySetCC(CCVal) || !SetCCOpVT.
isInteger())
16299 if (!Subtarget.hasStdExtZbb())
16302 EVT VT =
N->getValueType(0);
16304 if (VT != Subtarget.
getXLenVT() && VT != MVT::i32 && VT != MVT::i16)
16316 unsigned ShiftedAmount = 8 - ShAmtCLeft->getZExtValue();
16318 if (ShiftedAmount >= 8)
16322 SDValue RightShiftOperand = N1;
16324 if (ShiftedAmount != 0) {
16328 if (!ShAmtCRight || ShAmtCRight->getZExtValue() != ShiftedAmount)
16337 if (LeftShiftOperand != RightShiftOperand)
16341 Mask <<= ShiftedAmount;
16347 return DAG.
getNode(RISCVISD::ORC_B,
SDLoc(
N), VT, LeftShiftOperand);
16355 EVT VT =
N->getValueType(0);
16387 bool IsAnd =
N->getOpcode() ==
ISD::AND;
16411 EVT VT =
N->getValueType(0);
16435 EVT VT =
N->getValueType(0);
16462 if (CondLHS != True)
16469 if (!CondRHSC || CondRHSC->
getAPIntValue() != (1ULL << ScalarBits))
16481 if (!FalseRHSC || !FalseRHSC->
isZero())
16505 EVT VT =
N->getValueType(0);
16510 if (VecVT != MVT::v4i16 && VecVT != MVT::v2i16 && VecVT != MVT::v8i8 &&
16511 VecVT != MVT::v4i8 && VecVT != MVT::v2i32)
16530 unsigned ShAmtVal =
C->getZExtValue();
16534 bool IsRounding =
false;
16535 if (
Op.getOpcode() ==
ISD::ADD && (EltBits == 16 || EltBits == 32)) {
16540 uint64_t ExpectedRnd = 1ULL << (EltBits - 1);
16541 if (RndC->getZExtValue() == ExpectedRnd &&
16543 Op =
Op.getOperand(0);
16558 if (!(LHSIsSExt || LHSIsZExt) || !(RHSIsSExt || RHSIsZExt))
16564 if (
A.getValueType() != VT ||
B.getValueType() != VT)
16568 switch (
Op.getOpcode()) {
16575 if (LHSIsSExt && RHSIsSExt)
16576 Opc = RISCVISD::PASUB;
16577 else if (LHSIsZExt && RHSIsZExt)
16578 Opc = RISCVISD::PASUBU;
16584 if (ShAmtVal != EltBits || (EltBits != 16 && EltBits != 32))
16587 if (LHSIsSExt && RHSIsSExt) {
16588 Opc = RISCVISD::PMULHR;
16589 }
else if (LHSIsZExt && RHSIsZExt) {
16590 Opc = RISCVISD::PMULHRU;
16591 }
else if ((LHSIsSExt && RHSIsZExt) || (LHSIsZExt && RHSIsSExt)) {
16592 Opc = RISCVISD::PMULHRSU;
16594 if (LHSIsZExt && RHSIsSExt)
16600 if ((LHSIsSExt && RHSIsZExt) || (LHSIsZExt && RHSIsSExt)) {
16601 Opc = RISCVISD::PMULHSU;
16603 if (LHSIsZExt && RHSIsSExt)
16617 EVT VT =
N->getValueType(0);
16627 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() && VT == MVT::i1 &&
16670 EVT VT =
N->getValueType(0);
16689 EVT WideVT =
X.getValueType();
16716 auto IsEqualCompZero = [](
SDValue &V) ->
bool {
16725 if (!IsEqualCompZero(N0) || !N0.
hasOneUse())
16727 if (!IsEqualCompZero(N0) || !N0.
hasOneUse())
16734 unsigned CzeroOpcode =
16736 ? RISCVISD::CZERO_EQZ
16737 : RISCVISD::CZERO_NEZ;
16739 EVT VT =
N->getValueType(0);
16766 if (Mask != ExpectedMask)
16783 EVT VT =
N->getValueType(0);
16789 APInt MaskVal, ShiftVal;
16804 APInt InnerMask = MaskVal.
lshr(ShiftAmt);
16805 bool IsNarrowable =
16806 InnerMask == 0xff || InnerMask == 0xffff || InnerMask == 0xffffffff;
16834 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
16876 if (N0.
getOpcode() != RISCVISD::CZERO_EQZ ||
16877 N1.
getOpcode() != RISCVISD::CZERO_NEZ ||
16895 EVT VT =
N->getValueType(0);
16913 if (!Subtarget.hasVendorXqcibm())
16925 if (
N->getValueType(0) != MVT::i32)
16927 unsigned Width, ShAmt;
16944 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
16949 if (!Subtarget.hasVendorXqcibm())
16959 unsigned ShAmt, Width;
16963 if (
N->getValueType(0) != MVT::i32)
16968 if (Width == 1 && Subtarget.hasStdExtZbs())
16980 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
16988 if (!Subtarget.hasVendorXqcibm())
16994 APInt MaskImm, OrImm;
17013 unsigned ShAmt, Width;
17026 return DAG.
getNode(RISCVISD::QC_INSB,
DL, MVT::i32,
Ops);
17068 if (Subtarget.
is64Bit() && Subtarget.hasStdExtZbs() &&
17083 if (N0.
getOpcode() == RISCVISD::SLLW &&
17087 return DAG.
getNode(RISCVISD::ROLW,
DL, MVT::i64,
17098 const APInt &Imm = ConstN00->getAPIntValue();
17099 if ((Imm + 1).isSignedIntN(12))
17123 EVT VT =
N->getValueType(0);
17132 bool IsAdd = (
E & 3) == 1;
17133 E -= IsAdd ? 1 : -1;
17137 Result = DAG.
getNode(AddSubOp,
DL, VT, Result, ShiftVal);
17147 uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
17152 auto PreferSub = [
X, MulAmtLowBit]() {
17161 if (
isPowerOf2_64(MulAmt - MulAmtLowBit) && !(CanSub && PreferSub())) {
17163 ShiftAmt1 = MulAmt - MulAmtLowBit;
17164 }
else if (CanSub) {
17166 ShiftAmt1 = MulAmt + MulAmtLowBit;
17170 EVT VT =
N->getValueType(0);
17180 unsigned ShY,
bool AddX,
unsigned Shift) {
17182 EVT VT =
N->getValueType(0);
17197 ShlAdd = DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT, ShlAdd,
17207 uint64_t MulAmt,
unsigned Shift) {
17233 assert(ShX != 0 &&
"MulAmt=4,6,10 handled before");
17240 EVT VT =
N->getValueType(0);
17257 EVT VT =
N->getValueType(0);
17266 bool ShouldExpandMul =
17268 !Subtarget.hasStdExtZmmul();
17269 if (!ShouldExpandMul)
17299 if (Shift >= 1 && Shift <= 3 &&
isPowerOf2_64(MulAmt & (MulAmt - 1))) {
17304 return DAG.
getNode(RISCVISD::SHL_ADD,
DL, VT,
X,
17311 if (MulAmt > 2 &&
isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
17313 if (ScaleShift >= 1 && ScaleShift < 4) {
17345 if (!Subtarget.hasStdExtZmmul())
17355 EVT VT =
N->getValueType(0);
17362 if (
N->getOperand(0).getOpcode() !=
ISD::AND ||
17363 N->getOperand(0).getOperand(0).getOpcode() !=
ISD::SRL)
17376 if (!V1.
isMask(HalfSize) || V2 != (1ULL | 1ULL << HalfSize) ||
17377 V3 != (HalfSize - 1))
17393 EVT VT =
N->getValueType(0);
17401 unsigned AddSubOpc;
17407 auto IsAddSubWith1 = [&](
SDValue V) ->
bool {
17408 AddSubOpc = V->getOpcode();
17420 if (IsAddSubWith1(N0)) {
17422 return DAG.
getNode(AddSubOpc,
DL, VT, N1, MulVal);
17425 if (IsAddSubWith1(N1)) {
17427 return DAG.
getNode(AddSubOpc,
DL, VT, N0, MulVal);
17442 if (isIndexTypeSigned(IndexType))
17445 if (!
N->hasOneUse())
17448 EVT VT =
N.getValueType();
17487 EVT SrcVT = Src.getValueType();
17491 NewElen = std::max(NewElen, 8U);
17518 EVT OpVT =
X.getValueType();
17526 if (OpSize <= Subtarget.
getXLen() ||
17532 auto IsVectorBitCastCheap = [](
SDValue X) {
17537 if (!IsVectorBitCastCheap(
X) || !IsVectorBitCastCheap(
Y))
17541 Attribute::NoImplicitFloat))
17548 unsigned VecSize = OpSize / 8;
17560 DAG.
getNode(ISD::VP_REDUCE_OR,
DL, XLenVT,
17573 EVT VT =
N->getValueType(0);
17578 if (!isIntEqualitySetCC(
Cond))
17603 if (OpVT == MVT::i64 &&
isUInt<32>(AndRHSInt) &&
17607 if (NewC >= -2048 && NewC <= 2048) {
17613 return DAG.
getSetCC(dl, VT, Shift,
17623 if (OpVT != MVT::i64 || !Subtarget.
is64Bit())
17643 const APInt &C1 = N1C->getAPIntValue();
17661 EVT VT =
N->getValueType(0);
17663 unsigned Opc = Src.getOpcode();
17668 if (
Opc == RISCVISD::FMV_X_ANYEXTH && SrcVT.
bitsGE(MVT::i16) &&
17669 Subtarget.hasStdExtZfhmin())
17670 return DAG.
getNode(RISCVISD::FMV_X_SIGNEXTH,
DL, VT, Src.getOperand(0));
17676 return DAG.
getNode(RISCVISD::SLLW,
DL, VT, Src.getOperand(0),
17677 Src.getOperand(1));
17696struct CombineResult;
17698enum ExtKind : uint8_t {
17730struct NodeExtensionHelper {
17739 bool SupportsFPExt;
17741 bool SupportsBF16Ext;
17744 bool EnforceOneUse;
17754 case RISCVISD::VSEXT_VL:
17755 case RISCVISD::VZEXT_VL:
17756 case RISCVISD::FP_EXTEND_VL:
17759 return OrigOperand;
17765 return OrigOperand.
getOpcode() == RISCVISD::VMV_V_X_VL ||
17770 unsigned getExtOpc(ExtKind SupportsExt)
const {
17771 switch (SupportsExt) {
17772 case ExtKind::SExt:
17773 return RISCVISD::VSEXT_VL;
17774 case ExtKind::ZExt:
17775 return RISCVISD::VZEXT_VL;
17776 case ExtKind::FPExt:
17777 case ExtKind::BF16Ext:
17778 return RISCVISD::FP_EXTEND_VL;
17786 SDValue getOrCreateExtendedOp(SDNode *Root, SelectionDAG &DAG,
17787 const RISCVSubtarget &Subtarget,
17788 std::optional<ExtKind> SupportsExt)
const {
17789 if (!SupportsExt.has_value())
17790 return OrigOperand;
17792 MVT NarrowVT = getNarrowType(Root, *SupportsExt);
17796 if (
Source.getValueType() == NarrowVT)
17799 unsigned ExtOpc = getExtOpc(*SupportsExt);
17802 SDLoc
DL(OrigOperand);
17803 auto [
Mask, VL] = getMaskAndVL(Root, DAG, Subtarget);
17807 case RISCVISD::VSEXT_VL:
17808 case RISCVISD::VZEXT_VL:
17809 case RISCVISD::FP_EXTEND_VL:
17810 return DAG.
getNode(ExtOpc,
DL, NarrowVT, Source, Mask, VL);
17813 case RISCVISD::VMV_V_X_VL:
17814 return DAG.
getNode(RISCVISD::VMV_V_X_VL,
DL, NarrowVT,
17816 case RISCVISD::VFMV_V_F_VL:
17821 return DAG.
getNode(RISCVISD::VFMV_V_F_VL,
DL, NarrowVT,
17822 DAG.
getUNDEF(NarrowVT), Source, VL);
17835 static MVT getNarrowType(
const SDNode *Root, ExtKind SupportsExt) {
17841 MVT EltVT = SupportsExt == ExtKind::BF16Ext ? MVT::bf16
17842 : SupportsExt == ExtKind::FPExt
17844 : MVT::getIntegerVT(NarrowSize);
17846 assert((
int)NarrowSize >= (SupportsExt == ExtKind::FPExt ? 16 : 8) &&
17847 "Trying to extend something we can't represent");
17854 static unsigned getSExtOpcode(
unsigned Opcode) {
17857 case RISCVISD::ADD_VL:
17858 case RISCVISD::VWADD_W_VL:
17859 case RISCVISD::VWADDU_W_VL:
17861 case RISCVISD::OR_VL:
17862 return RISCVISD::VWADD_VL;
17864 case RISCVISD::SUB_VL:
17865 case RISCVISD::VWSUB_W_VL:
17866 case RISCVISD::VWSUBU_W_VL:
17867 return RISCVISD::VWSUB_VL;
17869 case RISCVISD::MUL_VL:
17870 return RISCVISD::VWMUL_VL;
17878 static unsigned getZExtOpcode(
unsigned Opcode) {
17881 case RISCVISD::ADD_VL:
17882 case RISCVISD::VWADD_W_VL:
17883 case RISCVISD::VWADDU_W_VL:
17885 case RISCVISD::OR_VL:
17886 return RISCVISD::VWADDU_VL;
17888 case RISCVISD::SUB_VL:
17889 case RISCVISD::VWSUB_W_VL:
17890 case RISCVISD::VWSUBU_W_VL:
17891 return RISCVISD::VWSUBU_VL;
17893 case RISCVISD::MUL_VL:
17894 return RISCVISD::VWMULU_VL;
17896 case RISCVISD::SHL_VL:
17897 return RISCVISD::VWSLL_VL;
17905 static unsigned getFPExtOpcode(
unsigned Opcode) {
17907 case RISCVISD::FADD_VL:
17908 case RISCVISD::VFWADD_W_VL:
17909 return RISCVISD::VFWADD_VL;
17910 case RISCVISD::FSUB_VL:
17911 case RISCVISD::VFWSUB_W_VL:
17912 return RISCVISD::VFWSUB_VL;
17913 case RISCVISD::FMUL_VL:
17914 return RISCVISD::VFWMUL_VL;
17915 case RISCVISD::VFMADD_VL:
17916 return RISCVISD::VFWMADD_VL;
17917 case RISCVISD::VFMSUB_VL:
17918 return RISCVISD::VFWMSUB_VL;
17919 case RISCVISD::VFNMADD_VL:
17920 return RISCVISD::VFWNMADD_VL;
17921 case RISCVISD::VFNMSUB_VL:
17922 return RISCVISD::VFWNMSUB_VL;
17930 static unsigned getSUOpcode(
unsigned Opcode) {
17932 "SU is only supported for MUL");
17933 return RISCVISD::VWMULSU_VL;
17938 static unsigned getWOpcode(
unsigned Opcode, ExtKind SupportsExt) {
17941 case RISCVISD::ADD_VL:
17943 case RISCVISD::OR_VL:
17944 return SupportsExt == ExtKind::SExt ? RISCVISD::VWADD_W_VL
17945 : RISCVISD::VWADDU_W_VL;
17947 case RISCVISD::SUB_VL:
17948 return SupportsExt == ExtKind::SExt ? RISCVISD::VWSUB_W_VL
17949 : RISCVISD::VWSUBU_W_VL;
17950 case RISCVISD::FADD_VL:
17951 return RISCVISD::VFWADD_W_VL;
17952 case RISCVISD::FSUB_VL:
17953 return RISCVISD::VFWSUB_W_VL;
17959 using CombineToTry = std::function<std::optional<CombineResult>(
17960 SDNode * ,
const NodeExtensionHelper & ,
17961 const NodeExtensionHelper & , SelectionDAG &,
17962 const RISCVSubtarget &)>;
17965 bool needToPromoteOtherUsers()
const {
return EnforceOneUse; }
17967 void fillUpExtensionSupportForSplat(SDNode *Root, SelectionDAG &DAG,
17968 const RISCVSubtarget &Subtarget) {
17973 "Unexpected Opcode");
17986 unsigned ScalarBits =
Op.getValueSizeInBits();
17988 if (ScalarBits < EltBits) {
17990 assert(
Opc == RISCVISD::VMV_V_X_VL && EltBits == 64 && ScalarBits == 32 &&
17991 !Subtarget.
is64Bit() &&
"Unexpected splat");
17993 SupportsSExt =
true;
17997 SupportsZExt =
true;
17999 EnforceOneUse =
false;
18003 unsigned NarrowSize = EltBits / 2;
18006 if (NarrowSize < 8)
18010 SupportsSExt =
true;
18014 SupportsZExt =
true;
18016 EnforceOneUse =
false;
18019 bool isSupportedFPExtend(MVT NarrowEltVT,
const RISCVSubtarget &Subtarget) {
18020 return (NarrowEltVT == MVT::f32 ||
18024 bool isSupportedBF16Extend(MVT NarrowEltVT,
const RISCVSubtarget &Subtarget) {
18025 return NarrowEltVT == MVT::bf16 &&
18031 void fillUpExtensionSupport(SDNode *Root, SelectionDAG &DAG,
18032 const RISCVSubtarget &Subtarget) {
18033 SupportsZExt =
false;
18034 SupportsSExt =
false;
18035 SupportsFPExt =
false;
18036 SupportsBF16Ext =
false;
18037 EnforceOneUse =
true;
18059 case RISCVISD::VZEXT_VL:
18060 SupportsZExt =
true;
18062 case RISCVISD::VSEXT_VL:
18063 SupportsSExt =
true;
18065 case RISCVISD::FP_EXTEND_VL: {
18068 if (isSupportedFPExtend(NarrowEltVT, Subtarget))
18069 SupportsFPExt =
true;
18070 if (isSupportedBF16Extend(NarrowEltVT, Subtarget))
18071 SupportsBF16Ext =
true;
18076 case RISCVISD::VMV_V_X_VL:
18077 fillUpExtensionSupportForSplat(Root, DAG, Subtarget);
18079 case RISCVISD::VFMV_V_F_VL: {
18090 unsigned ScalarBits =
Op.getOperand(0).getValueSizeInBits();
18091 if (NarrowSize != ScalarBits)
18094 if (isSupportedFPExtend(
Op.getOperand(0).getSimpleValueType(), Subtarget))
18095 SupportsFPExt =
true;
18096 if (isSupportedBF16Extend(
Op.getOperand(0).getSimpleValueType(),
18098 SupportsBF16Ext =
true;
18107 static bool isSupportedRoot(
const SDNode *Root,
18108 const RISCVSubtarget &Subtarget) {
18120 case RISCVISD::ADD_VL:
18121 case RISCVISD::MUL_VL:
18122 case RISCVISD::VWADD_W_VL:
18123 case RISCVISD::VWADDU_W_VL:
18124 case RISCVISD::SUB_VL:
18125 case RISCVISD::VWSUB_W_VL:
18126 case RISCVISD::VWSUBU_W_VL:
18128 case RISCVISD::FADD_VL:
18129 case RISCVISD::FSUB_VL:
18130 case RISCVISD::FMUL_VL:
18131 case RISCVISD::VFWADD_W_VL:
18132 case RISCVISD::VFWSUB_W_VL:
18134 case RISCVISD::OR_VL:
18138 Subtarget.hasStdExtZvbb();
18139 case RISCVISD::SHL_VL:
18140 return Subtarget.hasStdExtZvbb();
18141 case RISCVISD::VFMADD_VL:
18142 case RISCVISD::VFNMSUB_VL:
18143 case RISCVISD::VFNMADD_VL:
18144 case RISCVISD::VFMSUB_VL:
18152 NodeExtensionHelper(SDNode *Root,
unsigned OperandIdx, SelectionDAG &DAG,
18153 const RISCVSubtarget &Subtarget) {
18154 assert(isSupportedRoot(Root, Subtarget) &&
18155 "Trying to build an helper with an "
18156 "unsupported root");
18157 assert(OperandIdx < 2 &&
"Requesting something else than LHS or RHS");
18167 case RISCVISD::VWADD_W_VL:
18168 case RISCVISD::VWADDU_W_VL:
18169 case RISCVISD::VWSUB_W_VL:
18170 case RISCVISD::VWSUBU_W_VL:
18171 case RISCVISD::VFWADD_W_VL:
18172 case RISCVISD::VFWSUB_W_VL:
18174 if (OperandIdx == 1)
18178 fillUpExtensionSupport(Root, DAG, Subtarget);
18184 static std::pair<SDValue, SDValue>
18185 getMaskAndVL(
const SDNode *Root, SelectionDAG &DAG,
18186 const RISCVSubtarget &Subtarget) {
18187 assert(isSupportedRoot(Root, Subtarget) &&
"Unexpected root");
18206 switch (
N->getOpcode()) {
18210 case RISCVISD::ADD_VL:
18211 case RISCVISD::MUL_VL:
18212 case RISCVISD::OR_VL:
18213 case RISCVISD::FADD_VL:
18214 case RISCVISD::FMUL_VL:
18215 case RISCVISD::VFMADD_VL:
18216 case RISCVISD::VFNMSUB_VL:
18217 case RISCVISD::VFNMADD_VL:
18218 case RISCVISD::VFMSUB_VL:
18220 case RISCVISD::VWADD_W_VL:
18221 case RISCVISD::VWADDU_W_VL:
18223 case RISCVISD::SUB_VL:
18224 case RISCVISD::VWSUB_W_VL:
18225 case RISCVISD::VWSUBU_W_VL:
18226 case RISCVISD::VFWADD_W_VL:
18227 case RISCVISD::FSUB_VL:
18228 case RISCVISD::VFWSUB_W_VL:
18230 case RISCVISD::SHL_VL:
18245 getSupportedFoldings(
const SDNode *Root,
const RISCVSubtarget &Subtarget);
18250struct CombineResult {
18252 unsigned TargetOpcode;
18254 std::optional<ExtKind> LHSExt;
18255 std::optional<ExtKind> RHSExt;
18259 NodeExtensionHelper
LHS;
18261 NodeExtensionHelper
RHS;
18263 CombineResult(
unsigned TargetOpcode, SDNode *Root,
18264 const NodeExtensionHelper &
LHS, std::optional<ExtKind> LHSExt,
18265 const NodeExtensionHelper &
RHS, std::optional<ExtKind> RHSExt)
18266 : TargetOpcode(TargetOpcode), LHSExt(LHSExt), RHSExt(RHSExt), Root(Root),
18272 SDValue materialize(SelectionDAG &DAG,
18273 const RISCVSubtarget &Subtarget)
const {
18275 std::tie(Mask, VL) =
18276 NodeExtensionHelper::getMaskAndVL(Root, DAG, Subtarget);
18290 LHS.getOrCreateExtendedOp(Root, DAG, Subtarget, LHSExt),
18291 RHS.getOrCreateExtendedOp(Root, DAG, Subtarget, RHSExt),
18292 Passthru, Mask, VL);
18306static std::optional<CombineResult>
18307canFoldToVWWithSameExtensionImpl(
SDNode *Root,
const NodeExtensionHelper &
LHS,
18308 const NodeExtensionHelper &
RHS,
18311 if ((AllowExtMask & ExtKind::ZExt) &&
LHS.SupportsZExt &&
RHS.SupportsZExt)
18312 return CombineResult(NodeExtensionHelper::getZExtOpcode(Root->
getOpcode()),
18313 Root,
LHS, {ExtKind::ZExt},
RHS,
18315 if ((AllowExtMask & ExtKind::SExt) &&
LHS.SupportsSExt &&
RHS.SupportsSExt)
18316 return CombineResult(NodeExtensionHelper::getSExtOpcode(Root->
getOpcode()),
18317 Root,
LHS, {ExtKind::SExt},
RHS,
18319 if ((AllowExtMask & ExtKind::FPExt) &&
LHS.SupportsFPExt &&
RHS.SupportsFPExt)
18320 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
18321 Root,
LHS, {ExtKind::FPExt},
RHS,
18323 if ((AllowExtMask & ExtKind::BF16Ext) &&
LHS.SupportsBF16Ext &&
18324 RHS.SupportsBF16Ext)
18325 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
18326 Root,
LHS, {ExtKind::BF16Ext},
RHS,
18327 {ExtKind::BF16Ext});
18328 return std::nullopt;
18337static std::optional<CombineResult>
18338canFoldToVWWithSameExtension(
SDNode *Root,
const NodeExtensionHelper &
LHS,
18341 return canFoldToVWWithSameExtensionImpl(
18342 Root,
LHS,
RHS, ExtKind::ZExt | ExtKind::SExt | ExtKind::FPExt, DAG,
18350static std::optional<CombineResult>
18351canFoldToVWWithSameExtZEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
18354 return canFoldToVWWithSameExtensionImpl(Root,
LHS,
RHS, ExtKind::ZExt, DAG,
18362static std::optional<CombineResult>
18363canFoldToVWWithSameExtBF16(
SDNode *Root,
const NodeExtensionHelper &
LHS,
18366 return canFoldToVWWithSameExtensionImpl(Root,
LHS,
RHS, ExtKind::BF16Ext, DAG,
18374static std::optional<CombineResult>
18375canFoldToVW_W(
SDNode *Root,
const NodeExtensionHelper &
LHS,
18378 if (
RHS.SupportsFPExt)
18379 return CombineResult(
18380 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::FPExt),
18381 Root,
LHS, std::nullopt,
RHS, {ExtKind::FPExt});
18388 return CombineResult(
18389 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::ZExt), Root,
18390 LHS, std::nullopt,
RHS, {ExtKind::ZExt});
18392 return CombineResult(
18393 NodeExtensionHelper::getWOpcode(Root->
getOpcode(), ExtKind::SExt), Root,
18394 LHS, std::nullopt,
RHS, {ExtKind::SExt});
18395 return std::nullopt;
18402static std::optional<CombineResult>
18403canFoldToVWWithSEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
18406 if (
LHS.SupportsSExt)
18407 return CombineResult(NodeExtensionHelper::getSExtOpcode(Root->
getOpcode()),
18408 Root,
LHS, {ExtKind::SExt},
RHS,
18410 return std::nullopt;
18417static std::optional<CombineResult>
18418canFoldToVWWithZEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
18421 if (
LHS.SupportsZExt)
18422 return CombineResult(NodeExtensionHelper::getZExtOpcode(Root->
getOpcode()),
18423 Root,
LHS, {ExtKind::ZExt},
RHS,
18425 return std::nullopt;
18432static std::optional<CombineResult>
18433canFoldToVWWithFPEXT(
SDNode *Root,
const NodeExtensionHelper &
LHS,
18436 if (
LHS.SupportsFPExt)
18437 return CombineResult(NodeExtensionHelper::getFPExtOpcode(Root->
getOpcode()),
18438 Root,
LHS, {ExtKind::FPExt},
RHS,
18440 return std::nullopt;
18447static std::optional<CombineResult>
18448canFoldToVW_SU(
SDNode *Root,
const NodeExtensionHelper &
LHS,
18452 if (!
LHS.SupportsSExt || !
RHS.SupportsZExt)
18453 return std::nullopt;
18454 return CombineResult(NodeExtensionHelper::getSUOpcode(Root->
getOpcode()),
18455 Root,
LHS, {ExtKind::SExt},
RHS,
18460NodeExtensionHelper::getSupportedFoldings(
const SDNode *Root,
18467 case RISCVISD::ADD_VL:
18468 case RISCVISD::SUB_VL:
18469 case RISCVISD::OR_VL:
18470 case RISCVISD::FADD_VL:
18471 case RISCVISD::FSUB_VL:
18473 Strategies.
push_back(canFoldToVWWithSameExtension);
18477 case RISCVISD::FMUL_VL:
18478 case RISCVISD::VFMADD_VL:
18479 case RISCVISD::VFMSUB_VL:
18480 case RISCVISD::VFNMADD_VL:
18481 case RISCVISD::VFNMSUB_VL:
18482 Strategies.
push_back(canFoldToVWWithSameExtension);
18483 if (Subtarget.hasStdExtZvfbfa() && Root->
getOpcode() != RISCVISD::FMUL_VL)
18486 Strategies.
push_back(canFoldToVWWithSameExtBF16);
18487 else if (Subtarget.hasStdExtZvfbfwma() &&
18488 Root->
getOpcode() == RISCVISD::VFMADD_VL)
18489 Strategies.
push_back(canFoldToVWWithSameExtBF16);
18492 case RISCVISD::MUL_VL:
18494 Strategies.
push_back(canFoldToVWWithSameExtension);
18499 case RISCVISD::SHL_VL:
18501 Strategies.
push_back(canFoldToVWWithSameExtZEXT);
18503 case RISCVISD::VWADD_W_VL:
18504 case RISCVISD::VWSUB_W_VL:
18506 Strategies.
push_back(canFoldToVWWithSEXT);
18508 case RISCVISD::VWADDU_W_VL:
18509 case RISCVISD::VWSUBU_W_VL:
18511 Strategies.
push_back(canFoldToVWWithZEXT);
18513 case RISCVISD::VFWADD_W_VL:
18514 case RISCVISD::VFWSUB_W_VL:
18516 Strategies.
push_back(canFoldToVWWithFPEXT);
18527 assert(
N->getOpcode() == RISCVISD::ADD_VL);
18530 SDValue Passthru =
N->getOperand(2);
18564 if (!NodeExtensionHelper::isSupportedRoot(
N, Subtarget))
18571 Inserted.insert(
N);
18574 while (!Worklist.
empty()) {
18577 NodeExtensionHelper
LHS(Root, 0, DAG, Subtarget);
18578 NodeExtensionHelper
RHS(Root, 1, DAG, Subtarget);
18579 auto AppendUsersIfNeeded =
18580 [&Worklist, &Subtarget, &Inserted,
18581 &ExtensionsToRemove](
const NodeExtensionHelper &
Op) {
18582 if (
Op.needToPromoteOtherUsers()) {
18584 ExtensionsToRemove.
insert(
Op.OrigOperand.getNode());
18587 if (!NodeExtensionHelper::isSupportedRoot(TheUser, Subtarget))
18592 if (Inserted.insert(TheUser).second)
18605 NodeExtensionHelper::getSupportedFoldings(Root, Subtarget);
18607 assert(!FoldingStrategies.
empty() &&
"Nothing to be folded");
18608 bool Matched =
false;
18609 for (
int Attempt = 0;
18610 (Attempt != 1 + NodeExtensionHelper::isCommutative(Root)) && !Matched;
18613 for (NodeExtensionHelper::CombineToTry FoldingStrategy :
18614 FoldingStrategies) {
18615 std::optional<CombineResult> Res =
18616 FoldingStrategy(Root,
LHS,
RHS, DAG, Subtarget);
18620 if (!Res->LHSExt.has_value() &&
18621 ExtensionsToRemove.
contains(
LHS.OrigOperand.getNode()))
18623 if (!Res->RHSExt.has_value() &&
18624 ExtensionsToRemove.
contains(
RHS.OrigOperand.getNode()))
18632 if (Res->LHSExt.has_value())
18633 if (!AppendUsersIfNeeded(
LHS))
18635 if (Res->RHSExt.has_value())
18636 if (!AppendUsersIfNeeded(
RHS))
18648 SDValue InputRootReplacement;
18655 for (CombineResult Res : CombinesToApply) {
18656 SDValue NewValue = Res.materialize(DAG, Subtarget);
18657 if (!InputRootReplacement) {
18659 "First element is expected to be the current node");
18660 InputRootReplacement = NewValue;
18665 for (std::pair<SDValue, SDValue> OldNewValues : ValuesToReplace) {
18666 DCI.
CombineTo(OldNewValues.first.getNode(), OldNewValues.second);
18668 return InputRootReplacement;
18675 unsigned Opc =
N->getOpcode();
18676 assert(
Opc == RISCVISD::VWADD_W_VL ||
Opc == RISCVISD::VWADDU_W_VL ||
18677 Opc == RISCVISD::VWSUB_W_VL ||
Opc == RISCVISD::VWSUBU_W_VL);
18680 SDValue MergeOp =
N->getOperand(1);
18681 unsigned MergeOpc = MergeOp.
getOpcode();
18683 if (MergeOpc != RISCVISD::VMERGE_VL && MergeOpc !=
ISD::VSELECT)
18692 SDValue Passthru =
N->getOperand(2);
18698 if (Mask.getOpcode() != RISCVISD::VMSET_VL)
18706 Z = Z.getOperand(1);
18712 {Y, X, Y, MergeOp->getOperand(0), N->getOperand(4)},
18719 [[maybe_unused]]
unsigned Opc =
N->getOpcode();
18720 assert(
Opc == RISCVISD::VWADD_W_VL ||
Opc == RISCVISD::VWADDU_W_VL ||
18721 Opc == RISCVISD::VWSUB_W_VL ||
Opc == RISCVISD::VWSUBU_W_VL);
18748 EVT NewMemVT = (MemVT == MVT::i32) ? MVT::i64 : MVT::i128;
18756 if (MemVT == MVT::i32)
18757 Opcode = (Ext ==
ISD::ZEXTLOAD) ? RISCVISD::TH_LWUD : RISCVISD::TH_LWD;
18759 Opcode = RISCVISD::TH_LDD;
18762 Opcode,
SDLoc(LSNode1), DAG.
getVTList({XLenVT, XLenVT, MVT::Other}),
18763 {LSNode1->getChain(), BasePtr,
18764 DAG.getConstant(Imm, SDLoc(LSNode1), XLenVT)},
18775 unsigned Opcode = (MemVT == MVT::i32) ? RISCVISD::TH_SWD : RISCVISD::TH_SDD;
18779 {LSNode1->getChain(), LSNode1->getOperand(1), LSNode2->getOperand(1),
18780 BasePtr, DAG.getConstant(Imm, SDLoc(LSNode1), XLenVT)},
18797 if (!Subtarget.hasVendorXTHeadMemPair())
18809 auto ExtractBaseAndOffset = [](
SDValue Ptr) -> std::pair<SDValue, uint64_t> {
18812 return {Ptr->
getOperand(0), C1->getZExtValue()};
18816 auto [Base1, Offset1] = ExtractBaseAndOffset(LSNode1->
getOperand(OpNum));
18837 auto [Base2, Offset2] = ExtractBaseAndOffset(LSNode2->
getOperand(OpNum));
18840 if (Base1 != Base2)
18844 bool Valid =
false;
18845 if (MemVT == MVT::i32) {
18849 }
else if (MemVT == MVT::i64) {
18885 if (Src->isStrictFPOpcode())
18893 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
18903 EVT VT =
N->getValueType(0);
18906 MVT SrcVT = Src.getSimpleValueType();
18907 MVT SrcContainerVT = SrcVT;
18935 IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
18936 FpToInt = DAG.
getNode(
Opc,
DL, ContainerVT, XVal, Mask, VL);
18939 IsSigned ? RISCVISD::VFCVT_RM_X_F_VL : RISCVISD::VFCVT_RM_XU_F_VL;
18940 FpToInt = DAG.
getNode(
Opc,
DL, ContainerVT, XVal, Mask,
18953 if (VT != MVT::i32 && VT != XLenVT)
18958 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
18960 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
18983 EVT DstVT =
N->getValueType(0);
18984 if (DstVT != XLenVT)
18990 if (Src->isStrictFPOpcode())
18998 if (Src.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
19010 if (SatVT == DstVT)
19011 Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU;
19012 else if (DstVT == MVT::i64 && SatVT == MVT::i32)
19013 Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
19018 Src = Src.getOperand(0);
19026 if (
Opc == RISCVISD::FCVT_WU_RV64)
19039 assert(Subtarget.hasStdExtZbkb() &&
"Unexpected extension");
19045 EVT VT =
N->getValueType(0);
19051 return DAG.
getNode(RISCVISD::BREV8,
DL, VT, Src.getOperand(0));
19064 EVT LoadVT = VPLoad->getValueType(0);
19068 N->getOperand(2) != VPLoad->getVectorLength() ||
19069 !
N->getOperand(0).hasOneUse())
19076 SDValue LoadMask = VPLoad->getMask();
19081 if (LoadMask.
getOpcode() != ISD::EXPERIMENTAL_VP_REVERSE ||
19083 LoadMask.
getOperand(2) != VPLoad->getVectorLength())
19091 SDValue NumElem = VPLoad->getVectorLength();
19092 uint64_t ElemWidthByte = VPLoad->getValueType(0).getScalarSizeInBits() / 8;
19104 PtrInfo, VPLoad->getMemOperand()->getFlags(),
19108 LoadVT,
DL, VPLoad->getChain(),
Base, Stride, LoadMask,
19109 VPLoad->getVectorLength(), MMO, VPLoad->isExpandingLoad());
19123 if (VPStore->getValue().getOpcode() != ISD::EXPERIMENTAL_VP_REVERSE)
19126 SDValue VPReverse = VPStore->getValue();
19132 VPStore->getVectorLength() != VPReverse.
getOperand(2) ||
19136 SDValue StoreMask = VPStore->getMask();
19141 if (StoreMask.
getOpcode() != ISD::EXPERIMENTAL_VP_REVERSE ||
19143 StoreMask.
getOperand(2) != VPStore->getVectorLength())
19151 SDValue NumElem = VPStore->getVectorLength();
19165 PtrInfo, VPStore->getMemOperand()->getFlags(),
19170 VPStore->getOffset(), Stride, StoreMask, VPStore->getVectorLength(),
19171 VPStore->getMemoryVT(), MMO, VPStore->getAddressingMode(),
19172 VPStore->isTruncatingStore(), VPStore->isCompressingStore());
19184 EVT VT =
N->getValueType(0);
19196 if (In.getOpcode() != ISD::VP_SRL || In.getOperand(2) != Mask ||
19197 In.getOperand(3) != VL)
19206 if (
LHS.getOpcode() != ISD::VP_ADD ||
LHS.getOperand(2) != Mask ||
19207 LHS.getOperand(3) != VL)
19214 if (V.getOpcode() != ISD::VP_ADD || V.getOperand(2) != Mask ||
19215 V.getOperand(3) != VL)
19218 Operands[0] =
Other;
19227 if (!FindAdd(LHS0, LHS1) && !FindAdd(LHS1, LHS0))
19234 if (
I == std::end(Operands))
19241 if (
Op.getOpcode() != ISD::VP_ZERO_EXTEND ||
Op.getOperand(1) != Mask ||
19242 Op.getOperand(2) != VL)
19252 Operands[0].getOperand(0), Mask, VL);
19254 Operands[1].getOperand(0), Mask, VL);
19258 return DAG.
getNode(RISCVISD::AVGCEILU_VL,
DL, VT,
19259 {NewOp0, NewOp1, DAG.
getUNDEF(VT), Mask, VL});
19271 case RISCVISD::VFMADD_VL: Opcode = RISCVISD::VFNMSUB_VL;
break;
19272 case RISCVISD::VFNMSUB_VL: Opcode = RISCVISD::VFMADD_VL;
break;
19273 case RISCVISD::VFNMADD_VL: Opcode = RISCVISD::VFMSUB_VL;
break;
19274 case RISCVISD::VFMSUB_VL: Opcode = RISCVISD::VFNMADD_VL;
break;
19275 case RISCVISD::STRICT_VFMADD_VL: Opcode = RISCVISD::STRICT_VFNMSUB_VL;
break;
19276 case RISCVISD::STRICT_VFNMSUB_VL: Opcode = RISCVISD::STRICT_VFMADD_VL;
break;
19277 case RISCVISD::STRICT_VFNMADD_VL: Opcode = RISCVISD::STRICT_VFMSUB_VL;
break;
19278 case RISCVISD::STRICT_VFMSUB_VL: Opcode = RISCVISD::STRICT_VFNMADD_VL;
break;
19288 case RISCVISD::VFMADD_VL: Opcode = RISCVISD::VFMSUB_VL;
break;
19289 case RISCVISD::VFMSUB_VL: Opcode = RISCVISD::VFMADD_VL;
break;
19290 case RISCVISD::VFNMADD_VL: Opcode = RISCVISD::VFNMSUB_VL;
break;
19291 case RISCVISD::VFNMSUB_VL: Opcode = RISCVISD::VFNMADD_VL;
break;
19292 case RISCVISD::STRICT_VFMADD_VL: Opcode = RISCVISD::STRICT_VFMSUB_VL;
break;
19293 case RISCVISD::STRICT_VFMSUB_VL: Opcode = RISCVISD::STRICT_VFMADD_VL;
break;
19294 case RISCVISD::STRICT_VFNMADD_VL: Opcode = RISCVISD::STRICT_VFNMSUB_VL;
break;
19295 case RISCVISD::STRICT_VFNMSUB_VL: Opcode = RISCVISD::STRICT_VFNMADD_VL;
break;
19308 unsigned Offset = IsStrict ? 1 : 0;
19315 auto invertIfNegative = [&Mask, &VL](
SDValue &V) {
19316 if (V.getOpcode() == RISCVISD::FNEG_VL && V.getOperand(1) == Mask &&
19317 V.getOperand(2) == VL) {
19319 V = V.getOperand(0);
19326 bool NegA = invertIfNegative(
A);
19327 bool NegB = invertIfNegative(
B);
19328 bool NegC = invertIfNegative(
C);
19331 if (!NegA && !NegB && !NegC)
19337 {N->getOperand(0), A, B, C, Mask, VL});
19361 EVT VT =
N->getValueType(0);
19368 uint64_t ShAmt =
N->getConstantOperandVal(1);
19381 if (LShAmt < ExtSize) {
19394 if (ShAmt > 32 || VT != MVT::i64)
19424 U->getConstantOperandVal(1) > 32)
19479 if (!
Cond.hasOneUse())
19498 EVT VT =
Cond.getValueType();
19543 LHS =
LHS.getOperand(0);
19553 LHS.getOperand(0).getValueType() == Subtarget.
getXLenVT()) {
19561 RHS =
LHS.getOperand(1);
19562 LHS =
LHS.getOperand(0);
19571 auto isXorImmediate = [](
const SDValue &
Op) ->
bool {
19573 return isInt<12>(XorCnst->getSExtValue());
19577 auto singleBitOp = [&DAG](
const SDValue &VarOp,
19578 const SDValue &ConstOp) ->
bool {
19581 return (XorCnst->getSExtValue() == 1) &&
19586 auto onlyUsedBySelectOrBR = [](
const SDValue &
Op) ->
bool {
19587 for (
const SDNode *UserNode :
Op->users()) {
19588 const unsigned Opcode = UserNode->getOpcode();
19589 if (Opcode != RISCVISD::SELECT_CC && Opcode != RISCVISD::BR_CC)
19594 auto isFoldableXorEq = [isXorImmediate, singleBitOp, onlyUsedBySelectOrBR](
19597 (!isXorImmediate(
LHS.getOperand(1)) ||
19598 singleBitOp(
LHS.getOperand(0),
LHS.getOperand(1)) ||
19599 onlyUsedBySelectOrBR(
LHS));
19602 if (isFoldableXorEq(
LHS,
RHS)) {
19603 RHS =
LHS.getOperand(1);
19604 LHS =
LHS.getOperand(0);
19630 if (Subtarget.hasVendorXAndesPerf()) {
19640 ShAmt =
LHS.getValueSizeInBits() - 1 - ShAmt;
19683 bool Commutative =
true;
19684 unsigned Opc = TrueVal.getOpcode();
19694 Commutative =
false;
19704 if (!TrueVal.hasOneUse())
19708 if (FalseVal == TrueVal.getOperand(0))
19710 else if (Commutative && FalseVal == TrueVal.getOperand(1))
19715 EVT VT =
N->getValueType(0);
19717 SDValue OtherOp = TrueVal.getOperand(1 - OpToFold);
19723 assert(IdentityOperand &&
"No identity operand!");
19728 DAG.
getSelect(
DL, OtherOpVT,
N->getOperand(0), OtherOp, IdentityOperand);
19729 return DAG.
getNode(TrueVal.getOpcode(),
DL, VT, FalseVal, NewSel);
19750 CountZeroes =
N->getOperand(2);
19751 ValOnZero =
N->getOperand(1);
19753 CountZeroes =
N->getOperand(1);
19754 ValOnZero =
N->getOperand(2);
19773 if (
Cond->getOperand(0) != CountZeroesArgument)
19792 CountZeroes, BitWidthMinusOne);
19802 EVT VT =
N->getValueType(0);
19803 EVT CondVT =
Cond.getValueType();
19811 (Subtarget.
hasCZEROLike() || Subtarget.hasVendorXTHeadCondMov())) {
19817 const APInt &MaskVal =
LHS.getConstantOperandAPInt(1);
19828 if (!TrueVal.hasOneUse() || !FalseVal.hasOneUse())
19832 if (TrueVal.getOpcode() ==
ISD::SUB && FalseVal.getOpcode() ==
ISD::ADD) {
19840 SDValue A = FalseVal.getOperand(0);
19841 SDValue B = FalseVal.getOperand(1);
19843 return ((TrueVal.getOperand(0) ==
A && TrueVal.getOperand(1) ==
B) ||
19844 (TrueVal.getOperand(1) ==
A && TrueVal.getOperand(0) ==
B));
19852 EVT VT =
N->getValueType(0);
19854 SDValue TrueVal =
N->getOperand(1);
19855 SDValue FalseVal =
N->getOperand(2);
19885 SDValue TrueVal =
N->getOperand(1);
19886 SDValue FalseVal =
N->getOperand(2);
19901 EVT VT =
N->getValueType(0);
19908 const unsigned Opcode =
N->op_begin()->getNode()->getOpcode();
19923 if (
Op.isUndef()) {
19936 if (
Op.getOpcode() != Opcode || !
Op.hasOneUse())
19945 if (
Op.getOperand(0).getValueType() !=
Op.getOperand(1).getValueType())
19969 EVT AVT =
A.getValueType();
19970 EVT BVT =
B.getValueType();
20000 if (AOpt || BOpt) {
20018 EVT OpVT =
A.getValueType();
20040 EVT OpVT =
A.getOperand(0).getValueType();
20042 OpVT !=
B.getOperand(0).getValueType() ||
20071 if (!Subtarget.hasStdExtZvqdotq())
20075 EVT VT =
N->getValueType(0);
20100 const unsigned InVecOpcode = InVec->
getOpcode();
20117 InVecLHS, InValLHS, EltNo);
20119 InVecRHS, InValRHS, EltNo);
20131 unsigned Elt = IndexC->getZExtValue();
20137 unsigned NewIdx = Elt % ConcatNumElts;
20139 unsigned ConcatOpIdx = Elt / ConcatNumElts;
20144 ConcatOps[ConcatOpIdx] = ConcatOp;
20156 EVT VT =
N->getValueType(0);
20168 !
SDValue(BaseLd, 0).hasOneUse())
20171 EVT BaseLdVT = BaseLd->getValueType(0);
20179 if (!Ld || !Ld->isSimple() || !
Op.hasOneUse() ||
20181 Ld->getValueType(0) != BaseLdVT)
20190 using PtrDiff = std::pair<std::variant<int64_t, SDValue>,
bool>;
20192 LoadSDNode *Ld2) -> std::optional<PtrDiff> {
20197 if (BIO1.equalBaseIndex(BIO2, DAG))
20202 SDValue P2 = Ld2->getBasePtr();
20205 if (P1.getOpcode() ==
ISD::ADD && P1.getOperand(0) == P2)
20206 return {{P1.getOperand(1),
true}};
20208 return std::nullopt;
20212 auto BaseDiff = GetPtrDiff(Lds[0], Lds[1]);
20217 for (
auto *It = Lds.
begin() + 1; It != Lds.
end() - 1; It++)
20218 if (GetPtrDiff(*It, *std::next(It)) != BaseDiff)
20226 unsigned WideScalarBitWidth =
20239 auto [StrideVariant, MustNegateStride] = *BaseDiff;
20241 std::holds_alternative<SDValue>(StrideVariant)
20242 ? std::get<SDValue>(StrideVariant)
20245 if (MustNegateStride)
20254 ConstStride && ConstStride->getSExtValue() >= 0)
20258 ConstStride->getSExtValue() * (
N->getNumOperands() - 1);
20264 BaseLd->getPointerInfo(), BaseLd->getMemOperand()->getFlags(), MemSize,
20268 WideVecVT,
DL, BaseLd->getChain(), BaseLd->getBasePtr(), Stride,
20282 EVT VT =
N->getValueType(0);
20299 for (
int MaskIndex : Mask) {
20300 bool SelectMaskVal = (MaskIndex < (int)NumElts);
20303 assert(MaskVals.
size() == NumElts &&
"Unexpected select-like shuffle");
20340 if (
N->getValueType(0).isFixedLengthVector())
20343 SDValue Addend =
N->getOperand(0);
20346 if (
N->getOpcode() == RISCVISD::ADD_VL) {
20347 SDValue AddPassthruOp =
N->getOperand(2);
20348 if (!AddPassthruOp.
isUndef())
20352 auto IsVWMulOpc = [](
unsigned Opc) {
20354 case RISCVISD::VWMUL_VL:
20355 case RISCVISD::VWMULU_VL:
20356 case RISCVISD::VWMULSU_VL:
20371 if (!MulPassthruOp.
isUndef())
20381 return std::make_pair(
N->getOperand(3),
N->getOperand(4));
20382 }(
N, DAG, Subtarget);
20387 if (AddMask != MulMask || AddVL != MulVL)
20390 const auto &TSInfo =
20392 unsigned Opc = TSInfo.getMAccOpcode(MulOp.
getOpcode());
20395 EVT VT =
N->getValueType(0);
20406 if (!
N->getValueType(0).isVector())
20409 SDValue Addend =
N->getOperand(0);
20412 if (
N->getOpcode() == RISCVISD::ADD_VL) {
20413 SDValue AddPassthruOp =
N->getOperand(2);
20414 if (!AddPassthruOp.
isUndef())
20418 auto IsVqdotqOpc = [](
unsigned Opc) {
20420 case RISCVISD::VQDOT_VL:
20421 case RISCVISD::VQDOTU_VL:
20422 case RISCVISD::VQDOTSU_VL:
20442 return std::make_pair(
N->getOperand(3),
N->getOperand(4));
20443 }(
N, DAG, Subtarget);
20446 if (AddVL != MulVL)
20449 if (AddMask.getOpcode() != RISCVISD::VMSET_VL ||
20450 AddMask.getOperand(0) != MulVL)
20455 EVT VT =
N->getValueType(0);
20456 Addend = DAG.
getNode(RISCVISD::ADD_VL,
DL, VT, Addend, AccumOp,
20457 DAG.
getUNDEF(VT), AddMask, AddVL);
20475 const EVT IndexVT = Index.getValueType();
20479 if (!isIndexTypeSigned(IndexType))
20511 assert(ShuffleMask.empty());
20513 for (
unsigned i = 0; i < Index->getNumOperands(); i++) {
20516 if (Index->getOperand(i)->isUndef())
20518 uint64_t C = Index->getConstantOperandVal(i);
20519 if (
C % ElementSize != 0)
20521 C =
C / ElementSize;
20524 ShuffleMask.push_back(
C);
20525 ActiveLanes.
set(
C);
20527 return ActiveLanes.
all();
20545 if (NumElems % 2 != 0)
20549 const unsigned WiderElementSize = ElementSize * 2;
20550 if (WiderElementSize > ST.getELen()/8)
20553 if (!ST.enableUnalignedVectorMem() && BaseAlign < WiderElementSize)
20556 for (
unsigned i = 0; i < Index->getNumOperands(); i++) {
20559 if (Index->getOperand(i)->isUndef())
20563 uint64_t C = Index->getConstantOperandVal(i);
20565 if (
C % WiderElementSize != 0)
20570 if (
C !=
Last + ElementSize)
20589 if (!IsVLMAX || Mask.getOpcode() != RISCVISD::VMSET_VL ||
20590 Mask.getOperand(0) != VL)
20593 auto IsTruncNode = [&](
SDValue V) {
20594 return V.getOpcode() == RISCVISD::TRUNCATE_VECTOR_VL &&
20595 V.getOperand(1) == Mask && V.getOperand(2) == VL;
20602 while (IsTruncNode(
Op)) {
20603 if (!
Op.hasOneUse())
20605 Op =
Op.getOperand(0);
20638 assert(
N->getOpcode() == RISCVISD::TRUNCATE_VECTOR_VL);
20640 MVT VT =
N->getSimpleValueType(0);
20645 auto MatchMinMax = [&VL, &Mask](
SDValue V,
unsigned Opc,
unsigned OpcVL,
20647 if (V.getOpcode() !=
Opc &&
20648 !(V.getOpcode() == OpcVL && V.getOperand(2).isUndef() &&
20649 V.getOperand(3) == Mask && V.getOperand(4) == VL))
20657 Op.getOperand(1).getValueType().isFixedLengthVector() &&
20659 Op.getOperand(1).getOperand(0).getValueType() ==
Op.getValueType() &&
20661 Op =
Op.getOperand(1).getOperand(0);
20664 return V.getOperand(0);
20666 if (
Op.getOpcode() == RISCVISD::VMV_V_X_VL &&
Op.getOperand(0).isUndef() &&
20667 Op.getOperand(2) == VL) {
20670 Op1->getAPIntValue().sextOrTrunc(
Op.getScalarValueSizeInBits());
20680 auto DetectUSatPattern = [&](
SDValue V) {
20692 MatchMinMax(SMinOp,
ISD::SMAX, RISCVISD::SMAX_VL, LoC))
20701 MatchMinMax(SMaxOp,
ISD::SMIN, RISCVISD::SMIN_VL, HiC))
20704 return DAG.
getNode(RISCVISD::SMAX_VL,
DL, V.getValueType(), SMinOp,
20705 V.getOperand(1), DAG.
getUNDEF(V.getValueType()),
20711 auto DetectSSatPattern = [&](
SDValue V) {
20713 unsigned NumSrcBits = V.getScalarValueSizeInBits();
20720 MatchMinMax(SMinOp,
ISD::SMAX, RISCVISD::SMAX_VL, LoC))
20721 if (HiC == SignedMax && LoC == SignedMin)
20726 MatchMinMax(SMaxOp,
ISD::SMIN, RISCVISD::SMIN_VL, HiC))
20727 if (HiC == SignedMax && LoC == SignedMin)
20736 while (Src.getOpcode() == RISCVISD::TRUNCATE_VECTOR_VL &&
20737 Src.getOperand(1) == Mask && Src.getOperand(2) == VL &&
20739 Src = Src.getOperand(0);
20743 if ((Val = DetectUSatPattern(Src)))
20744 ClipOpc = RISCVISD::TRUNCATE_VECTOR_VL_USAT;
20745 else if ((Val = DetectSSatPattern(Src)))
20746 ClipOpc = RISCVISD::TRUNCATE_VECTOR_VL_SSAT;
20755 Val = DAG.
getNode(ClipOpc,
DL, ValVT, Val, Mask, VL);
20756 }
while (ValVT != VT);
20774 unsigned Opc =
N->getOpcode();
20776 "Unexpected opcode");
20777 EVT VT =
N->getValueType(0);
20786 Src = Src.getOperand(0);
20790 Src = Src.getOperand(0);
20794 Src = Src.getOperand(0);
20797 EVT SrcEVT = Src.getValueType();
20819 VectorBitsMax, EltSize, MinSize);
20824 MVT ContainerVT = SrcMVT;
20852 if (!
LHS.hasOneUse())
20855 switch (
LHS.getOpcode()) {
20857 case RISCVISD::VSEXT_VL:
20858 Opcode = RISCVISD::VWMULSU_VL;
20861 case RISCVISD::VZEXT_VL:
20862 Opcode = RISCVISD::VWMULU_VL;
20873 else if (
RHS.getOpcode() == RISCVISD::VMV_V_X_VL &&
20875 ShAmtInt =
RHS.getConstantOperandVal(1);
20888 if (ShAmtInt >= NarrowBits)
20890 MVT VT =
N->getSimpleValueType(0);
20897 switch (
N->getOpcode()) {
20902 case RISCVISD::SHL_VL:
20903 Passthru =
N->getOperand(2);
20904 Mask =
N->getOperand(3);
20905 VL =
N->getOperand(4);
20910 return DAG.
getNode(Opcode,
DL, VT, NarrowOp,
20912 Passthru, Mask, VL);
20918 const MVT XLenVT = Subtarget.getXLenVT();
20924 auto SimplifyDemandedLowBitsHelper = [&](
unsigned OpNo,
unsigned LowBits) {
20935 switch (
N->getOpcode()) {
20938 case RISCVISD::SplitF64: {
20942 if (Op0->
getOpcode() == RISCVISD::BuildPairF64)
20955 APInt V =
C->getValueAPF().bitcastToAPInt();
20984 case RISCVISD::SLLW:
20985 case RISCVISD::SRAW:
20986 case RISCVISD::SRLW:
20987 case RISCVISD::RORW:
20988 case RISCVISD::ROLW: {
20990 if (SimplifyDemandedLowBitsHelper(0, 32) ||
20991 SimplifyDemandedLowBitsHelper(1, 5))
20996 case RISCVISD::ABSW:
20997 case RISCVISD::CLSW:
20998 case RISCVISD::CLZW:
20999 case RISCVISD::CTZW: {
21001 if (SimplifyDemandedLowBitsHelper(0, 32))
21005 case RISCVISD::FMV_W_X_RV64: {
21010 if (Op0.
getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64)
21014 case RISCVISD::FMV_X_ANYEXTH:
21015 case RISCVISD::FMV_X_ANYEXTW_RV64: {
21018 MVT VT =
N->getSimpleValueType(0);
21029 if ((
N->getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64 &&
21030 Op0->
getOpcode() == RISCVISD::FMV_W_X_RV64) ||
21031 (
N->getOpcode() == RISCVISD::FMV_X_ANYEXTH &&
21032 Op0->
getOpcode() == RISCVISD::FMV_H_X)) {
21034 "Unexpected value type!");
21044 LN0->getBasePtr(), IVT, LN0->getMemOperand());
21057 unsigned FPBits =
N->getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64 ? 32 : 16;
21068 EVT VT =
N->getValueType(0);
21117 EVT VT =
N->getValueType(0);
21135 if (!
C || !
C->getValueAPF().isExactlyValue(+1.0))
21167 EVT VT =
N->getValueType(0);
21181 if (
N->getValueType(0) == MVT::i64 && Subtarget.is64Bit()) {
21186 Src.getOperand(0));
21191 Src.getOperand(0), Src.getOperand(1));
21199 case RISCVISD::TRUNCATE_VECTOR_VL:
21203 case ISD::VP_TRUNCATE: